PortAudio / portaudio

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

CoreAudio implementation doesn't support non-interleaved ReadStream and WriteStream #77

Open PortAudio-admin opened 16 years ago

PortAudio-admin commented 16 years ago

Issue created by @RossBencina

There is no test for this case either.

See mailing list discussion thread 19/2/2008: Re: [Portaudio] ASIO Blocking I/O Patch Implementation (a ring buffercontaining frames, not bytes)

So I took a look at pa_mac_core_blocking.c, what I noticed is:

  • It doesn't seem to use the buffer processor

  • It doesn't appear to handle non-interleaved calls to ReadStream/ WriteStream (shall I create a ticket for that?). This particular
    case is one of the reasons why Sven is using the buffer processor on
    the ReadStream()/WriteStream() side of the queue.

Yes, since that sounds like a major issue and I won't be able to
address that anytime soon. Is there a test for it?

[nope]

There is a ticket to implement the test: #83

PortAudio-admin commented 16 years ago

Comment by @RossBencina

Moved half of this to a separate ticket targetting the buffer processor.

PortAudio-admin commented 13 years ago

Comment by @philburk

A long time ago Roman M. Shulakov wrote: I believe there might be a bug in a MacOS part when playing audio from separate non-interleaved buffers using blocking API. If I got it right, one needs to OR 'paNonInterleaved' flag with a sample format in use when describing PA stream parameters. After this Pa_WriteStream() will take an array of (void *) pointers to separate buffers, one per channel, instead of a pointer to one large interleaved buffer. This works nicely on Linux. On OSX however, Pa_WriteStream() never returns. I traced it down to internal ring buffer having size of zero thus never being ready to accept a single byte of data. This condition seems to be caused by 'computeSampleSizeFromFormat()' and 'computeSampleSizeFromFormatPow2()' procs in 'pa_mac_core_blocking.c' not expecting any extra flags OR'ed with a sample format.

Next I tried to help it by changing lines 79 and 94 from:

switch( format ) {

to:

switch( format & (~paNonInterleaved) ) {

This gave an internal ring buffer a reasonable size, however it also caused a memory corruption in CoreAudo RT thread (I think). Any ideas?

PortAudio-admin commented 13 years ago

Comment by @philburk

I verified Roman's analysis of the computeSampleSizeFromFormat() error.

PortAudio-admin commented 13 years ago

Comment by @philburk

It looks like the fix is non-trivial. The implementation uses the ringbuffer to write data to CoreAudio. We probably need to interleave the data as it is written to the ringbuffer and then make the back iend run in interleaved mode.

For now I just added code to detect paNonInterleaved and return paSampleFormatNotSupported. I also fixed the switch statements that return sample size.

PortAudio-admin commented 12 years ago

Comment by @RossBencina

TRAC migration: propagating ticket status from TRAC

RossBencina commented 2 years ago

Note that PA/ASIO implements ReadStream() and WriteStream() using the PaBufferProcessor, which should be able to handle the interleaved and non-interleaved cases. This code code could be copied/adapted.

ReadStream: https://github.com/PortAudio/portaudio/blob/f217b421cf7336a5e7cc03181289df6c8974966e/src/hostapi/asio/pa_asio.cpp#L3547

WriteStream: https://github.com/PortAudio/portaudio/blob/f217b421cf7336a5e7cc03181289df6c8974966e/src/hostapi/asio/pa_asio.cpp#L3718

But note that there might be a bug in the PA/ASIO ReadStream implementation: https://github.com/PortAudio/portaudio/issues/746