iOS: Obtaining raw PCM data from audio file - ios

I'm investigating a straightforward task:
open an audio file from the iPhone's 'iPod audio library'
allows the user to select a chunk by setting two markers: start and end time
time-reverse this chunk
save it as a new file
What are my options?
I will list the results of a couple of hours of research: ( forgive the mess, I will as always tidy pu once I have figured it out )
http://lists.apple.com/archives/coreaudio-api/2005/May/msg00096.html <-- 'I'm currently trying to create a program that plays back audio using an AUAudioFilePlayer
AudioUnit plugin that streams the audio to an output AudioUnit'
AUFilePlayer
http://lists.apple.com/archives/coreaudio-api/2008/Dec/msg00156.html
http://zerokidz.com/audiograph/docs/audiograph.pdf <-- this possibly links to code that does it, but it says it is in beta
When reading audio file with ExtAudioFile read, is it possible to read audio floats not consecutively? <-- this leads to an OS X project that reads an audio file from disk into memory; looking through the code leads us to:
https://developer.apple.com/library/mac/#documentation/MusicAudio/Reference/ExtendedAudioFileServicesReference/Reference/reference.html
as far as I can see the audio Graph project attempts to stream the audio from file in real-time, whereas Stephan's Project just exposes the audio; however it looks like he is using obsolete API calls.
this looks like the right code ( apart from the fact that there seems to be a bug in it ): https://stackoverflow.com/questions/8533143/decoding-mp3-files-by-extaudiofileopenurl
http://cocoadev.com/forums/discussion/499/core-audio/p1
https://developer.apple.com/library/ios/#samplecode/iPhoneExtAudioFileConvertTest/Introduction/Intro.html <-- here is an official Apple sample project that could probably be modified to get what I'm after

I believe you can use IphoneExtAudioFileConvertTest like you said to get what you need, after the user marks what times he wants, first thing you want to do is convert to PCM, next you need to find out which packets are the ones you need, write that to an audio file and then recompress... I wrote an answer here on how to get x amount of seconds from an audio file, ive only tested it with mp3 and m4a, but it can be adapted to PCM (pcm should be easier to do since its linear).
Daniel

Related

How to play mp3 content from resource in Delphi?

I have a TResourceStream contains a simple WAV sound.
I wrote that line into the resource.res file:
sound WAV "res\notify.wav"
I have the following method that works with WAV:
Res := TResourceStream.Create(HInstance, 'sound', 'WAV');
Res.Position := 0;
SndPlaySound(res.Memory, SND_MEMORY or SND_ASYNC);
Res.free;
I converted the WAV into MP3 and did the following things:
resource.res file: sound MP3 "res\notify.MP3"
Changed the play method first line to:
Res := TResourceStream.Create(HInstance, 'sound', 'MP3');
But nothing happens. It doesn't throw any exception, simple no sound heard.
How can I play MP3 as simple as WAV files?
The SndPlaySound API only supports waveform audio. It is not a general purpose multi-media API and as such does not (directly nor easily) support MP3 playback.
To play your audio through this API you would first need to decode the MP3 into the waveform format that the API expects.
(I should note that it appears to be possible to get the SndPlaySound API to play MP3 data by attaching a WAV header to the data. But detailed information about the audio is required in that header and the process is a decidely non-trivial exercise. It is almost certainly harder than using an API more suited to the task from the start.)
Your approach appears to be correct for obtaining a stream containing your MP3 data and with that data in memory there are a number of options available for playing that MP3 audio.
The BASS Audio Library is one such option though this is a commercial library and is not particularly cheap. It is however capable of exactly what you need.
There are numerous alternatives however, some cheaper, some even free which might also do the job though you may find it harder to get assistance with these if they are not as widely used or as well supported.
Even so, you might wish to review some of the alternatives listed on the torry.net directory. Specifically in the Components \ Effects and Multimedia section of the catalog.

How to play wav file with 8Kbps bit rate in iOS application?

I develop an iOS application where i should call web service and return audio file ( as byte array ) then play it to user .
I have problem with audio file format as it has 8 Kbps bit rate and no player inside app can play it. when I convert it to any other bit rate for example (13 Kbps) from server side to test it works properly . However i have a huge number of file where converting them manually is impossible . is there any way to convert file inside iOS app code ?
To address your comment about converting the files manually: Is it a plausible solution for you to do it automatically, server side? If so, you probably have a few options.
One would be to install Audacity, which handles all of these bit rates, and use the Chains feature for batch processing. If it's a one-off conversion you could initiate it manually, otherwise you may need to find a way of scripting the process (if new files come in from an external source, that is).
As for playing these files in iOS, have you considered embedding libpd (just one example of many, but one that you can get up and running in minutes)? It has a fairly open approach to file playback, and may handle these file formats. If you send me an example I can test right away!

Capture, encode then stream video from an iPhone to a server

I've got experience with building iOS apps but don't have experience with video. I want to build an iPhone app that streams real time video to a server. Once on the server I will deliver that video to consumers in real time.
I've read quite a bit of material. Can someone let me know if the following is correct and fill in the blanks for me.
To record video on the iPhone I should use the AVFoundation classes. When using the AVCaptureSession the delegate method captureOutput:didOutputSampleBuffer::fromConnection I can get access to each frame of video. Now that I have the video frame I need to encode the frame
I know that the Foundation classes only offer H264 encoding via AVAssetWriter and not via a class that easily supports streaming to a web server. Therefore, I am left with writing the video to a file.
I've read other posts that say they can use two AssetWritters to write 10 second blocks then NSStream those 10 second blocks to the server. Can someone explain how to code the use of two AVAssetWriters working together to achieve this. If anyone has code could they please share.
You are correct that the only way to use the hardware encoders on the iPhone is by using the AVAssetWriter class to write the encoded video to a file. Unfortunately the AVAssetWriter does not write the moov atom to the file (which is required to decode the encoded video) until the file is closed.
Thus one way to stream the encoded video to a server would be to write 10 second blocks of video to a file, close it, and send that file to the server. I have read that this method can be used with no gaps in playback caused by the closing and opening of files, though I have not attempted this myself.
I found another way to stream video here.
This example opens 2 AVAssetWriters. Then on the first frame it writes to two files but immediately closes one of the files so the moov atom gets written. Then with the moov atom data the second file can be used as a pipe to get a stream of encoded video data. This example only works for sending video data but it is very clean and easy to understand code that helped me figure out how to deal with many issues with video on the iPhone.

AUGraph setup on iOS

I am designing an AUGraph for an iOS application and would appreciate help on the following things.
If I want to play a number of audio files at once, does each file need an audio unit?
From the Core-Audio docs
Linear PCM and IMA/ADPCM (IMA4) audio You can play multiple linear PCM or IMA4 format sounds simultaneously in iOS without incurring CPU resource problems.
AAC, MP3, and Apple Lossless (ALAC) audio Playback for AAC, MP3, and Apple Lossless (ALAC) sounds uses efficient hardware-based decoding on iPhone and iPod touch. You can play only one such sound at a time.
So multiple AAC or MP3 files cannot be played at the same time. What is the optimal LPCM format to play multiple sounds at once?
Does this apply to Audio-Units too, as this in under the AudioQueue documentation.
Can an audio unit in an AUGraph be inactive? If an AUGraph looks like this
Speaker/output < recorder unit < mixer unit < number of audio file playing units
what happens if the recorder is not active, would it still pull, but just not write the buffers to a file?
No; you need to use the mixer audio unit. Check this:
http://developer.apple.com/library/ios/DOCUMENTATION/MusicAudio/Conceptual/AudioUnitHostingGuide_iOS/ConstructingAudioUnitApps/ConstructingAudioUnitApps.html#//apple_ref/doc/uid/TP40009492-CH16-SW1
Mostly reading the document above, wrapping the sample code in a class and creating a pair of utility structures, I coded this 'Simple Sound Engine' from scratch:
ttp://nicolasmiari.com/blog/a-simple-sound-engine-for-ios-using-the-audio-unit-framework/
(Link to article in my blog containing the source code). Sorry, moved blog to Jekyll/Github and this article didn't make the cut.
...I was going to start a repo on github, but it's too much trouble. I am a visual guy, still pretty much git-phobic. Okay, that was a long time ago... Now I use git from the command line :-)
You can use it as-is, or extract the Audio Unit-related code and adapt it to your project.
I believe the Cocos Denshion 'Simple Audio Engine' does pretty much the same thing, but haven't checked the source code.
Known issues
If you have an exception breakpoint set for C++ exceptions, when debugging, the code will stop 2 or 3 times on AUGraphInitialize(). This is a 'non-crashing' exception, so you can click on continue and the code works OK.
To convert your wav files to the uncompressed .caf format, use this command on the Terminal:
%afconvert -f caff -d LEI16 mysoundFile.wav mySoundFile.caf
EDIT: So I created a GitHub repo after all:
https://github.com/nicolas-miari/Sound-Engine
Both ordinary common .wav and .caf files contain raw PCM audio samples, and can be played without hardware assist or DSP processing if already at the destination sample rate.
When there's no audio file or other synthesized data to feed an audio unit that's pulling buffers, the usual practice is to feed it buffers of silence (or perhaps a taper to zero if the previous buffer ended with non-zero amplitude).

Using Audio Units to play several short audio files with overlap

I have run through an audio units tutorial for a sine wave generator and done a bit of reading, and I understand basically how it is working. What I would actually like to do for my app, is play a short sound file in response to some external event. These sounds would be about 1-2 seconds in duration and occur at a rate of about about 1-2 per second.
Basically where I am at right now is trying to figure out how to play an actual audio file using my audio unit, rather than generating a sine wave. So basically my question is, how do I get an audio unit to play an audio file?
Do I simply read bytes from the audio file into the buffer in the render callback?
(if so what class do I need to deal with to open / convert / decompress / read the audio file)
or is there some simpler method where I could maybe just hand off the entire buffer and tell it to play?
Any names of specific classes or APIs I will need to look at to accomplish this would be very helpful.
OK, check this:
http://developer.apple.com/library/ios/samplecode/MixerHost/Introduction/Intro.html
EDIT: That is a sample project. This page has detailed instructions with inline code to setup common configurations: http://developer.apple.com/library/ios/ipad/#DOCUMENTATION/MusicAudio/Conceptual/AudioUnitHostingGuide_iOS/ConstructingAudioUnitApps/ConstructingAudioUnitApps.html#//apple_ref/doc/uid/TP40009492-CH16-SW1
If you don't mind being tied to IOS 5+, you should look into AUFilePlayer. It is much easer then using the callbacks and you don't have to worry about setting up your own ring buffer (something that you would need to do if you want to avoid loading all of your audio data into memory on start-up)

Resources