I found a library that wraps Timidity
http://libtimidity.sourceforge.net/
I'm changing it for my needs and porting to GP2X, let's see what I can get out of it.
I use that for oldplay. (although i do load from file)
CODE
extern MidIStream *mid_istream_open_mem (void *mem, size_t size,
int autofree);
Looks like it can load from memory as well.
Here is the oldplay plugin, i'm sure you can convert it to your needs easily.
Oh, and do use: mid_init("/mnt/sd/timidity/timidity.cfg") as it's somewhat the standard path to find timidity on the GP2X.
CODE
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
extern "C" {
#include "timidity/timidity.h"
}
#include "../plugin.h"
#include "../util.h"
static struct sound_plugin plugin;
MidIStream *stream;
MidSongOptions options;
MidSong *song;
static int playing;
static string fieldname[5];
static string fielddata[5];
static int close();
static int init_file(char *fname)
{
playing = 0;
plugin.clockfreq = 150;
if (mid_init("timidity/timidity.cfg") < 0 &&
mid_init("/mnt/sd/timidity/timidity.cfg") < 0)
{
fprintf (stderr, "timidityplugin:init_file - Could not initialise libTiMidity.\n"
" Please install timidity patches in\n"
" oldplay directory.\n");
return -1;
}
if (!(stream = mid_istream_open_file(fname)))
{
fprintf(stderr, "timidityplugin:init_file - Could not open file %s\n", fname);
mid_exit();
return -1;
}
options.rate = plugin.freq;
options.format = MID_AUDIO_S16LSB;
options.channels = plugin.channels;
options.buffer_size = 2048; // Ugh.. i don't want to specify this here.
song = mid_song_load(stream, &options);
mid_istream_close (stream);
if (!song)
{
fprintf (stderr, "timidityplugin:init_file - Invalid MIDI file: %s\n",fname);
mid_exit ();
return 1;
}
mid_song_set_volume(song, 60);
mid_song_start(song);
int x = 0;
char *title = mid_song_get_meta(song, MID_SONG_TEXT);
char *copyr = mid_song_get_meta(song, MID_SONG_COPYRIGHT);
fieldname[x] = "File";
fielddata[x] = strrchr(fname,'/')+1;
x++;
if (title)
{
fieldname[x] = "Title";
fielddata[x] = title;
x++;
}
if (copyr)
{
fieldname[x] = "Copyright";
fielddata[x] = copyr;
x++;
}
if (x < 3)
{
fieldname[x] = "Channels";
fielddata[x] = "Stereo";
x++;
}
fieldname[x] = "Frequency";
fielddata[x] = "44.1 KHz";
x++;
fieldname[x] = "Format";
fielddata[x] = "MIDI";
x++;
plugin.nfields = x;
plugin.fieldname = fieldname;
plugin.fielddata = fielddata;
printf("7\n");
plugin.length = mid_song_get_total_time(song);
printf("8\n");
playing = 1;
return 0;
}
static int close()
{
if (song)
{
mid_song_free(song);
mid_exit();
song = NULL;
}
for(int i = 0; i < 5; i++)
{
fieldname
.clear();
fielddata.clear();
}
playing = plugin.length = plugin.nfields = 0;
return 0;
}
static int fill_buffer(signed short *dest, int len)
{
if(playing)
{
int writtenbytes = mid_song_read_wave(song, dest, len);
return writtenbytes;
}
return 0;
}
static int can_handle(const char *name)
{
return (is_ext(name, ".midi") || is_ext(name, ".mid"));
}
static int set_position(int msecs, int subtune)
{
if (playing)
{
int now = mid_song_get_time(song);
int skip = msecs;
int then = now + skip;
if (then < 0)
{
then = 0;
skip = -now;
}
mid_song_seek(song, then);
return skip;
}
}
extern "C" {
#ifndef INIT_SOUND_PLUGIN
#define INIT_SOUND_PLUGIN timidity_init_sound_plugin
#endif
struct sound_plugin *INIT_SOUND_PLUGIN()
{
memset(&plugin, 0, sizeof(plugin));
plugin.plugname = "Timidity";
//plugin.init_data = init_data;
plugin.init_file = init_file;
//plugin.request_format = NULL;
plugin.set_position = set_position;
plugin.fill_buffer = fill_buffer;
plugin.can_handle = can_handle;
plugin.close = close;
plugin.tune = 0;
plugin.subtunes = 1;
plugin.clockfreq = 100;
plugin.channels = 2;
plugin.freq = 44100;
plugin.replaygain = 1;
return &plugin;
}
}