view yeti/scratch/generateTemplatesC.yeti @ 325:4cf4313d7e30 livemode

Always use q=0.8 and accept the hit on speed -- the templates are made for that configuration and it does work better. Also some adjustments to thresholding and peak picking for live mode in particular.
author Chris Cannam
date Mon, 18 May 2015 13:58:27 +0100
parents a144217a9cfb
children
line wrap: on
line source

program generateTemplatesC;

vec = load may.vector;

instruments = [
    "bassoon",
    "cello",
    "clarinet",
    "flute",
    "guitar",
    "horn",
    "oboe",
    "tenorsax",
    "violin",
    "viola",
//    "piano-maps-SptkBGCl",
    "piano1",
    "piano2",
    "piano3",
    "pianorwc",
];

hardcodedRanges = [
    "bassoon": { lowest = 15, highest = 51 },
    "cello": { lowest = 15, highest = 60 },
    "clarinet": { lowest = 29, highest = 68 },
    "flute": { lowest = 39, highest = 72 },
    "guitar": { lowest = 19, highest = 55 },
    "horn": { lowest = 20, highest = 56 },
    "oboe": { lowest = 37, highest = 70 },
    "tenorsax": { lowest = 23, highest = 54 },
    "violin": { lowest = 34, highest = 72 },
//    "piano-maps-SptkBGCl": { lowest = 16, highest = 72 },
    "piano1": { lowest = 16, highest = 72 },
    "piano2": { lowest = 16, highest = 72 },
    "piano3": { lowest = 16, highest = 72 },
    "pianorwc": { lowest = 16, highest = 72 },
];

overallLowest = 15;
overallHighest = 72;

dataDir = "../../data";
includeDir = "\(dataDir)/include";

warning = "/* Do not edit: this file was automatically generated by generateTemplatesC */";

noteCount = 88;
templateHeight = 545;
shiftRange = 2;

convert instrument lines ostr =
   (notes = map do line:
                vec.fromList (map number (strSplit "," line))
            done lines;
    if (length notes) != noteCount then
        failWith "Wrong number of notes in instrument \(instrument): found (\(length notes), expected \(noteCount)";
    fi;
    for notes do n:
        if (vec.length n) != templateHeight then
            failWith "Wrong number of values in template while processing instrument \(instrument): found \(vec.length n), expected \(templateHeight)";
        fi
    done;
    levels = map vec.sum notes;
    first = 
        if instrument in hardcodedRanges then
            hardcodedRanges[instrument].lowest;
        else
            length levels - length (find (>0) levels);
        fi;
    last =
        if instrument in hardcodedRanges then
            hardcodedRanges[instrument].highest;
        else
            length (find (>0) (reverse levels)) - 1;
        fi;
    ostr.writeln warning;
    ostr.writeln "";
    ostr.writeln "{\n    \"\(instrument)\",\n    \(first),\n    \(last),";
    ostr.writeln "    {";
    for notes do note:
        ostr.write "        { ";
        for [0..shiftRange-1] do s:
            ostr.write "0.0, ";
        done;
        for (vec.list note) do v:
            ostr.write "\(v), ";
        done;
        for [0..shiftRange-1] do s:
            ostr.write "0.0, ";
        done;
        ostr.writeln "},";
    done;
    ostr.writeln "    }";
    ostr.writeln "},";
    ostr.close ()); 

writeMainHeader () =
   (ostr = openOutFile "\(includeDir)/templates.h" "UTF-8";
    for [
        warning,
        "",
        "#ifndef SILVET_DATA_TEMPLATES_H",
        "#define SILVET_DATA_TEMPLATES_H",
        "",
        "/* note: intended to parse as both C and C++ */",
        "",
        "#define SILVET_TEMPLATE_COUNT      \(length instruments)   /* Number of instruments */",
        "#define SILVET_TEMPLATE_NOTE_COUNT \(noteCount)   /* Number of notes per instrument */ ",
        "#define SILVET_TEMPLATE_HEIGHT     \(templateHeight)  /* Frequency bins per template */",
        "#define SILVET_TEMPLATE_MAX_SHIFT  \(shiftRange)    /* Zeros at either end of template */ ",
        "#define SILVET_TEMPLATE_SIZE       \(templateHeight + 2 * shiftRange)  /* Height + 2 * max shift space */ ",
        "",
        "typedef struct {",
        "    const char *name;",
        "    int lowest;",
        "    int highest;",
        "    float data[SILVET_TEMPLATE_NOTE_COUNT][SILVET_TEMPLATE_SIZE];",
        "} silvet_template_t;",
        "",
        "static int silvet_templates_lowest_note = \(overallLowest);",
        "static int silvet_templates_highest_note = \(overallHighest);",
        "",
        "static silvet_template_t silvet_templates[SILVET_TEMPLATE_COUNT] = {",
    ] ostr.writeln;
    for instruments do instrument:
        ostr.writeln "#include \"\(instrument).h\"";
    done;
    for [
        "};",
        "",
        "#endif",
    ] ostr.writeln;
    ostr.close ()); 

convertAll () = 
   (writeMainHeader ();
    for instruments do instrument:
        i = openInFile "\(dataDir)/\(instrument).csv" "UTF-8";
        o = openOutFile "\(includeDir)/\(instrument).h" "UTF-8";
        eprintln "converting instrument \"\(instrument)\"...";
        convert instrument (i.lines ()) o;
    done);

convertAll ();