Is Alsa Or Oss Sequencer (midi) Available?


Hitnrun

Member
Joined
Mar 1, 2008
Messages
427
Hello!

After searching all this forum for an anwser, and not finding it, let me ask:

Is Alsa or OSS (open sound system) /dev/sequencer available on gp2x? I compiled a sequecer library (tse3.sourceforge.net) with the gp2x toolchain, and it compiled with OSS support, found all header files, etc, but I've read somewhere that the gp2x does not support a sequencer interface.

Does it? Can I use applications using /dev/sequencer in gp2x?

Also, does gp2x have OSS and/or Alsa?

Thanks
 
Don't think there is a midi sequencer in the hardware, but the port of Doom makes use of some software sequencer if I remember right.
 
Daid said:
Don't think there is a midi sequencer in the hardware, but the port of Doom makes use of some software sequencer if I remember right.
Yes it uses Timidity, but this is able only to play a mid file, I have the midi data in memory from another application, and I would like to play it directly, so Timidity isn't an option on the gp2x...
 
Last edited by a moderator:
You could possibly use some kind of sound library such as AdPlug (an adlib emulator) or something along those lines to synthesize the sounds of the midi instruments, but you'd need to write some intermediate code in order to translate the midi data into data for the plugin.
 
Hitnrun said:
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;
}

}
 
Last edited by a moderator:
Micket said:
Hitnrun said:
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.


For my application, I use a sequencer library (tse3 - http://tse3.sourceforge.net), an it reads and stores the midi in its own memory format. I modified libtimidity to allow me to send the raw MIDI events (note on, note off, etc) without loading a song, it it looks like it will work. I created a function:

CODE

/* Play event on song
*/
extern void mid_song_event (MidSong *song, MidEvent *event);




this way I can pass a raw event, and it gets mixed inline.

It is working well on windows and linux, but no gp32 I get a very big delay (more than 3 seconds), still more debugging to do...
 
Last edited by a moderator:
Back
Top