Convert bit-depth to 24 bit


I use mocp to play music and use oss as my sound card (ICE1724) driver. When MOCP is playing a source audio file of 16 bit, can MOCP change the sample format to 24 bit, which is output to OSS device?

Can ffmpeg or modplugin do this?


First of all - why would you want that? That would not affect quality at all. Doesn't your card support 16-bit output?

Second - MOC currently has only a rudimentary support of OSS4 with no advanced features as far as I know. Thus it doesn't support 24-bit output.

If you would have used ALSA, if MOC would detect that 16-bit sound is unsupported given you have set Allow24bitOutput = yes in .moc/config) it would automatically convert to 24-bits. With experimental code (see it is possible to force that behaviour.

Please tell us also your MOC version and post initial part of MOC debug log (mocp -D) - including sound card detection lines.

Thank, tomaszg!

I want to play bit-perfect audio using my envy24 sound card with OSS as driver. Please see the envy24 oss manpage:-

OSS creates mmap() device file for envy24 for bit-perfect playing, which only accepts sample format of 32 bit msb aligned (AFMT_S32_LE), i.e. 24 bit msb zero padded to S32_LE. Therefore, if I play the 16 bits 44100 hz wav file, I have to convert the file to AFMT_S32_LE first. If MOC can do the conversion on the fly, this will save many manual operations and much disk space (space doubled after converting from 16 bit to AFMT_S32_LE.

I shall post the MOC debug log later.

Grateful if MOC can support OSS to output 24 bit, particularly AFMT_S32_LE, to the sound card.


P.S. A bit off the topic, may I know how I can convert 16 bit wav file to the format AFMT_S32_LE manually? By ffmpeg or sox?

I don't see anything in that man page suggesting that mmap() devices are bit-perfect and usual methods are not. The only reason to use them stated there is latencies. I wouldn't expect any change of quality.

What happens now with MOC when you try to use this device? Do you hear some sound? I'll try to prepare some patch to MOC to support S32 samples but that will be a work in the dark. I hope you will be able to compile MOC from sources?

You can just use sox to convert sample type, something like sox in.wav -b24 out.wav should do the trick. But that will not help you with MOC :)

I've prepared a set of patches (previous work + oss4 related stuff), but I couldn't test it with OSS 4. The patches work against MOC 2.6-alpha1 (probably also against current SVN sources), just ignore warnings about offsets.

You can apply these patches by hand or use quilt (quilt -a push).


Many thanks again, tomaszg!!!

You are right that using mmap only affect the latency by reducing the buffer. However, in playing audio, reducing latency is of utmost importance and that is why people always recommend using rt-kernel. I now successfully play audio using mmap() (i.e. /dev/dsp_mmap in OSS) using ossplay and find the the SQ improves a lot.

I now do the on-the-fly conversion using the following script:-

sudo nano /usr/local/bin/music

cd /mnt/ramdisk #[I mount a ramdisk at /mnt/ramdisk and copy the wav in an album there]
sudo umount /media/sda5 #[I use boot-to-ram so that the whole os is on ram and I turn off and unplug the hard disk when playing music]
for i in *.wav #[that is the trick, inspired by sox batch processing .bat file]
do sudo sox -V4 “$i” -b 24 tmp.wav
sudo xfs_fsr tmp.wav
sudo taskset -c 0 ossplay -vvvv -R -d/dev/dsp_mmap tmp.wav” #[I use taskset and to optimise the playing]
sudo rm tmp.wav

sudo chmod 755 /usr/local/bin/music

When I play the wav files, I simply type "music" at prompt. For sharing, please.

I shall try the patch later.

Thank you again, tomaszg.


In playing audio, reducing latency is of no importance at all (unless buffering is in some way buggy/broken). Those who recommend using rt-kernel or other weird tricks are simply followers of audio-voodoo cult. In your case the improvement of quality might be caused by some other feature or driver (bad resampling?) or just power of suggestion. I recommend some ABX testing to make sure that the improvement is really there and that it is worth the effort (see e.g. here ).

All that that unplugging disks and tuning cpu seems also like a black magic. It might help reduce electric interference from badly shielded soundcards but if you are concerned about it, using external DAC connected by fiber is a way to go.

Although the change in sound quality is truly audible, the link provides very useful information. Thank you, tomaszg!

Script revised:-

sudo nano /usr/local/bin/music

cd /mnt/ramdisk
sudo umount /media/sda5
for i in *.wav
do sudo sox “$i” -b 24 tmp.wav
echo “$1”
sudo xfs_fsr tmp.wav
sudo taskset -c 0 ossplay -R -d/dev/dsp_mmap tmp.wav &
sudo chrt -f -p 85 $!
sudo rm tmp.wav

sudo chmod 755 /usr/local/bin/music

Add "&" at the end of the command "taskset ... ossplay ..." to put it to the background, then chrt to change the priority of the ossplay. The command "wait" is then added to let ossplay in the background to finish the current wav before tmp.wav is deleted and proceeded to the next one. The sound is more refined. ^.^