--- include/fluidsynth/midi.h +++ include/fluidsynth/midi.h @@ -124,6 +124,7 @@ enum fluid_player_status FLUIDSYNTH_API fluid_player_t* new_fluid_player(fluid_synth_t* synth); FLUIDSYNTH_API int delete_fluid_player(fluid_player_t* player); FLUIDSYNTH_API int fluid_player_add(fluid_player_t* player, const char *midifile); +FLUIDSYNTH_API int fluid_player_add_mem(fluid_player_t* player, const void *buffer, size_t len); FLUIDSYNTH_API int fluid_player_play(fluid_player_t* player); FLUIDSYNTH_API int fluid_player_stop(fluid_player_t* player); FLUIDSYNTH_API int fluid_player_join(fluid_player_t* player); --- src/midi/fluid_midi.c +++ src/midi/fluid_midi.c @@ -1243,6 +1243,36 @@ fluid_player_add(fluid_player_t* player, return FLUID_OK; } +/** + * Add a MIDI file to a player queue, from a buffer in memory. + * @param player MIDI player instance + * @param buffer Pointer to memory containing the bytes of a complete MIDI + * file. The data is copied, so the caller may free or modify it immediately + * without affecting the playlist. + * @param len Length of the buffer, in bytes. + * @return #FLUID_OK or #FLUID_FAILED + */ +int +fluid_player_add_mem(fluid_player_t* player, const void *buffer, size_t len) +{ + /* Take a copy of the buffer, so the caller can free immediately. */ + fluid_playlist_item *pi = FLUID_MALLOC(sizeof(fluid_playlist_item)); + void *buf_copy = FLUID_MALLOC(len); + if (!pi || !buf_copy) { + FLUID_FREE(pi); + FLUID_FREE(buf_copy); + FLUID_LOG(FLUID_PANIC, "Out of memory"); + return FLUID_FAILED; + } + + FLUID_MEMCPY(buf_copy, buffer, len); + pi->filename = NULL; + pi->buffer = buf_copy; + pi->buffer_len = len; + player->playlist = fluid_list_append(player->playlist, pi); + return FLUID_OK; +} + /* * fluid_player_load */ --- src/midi/fluid_midi.h +++ src/midi/fluid_midi.h @@ -264,6 +264,18 @@ int fluid_track_send_events(fluid_track_ #define fluid_track_eot(track) ((track)->cur == NULL) +/** + * fluid_playlist_item + * Used as the `data' elements of the fluid_player.playlist. + * Represents either a filename or a pre-loaded memory buffer. + * Exactly one of `filename' and `buffer' is non-NULL. + */ +typedef struct +{ + char* filename; /** Name of file (owned); NULL if data pre-loaded */ + void* buffer; /** The MIDI file data (owned); NULL if filename */ + size_t buffer_len; /** Number of bytes in buffer; 0 if filename */ +} fluid_playlist_item; /* * fluid_player