PortAudio / portaudio

PortAudio is a cross-platform, open-source C language library for real-time audio input and output.
Other
1.43k stars 296 forks source link

WASAPI SPDIF Passthrough needs data format clarifications #816

Open RossBencina opened 1 year ago

RossBencina commented 1 year ago
  1. It's not clear what the data format should be for EAC3 (i.e. just AC3? or including IEC61937 wrapping or also including SPDIF framing). We think it's one of the first two. Right now you have to experiment or check the MS docs.

https://github.com/PortAudio/portaudio/pull/778

This is the unresolved review: https://github.com/PortAudio/portaudio/pull/778#discussion_r1154972224

  1. In addition, there is a lack of clarity about whether data streams should be 2-byte or 4-byte aligned. The current test programs imply that data can be 2-byte aligned but this seems unlikely and if it is the case it should be clearly documented, or the tests should be cleaned up to use 4-byte (stereo 16-bit) alignment using a frameCount variable rather than a sampleCount variable.

This second issue is discussed (along with a solution) in the following unresolved review: https://github.com/PortAudio/portaudio/pull/778#discussion_r1181968284 thru https://github.com/PortAudio/portaudio/pull/778#discussion_r1181974222

We merged the PR without resolving this issue.

dmitrykos commented 1 year ago

@RossBencina I think that review is really outdated. Check PaWasapiPassthroughFormat, it describes not only EAC3 or AC3 but also other formats too. PA WASAPI is a direct proxy for this WASAPI's functionality (passthrough), so we do not need to duplicate MS documentation and user shall refer to MS WASAPI docs about how encoded format shall look like.

RossBencina commented 1 year ago

If the approach is to defer to Microsoft documentation there should be a comment with a reference to the MS documentation.

gabys999 commented 1 year ago

I modified the ac3 test code according to @RossBencina suggestion, and when using 2 channels audio passthrough output, the dolby device plays fine. But when using 5.1 channels audio passthrough output, the number of channels is set to 6 and Pa_OpenStream returns -9996 error, the problem is in IAudioClient_Initialize here. I remember I mentioned before that vlc's nChannels parameter in WAVEFORMATEX is always set to 2, and it gives the comment /* To prevent channel re-ordering */, And after setting the Channels parameter to 2, the dolby device will still be recognized as 5.1 channels

dmitrykos commented 1 year ago

Hi @gabys999! Transport channel count must be 2, i.e CHANNEL_COUNT 2 define, for any number of encoded channels. We give a hint to the driver about encoded channel number in channelMask only but as you have found it out in practice decoder's hardware/firmware is able to guess number of encoded channels without this hint.

gabys999 commented 1 year ago

Sorry, since I haven't written the portaudio interface code for a while, I forgot the settings here, but the dolby device recognizes the passthrough data normally regardless of whether the channelMask is set to PAWIN_SPEAKER_STEREO or PAWIN_SPEAKER_5POINT1

dmitrykos commented 1 year ago

If modified test is working ok, could you please create new PR, so that @RossBencina and @philburk could review changes. It would compliment #778 as there in discussion it was decided to commit initial PR and then apply new PR with proposed changes as an additional refactoring iteration.

gabys999 commented 1 year ago

Ok, I haven't figured out how to handle the odd bytes that RossBencina mentioned, please let me understand and modify test code, or I'll submit PR first

dmitrykos commented 1 year ago

I am not sure that odd data bytes are possible at all because as we know encoded data with any number of channels is sent in 2 channel transport stream in uint16 containers, that means data stream is normally aligned to 4 bytes (2 * sizeof(uint16)). Odd byte count would signal that data stream is truncated/corrupted.

For safety of operation I would just truncate data size to 4 byte alignment:

dataBytes = dataBytes - (dataBytes & (4 - 1))
gabys999 commented 1 year ago

So does it work if I use Pa_WriteStream to feed the data stream by odd units? I'm not sure now how the Dolby device handles this incoming data and if there is a possibility to merge packets, I contacted the device provider but they didn't give any information that I can refer to and there is no technician who can interface with me. By the way, the test team in the past few days to occupy the device to test ac3 multi-channel passthrough output, the current test results seem to be correct, but the sw channel output, in dobly web monitoring is a waveform, but external speakers can not hear the sound, this probably need to test with a subwoofer to it

dmitrykos commented 1 year ago

So does it work if I use Pa_WriteStream to feed the data stream by odd units?

To my view there can't be odd units as data stream is always 4 byte aligned (2 bytes of encoded data per channel), so handling odd units is not needed. The best is to make sure that data stream length is 4-byte aligned by force-aligning length as per my previous reply.

gabys999 commented 1 year ago

So does it work if I use Pa_WriteStream to feed the data stream by odd units?

To my view there can't be odd units as data stream is always 4 byte aligned (2 bytes of encoded data per channel), so handling odd units is not needed. The best is to make sure that data stream length is 4-byte aligned by force-aligning length as per my previous reply.

I am also considering this situation can only be an odd number of short, but I'm not sure how the portaudio will respond if I force an odd number of bytes to be written, it will be out of bounds and report an error, right? @RossBencina said in the previous communication that we should consider the case of odd bytes of ac3 data, it would be simpler to do a 4-byte aligned by force-aligning length