Hello Yue,

I think you may be trying too hard to achieve "bit perfect." It's entirely 
possible to do bit perfect audio up to 24-bit, including 16-bit, within the 
32-bit float format that CoreAudio defaults to using at the system level. Even 
though the device format does not literally match the format you're sending you 
can still have a lossless conversion.

For 16-bit audio, all you need to do is divide the signed 16-bit sample by 
32768 (2^15) and send the 32-bit floating point result. For 24-bit audio, the 
constant is 2^23, or 8,388,608. You could also support 20-bit audio with the 
appropriate conversion factor.

I have confirmed this using iTunes, the Metric Halo Labs MobileIO interfaces, 
and loopback of the audio stream to a bit viewer such as TobyBear BitViewer or 
my own AudioUnit. Those interfaces have a custom FireWire CoreAudio driver with 
a 32-bit transport, but it's perfectly feasible to send and receive 32-bit 
float without altering the original 16-bit or 24-bit sample data.

You may need to devise some sort of loopback test to confirm that the 
translations to 32-bit float and back to 24-bit fixed point format are indeed 
lossless and bit perfect for your driver code.

Note that it's often good to allow the option for dithering the samples if the 
input file exceeds the DAC, such as 32-bit files to 24-bit DAC or 20-bit files 
to 16-bit DAC. If you support an option for dither, then you should allow it to 
be turned off for "bit perfect" operations.

Brian Willoughby
Sound Consulting


On Jan 3, 2016, at 12:27 AM, Yue Wang <[email protected]> wrote:
> I am a contributor to the cmus music player project (https://cmus.github.io/) 
> who implemented the coreaudio output plugin. My original implementation is 
> based on AudioOutputUnit, which works perfectly fine. Latest code is hosted 
> at https://github.com/Wang-Yue/cmus/blob/master/coreaudio.c.
> 
> I'm currently doing an experiment to provide "bit perfect" support (similar 
> what BitPerfect on App Store is doing), that sends the unmodified linear PCM 
> data directly to an output device (such as a DAC), if the device supports 
> such data format. 
> 
> I ran into problem that I cannot change the device stream format from 32 bit 
> float (system default) to 16 bit int (CD format). My hardware does support 
> the 16 bit integer format as an available physical format, and I can set it 
> as kAudioStreamPropertyPhysicalFormat. In Audio Midi Setup I can see it's 
> correctly updated. 
> 
> Then I try to set the kAudioDevicePropertyStreamFormat with 16bit integer 
> AudioStreamBasicDescription. It returns without any error. However, when 
> getting the description from the device again, it seems unchanged (still 32 
> bit float). 
> 
> My code is listed in 
> https://github.com/Wang-Yue/cmus/blob/exclusive/coreaudio.c#L821
> 
> If I force to call AudioDeviceStart, I will get very noisy audio (which is 
> also 2x faster than normal speed).
> 
> Could someone help and take a look?


 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/coreaudio-api/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to