diff -r 16f32be6b8b9 aplay/aplay.c --- a/aplay/aplay.c Tue Feb 05 10:08:11 2008 +0100 +++ b/aplay/aplay.c Mon Mar 10 13:19:38 2008 +0100 @@ -745,15 +745,29 @@ static ssize_t test_wavefile(int fd, u_c check_wavefile_space(buffer, len, blimit); test_wavefile_read(fd, buffer, &size, len, __LINE__); f = (WaveFmtBody*) buffer; - if (LE_SHORT(f->format) != WAV_PCM_CODE) { - error(_("can't play not PCM-coded WAVE-files")); + if (LE_SHORT(f->format) == WAV_FMT_EXTENSIBLE) { + WaveFmtExtensibleBody *fe = (WaveFmtExtensibleBody*)buffer; + if (len < sizeof(WaveFmtExtensibleBody)) { + error(_("unknown length of extensible 'fmt ' chunk (read %u, should be %u at least)"), + len, (u_int)sizeof(WaveFmtExtensibleBody)); + exit(EXIT_FAILURE); + } + if (memcmp(fe->guid_tag, WAV_GUID_TAG, 14) != 0) { + error(_("wrong format tag in extensible 'fmt ' chunk")); + exit(EXIT_FAILURE); + } + f->format = fe->guid_format; + } + if (LE_SHORT(f->format) != WAV_FMT_PCM && + LE_SHORT(f->format) != WAV_FMT_IEEE_FLOAT) { + error(_("can't play WAVE-file format 0x%04x which is not PCM or FLOAT encoded"), LE_SHORT(f->format)); exit(EXIT_FAILURE); } - if (LE_SHORT(f->modus) < 1) { - error(_("can't play WAVE-files with %d tracks"), LE_SHORT(f->modus)); + if (LE_SHORT(f->channels) < 1) { + error(_("can't play WAVE-files with %d tracks"), LE_SHORT(f->channels)); exit(EXIT_FAILURE); } - hwparams.channels = LE_SHORT(f->modus); + hwparams.channels = LE_SHORT(f->channels); switch (LE_SHORT(f->bit_p_spl)) { case 8: if (hwparams.format != DEFAULT_FORMAT && @@ -788,7 +802,10 @@ static ssize_t test_wavefile(int fd, u_c } break; case 32: - hwparams.format = SND_PCM_FORMAT_S32_LE; + if (LE_SHORT(f->format) == WAV_FMT_PCM) + hwparams.format = SND_PCM_FORMAT_S32_LE; + else if (LE_SHORT(f->format) == WAV_FMT_IEEE_FLOAT) + hwparams.format = SND_PCM_FORMAT_FLOAT_LE; break; default: error(_(" can't play WAVE-files with sample %d bits wide"), @@ -1778,6 +1795,7 @@ static void begin_wave(int fd, size_t cn bits = 16; break; case SND_PCM_FORMAT_S32_LE: + case SND_PCM_FORMAT_FLOAT_LE: bits = 32; break; case SND_PCM_FORMAT_S24_LE: @@ -1796,8 +1814,11 @@ static void begin_wave(int fd, size_t cn cf.type = WAV_FMT; cf.length = LE_INT(16); - f.format = LE_SHORT(WAV_PCM_CODE); - f.modus = LE_SHORT(hwparams.channels); + if (hwparams.format == SND_PCM_FORMAT_FLOAT_LE) + f.format = LE_SHORT(WAV_FMT_IEEE_FLOAT); + else + f.format = LE_SHORT(WAV_FMT_PCM); + f.channels = LE_SHORT(hwparams.channels); f.sample_fq = LE_INT(hwparams.rate); #if 0 tmp2 = (samplesize == 8) ? 1 : 2; diff -r 16f32be6b8b9 aplay/formats.h --- a/aplay/formats.h Tue Feb 05 10:08:11 2008 +0100 +++ b/aplay/formats.h Mon Mar 10 13:19:38 2008 +0100 @@ -64,7 +64,15 @@ typedef struct voc_ext_block { #define WAV_WAVE COMPOSE_ID('W','A','V','E') #define WAV_FMT COMPOSE_ID('f','m','t',' ') #define WAV_DATA COMPOSE_ID('d','a','t','a') -#define WAV_PCM_CODE 1 + +/* WAVE fmt block constants from Microsoft mmreg.h header */ +#define WAV_FMT_PCM 0x0001 +#define WAV_FMT_IEEE_FLOAT 0x0003 +#define WAV_FMT_DOLBY_AC3_SPDIF 0x0092 +#define WAV_FMT_EXTENSIBLE 0xfffe + +/* Used with WAV_FMT_EXTENSIBLE format */ +#define WAV_GUID_TAG "\x00\x00\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71" /* it's in chunks like .voc and AMIGA iff, but my source say there are in only in this combination, so I combined them in one header; @@ -77,13 +85,22 @@ typedef struct { } WaveHeader; typedef struct { - u_short format; /* should be 1 for PCM-code */ - u_short modus; /* 1 Mono, 2 Stereo */ + u_short format; /* see WAV_FMT_* */ + u_short channels; u_int sample_fq; /* frequence of sample */ u_int byte_p_sec; u_short byte_p_spl; /* samplesize; 1 or 2 bytes */ u_short bit_p_spl; /* 8, 12 or 16 bit */ } WaveFmtBody; + +typedef struct { + WaveFmtBody format; + u_short ext_size; + u_short bit_p_spl; + u_int channel_mask; + u_short guid_format; /* WAV_FMT_* */ + u_char guid_tag[14]; /* WAV_GUID_TAG */ +} WaveFmtExtensibleBody; typedef struct { u_int type; /* 'data' */ diff -r 16f32be6b8b9 configure.in --- a/configure.in Tue Feb 05 10:08:11 2008 +0100 +++ b/configure.in Mon Mar 10 13:19:38 2008 +0100 @@ -27,9 +27,7 @@ dnl AC_PROG_CXX dnl AC_PROG_CXX AC_PROG_INSTALL AC_PROG_LN_S -AM_PATH_ALSA(1.0.15) -AC_CHECK_FUNC(snd_tlv_get_dB_range,, - AC_ERROR([No TLV support code in alsa-lib])) +AM_PATH_ALSA(1.0.16) AC_ARG_ENABLE(alsamixer, [ --disable-alsamixer Disable alsamixer compilation], diff -r 16f32be6b8b9 seq/aplaymidi/arecordmidi.c --- a/seq/aplaymidi/arecordmidi.c Tue Feb 05 10:08:11 2008 +0100 +++ b/seq/aplaymidi/arecordmidi.c Mon Mar 10 13:19:38 2008 +0100 @@ -857,7 +857,7 @@ int main(int argc, char *argv[]) pfds = alloca(sizeof(*pfds) * npfds); for (;;) { snd_seq_poll_descriptors(seq, pfds, npfds, POLLIN); - if (poll(pfds, npfds, 69) < 0) + if (poll(pfds, npfds, -1) < 0) break; do { snd_seq_event_t *event; diff -r 16f32be6b8b9 seq/aseqdump/aseqdump.c --- a/seq/aseqdump/aseqdump.c Tue Feb 05 10:08:11 2008 +0100 +++ b/seq/aseqdump/aseqdump.c Mon Mar 10 13:19:38 2008 +0100 @@ -133,71 +133,75 @@ static void dump_event(const snd_seq_eve printf("%3d:%-3d ", ev->source.client, ev->source.port); switch (ev->type) { case SND_SEQ_EVENT_NOTEON: - printf("Note on %2d %3d %3d\n", - ev->data.note.channel, ev->data.note.note, ev->data.note.velocity); + if (ev->data.note.velocity) + printf("Note on %2d, note %d, velocity %d\n", + ev->data.note.channel, ev->data.note.note, ev->data.note.velocity); + else + printf("Note off %2d, note %d\n", + ev->data.note.channel, ev->data.note.note); break; case SND_SEQ_EVENT_NOTEOFF: - printf("Note off %2d %3d %3d\n", + printf("Note off %2d, note %d, velocity %d\n", ev->data.note.channel, ev->data.note.note, ev->data.note.velocity); break; case SND_SEQ_EVENT_KEYPRESS: - printf("Polyphonic aftertouch %2d %3d %3d\n", + printf("Polyphonic aftertouch %2d, note %d, value %d\n", ev->data.note.channel, ev->data.note.note, ev->data.note.velocity); break; case SND_SEQ_EVENT_CONTROLLER: - printf("Control change %2d %3d %3d\n", + printf("Control change %2d, controller %d, value %d\n", ev->data.control.channel, ev->data.control.param, ev->data.control.value); break; case SND_SEQ_EVENT_PGMCHANGE: - printf("Program change %2d %3d\n", + printf("Program change %2d, program %d\n", ev->data.control.channel, ev->data.control.value); break; case SND_SEQ_EVENT_CHANPRESS: - printf("Channel aftertouch %2d %3d\n", + printf("Channel aftertouch %2d, value %d\n", ev->data.control.channel, ev->data.control.value); break; case SND_SEQ_EVENT_PITCHBEND: - printf("Pitch bend %2d %6d\n", + printf("Pitch bend %2d, value %d\n", ev->data.control.channel, ev->data.control.value); break; case SND_SEQ_EVENT_CONTROL14: - printf("Control change %2d %3d %5d\n", + printf("Control change %2d, controller %d, value %5d\n", ev->data.control.channel, ev->data.control.param, ev->data.control.value); break; case SND_SEQ_EVENT_NONREGPARAM: - printf("Non-reg. parameter %2d %5d %5d\n", + printf("Non-reg. parameter %2d, parameter %d, value %d\n", ev->data.control.channel, ev->data.control.param, ev->data.control.value); break; case SND_SEQ_EVENT_REGPARAM: - printf("Reg. parameter %2d %5d %5d\n", + printf("Reg. parameter %2d, parameter %d, value %d\n", ev->data.control.channel, ev->data.control.param, ev->data.control.value); break; case SND_SEQ_EVENT_SONGPOS: - printf("Song position pointer %5d\n", + printf("Song position pointer value %d\n", ev->data.control.value); break; case SND_SEQ_EVENT_SONGSEL: - printf("Song select %3d\n", + printf("Song select value %d\n", ev->data.control.value); break; case SND_SEQ_EVENT_QFRAME: - printf("MTC quarter frame %02xh\n", + printf("MTC quarter frame %02xh\n", ev->data.control.value); break; case SND_SEQ_EVENT_TIMESIGN: // XXX how is this encoded? - printf("SMF time signature (%#08x)\n", + printf("SMF time signature (%#010x)\n", ev->data.control.value); break; case SND_SEQ_EVENT_KEYSIGN: // XXX how is this encoded? - printf("SMF key signature (%#08x)\n", + printf("SMF key signature (%#010x)\n", ev->data.control.value); break; case SND_SEQ_EVENT_START: if (ev->source.client == SND_SEQ_CLIENT_SYSTEM && ev->source.port == SND_SEQ_PORT_SYSTEM_TIMER) - printf("Queue start %d\n", + printf("Queue start queue %d\n", ev->data.queue.queue); else printf("Start\n"); @@ -205,7 +209,7 @@ static void dump_event(const snd_seq_eve case SND_SEQ_EVENT_CONTINUE: if (ev->source.client == SND_SEQ_CLIENT_SYSTEM && ev->source.port == SND_SEQ_PORT_SYSTEM_TIMER) - printf("Queue continue %d\n", + printf("Queue continue queue %d\n", ev->data.queue.queue); else printf("Continue\n"); @@ -213,19 +217,19 @@ static void dump_event(const snd_seq_eve case SND_SEQ_EVENT_STOP: if (ev->source.client == SND_SEQ_CLIENT_SYSTEM && ev->source.port == SND_SEQ_PORT_SYSTEM_TIMER) - printf("Queue stop %d\n", + printf("Queue stop queue %d\n", ev->data.queue.queue); else printf("Stop\n"); break; case SND_SEQ_EVENT_SETPOS_TICK: - printf("Set tick queue pos. %d\n", ev->data.queue.queue); + printf("Set tick queue pos. queue %d\n", ev->data.queue.queue); break; case SND_SEQ_EVENT_SETPOS_TIME: - printf("Set rt queue pos. %d\n", ev->data.queue.queue); + printf("Set rt queue pos. queue %d\n", ev->data.queue.queue); break; case SND_SEQ_EVENT_TEMPO: - printf("Set queue tempo %d\n", ev->data.queue.queue); + printf("Set queue tempo queue %d\n", ev->data.queue.queue); break; case SND_SEQ_EVENT_CLOCK: printf("Clock\n"); @@ -234,7 +238,7 @@ static void dump_event(const snd_seq_eve printf("Tick\n"); break; case SND_SEQ_EVENT_QUEUE_SKEW: - printf("Queue timer skew %d\n", ev->data.queue.queue); + printf("Queue timer skew queue %d\n", ev->data.queue.queue); break; case SND_SEQ_EVENT_TUNE_REQUEST: printf("Tune request\n"); @@ -246,43 +250,43 @@ static void dump_event(const snd_seq_eve printf("Active Sensing\n"); break; case SND_SEQ_EVENT_CLIENT_START: - printf("Client start %d\n", + printf("Client start client %d\n", ev->data.addr.client); break; case SND_SEQ_EVENT_CLIENT_EXIT: - printf("Client exit %d\n", + printf("Client exit client %d\n", ev->data.addr.client); break; case SND_SEQ_EVENT_CLIENT_CHANGE: - printf("Client changed %d\n", + printf("Client changed client %d\n", ev->data.addr.client); break; case SND_SEQ_EVENT_PORT_START: - printf("Port start %d:%d\n", + printf("Port start %d:%d\n", ev->data.addr.client, ev->data.addr.port); break; case SND_SEQ_EVENT_PORT_EXIT: - printf("Port exit %d:%d\n", + printf("Port exit %d:%d\n", ev->data.addr.client, ev->data.addr.port); break; case SND_SEQ_EVENT_PORT_CHANGE: - printf("Port changed %d:%d\n", + printf("Port changed %d:%d\n", ev->data.addr.client, ev->data.addr.port); break; case SND_SEQ_EVENT_PORT_SUBSCRIBED: - printf("Port subscribed %d:%d -> %d:%d\n", + printf("Port subscribed %d:%d -> %d:%d\n", ev->data.connect.sender.client, ev->data.connect.sender.port, ev->data.connect.dest.client, ev->data.connect.dest.port); break; case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: - printf("Port unsubscribed %d:%d -> %d:%d\n", + printf("Port unsubscribed %d:%d -> %d:%d\n", ev->data.connect.sender.client, ev->data.connect.sender.port, ev->data.connect.dest.client, ev->data.connect.dest.port); break; case SND_SEQ_EVENT_SYSEX: { unsigned int i; - printf("System exclusive "); + printf("System exclusive "); for (i = 0; i < ev->data.ext.len; ++i) printf(" %02X", ((unsigned char*)ev->data.ext.ptr)[i]); printf("\n"); @@ -405,7 +409,7 @@ int main(int argc, char *argv[]) printf("Waiting for data at port %d:0.", snd_seq_client_id(seq)); printf(" Press Ctrl+C to end.\n"); - printf("Source_ Event_________________ Ch _Data__\n"); + printf("Source Event Ch Data\n"); signal(SIGINT, sighandler); signal(SIGTERM, sighandler); @@ -414,7 +418,7 @@ int main(int argc, char *argv[]) pfds = alloca(sizeof(*pfds) * npfds); for (;;) { snd_seq_poll_descriptors(seq, pfds, npfds, POLLIN); - if (poll(pfds, npfds, 69) < 0) + if (poll(pfds, npfds, -1) < 0) break; do { snd_seq_event_t *event; @@ -424,6 +428,7 @@ int main(int argc, char *argv[]) if (event) dump_event(event); } while (err > 0); + fflush(stdout); if (stop) break; }