view yeti/scratch/generateTemplatesC.yeti @ 167:416b555df3b2 finetune

More on returning fine tuning (but we're treating different shifts of the same pitch as different notes at the moment which is not right)
author Chris Cannam
date Tue, 20 May 2014 17:49:07 +0100
parents 6003a9af43af
children a175b693b3ae
line wrap: on
line source

program generateTemplatesC;

vec = load may.vector;

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

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 },
];

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 = length levels - length (find (>0) levels);
//    last = length (find (>0) (reverse levels)) - 1;
    first = hardcodedRanges[instrument].lowest;
    last = hardcodedRanges[instrument].highest;
    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 ();