Re: Cannot change device stream format
Re: Cannot change device stream format
- Subject: Re: Cannot change device stream format
- From: Brian Willoughby <email@hidden>
- Date: Sun, 03 Jan 2016 18:05:58 -0800
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@hidden> 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@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden