Distorted sound when using remote I/O AudioUnit - iphone

Consider aurioTouch sample application provided by Apple. I wanted to simulate a lengthy processing of the recorded audio and modified the sample by introducing a delay of 0.1 second in the render callback method: PerformThru. This leads to a distorted audio and static noise being played through iPhone's speaker or headphones. The noise is heard even when the mute button in the application is on which essentially outputs silence into AudioUnit output bus.
Can anybody give a detailed explanation what happens on the low level when the host's callback function (in our sample it is PerformThru) does not return in a timely fashion?
Why a callback function that performs poorly makes iPhone playback the noise?
I understand that the code in the callback function must be highly optimized. Still I would like to know if it is possible to prevent the noise from happening.
Is it possible to modify aurioTouch sample to make AudioUnit do just the recording and switch the playback off completely?

If you want to introduce a delay then you need to do this via buffering, not by simply delaying the callback. E.g. for 0.1 s and a 44.1 kHz sample rate you would need to buffer an additional 4410 samples. Initially you would pass 4410 0s and then start passing your buffered (delayed) samples.

Related

iOS7 robotic/garbled in speaker mode on iPhone5s

We have a VOIP application, that records and plays audio. As such, we are using PlayAndRecord (kAudioSessionCategory_PlayAndRecord) audio session category.
So far, we have used it successfully with iPhone 4/4s/5 with both iOS 6 and iOS 7 where call audio and tones played clearly and were audible.
However, with iPhone 5s, we observed that both the call audio and tones sound robotic/garbled in speaker mode. When using earpiece/bluetooth/headset, sound is clear and audible.
iOS Version used with iPhone 5s: 7.0.4
We are using audiounits for recording/playing of call audio.
When setting audio properties like session category, audio route, session mode etc., we tried both the older (deprecated) AudioSessionSetProperty() and AVAudioSession APIs.
For playing tones, we are using AVAudioPlayer. Playing of tones during the VOIP call and also when pressing keypad controller within the app produces robotic sound.
When instantiating the audio component using AudioComponentInstanceNew, we set componentSubType to kAudioUnitSubType_VoiceProcessingIO.
When replacing kAudioUnitSubType_VoiceProcessingIO with kAudioUnitSubType_RemoteIO, we noticed that the sound of call audio and tones was no longer robotic, it was quite clear, but the volume level was very low when using speaker mode.
In summary, keeping all the other audio APIs the same:
kAudioUnitSubType_VoiceProcessingIO: Volume is high (desirable) but sound of tones and call audio was robotic in speaker mode.
kAudioUnitSubType_RemoteIO: Sound of tones and call audio was clear but it is not audible.
STEPS TO REPRODUCE
- Set audio session category to playAndRecord.
- Set audio route to speaker
- Set all the other audio properties like starting audio unit, activating the audio session, instantiating the audio components.
- Set the input and render callbacks
- Try both options
1. Play tones using AVAudioPlayer
2. Play call audio
Any suggestions on how to get over this issue. Raised as an issue with Apple but no response yet from them.
i have shared the code here github link
The only difference between kAudioUnitSubType_VoiceProcessingIO and kAudioUnitSubType_RemoteIO is that voiceProcessing includes code to tune out acoustic echo i.e. tunes out the noise from the speaker so the microphone doesn't pick it up. Its been a long time since I've played with the audio framework but I remember that to sound off there could be any number of things,
Are you doing any work in the audio callbacks that could be taking a long time?
The callbacks run on realtime threads. if your processing takes too long you can miss data. Would be helpful to track the data over a fixed period of time to see are you capturing it all. Use something like wireShark to sniff the network. Record the number of packets and see did the phone capture the same.
Are you modifying any of the audio?
Do you have a circular buffer that might be causing an issue?
I've had several issues doing this and one was using a third party circular buffer that was described as low latency and efficient ... it wasn't. I answered my own question here and included my circular buffer implementation that greatly improved my audio as the issue was I was skipping data.
Give this a go and let me know:
iOS UI are causing a glitch in my audio stream
Please be aware that some of this code is unique to the audio format ALaw, 0xD5 is a byte of silence in ALaw, if you are using linear PCM or any other that will probably be a noise of some kind.

Generate paused/discontinuous beeps in iPhone App

I am creating one sound based application where I need to generate different oscillations for sound wave. One part that I need to achieve in this is the discontinuous or paused beep. I am trying to do this using I'm doing variations in the sine wave using Core Audio, but I'm not getting the desired output.
Basically I need to generate variable sound oscillation patterns like Dog Whistler app.
Can anyone help me in proper direction for this
have a look at my other answer how to loop background music. You can create an audio file with 0.5 sec beep and 1 sec silence and loop that file infinitely via AVAudioPlayer. As well as pausing the beep sequence via [player pause];
This will work if you have some predefined beep intervals/oscillations but not if you need 100% user customization. You can also look for sound effects to adjust the pitch and frequency.

Best way to play a sound with an attack / sustain (loop) / decay with AVAudioPlayer

I am having a problem finding resources on playing an attack (start of sound) / sustain (looping sound) / decay (ending of sound) sequence with no transition breaks. Are there any good libraries for handling this, or should I roll my own with AVAudioPlayer? Is AudioQueue a better place to look? I used to use SoundEngine.cpp, but that's been long gone for a while. Is CAF still the best format to use for it?
Thanks!
From your description, it sounds as if you're trying to write a software synthesizer. The only way that you could use AVAudioPlayer for something like this would be to compose the entire duration of a note as a single WAV file and then play the whole thing with AVAudioPlayer.
To create a note sound of arbitrary duration, one that begins playing in response to a user action (like tapping a button) and then continues playing until a second user action (like tapping a "stop" button or lifting the finger off the first button) begins the process of ramping the looped region's volume down to zero (the "release" part), you will need to use AudioQueue (AVAudioPlayer can be used to play audio constructed entirely in memory, but the entire playback has to be constructed before play begins, meaning that you cannot change what is being played in response to user actions [other than to stop playback]).
Here's another question/answer that shows simply how to use AudioQueue. AudioQueue calls a callback method whenever it needs to load up more data to play - you would have to implement all the code that loops and envelope-wraps the original WAV file data.
creating your own envelope generator is very simple. the tough part will be updating your program to use lower level audio services in order to alter the signal directly.
to do this, you will need:
the audio file's samples
set up an AudioQueue (that's one approach, but i am going with it because it was mentioned in the OP, and it is relatively high level API for a user provided sample buffer)
provide a signal to the queue
determine if your program is best in realtime or pre-rendered
Realtime
Allows live variations
manage your loop points
manage your render position
be able to determine the amplitude to apply based on the sample position range you are reading
or
Prerendered
May require more memory
Requires less CPU
apply the envelope to your copy of the sample buffer
manage your render position
I also assume that you need only slow/simple transitions. If you want some crazy/fast LFO, without aliasing, you will have a lot more work to do. This approach should not produce audible aliasing unless your changes are too abrupt:
Writing a simple envelope generator (EG) is easy; check out Apple's SinSynth for a very basic EG if you need a push in that direction.

Audio recording and wave form drawing on ios

I'm recording audio using AVAudioRecorder and after recording I want to draw a wave form of the recorded audio. I've found a nice article about wave form drawing, but it first I need the frequencies at a certain sample rate as floats, right?
Do I need to do FFT on the audio and how do I do this? Is *AVAudioRecorder** even the API for this purpose? Or do I need to use some lower API to record the audio?
Hope someone can help me.
AVAudioRecorder doesn't look like it's much use for this (although it may be possible). You need to look at recording with AudioQueue.
The 'waveform' of the audio isn't the frequencies. The waveform is the value of the samples that make up the audio (you can get these when recording with an AudioQueue). FFT converts the audio samples from the time domain to the frequency domain - if you draw the output of the FFT you will have a Spectrograph instead of a waveform.

iOS: Audio Unit RemoteIO AudioBuffer manipulation (i.e. sound effects from microphone)

I've been playing around with Apple's aurioTouch demo which is sample code for their Audio Unit tutorial. This application allows simultaneous input/output from the mic. to speaker. It also renders a stereograph of the inputted sound from the mic.
At a really high-level of this low-level process, the sample code defines an AudioComponent (in this case RemoteIO which allows for simultaneous input/output) and there is a render callback for this Audio Unit. In the callback they do some audio filtering (a DC Rejection Filter) and visualization of the stereograph based on the AudioBuffer sound data from the mic.
My ultimate goal is to create my own custom sound distortion Audio Unit based on the input from the mic. I think the proper way to do this based on the Audio Unit tutorial is to make a second Audio Unit and connect them with an Audio Processing Graph. However, I've read that iOS doesn't allow you to register your own custom Audio Units. My questions are:
Can I do direct manipulation on the AudioBufferList that I have access to in the render callback from the remoteIO Audio Unit (since they already seem to be doing this and applying an audio filter on it) and create my own custom sound distortion there?
I've tried assigning the AudioBufferList data to a constant (a value I've seen it hold from a sample run and logging of the AudioBufferList), but it appears to do nothing.
The answer to your first question is yes. That is generally how it is done.
I believe that you need to manipulate the data in the pointer directly, rather than reassigning. You may want to take a look at the code in openframeworks that handles assigning buffers and passing them to a callback: https://github.com/openframeworks/openFrameworks/blob/master/addons/ofxiPhone/src/sound/ofxiPhoneSoundStream.mm
There is other code out there that you can look at, nick collins has a basic application for getting sound off the microphone and out the speaker, whist processing inbetween: http://www.cogs.susx.ac.uk/users/nc81/code.html. He also has code there that gets sample buffers out of a iPod track that may be useful to you.
It is true that you can not add your own custom AudioUnits to the iPhone.
The way it works it like this: The speaker drives the pull-chain of data through the system. You add a render callback to the ioUnit, as you have already done.
The callback runs whenever the speaker (bus #0) is hungry and it is your job to fill in as many samples as it has requested, in the buffer that the speaker has provided. The size of the provided buffer will be a power of two that is as close as possible to the Preferred IO Buffer Duration you specified when configuring the AudioSession.
The simplest way to do that is to take the AudioBufferList you were given and pass it to AudioUnitRender on the the microphone (bus #1). After you fill in the buffer with Render(), but before the callback returns, you can manipulate the data any way you like. For example, AurioTouch zeroes it out to mute it.
The important thing to remember is that the speaker is going to read from the actual data buffer that it passed you. It is not going to look at the AudioBufferList descriptor and check if you pointed to another databuffer. If you start changing the AudioBufferList that you were given, you will run into problems. At best, you will be ignored. At worst, you will run into memory management issues.
If you don't want to be constrained to working in just the ioData buffer, then you can use your own AudioBufferList, allocated any way you like, in any size, and ask the microphone to Render() into that. Then you can do all the manipulation you like so long as in the end you copy the results into the buffer provided by the callback (i.e. ioData->mBuffers[0].mData as it was at the time the Callback was invoked).