How to stream audio as data is downloaded? - ios

How can I take data as it is being downloaded/received by my device and then play it through the iPhone speaker? I do not want to wait until the audio is fully downloaded.
Platform: iOS 8.0 +
File type: WAV
Sample Rate: 4000 Hz
Audio Type: PCM, 16 bit
Audio Channels: 1

To minimize latency, pre-enable the apps audio session and request very short buffer durations. Start the RemoteIO Audio Unit output running with the output callback polling a circular buffer, otherwise playing a bit of silence. Then format (resample if needed) and store samples of the wave file, as any portions of the wave file are received, in the circular buffer.

Related

Resample audio in iOS

I have a wave file recorded in 48000 sample rate. I need to play the recorded audio file in BLE device configured with 44100 sample rate. When the BLE device is disconnected from iPhone, i need to resume the playback in iPhone speaker which is configured by 48000 sample rate. So is it possible to resample the audio data to 44100 while sending data to connected BLE device
Please help
Yes, this is handled automatically for you if you use AVAudioPlayer.

Getting audio samples from speakers

So I have two questions:
Is there another (maybe low-level) way to get float* samples of the audio that is currently playing?
Is it possible to do it from inside a framework? I mean when you don't have access to the instance of AVPlayer(or AVAudioPlayerNode, AudioEngine, or even low-level CoreAudio classes, whatever) who owns the audio file? Is there a way to subscribe (in order to analyze, or also may be for modifying/equalizing) to audio samples that are being played via speakers/earphones?
I've tried to install a tap on audioEngine.mainMixerNode which works, but when I set the bufferSize more than 4096 (in order to compute high-density FFT), the callback is called less frequently than it should (about 3 times in a second instead of 30 times or even frequently).
mixerNode.installTap(onBus: 0,
bufferSize: 16384, //or 8192
format: mixerNode.outputFormat(forBus: 0))
{[weak self] (buffer, time) in
//this block is being called LESS frequently...
}
I know that CoreAudio is very powerful and there should be something for this kind of purposes..
An iOS app can only get played audio samples from raw PCM samples that the app itself is playing. Any visibility into samples output by other apps or processes is blocked by the iOS security sandbox. An iOS app can sample audio from the device's microphone.
In an audio engine tap-on-bus, audio samples are delivered to the application's main thread, and thus limited in callback frequency and latency. In order to get the most recent few milliseconds of microphone audio samples, an app needs to use the RemoteIO Audio Unit callback API, where audio samples can be delivered in a high-priority audio context thread.

iOS AudioQueue playing AAC data always delay for 2-3 seconds

Recently I was using AudioQueue to play network AAC data. My plan is that once a AAC data is received, audioqueue enqueue this buffer and play immediately.
When I start audioQueue, I use AudioQueueStart(audioQueue, NULL) to start audioQueue as soon as possible.
However, when I print log, I notice that the AAC buffer was enqueued by AudioQueueEnqueueBuffer(audioQueue, buffer, 0, NULL) immediately but the sound played after enqueuing buffer which delayed for around 2-3 seconds. It means I received and enqueued the data at beginning but the first sound started 2-3 seconds later.
I wonder if it is because that audioqueue service decode AAC to PCM itself so the sounds delayed. If so, should I decode AAC myself and use Audio Unit instead?
I've been confused for a while and wish anyone can light me up!
Finally I found the reason. When the AAC data is late, I pause the audioQueue and start again when the data come. the PAUSE operation lead to the delay of playback.

EZAudio doesn't work with Bluetooth devices

I am using EZAudio to playback streaming audio data. Here is the graph: AUConverter -> MultiChannelMixer -> Output. The converter is configured such that it converts audio data with a sampling rate of 48000 to device sampling rate (normally 44100). The audio data will be written into a converter node
AURenderCallbackStruct converterCallback;
converterCallback.inputProc = EZOutputConverterInputCallback;
converterCallback.inputProcRefCon = (__bridge void *)(self);
[EZAudioUtilities checkResult:AUGraphSetNodeInputCallback(self.info->graph,
self.info->converterNodeInfo.node,
0,
&converterCallback)
operation:"Failed to set render callback on converter node"];
This graph works well with iphone's speakers. But when I select a bluetooth device, the callback is no longer triggered and no audio is played.
If I remove the converter node, I can play the audio again with a bluetooth device, but the sound quality is terrible. Please help, what am I missing in order to play audio in a bluetooth device.
Thanks.

Sending Serial Data via AudioQueue in conjunction with Audio via Audio Out

Looking to send 9600 baud symbols generated from AudioQueue syncronized with audio, both of which will output via audio out port. If the serial data is at 19.2kHz is that effectively out of hearing range? Trying to get the audio out clean without audible distortion from serial data.
Thanks for input.

Resources