diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2013-05-03 21:08:42 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2013-05-03 21:08:42 +0400 |
commit | 1058def8e7827e56ce4a70afb4aeacb5dc44148f (patch) | |
tree | 4495d23e7b54ab5700e3839081e797c1eafe0db9 /lib/libOSSlib/play_event.c | |
download | oss4-upstream/4.2-build2006.tar.gz |
Imported Upstream version 4.2-build2006upstream/4.2-build2006upstream
Diffstat (limited to 'lib/libOSSlib/play_event.c')
-rw-r--r-- | lib/libOSSlib/play_event.c | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/lib/libOSSlib/play_event.c b/lib/libOSSlib/play_event.c new file mode 100644 index 0000000..62687ef --- /dev/null +++ b/lib/libOSSlib/play_event.c @@ -0,0 +1,273 @@ +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include "../../include/soundcard.h" +#include <sys/time.h> + +#undef DEBUG + +extern int __seqfd; + +static midi_packet_t midi_packet; + +static unsigned char *midibuf = &midi_packet.payload[0]; +static int mp = 0; + +oss_midi_time_t current_tick = 0; + +static int timer_started = 0; + +void +OSS_set_timebase (int tb) +{ +/* TODO? */ +} + +#if 1 +#define _write write +#else +static size_t +_write (int fildes, void *b, size_t nbyte) +{ + midi_packet_header_t *hdr = b; + unsigned char *buf; + int l = nbyte; + + + buf = (unsigned char *) b + sizeof (*hdr); + + if (hdr->magic == MIDI_HDR_MAGIC) /* Timed mode write */ + { + l -= sizeof (*hdr); + + switch (hdr->event_type) + { + case MIDI_EV_WRITE: + printf ("%9lu: MIDI_EV_WRITE: ", hdr->time); + break; + case MIDI_EV_TEMPO: + printf ("%9lu: MIDI_EV_TEMPO: ", hdr->time); + break; + case MIDI_EV_ECHO: + printf ("%9lu: MIDI_EV_ECHO: ", hdr->time); + break; + case MIDI_EV_START: + printf ("%9lu: MIDI_EV_START: ", hdr->time); + break; + case MIDI_EV_STOP: + printf ("%9lu: MIDI_EV_STOP: ", hdr->time); + break; + default: + printf ("%9lu: MIDI_EV_%d: ", hdr->time, hdr->event_type); + break; + } + + if (hdr->options & MIDI_OPT_TIMED) + printf ("TIMED "); + + if (l > 0) + { + int i; + + printf ("%d bytes (", l); + + for (i = 0; i < l; i++) + printf ("%02x ", buf[i]); + printf (")"); + } + + printf ("\n"); + } + + return write (fildes, b, nbyte); +} +#endif + +static void +start_timer (void) +{ +#ifndef DEBUG + midi_packet_header_t hdr; + + hdr.magic = MIDI_HDR_MAGIC; + hdr.event_type = MIDI_EV_START; + hdr.options = MIDI_OPT_NONE; + hdr.time = 0; + hdr.parm = 0; + if (_write (__seqfd, &hdr, sizeof (hdr)) != sizeof (hdr)) + { + perror ("Write start timer"); + exit (-1); + } + + timer_started = 1; + printf ("Timer started\n"); +#endif +} + +void +_dump_midi (void) +{ + if (mp > 0) + { + if (!timer_started) + start_timer (); + midi_packet.hdr.magic = MIDI_HDR_MAGIC; + midi_packet.hdr.options = MIDI_OPT_TIMED; + midi_packet.hdr.event_type = MIDI_EV_WRITE; + midi_packet.hdr.parm = 0; + midi_packet.hdr.time = current_tick; + +#ifdef DEBUG + if (write (1, &midi_packet.payload[0], mp) == -1) +#else + if (_write (__seqfd, &midi_packet, sizeof (midi_packet_header_t) + mp) + == -1) +#endif + { + perror ("MIDI write"); + exit (-1); + } + mp = 0; + } +} + +static void +oss_do_timing (unsigned char *ev) +{ + unsigned int parm = *(unsigned int *) &ev[4]; + midi_packet_header_t hdr; + + oss_midi_time_t tick; + + _dump_midi (); + + switch (ev[1]) + { + case TMR_TEMPO: +#ifndef DEBUG + if (!timer_started) + start_timer (); + hdr.magic = MIDI_HDR_MAGIC; + hdr.event_type = MIDI_EV_TEMPO; + hdr.options = MIDI_OPT_TIMED; + hdr.time = current_tick; + hdr.parm = parm; + if (_write (__seqfd, &hdr, sizeof (hdr)) != sizeof (hdr)) + { + perror ("Write tempo"); + exit (-1); + } +#endif + break; + + case TMR_WAIT_REL: + tick = current_tick + parm; + + current_tick = tick; + break; + + case TMR_WAIT_ABS: + tick = parm; + current_tick = tick; + break; + } + +} + +static void +out_midi3 (unsigned char a, unsigned char b, unsigned char c) +{ + if (mp > 950) + _dump_midi (); + midibuf[mp++] = a; + midibuf[mp++] = b; + midibuf[mp++] = c; +/* printf("Out %02x %02x %02x\n", a, b, c); */ +} + +static void +out_midi2 (unsigned char a, unsigned char b) +{ + if (mp > 950) + _dump_midi (); + midibuf[mp++] = a; + midibuf[mp++] = b; +/* printf("Out %02x %02x\n", a, b); */ +} + +void +play_event (unsigned char *ev) +{ + int i; + + switch (ev[0]) + { + case EV_TIMING: + oss_do_timing (ev); + return; + break; + + case EV_SEQ_LOCAL: + break; + + case EV_CHN_COMMON: + switch (ev[2]) + { + case MIDI_PGM_CHANGE: + /* printf("PGM change %02x %d\n", ev[2]|ev[3], ev[4]); */ + out_midi2 (ev[2] | ev[3], ev[4]); + break; + + case MIDI_CHN_PRESSURE: + out_midi2 (ev[2] | ev[3], ev[4]); + break; + + case MIDI_CTL_CHANGE: + out_midi3 (ev[2] | ev[3], ev[4], *(short *) &ev[6]); + break; + + default: + out_midi3 (ev[2] | ev[3], ev[4], *(short *) &ev[6]); + } + return; + break; + + case EV_CHN_VOICE: + out_midi3 (ev[2] | ev[3], ev[4], ev[5]); + return; + break; + + case EV_SYSEX: + { + int i, l; + l = 8; + for (i = 2; i < 8; i++) + if (ev[i] == 0xff) + { + l = i; + break; + } + if (mp > 950) + _dump_midi (); + for (i = 2; i < l; i++) + midibuf[mp++] = ev[i]; + } + return; + break; + + case EV_SYSTEM: + printf ("EV_SYSTEM: "); + break; + + default: + printf ("Unknown event %d: ", ev[0]); + + } + + for (i = 0; i < 8; i++) + printf ("%02x ", ev[i]); + printf ("\n"); +} |