How to set bit rate in audio queue - iphone

I'm using speak here code for audio recording with audio format kAudioFormatMPEG4AAC.
How can i change bit rate to 96K, 128K or 320K?
Regards,
John

I'm not sure if you can do this directly using AudioQueue by setting a parameter. However, I think the following approach will work:
Setup your AudioQueue to record to linear PCM
Setup an ExtAudioFile with a client data format matching the AudioQueue and a file data format of AAC
Set the desired AAC bitrate by getting the AudioConverter associated with the ExtAudioFile (kExtAudioFileProperty_AudioConverter) and set the converter's bitrate (kAudioConverterEncodeBitRate).
I haven't tried this on iOS, but if the AAC encoder is using a hardware codec I doubt you will be able to set the bitrate. AudioFormat.h gives some methods to determine which codecs are hardware vs. software and ways to request one implementation vs. another.

The fact is, AudioQueue is using the same backend as AudioConverter, although there is no key for bitRate in AudioQueueProperty enom, you can still borrow them from converter. Get the bit rate like this:
AudioQueueGetProperty(mQueue, kAudioConverterEncodeBitRate, &bitRate, &propertySize);
and set it like this:
AudioQueueSetProperty(mQueue, kAudioConverterEncodeBitRate, &bitRate, propertySize);

Related

mp4v2 extracting and decoding data from .M4A file

I have extracted the audio data from .m4a file using mp4v2 library (sample-by-sample). Does this library have function that decodes the data? Anybody with experience with this library and can provide some help?
The documentation says:
MP4ReadSample function reads the specified sample from the specified track.
Typically this sample is then decoded in a codec dependent fashion and
rendered in an appropriate fashion.
I am interesed in decoding the output.
Thanks in advance.
You tagged MP4(video data) and M4A(audio data). Since you are extracting from M4A, I can only imagine you actually have either AAC or MP3 audio data.
Each extracted sample (bytes) is audio frame.
To make a playable MP3 file : Simply join all MP3 frames' bytes together. Save as .mp3 to play later.
To make a playable AAC file : For each AAC frame, first create an ADTS header (7 bytes) followed by that frame's data. You can test your header bytes here (site shows what your byte values mean). When all your AAC frames each begin with an ADTS header, simply save as .aac to play later using some audio payer code.
I have researched everything and the answer is NO. There is no decoder in mp4/mp4v2 libraries. One has to use some other library to do that.

How to create an Mp4 file from H264 raw data that I am receiving from a live streamer

How to create an Mp4 file from H264 raw data that I am receiving from a live streamer (no predefined duration or moov atom), unfortunately can't use FFMPEG, I have to write my own code using live555. Can somebody help me with Mp4 container and how h264 data has to be pushed into it.? Thank you in advance : )
There are several operations to be made to store H.264 raw data into MP4, among them:
create box structures, in particular the moov box
store the NAL units in a mdatbox, possibly storing non-VCL NAL units in the moovbox
replace start codes with length fields
It also depends on your requirements. If you want to do the conversion on-the-fly, you have to use fragmented mp4. If you can store the H264 and then do the conversion, you may use non-fragmented mp4. In particular using MP4Box:
MP4Box -add file.264 file.mp4

microphone input listening on iOS, AVAudioRecorder or something else?

I'm wondering if there is a way to "listen" without recording and display the microphone's input levels?
Apples SpeakHere sample does the record and playback, and am wondering if there could a be a lighter version of just "listening" without actually recording and saving a file.
I use AudioQueues for this purpose. In your callback, get the input level like so:
AudioQueueLevelMeterState meter[NUM_INPUT_CHANNELS];
UInt32 dataSize = sizeof(meter);
AudioQueueGetProperty(aqInput, kAudioQueueProperty_CurrentLevelMeterDB, meter, &dataSize);
// input 'level' is in meter.mAveragePower
And simply don't write the audio into a file.

x264 IDR access unit with a SPS and a PPS

I am trying to encode video in h.264 that when split with Apples HTTP Live Streaming tools media file segmenter will pass the media file validator I am getting two errors on the split MPEG-TS file
WARNING: Media segment contains a video track but does not contain any IDR access unit with a SPS and a PPS.
WARNING: 7 samples (17.073 %) do not have timestamps in track 257 (avc1).
After hours of research I think the "IDR" warning relates to not having keyframes in the right place on the segmented MPEG-TS file so in my ffmpeg command I set -keyint_min 1 to ensure keyframes where at every frame, but this didn't work.
Although it would be great to get an answer, if anyone can shed any light on what a "IDR access unit with a SPS and a PPS" is or what the timestamps warning means I would be very grateful, thanks.
Fix can be found on this thread https://devforums.apple.com/thread/45830?tstart=15

Playback skipping/seeking in an MP4 file

I'm trying to figure out the proper technique for performing skipping ahead or seeking within an mp4 (or m4a) audio file while playing it using the AudioFileStream and AudioQueue APIs on the iPhone.
If I pass the complete mp4 header (up to the mdat box) to an open AudioFileStream, the underlying audio file type is properly identified (in my case, AAC) and when I then pass the actual mdat data portion of the file, the AudioFileStream correctly begins generating audio packets and these can be sent to the AudioQueue and playback works.
However, if I try a random access approach to the playing back the file, I can't seem to get it to work properly, unless I always send the first frame of the mdat box to the AudioFileStream. If instead, after sending the mp4 header to the AudioFileStream, I then attempt to initially skip ahead to a later frame in the mdat by first calling AudioFileStreamSeek() and then passing the data for the associated packets, the AudioFileStream appears to generate audio packets, but when I pass these on to the AudioQueue and call AudioQueuePrime(), I always get an error of 'nope' returned.
My question is this: am I always required to at least pass in the first packet of the mdat box before attempting to do random playback of other packets in the mp4 file?
I can't seem to find any documentation on doing random playback of sections of an mp4 file while using an AudioFileStream and an AudioQueue. I've found Apple's QuickTime File Format pdf which describes the technique of randomly seeking within an mp4 file, but it's just a high level description and doesn't have any mention of using specific APIs (such as AudioFileStream).
Thanks for any insights.
It turns out the approach I was using with AudioFileStreamSeek() is valid, I just wasn't sending the full initial mp4 header to the AudioFileStreamParseBytes() routine.
The problem was I had assumed the packets began immediately after the mdat box tag. By examining the data offset value (kAudioFileStreamProperty_DataOffset) returned by the AudioFileStream Property Listener callback, I discovered the true start of the packet data was 18 bytes later.
These 18 bytes are considered part of the initial mp4 header that must be sent to the AudioFileStream parser before sending the data of arbitrary packets after calls to AudioFileStreamSeek().
If these extra bytes are left out, then the AudioQueuePrime() call will always fail with a 'nope' error even though you may have sent valid parsed audio packets to the AudioQueue.