Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

output on iOS is mono #28

Closed
morganpackard opened this issue Aug 14, 2012 · 31 comments
Closed

output on iOS is mono #28

morganpackard opened this issue Aug 14, 2012 · 31 comments

Comments

@morganpackard
Copy link
Collaborator

Am I crazy? Has this always been the case and nobody noticed until now? Novocaine is outputting audio in mono through headphones. ioData->mBuffers[0].mNumberChannels is 1.

If I figure out why, I'll make a note, and, with luck and a good attitude, commit some code.

@alexbw
Copy link
Owner

alexbw commented Aug 14, 2012

That'd be weird. I thought I always let the device decide what to output...

On Tue, Aug 14, 2012 at 2:38 PM, Morgan Packard notifications@github.comwrote:

Am I crazy? Has this always been the case and nobody noticed until now?
Novocaine is outputting audio in mono through headphones.
ioData->mBuffers[0].mNumberChannels is 1.

If I figure out why, I'll make a note, and, with luck and a good attitude,
commit some code.


Reply to this email directly or view it on GitHubhttps://github.com//issues/28.

@morganpackard
Copy link
Collaborator Author

Just downloaded Novocaine fresh from github to make sure and am getting only one channel of TLC.

@alexbw
Copy link
Owner

alexbw commented Aug 14, 2012

What in the what
Goshdarnit

On Tue, Aug 14, 2012 at 2:59 PM, Morgan Packard notifications@github.comwrote:

Just downloaded Novocaine fresh from github to make sure and am getting
only one channel of TLC.


Reply to this email directly or view it on GitHubhttps://github.com//issues/28#issuecomment-7736377.

@morganpackard
Copy link
Collaborator Author

I'm not sure I trust the ASBD that the iPhone provides. After this bit:

// Check the input stream format

# if defined ( USING_IOS )
UInt32 size;
size = sizeof( AudioStreamBasicDescription );
CheckError( AudioUnitGetProperty( inputUnit, 
                                 kAudioUnitProperty_StreamFormat, 
                                 kAudioUnitScope_Input, 
                                 1, 
                                 &inputFormat, 
                                 &size ), 

inputFormat.mNumberChannels is 2. I'd expect it to be 1.

@morganpackard
Copy link
Collaborator Author

also after this bit:

CheckError(AudioUnitSetProperty(inputUnit,
                                kAudioUnitProperty_StreamFormat,
                                kAudioUnitScope_Output,
                                kInputBus,
                                &outputFormat,
                                size),
           "Couldn't set the ASBD on the audio unit (after setting its sampling rate)");

inputFormat.mNumberChannels is 2. I tried explicitly setting the ASBD for kAudioUnitScope_Input, bus 0, which seems like it should control the number of channels in the render callback, but it had no effect. I also threw my phone out the window, and that didn't help either. I will toss my computer after it and see if that helps.

@alexbw
Copy link
Owner

alexbw commented Aug 14, 2012

Gosh diggity darn it
You getting stereo out of the iPod app?

On Tue, Aug 14, 2012 at 3:13 PM, Morgan Packard notifications@github.comwrote:

also after this bit:

CheckError(AudioUnitSetProperty(inputUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
kInputBus,
&outputFormat,
size),
"Couldn't set the ASBD on the audio unit (after setting its sampling rate)");

inputFormat.mNumberChannels is 2. I tried explicitly setting the ASBD for
kAudioUnitScope_Input, bus 0, which seems like it should control the number
of channels in the render callback, but it had no effect. I also threw my
phone out the window, and that didn't help either. I will toss my computer
after it and see if that helps.


Reply to this email directly or view it on GitHubhttps://github.com//issues/28#issuecomment-7736826.

@morganpackard
Copy link
Collaborator Author

Mono out of my phone running the demo ios app in the latest from github, stereo from simulator (running an older version of novocaine, but I suspect a newer would also be stereo).

My phone is working correctly. I'm getting audio in stereo from other apps.

@alexbw
Copy link
Owner

alexbw commented Aug 14, 2012

Aight. Gotta think about that.

On Tue, Aug 14, 2012 at 3:24 PM, Morgan Packard notifications@github.comwrote:

Mono out of my phone running the demo ios app in the latest from github,
stereo from simulator (running an older version of novocaine, but I suspect
a newer would also be stereo).

My phone is working correctly. I'm getting audio in stereo from other apps.


Reply to this email directly or view it on GitHubhttps://github.com//issues/28#issuecomment-7737150.

@morganpackard
Copy link
Collaborator Author

I will do the same.

@morganpackard
Copy link
Collaborator Author

Closing in on the problem (maybe). Looks like the render callback is expecting non-interleaved data. Does that square with your understanding Alex? I'm going to take a closer look and see if that could explain why the audio is coming through clean, but mono.

@alexbw
Copy link
Owner

alexbw commented Aug 15, 2012

Interesting. The render callback was designed to always ask for interleaved data, and then inside the machinery of Novocaine, everything gets massaged into exactly what the hardware expects, which can be any number of things (interleaved, non-interleaved, mono, stereo, SInt16 or float).

On Aug 15, 2012, at 9:29 AM, Morgan Packard wrote:

Closing in on the problem (maybe). Looks like the render callback is expecting non-interleaved data. Does that square with your understanding Alex? I'm going to take a closer look and see if that could explain why the audio is coming through clean, but mono.


Reply to this email directly or view it on GitHub.

@morganpackard
Copy link
Collaborator Author

Ok, so my previous comment about knowing things are busted because ioData->mBuffers[0].mNumberChannels is 1 may not indicate a problem. mNumberChannels indicates the number of interleaved channels.

Next potential problem:

        int thisNumChannels = ioData->mBuffers[iBuffer].mNumberChannels;

        for (int iChannel = 0; iChannel < thisNumChannels; ++iChannel) {
            vDSP_vsadd(sm.outData+iChannel, sm.numOutputChannels, &zero, (float *)ioData->mBuffers[iBuffer].mData, thisNumChannels, inNumberFrames);
        }

Even if thisNumChannels was 2, the starting point on the destination buffer is ioData->mBuffers[iBuffer].mData on every iteration. Wouldn't successive iterations just overwrite data in the same place here? Based on what I"m seeing here and what I think I understand, I'd expect the audio to be either noise/glitch in the right channel, or maybe pitched 2x too fast, but I'm hearing clean audio, just the same in each channel.

EDIT

Nevermind. Bear with me while I de-stupid myself.

@morganpackard
Copy link
Collaborator Author

Still keep ignoring me please.

@alexbw
Copy link
Owner

alexbw commented Aug 15, 2012

On it

On Wed, Aug 15, 2012 at 10:35 AM, Morgan Packard
notifications@github.comwrote:

Still keep ignoring me please.


Reply to this email directly or view it on GitHubhttps://github.com//issues/28#issuecomment-7757402.

@morganpackard
Copy link
Collaborator Author

Ok. Found the problem. Give me a cookie.

    for (int iBuffer=0; iBuffer < ioData->mNumberBuffers; ++iBuffer) {  

        int thisNumChannels = ioData->mBuffers[iBuffer].mNumberChannels;

        for (int iChannel = 0; iChannel < thisNumChannels; ++iChannel) {
            vDSP_vsadd(sm.outData+iChannel, sm.numOutputChannels, &zero, (float *)ioData->mBuffers[iBuffer].mData, thisNumChannels, inNumberFrames);
        }
    }

With interleaved data, thisNumChannels is 1 and ioData->mNumberBuffers is 2. If the data is non-interleaved, we loop through the outer loop twice and the inner loop once. If it's interleaved, the opposite happens. Either way, for a stereo signal, vDSP_vsadd gets called twice. We need to get the correct start point on sm.outData. If thisNumChannels is 2 and mNumberBuffers is 1, this works fine, but if thisNumChannels is 1 and mNumberBuffers is 2, we start at the very first sample every time in sm.outData. Adding iBuffer to the pointer offset in vDSP_vsadd fixes the problem in my particular case. Don't know what it might break in other cases though.

vDSP_vsadd(sm.outData+iChannel+iBuffer, sm.numOutputChannels, &zero, (float *)ioData->mBuffers[iBuffer].mData, thisNumChannels, inNumberFrames);

@bordev
Copy link

bordev commented Jan 27, 2013

thanks morganpackard for saving lots of time 👍

@ndonald2
Copy link
Collaborator

Reviving an old thread, but there still seems to be a problem with stereo non-interleaved output on iOS devices, at least with iPhone 4/iOS6.

The problem lies here:

for (int iBuffer=0; iBuffer < ioData->mNumberBuffers; ++iBuffer) {

    int thisNumChannels = ioData->mBuffers[iBuffer].mNumberChannels;

    for (int iChannel = 0; iChannel < thisNumChannels; ++iChannel) {
        vDSP_vfix16(sm.outData+iChannel, sm.numOutputChannels, (SInt16 *)ioData->mBuffers[iBuffer].mData+iChannel, thisNumChannels, inNumberFrames);
    }
}

For non-interleaved stereo output, there will be 2 mBuffers each with one channel of non-interleaved output. The existing code will loop through both of these, but copies the first (left) channel from the interleaved sm.outData to each output channel, since iChannel will never be larger than 0.

Fix is something like this:

if (sm.isInterleaved){

    for (int iBuffer=0; iBuffer < ioData->mNumberBuffers; ++iBuffer) {  

        int thisNumChannels = ioData->mBuffers[iBuffer].mNumberChannels;

        for (int iChannel = 0; iChannel < thisNumChannels; ++iChannel) {
            vDSP_vsadd(sm.outData+iChannel, sm.numOutputChannels, &zero, (float *)ioData->mBuffers[iBuffer].mData, thisNumChannels, inNumberFrames);
        }
    }
}
else{
    for (int iChannel = 0; iChannel < sm.numOutputChannels; iChannel++){
      if (iChannel > ioData->mNumberBuffers) break; // this shouldn't happen
      vDSP_vsadd(sm.outData+iChannel, sm.numOutputChannels, &zero, (float *)ioData->mBuffers[iChannel].mData, 1, inNumberFrames);
    }
}

The break statement is a safeguard but unless CoreAudio is reporting incorrect format info, it should never happen.

I have it working on another project (collab with @morganpackard actually). Happy to submit a pull request if this looks good.

@ndonald2
Copy link
Collaborator

Or what morgan said 7 months ago also works...

@alexbw
Copy link
Owner

alexbw commented Mar 21, 2013

I would totally love a pull request. Nick and Morgan — you guys are some of
the most active users of Novocaine, do either of you want to be able to
contribute directly to the project?
My involvement has dipped significantly because of other obligations.
Would love to have some other devs onboard as contributors.

On Wed, Mar 20, 2013 at 7:41 PM, Nick D. notifications@github.com wrote:

Or what morgan said 7 months ago also works...


Reply to this email directly or view it on GitHubhttps://github.com//issues/28#issuecomment-15211054
.

@morganpackard
Copy link
Collaborator Author

I don't see why not. I'll be gentle, I promise.
-m-

On Wed, Mar 20, 2013 at 8:52 PM, Alex Wiltschko notifications@github.comwrote:

I would totally love a pull request. Nick and Morgan — you guys are some
of
the most active users of Novocaine, do either of you want to be able to
contribute directly to the project?
My involvement has dipped significantly because of other obligations.
Would love to have some other devs onboard as contributors.

On Wed, Mar 20, 2013 at 7:41 PM, Nick D. notifications@github.com
wrote:

Or what morgan said 7 months ago also works...


Reply to this email directly or view it on GitHub<
https://github.com/alexbw/novocaine/issues/28#issuecomment-15211054>
.


Reply to this email directly or view it on GitHubhttps://github.com//issues/28#issuecomment-15213556
.

Morgan Packard
cell: (720) 891-0122
aim: mpackardatwork
twitter: @morganpackard

@alexbw
Copy link
Owner

alexbw commented Mar 24, 2013

Ok Morgan and Nick. You're contributors and stewards. Nick, we haven't met (I don't think...) but Morgan says you're a smarty pants and a half, so you're in too.

@morganpackard
Copy link
Collaborator Author

Thanks Alex!

Sent from my iPhone

On Mar 24, 2013, at 6:23 PM, Alex Wiltschko notifications@github.com
wrote:

Ok Morgan and Nick. You're contributors and stewards. Nick, we haven't met
(I don't think...) but Morgan says you're a smarty pants and a half, so
you're in too.


Reply to this email directly or view it on
GitHubhttps://github.com//issues/28#issuecomment-15370802
.

@dwsolberg
Copy link

I"m experiencing this same problem.

@alexbw
Copy link
Owner

alexbw commented Mar 29, 2013

Morgan, if you find the time, can you pull in your changes that fix this?

On Fri, Mar 29, 2013 at 12:17 PM, David Solberg notifications@github.comwrote:

I"m experiencing this same problem.


Reply to this email directly or view it on GitHubhttps://github.com//issues/28#issuecomment-15648135
.

@ghost
Copy link

ghost commented Mar 29, 2013

Sorry, how can I unsubscribe from this list?

On Mar 29, 2013, at 12:18 PM, Alex Wiltschko notifications@github.com wrote:

Morgan, if you find the time, can you pull in your changes that fix this?

On Fri, Mar 29, 2013 at 12:17 PM, David Solberg notifications@github.comwrote:

I"m experiencing this same problem.


Reply to this email directly or view it on GitHubhttps://github.com//issues/28#issuecomment-15648135
.


Reply to this email directly or view it on GitHub.

Hans Tutschku
www.tutschku.com

@dwsolberg
Copy link

FYI, either suggested fix worked for me on an iPad with iOS 6 using a .m4a file.

@morganpackard
Copy link
Collaborator Author

Will do.

On Fri, Mar 29, 2013 at 12:18 PM, Alex Wiltschko
notifications@github.comwrote:

Morgan, if you find the time, can you pull in your changes that fix this?

On Fri, Mar 29, 2013 at 12:17 PM, David Solberg notifications@github.comwrote:

I"m experiencing this same problem.


Reply to this email directly or view it on GitHub<
https://github.com/alexbw/novocaine/issues/28#issuecomment-15648135>
.


Reply to this email directly or view it on GitHubhttps://github.com//issues/28#issuecomment-15648204
.

Morgan Packard
cell: (720) 891-0122
aim: mpackardatwork
twitter: @morganpackard

@alexbw
Copy link
Owner

alexbw commented May 23, 2013

Is this pulled in yet?

@alexbw
Copy link
Owner

alexbw commented Nov 15, 2013

@morganpackard Is this a dead issue?

@morganpackard
Copy link
Collaborator Author

I think so.

Sent from my iPhone

On Nov 14, 2013, at 11:36 PM, Alex Wiltschko notifications@github.com
wrote:

@morganpackard https://github.com/morganpackard Is this a dead issue?


Reply to this email directly or view it on
GitHubhttps://github.com//issues/28#issuecomment-28546840
.

@alexbw alexbw closed this as completed Nov 15, 2013
@MohdFarhanKhan
Copy link

Hi,

Am novocain addicted new ios developer. Am using novocain in an ios project. App is recording 2 channel audio. Client records audio with a sensor device. That sensor also can work as receiver. Client's requirement is to send a tone to sensor not speaker while recording from sensor. Please help me how to send tone to sensor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants