From: Takashi Iwai Date: Mon, 10 Dec 2001 16:45:05 +0000 (+0000) Subject: Added time skew on queue. X-Git-Tag: android-x86-9.0-r1~2585 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=bcf50519e4a248c5361541f7c56890bcd5392fe5;p=android-x86%2Fexternal-alsa-lib.git Added time skew on queue. The timer speed can be controlled via skew value, smaller = slower centered on the skew-base value. --- diff --git a/include/seq.h b/include/seq.h index c0980c5a..02f9a55e 100644 --- a/include/seq.h +++ b/include/seq.h @@ -438,8 +438,12 @@ void snd_seq_queue_tempo_copy(snd_seq_queue_tempo_t *dst, const snd_seq_queue_te int snd_seq_queue_tempo_get_queue(const snd_seq_queue_tempo_t *info); unsigned int snd_seq_queue_tempo_get_tempo(const snd_seq_queue_tempo_t *info); int snd_seq_queue_tempo_get_ppq(const snd_seq_queue_tempo_t *info); +unsigned int snd_seq_queue_tempo_get_skew(const snd_seq_queue_tempo_t *info); +unsigned int snd_seq_queue_tempo_get_skew_base(const snd_seq_queue_tempo_t *info); void snd_seq_queue_tempo_set_tempo(snd_seq_queue_tempo_t *info, unsigned int tempo); void snd_seq_queue_tempo_set_ppq(snd_seq_queue_tempo_t *info, int ppq); +void snd_seq_queue_tempo_set_skew(snd_seq_queue_tempo_t *info, unsigned int skew); +void snd_seq_queue_tempo_set_skew_base(snd_seq_queue_tempo_t *info, unsigned int base); int snd_seq_get_queue_tempo(snd_seq_t *handle, int q, snd_seq_queue_tempo_t *tempo); int snd_seq_set_queue_tempo(snd_seq_t *handle, int q, snd_seq_queue_tempo_t *tempo); diff --git a/include/seq_event.h b/include/seq_event.h index abb21263..9c774a81 100644 --- a/include/seq_event.h +++ b/include/seq_event.h @@ -98,8 +98,8 @@ enum snd_seq_event_type { SND_SEQ_EVENT_CLOCK, /** MIDI Real Time Tick message; event data type = #snd_seq_ev_queue_control_t */ SND_SEQ_EVENT_TICK, - /** Sync signal; event data type = #snd_seq_ev_queue_control_t */ - SND_SEQ_EVENT_SYNC, + /** Queue timer skew; event data type = #snd_seq_ev_queue_control_t */ + SND_SEQ_EVENT_QUEUE_SKEW, /** Sync position changed; event data type = #snd_seq_ev_queue_control_t */ SND_SEQ_EVENT_SYNC_POS, @@ -403,6 +403,11 @@ typedef struct snd_seq_result { int result; /**< status */ } snd_seq_result_t; +/** Queue skew values */ +typedef struct snd_seq_queue_skew { + unsigned int value; + unsigned int base; +} snd_seq_queue_skew_t; /** queue timer control */ typedef struct snd_seq_ev_queue_control { @@ -412,6 +417,7 @@ typedef struct snd_seq_ev_queue_control { signed int value; /**< affected value (e.g. tempo) */ snd_seq_timestamp_t time; /**< time */ unsigned int position; /**< sync position */ + snd_seq_queue_skew_t skew; /**< queue skew */ unsigned int d32[2]; /**< any data */ unsigned char d8[8]; /**< any data */ } param; /**< data value union */ diff --git a/src/seq/seq.c b/src/seq/seq.c index 66e52b3a..26c5fede 100644 --- a/src/seq/seq.c +++ b/src/seq/seq.c @@ -2261,6 +2261,28 @@ int snd_seq_queue_tempo_get_ppq(const snd_seq_queue_tempo_t *info) } /** + * \brief Get the timer skew value of a queue_status container + * \param info queue_status container + * \return timer skew value + */ +unsigned int snd_seq_queue_tempo_get_skew(const snd_seq_queue_tempo_t *info) +{ + assert(info); + return info->skew_value; +} + +/** + * \brief Get the timer skew base value of a queue_status container + * \param info queue_status container + * \return timer skew base value + */ +unsigned int snd_seq_queue_tempo_get_skew_base(const snd_seq_queue_tempo_t *info) +{ + assert(info); + return info->skew_base; +} + +/** * \brief Set the tempo of a queue_status container * \param info queue_status container * \param tempo tempo value @@ -2282,6 +2304,30 @@ void snd_seq_queue_tempo_set_ppq(snd_seq_queue_tempo_t *info, int ppq) info->ppq = ppq; } +/** + * \brief Set the timer skew value of a queue_status container + * \param info queue_status container + * \param skew timer skew value + * + * The skew of timer is calculated as skew / base. + * For example, to play with double speed, pass base * 2 as the skew value. + */ +void snd_seq_queue_tempo_set_skew(snd_seq_queue_tempo_t *info, unsigned int skew) +{ + assert(info); + info->skew_value = skew; +} + +/** + * \brief Set the timer skew base value of a queue_status container + * \param info queue_status container + * \param base timer skew base value + */ +void snd_seq_queue_tempo_set_skew_base(snd_seq_queue_tempo_t *info, unsigned int base) +{ + assert(info); + info->skew_base = base; +} /** * \brief obtain the current tempo of the queue diff --git a/test/playmidi1.c b/test/playmidi1.c index be68e463..4f711ced 100644 --- a/test/playmidi1.c +++ b/test/playmidi1.c @@ -73,6 +73,8 @@ static int local_ticks = 0; static int local_tempo = 500000; static int dest_queue = -1; +static int shared_queue = 0; +static int tick_offset = 0; static int dest_client = DEST_CLIENT_NUMBER; static int dest_port = DEST_PORT_NUMBER; static int my_port = 0; @@ -153,7 +155,8 @@ static void do_header(int format, int ntracks, int division) if (format != 0 || ntracks != 1) { printf("This player does not support merging of tracks.\n"); - alsa_stop_timer(); + if (! shared_queue) + alsa_stop_timer(); exit(1); } /* set ppq */ @@ -163,12 +166,11 @@ static void do_header(int format, int ntracks, int division) perror("get_queue_tempo"); exit(1); } - if (snd_seq_queue_tempo_get_ppq(tempo) != ppq) { - slave_ppq = snd_seq_queue_tempo_get_ppq(tempo); + if ((slave_ppq = snd_seq_queue_tempo_get_ppq(tempo)) != ppq) { snd_seq_queue_tempo_set_ppq(tempo, ppq); if (snd_seq_set_queue_tempo(seq_handle, dest_queue, tempo) < 0) { perror("set_queue_tempo"); - if (!slave) + if (!slave && !shared_queue) exit(1); else printf("different PPQ %d in SMF from queue PPQ %d\n", ppq, slave_ppq); @@ -185,8 +187,16 @@ static void do_header(int format, int ntracks, int division) wait_start(); if (verbose >= VERB_INFO) printf("Go!\n"); - } else + } else if (shared_queue) { + snd_seq_queue_status_t *stat; + snd_seq_queue_status_alloca(&stat); + snd_seq_get_queue_status(seq_handle, dest_queue, stat); + tick_offset = snd_seq_queue_status_get_tick_time(stat); + fprintf(stderr, "tick offset = %d\n", tick_offset); + } else { alsa_start_timer(); + tick_offset = 0; + } } /* fill time */ @@ -201,6 +211,7 @@ static void set_event_time(snd_seq_event_t *ev, unsigned int currtime) } else { if (ppq != slave_ppq) currtime = (currtime * slave_ppq) / ppq; + currtime += tick_offset; snd_seq_ev_schedule_tick(ev, dest_queue, 0, currtime); } } @@ -254,7 +265,7 @@ static void do_noteon(int chan, int pitch, int vol) snd_seq_event_t ev; if (verbose >= VERB_EVENT) - printf("NoteOn (%d) %d %d\n", chan, pitch, vol); + printf("%d: NoteOn (%d) %d %d\n", Mf_currtime, chan, pitch, vol); set_event_header(&ev); snd_seq_ev_set_noteon(&ev, chan, pitch, vol); write_ev(&ev); @@ -266,7 +277,7 @@ static void do_noteoff(int chan, int pitch, int vol) snd_seq_event_t ev; if (verbose >= VERB_EVENT) - printf("NoteOff (%d) %d %d\n", chan, pitch, vol); + printf("%d: NoteOff (%d) %d %d\n", Mf_currtime, chan, pitch, vol); set_event_header(&ev); snd_seq_ev_set_noteoff(&ev, chan, pitch, vol); write_ev(&ev); @@ -278,7 +289,7 @@ static void do_program(int chan, int program) snd_seq_event_t ev; if (verbose >= VERB_EVENT) - printf("Program (%d) %d\n", chan, program); + printf("%d: Program (%d) %d\n", Mf_currtime, chan, program); set_event_header(&ev); snd_seq_ev_set_pgmchange(&ev, chan, program); write_ev(&ev); @@ -290,7 +301,7 @@ static void do_parameter(int chan, int control, int value) snd_seq_event_t ev; if (verbose >= VERB_EVENT) - printf("Control (%d) %d %d\n", chan, control, value); + printf("%d: Control (%d) %d %d\n", Mf_currtime, chan, control, value); set_event_header(&ev); snd_seq_ev_set_controller(&ev, chan, control, value); write_ev(&ev); @@ -302,7 +313,7 @@ static void do_pitchbend(int chan, int lsb, int msb) snd_seq_event_t ev; if (verbose >= VERB_EVENT) - printf("Pitchbend (%d) %d %d\n", chan, lsb, msb); + printf("%d: Pitchbend (%d) %d %d\n", Mf_currtime, chan, lsb, msb); set_event_header(&ev); snd_seq_ev_set_pitchbend(&ev, chan, (lsb + (msb << 7)) - 8192); write_ev(&ev); @@ -313,7 +324,7 @@ static void do_pressure(int chan, int pitch, int pressure) snd_seq_event_t ev; if (verbose >= VERB_EVENT) - printf("KeyPress (%d) %d %d\n", chan, pitch, pressure); + printf("%d: KeyPress (%d) %d %d\n", Mf_currtime, chan, pitch, pressure); set_event_header(&ev); snd_seq_ev_set_keypress(&ev, chan, pitch, pressure); write_ev(&ev); @@ -324,7 +335,7 @@ static void do_chanpressure(int chan, int pressure) snd_seq_event_t ev; if (verbose >= VERB_EVENT) - printf("ChanPress (%d) %d\n", chan, pressure); + printf("%d: ChanPress (%d) %d\n", Mf_currtime, chan, pressure); set_event_header(&ev); snd_seq_ev_set_chanpress(&ev, chan, pressure); write_ev(&ev); @@ -336,7 +347,7 @@ static void do_sysex(int len, char *msg) if (verbose >= VERB_MUCH) { int c; - printf("Sysex, len=%d\n", len); + printf("%d: Sysex, len=%d\n", Mf_currtime, len); for (c = 0; c < len; c++) { printf(" %02x", (unsigned char)msg[c]); if (c % 16 == 15) @@ -440,7 +451,7 @@ int main(int argc, char *argv[]) int tmp; int c; snd_seq_addr_t dest_addr; - const char *addr = NULL; + const char *addr = "65:0"; while ((c = getopt(argc, argv, "s:a:p:q:vrb")) != -1) { switch (c) { @@ -525,11 +536,13 @@ int main(int argc, char *argv[]) /* setup queue */ if (dest_queue >= 0) { + shared_queue = 1; if (snd_seq_set_queue_usage(seq_handle, dest_queue, 1) < 0) { perror("use queue"); exit(1); } } else { + shared_queue = 0; dest_queue = snd_seq_alloc_queue(seq_handle); if (dest_queue < 0) { perror("alloc queue"); @@ -590,7 +603,8 @@ int main(int argc, char *argv[]) mfread(); alsa_sync(); - alsa_stop_timer(); + if (! shared_queue) + alsa_stop_timer(); snd_seq_close(seq_handle);