view yeti/scratch/generateTemplatesC.yeti @ 372:af71cbdab621 tip

Update bqvec code
author Chris Cannam
date Tue, 19 Nov 2019 10:13:32 +0000
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 ();