// bp.h - Spotify's Basic Pitch in C. Needs GCC or Clang. One model per thread. // // Audio: mono floats at BP_SAMPLE_RATE. Output: a row per frame, frames[row * BP_NOTES + key] // (key 0 is MIDI 21), the same for onsets, and optional contours (3 bins a semitone). // Errors are < 0: -1 no model, -2 bad plan, -3 out of memory. #ifndef BP_H #define BP_H #define BP_SAMPLE_RATE 22050 #define BP_HOP 256 // samples per frame #define BP_NOTES 88 #define BP_BINS 264 #define BP_WINDOW 43844 // samples per window #define BP_WINDOW_ROWS 142 // rows per bp_window typedef struct bp_model bp_model; // plan.bin and weights.bin, kept alive while the model is used. NULL if invalid. bp_model *bp_load(const int *plan, int plan_words, const float *weights); bp_model *bp_load_files(const char *plan_path, const char *weights_path); void bp_unload(bp_model *model); // A whole recording, bp_frame_count(samples) rows. Returns the rows. int bp_frame_count(int samples); int bp_transcribe(bp_model *model, const float *audio, int samples, float *frames, float *onsets, float *contours); // One window, rows index * BP_WINDOW_ROWS onwards, for sharing the work between threads. int bp_window_count(int samples); int bp_window(bp_model *model, const float *audio, int samples, int index, float *frames, float *onsets, float *contours); // One raw window of BP_WINDOW samples, all 172 rows. int bp_run(bp_model *model, const float *window, float *frames, float *onsets, float *contours); // basicpitch.spotify.com's settings, BP_SETTINGS has its defaults. typedef struct { double onset_threshold; // note segmentation double frame_threshold; // model confidence double min_note_ms; double min_frequency; // Hz, 0 for no limit double max_frequency; // Hz, 0 for no limit int boost_onsets; } bp_settings; #define BP_SETTINGS { 0.5, 0.3, 128, 0, 3000, 1 } typedef struct { int pitch; double start, duration, amplitude; } bp_note; // MIDI pitch, seconds, 0 to 1 // The notes (*notes malloc'ed). Returns their count. int bp_find_notes(const float *frames, const float *onsets, int rows, const bp_settings *settings, bp_note **notes); // A MIDI file (*bytes malloc'ed). The tempo only sets the beat grid. Returns its size. int bp_midi(const bp_note *notes, int count, double tempo, unsigned char **bytes); // All of it at once. settings NULL for the defaults. int bp_audio_to_midi(bp_model *model, const float *audio, int samples, const bp_settings *settings, double tempo, unsigned char **bytes); #endif