* Bug in aplay? @ 2012-12-12 11:01 Damien Zammit 2012-12-12 11:38 ` Takashi Iwai 0 siblings, 1 reply; 7+ messages in thread From: Damien Zammit @ 2012-12-12 11:01 UTC (permalink / raw) To: alsa-devel Hi, I think i found a small bug in alsa utility "aplay". If you have a sound device that supports the S24_3BE format natively, and you have a wav file of the same format, aplay will not play it because it detects the wrong format and assumes it is default format. (ie 8000Hz Mono 1 channel). I compiled my own version of aplay and it works because I hacked the default format to match this format, but it is not the ideal solution. pi@raspberrypi ~ $ aplay --version aplay: version 1.0.25 by Jaroslav Kysela <perex@perex.cz> pi@raspberrypi ~ $ aplay -D hw:1 48000-S24_3BE.wav Playing raw data '48000-S24_3BE.wav' : Unsigned 8 bit, Rate 8000 Hz, Mono aplay: set_params:1081: Sample format non available Available formats: - S24_3BE My version: pi@raspberrypi ~ $ ./aplay -D hw:1 48000-S24_3BE.wav Playing raw data '48000-S24_3BE.wav' : Signed 24 bit Big Endian in 3bytes, Rate 48000 Hz, Stereo aplay: set_params:1145: Unable to install hw params: ACCESS: RW_INTERLEAVED FORMAT: S24_3BE SUBFORMAT: STD SAMPLE_BITS: 24 FRAME_BITS: 48 CHANNELS: 2 RATE: 48000 PERIOD_TIME: 125000 PERIOD_SIZE: 6000 PERIOD_BYTES: 36000 PERIODS: 4 BUFFER_TIME: 500000 BUFFER_SIZE: 24000 BUFFER_BYTES: 144000 TICK_TIME: 0 pi@raspberrypi ~ $ This is making it tricky for me to use my sound card. For some reason it works better with jackd. The error above is also a mystery to me, but it seems to be detecting the format better. Regards, Damien ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Bug in aplay? 2012-12-12 11:01 Bug in aplay? Damien Zammit @ 2012-12-12 11:38 ` Takashi Iwai 2012-12-12 11:54 ` Damien Zammit 0 siblings, 1 reply; 7+ messages in thread From: Takashi Iwai @ 2012-12-12 11:38 UTC (permalink / raw) To: Damien Zammit; +Cc: alsa-devel At Wed, 12 Dec 2012 22:01:38 +1100, Damien Zammit wrote: > > Hi, > I think i found a small bug in alsa utility "aplay". > > If you have a sound device that supports the S24_3BE format natively, > and you have a wav file of the same format, aplay will not play it > because it detects the wrong format and assumes it is default format. > (ie 8000Hz Mono 1 channel). > I compiled my own version of aplay and it works because I hacked the > default format to match this format, but it is not the ideal solution. > > pi@raspberrypi ~ $ aplay --version > aplay: version 1.0.25 by Jaroslav Kysela <perex@perex.cz> > > pi@raspberrypi ~ $ aplay -D hw:1 48000-S24_3BE.wav > Playing raw data '48000-S24_3BE.wav' : Unsigned 8 bit, Rate 8000 Hz, Mono > aplay: set_params:1081: Sample format non available > Available formats: > - S24_3BE Does your WAV file have a valid WAV_FMT_* chunk indicating the 24bit format? aplay checks bit_p_spl and byte_p_spl fields of WaveFmtBody defined in formats.h. Takashi ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Bug in aplay? 2012-12-12 11:38 ` Takashi Iwai @ 2012-12-12 11:54 ` Damien Zammit 2012-12-12 11:59 ` Clemens Ladisch 0 siblings, 1 reply; 7+ messages in thread From: Damien Zammit @ 2012-12-12 11:54 UTC (permalink / raw) To: Takashi Iwai; +Cc: alsa-devel pi@raspberrypi ~ $ hexdump -C 48000-S24_3BE.wav |head 00000000 52 49 46 58 01 c3 20 48 57 41 56 45 66 6d 74 20 |RIFX.. HWAVEfmt | 00000010 00 00 00 28 ff fe 00 02 00 00 bb 80 00 04 65 00 |...(..........e.| 00000020 00 06 00 18 00 16 00 18 00 00 00 03 00 01 00 00 |................| 00000030 00 00 10 00 80 00 00 aa 00 38 9b 71 66 61 63 74 |.........8.qfact| 00000040 00 00 00 04 00 4b 30 00 64 61 74 61 01 c3 20 00 |.....K0.data.. .| 00000050 ff f6 00 00 14 00 00 3f 00 00 26 00 00 25 00 00 |.......?..&..%..| 00000060 2c 00 ff cf 00 00 2b 00 00 0b 00 00 25 00 00 44 |,.....+.....%..D| 00000070 00 00 1d 00 00 1b 00 00 13 00 00 19 00 00 06 00 |................| 00000080 ff f8 00 00 00 00 ff ab 00 00 04 00 ff f1 00 00 |................| 00000090 0a 00 00 5a 00 00 0d 00 00 38 00 00 0a 00 00 08 |...Z.....8......| On 12 December 2012 22:38, Takashi Iwai <tiwai@suse.de> wrote: > At Wed, 12 Dec 2012 22:01:38 +1100, > Damien Zammit wrote: >> >> Hi, >> I think i found a small bug in alsa utility "aplay". >> >> If you have a sound device that supports the S24_3BE format natively, >> and you have a wav file of the same format, aplay will not play it >> because it detects the wrong format and assumes it is default format. >> (ie 8000Hz Mono 1 channel). >> I compiled my own version of aplay and it works because I hacked the >> default format to match this format, but it is not the ideal solution. >> >> pi@raspberrypi ~ $ aplay --version >> aplay: version 1.0.25 by Jaroslav Kysela <perex@perex.cz> >> >> pi@raspberrypi ~ $ aplay -D hw:1 48000-S24_3BE.wav >> Playing raw data '48000-S24_3BE.wav' : Unsigned 8 bit, Rate 8000 Hz, Mono >> aplay: set_params:1081: Sample format non available >> Available formats: >> - S24_3BE > > Does your WAV file have a valid WAV_FMT_* chunk indicating the 24bit > format? aplay checks bit_p_spl and byte_p_spl fields of WaveFmtBody > defined in formats.h. > > > Takashi ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Bug in aplay? 2012-12-12 11:54 ` Damien Zammit @ 2012-12-12 11:59 ` Clemens Ladisch 2012-12-12 12:08 ` Damien Zammit 2012-12-12 14:23 ` Takashi Iwai 0 siblings, 2 replies; 7+ messages in thread From: Clemens Ladisch @ 2012-12-12 11:59 UTC (permalink / raw) To: Damien Zammit; +Cc: Takashi Iwai, alsa-devel Damien Zammit wrote: > pi@raspberrypi ~ $ hexdump -C 48000-S24_3BE.wav |head > 00000000 52 49 46 58 01 c3 20 48 57 41 56 45 66 6d 74 20 |RIFX.. HWAVEfmt | aplay does not support big-endian .wav files. Regards, Clemens ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Bug in aplay? 2012-12-12 11:59 ` Clemens Ladisch @ 2012-12-12 12:08 ` Damien Zammit 2012-12-12 13:01 ` Clemens Ladisch 2012-12-12 14:23 ` Takashi Iwai 1 sibling, 1 reply; 7+ messages in thread From: Damien Zammit @ 2012-12-12 12:08 UTC (permalink / raw) To: Clemens Ladisch; +Cc: Takashi Iwai, alsa-devel I wish to record and playback streams from my sound card which uses 24 bit big endian format, but I do not wish to resample it. Is it possible to reorder the endianess on the fly so that I can play and record using alsa tools without losing any quality? On 12 December 2012 22:59, Clemens Ladisch <clemens@ladisch.de> wrote: > Damien Zammit wrote: >> pi@raspberrypi ~ $ hexdump -C 48000-S24_3BE.wav |head >> 00000000 52 49 46 58 01 c3 20 48 57 41 56 45 66 6d 74 20 |RIFX.. HWAVEfmt | > > aplay does not support big-endian .wav files. > > > Regards, > Clemens ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Bug in aplay? 2012-12-12 12:08 ` Damien Zammit @ 2012-12-12 13:01 ` Clemens Ladisch 0 siblings, 0 replies; 7+ messages in thread From: Clemens Ladisch @ 2012-12-12 13:01 UTC (permalink / raw) To: Damien Zammit; +Cc: Takashi Iwai, alsa-devel Damien Zammit wrote: > I wish to record and playback streams from my sound card which uses 24 > bit big endian format, but I do not wish to resample it. You get resampling only if the sample rates do not match. Regards, Clemens ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Bug in aplay? 2012-12-12 11:59 ` Clemens Ladisch 2012-12-12 12:08 ` Damien Zammit @ 2012-12-12 14:23 ` Takashi Iwai 1 sibling, 0 replies; 7+ messages in thread From: Takashi Iwai @ 2012-12-12 14:23 UTC (permalink / raw) To: Clemens Ladisch; +Cc: alsa-devel, Damien Zammit At Wed, 12 Dec 2012 12:59:01 +0100, Clemens Ladisch wrote: > > Damien Zammit wrote: > > pi@raspberrypi ~ $ hexdump -C 48000-S24_3BE.wav |head > > 00000000 52 49 46 58 01 c3 20 48 57 41 56 45 66 6d 74 20 |RIFX.. HWAVEfmt | > > aplay does not support big-endian .wav files. Indeed. The (untested) patch below should add the support for BE format. Give it a try. Takashi --- diff --git a/aplay/aplay.c b/aplay/aplay.c index f35f603..4852b20 100644 --- a/aplay/aplay.c +++ b/aplay/aplay.c @@ -892,11 +892,20 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) WaveFmtBody *f; WaveChunkHeader *c; u_int type, len; + unsigned short format, channels; + int big_endian, native_format; if (size < sizeof(WaveHeader)) return -1; - if (h->magic != WAV_RIFF || h->type != WAV_WAVE) + if (h->magic == WAV_RIFF) + big_endian = 0; + else if (h->magic == WAV_RIFX) + big_endian = 1; + else + return -1; + if (h->type != WAV_WAVE) return -1; + if (size > sizeof(WaveHeader)) { check_wavefile_space(buffer, size - sizeof(WaveHeader), blimit); memcpy(buffer, _buffer + sizeof(WaveHeader), size - sizeof(WaveHeader)); @@ -907,7 +916,7 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) test_wavefile_read(fd, buffer, &size, sizeof(WaveChunkHeader), __LINE__); c = (WaveChunkHeader*)buffer; type = c->type; - len = LE_INT(c->length); + len = TO_CPU_INT(c->length, big_endian); len += len % 2; if (size > sizeof(WaveChunkHeader)) memmove(buffer, buffer + sizeof(WaveChunkHeader), size - sizeof(WaveChunkHeader)); @@ -929,7 +938,8 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) check_wavefile_space(buffer, len, blimit); test_wavefile_read(fd, buffer, &size, len, __LINE__); f = (WaveFmtBody*) buffer; - if (LE_SHORT(f->format) == WAV_FMT_EXTENSIBLE) { + format = TO_CPU_SHORT(f->format, big_endian); + if (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)"), @@ -940,19 +950,20 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) error(_("wrong format tag in extensible 'fmt ' chunk")); prg_exit(EXIT_FAILURE); } - f->format = fe->guid_format; + format = TO_CPU_SHORT(fe->guid_format, big_endian); } - 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)); + if (format != WAV_FMT_PCM && + format != WAV_FMT_IEEE_FLOAT) { + error(_("can't play WAVE-file format 0x%04x which is not PCM or FLOAT encoded"), format); prg_exit(EXIT_FAILURE); } - if (LE_SHORT(f->channels) < 1) { - error(_("can't play WAVE-files with %d tracks"), LE_SHORT(f->channels)); + channels = TO_CPU_SHORT(f->channels, big_endian); + if (channels < 1) { + error(_("can't play WAVE-files with %d tracks"), channels); prg_exit(EXIT_FAILURE); } - hwparams.channels = LE_SHORT(f->channels); - switch (LE_SHORT(f->bit_p_spl)) { + hwparams.channels = channels; + switch (TO_CPU_SHORT(f->bit_p_spl, big_endian)) { case 8: if (hwparams.format != DEFAULT_FORMAT && hwparams.format != SND_PCM_FORMAT_U8) @@ -960,43 +971,69 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) hwparams.format = SND_PCM_FORMAT_U8; break; case 16: + if (big_endian) + native_format = SND_PCM_FORMAT_S16_BE; + else + native_format = SND_PCM_FORMAT_S16_LE; if (hwparams.format != DEFAULT_FORMAT && - hwparams.format != SND_PCM_FORMAT_S16_LE) - fprintf(stderr, _("Warning: format is changed to S16_LE\n")); - hwparams.format = SND_PCM_FORMAT_S16_LE; + hwparams.format != native_format) + fprintf(stderr, _("Warning: format is changed to %s\n"), + snd_pcm_format_name(native_format)); + hwparams.format = native_format; break; case 24: - switch (LE_SHORT(f->byte_p_spl) / hwparams.channels) { + switch (TO_CPU_SHORT(f->byte_p_spl, big_endian) / hwparams.channels) { case 3: + if (big_endian) + native_format = SND_PCM_FORMAT_S24_3BE; + else + native_format = SND_PCM_FORMAT_S24_3LE; if (hwparams.format != DEFAULT_FORMAT && - hwparams.format != SND_PCM_FORMAT_S24_3LE) - fprintf(stderr, _("Warning: format is changed to S24_3LE\n")); - hwparams.format = SND_PCM_FORMAT_S24_3LE; + hwparams.format != native_format) + fprintf(stderr, _("Warning: format is changed to %s\n"), + snd_pcm_format_name(native_format)); + hwparams.format = native_format; break; case 4: + if (big_endian) + native_format = SND_PCM_FORMAT_S24_BE; + else + native_format = SND_PCM_FORMAT_S24_LE; if (hwparams.format != DEFAULT_FORMAT && - hwparams.format != SND_PCM_FORMAT_S24_LE) - fprintf(stderr, _("Warning: format is changed to S24_LE\n")); - hwparams.format = SND_PCM_FORMAT_S24_LE; + hwparams.format != native_format) + fprintf(stderr, _("Warning: format is changed to %s\n"), + snd_pcm_format_name(native_format)); + hwparams.format = native_format; break; default: error(_(" can't play WAVE-files with sample %d bits in %d bytes wide (%d channels)"), - LE_SHORT(f->bit_p_spl), LE_SHORT(f->byte_p_spl), hwparams.channels); + TO_CPU_SHORT(f->bit_p_spl, big_endian), + TO_CPU_SHORT(f->byte_p_spl, big_endian), + hwparams.channels); prg_exit(EXIT_FAILURE); } break; case 32: - 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; + if (format == WAV_FMT_PCM) { + if (big_endian) + native_format = SND_PCM_FORMAT_S32_BE; + else + native_format = SND_PCM_FORMAT_S32_LE; + hwparams.format = native_format; + } else if (format == WAV_FMT_IEEE_FLOAT) { + if (big_endian) + native_format = SND_PCM_FORMAT_FLOAT_BE; + else + native_format = SND_PCM_FORMAT_FLOAT_LE; + hwparams.format = native_format; + } break; default: error(_(" can't play WAVE-files with sample %d bits wide"), - LE_SHORT(f->bit_p_spl)); + TO_CPU_SHORT(f->bit_p_spl, big_endian)); prg_exit(EXIT_FAILURE); } - hwparams.rate = LE_INT(f->sample_fq); + hwparams.rate = TO_CPU_INT(f->sample_fq, big_endian); if (size > len) memmove(buffer, buffer + len, size - len); @@ -1009,7 +1046,7 @@ static ssize_t test_wavefile(int fd, u_char *_buffer, size_t size) test_wavefile_read(fd, buffer, &size, sizeof(WaveChunkHeader), __LINE__); c = (WaveChunkHeader*)buffer; type = c->type; - len = LE_INT(c->length); + len = TO_CPU_INT(c->length, big_endian); if (size > sizeof(WaveChunkHeader)) memmove(buffer, buffer + sizeof(WaveChunkHeader), size - sizeof(WaveChunkHeader)); size -= sizeof(WaveChunkHeader); diff --git a/aplay/formats.h b/aplay/formats.h index b5314f9..ac0a2b0 100644 --- a/aplay/formats.h +++ b/aplay/formats.h @@ -60,7 +60,14 @@ typedef struct voc_ext_block { #error "Wrong endian" #endif +/* Note: the following macros evaluate the parameter v twice */ +#define TO_CPU_SHORT(v, be) \ + ((be) ? BE_SHORT(v) : LE_SHORT(v)) +#define TO_CPU_INT(v, be) \ + ((be) ? BE_INT(v) : LE_INT(v)) + #define WAV_RIFF COMPOSE_ID('R','I','F','F') +#define WAV_RIFX COMPOSE_ID('R','I','F','X') #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') ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-12-12 14:23 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-12-12 11:01 Bug in aplay? Damien Zammit 2012-12-12 11:38 ` Takashi Iwai 2012-12-12 11:54 ` Damien Zammit 2012-12-12 11:59 ` Clemens Ladisch 2012-12-12 12:08 ` Damien Zammit 2012-12-12 13:01 ` Clemens Ladisch 2012-12-12 14:23 ` Takashi Iwai
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.