How to convert caf to mp3/amr? - iphone

Is there a way to convert the iphone record .caf files to .mp3 or amr files? Because the caf file need to upload, and server part can't use this format.
I am not familiar with audio processing. Here is my conclude :
The iphone sdk don't have a direct api to do this. We can only change the encoding format (AAC, IMA, iLBC, ALAC), see ACAudioFileConvert Demo. But it's still a caf file, I want to know if I can convert to mp3 by this.
Some guys suggest to use "LAME" api. Is anyone successful to use it in ios? Can anyone share a simple demo ?
Someone said it may cause a licence issue ?
Can anyone give me any advice ?
Sincere thanks!!!

It's quite simple:
int read, write;
FILE *pcm = fopen("file.caf", "rb");
FILE *mp3 = fopen("file.mp3", "wb");
const int PCM_SIZE = 8192;
const int MP3_SIZE = 8192;
short int pcm_buffer[PCM_SIZE*2];
unsigned char mp3_buffer[MP3_SIZE];
lame_t lame = lame_init();
lame_set_in_samplerate(lame, 44100);
lame_set_VBR(lame, vbr_default);
lame_init_params(lame);
do {
read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);
if (read == 0)
write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
else
write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
fwrite(mp3_buffer, write, 1, mp3);
} while (read != 0);
lame_close(lame);
fclose(mp3);
fclose(pcm);

Related

Extract frames from pcap files (tcpdump output) without using Libraries

I need to parse the pcap files and count the packets separately (TCP,UDP,IP). I found a lot of libraries for this like pcap, jnetpcap but I want to do this without using any external libraries.I do not need a code but a just a conceptual explanation.
Question
While parsing pcap files how should I distinguish between the frames(be it TCP,UDP,IP). I tried reading about the format but what I do not understand is how would I come to know about how many bytes should I read for a particular frame and how would i know what type of a frame is it.Because only once I am able to extract the packets separately I will be able to filter out other information.
You'd have to parse each frame separately and have a counter for each value you are trying to count. Assuming the capture you are examining is in pcap/pcapng format you might find libpcap helpful.
To give a quick run of what you might have to do (assuming the lower level is Ethernet without VLAN tags)
uint64_t ip_count, tcp_count, udp_count;
void parse_pkt(uint8_t *data, uint32_t data_len) {
uint8_t *ether_hdr = data;
uint16_t ether_type = ntohs(*(uint16_t *) (data + 12))
if (ether_type != 0x800) {
return;
}
ip_count += 1;
uint8_t *ip_hdr = data + 14;
protocol = ntohs(*(uint16_t *) (ip_hdr + 9))
//protocol is either udp/tcp/sctp...etc
if (protocol == 0x11) {
udp_count++;
} else if (protocol == 0x06) {
tcp_count++;
}
}
// foreach pkt from libpcap_open call parse_pkt with the data and data_len
This code is fragile. Jumping to direct offsets without the proper length and type checks is not a good idea.

TagLib-Sharp - Can it read/write chapter marks?

I am trying to read chapters from mp4 video files. I don't see this in the File.Tags list, but I was hoping there was a way to get them via requesting the chap atom.
I did try mp4chap, but it only gets me the first chapter. I think it may be meant for audio files only.
I am the author of mp4chap lib.
Yes, you are correct. mp4chap library is meant to use for audio files only.
Library is open source and really simple, you are free to modify it.
Here library analyze only first track (see code below). You can play with this code and get more data from mp4 tracks.
http://mp4chap.codeplex.com/SourceControl/latest#Mp4Chapters/ChapterExtractor.cs
private void ReadChapters(MoovInfo moovBox)
{
var soundBox = moovBox.Tracks.Where(b => b.Type == "soun").ToArray();
if (soundBox.Length == 0) return;
if (soundBox[0].Chaps != null && soundBox[0].Chaps.Length > 0)
{
var cb = new HashSet<uint>(soundBox[0].Chaps);
var textBox = moovBox.Tracks.Where(b => b.Type == "text" && cb.Contains(b.Id)).ToArray();
if (textBox.Length == 0) return;
ReadChaptersText(textBox[0]);
}
}

Using FFMPEG Audio conversion in the iPhone

I'm using ffmpeg in the iPhone, reading an wma stream from an mms server, but I want to save the stream to an m4a file using the ALAC encoder in ffmpeg, the problem is that trying to save the raw stream, the stream processed using avcodec_decode_audio2 , the file is not even recognized with the wma format, and obviously, not played, so before convert the stream to m4a (using avcodec_encode_audio) I want to be sure that the streaming is being processed and saved correctly. Anyone had experiencie doing this kind of stuff ? thanks
P.S. I'm writing the bytes buffer using CFWriteStreamWrite, and everything seems to be ok.
My code :
while (av_read_frame(mms_IOCtx, &_packet) >= 0) {
if (_packet.stream_index == audioStreamIdx) {
uint8_t *_packetData = _packet.data;
int _packetSize = _packet.size;
// Align output buffer
uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2 + 16];
int16_t *aligned_buffer;
size_t buffer_size;
int audio_size, len;
buffer_size = sizeof(audio_buf);
aligned_buffer = align16(audio_buf, &buffer_size);
while (currentState != STATE_CLOSED && (_packetSize > 0)) {
audio_size = buffer_size;
len = avcodec_decode_audio2(mms_CodecCtx, aligned_buffer, &audio_size, _packetData, _packetSize);
// call to the method that write the bytes ....
}
}
}
After decoding, it is no longer a WMA stream, it's a raw audio stream. If you want to write the WMA stream, you'd write out the data before decoding.

How to get the uncompressed file size of an MP3 file using CoreAudio API

Using CoreAudio, I am able to get the sampleRate (frames per second) and the file size, but in order to get the "total" time of the song, I need to know the Real file size of that compressed mp3.
AudioStreamBasicDescription asbd;
UInt32 asbdSize = sizeof(asbd);
// get the stream format.
err = AudioFileStreamGetProperty(inAudioFileStream, kAudioFileStreamProperty_DataFormat, &asbdSize, &asbd);
if (err)
{
[self failWithErrorCode:AS_FILE_STREAM_GET_PROPERTY_FAILED];
return;
}
sampleRate = asbd.mSampleRate;
Is there any way I can know the real size of the song using Objective-C?
Thanks in advance.
See the answer to this question
There's a property you can ask in AudioFileGetProperty called kAudioFilePropertyEstimatedDuration that should do the trick.

Can anyone provide a working example of AudioFileStreamSeek for the iPhone?

I find Apple's documentation quite limited on AudioFileStreamSeek and I cannot find any examples of actual usage anywhere. I have a working streaming audio player, but I just can't seem to get AudioFileStreamSeek to work as advertised...
Any help tips or a little example would be greatly appreciated!
I am told this works:
AudioQueueStop(audioQueue, true);
UInt32 flags = 0;
err = AudioFileStreamParseBytes(audioFileStream, length, bytes,
kAudioFileStreamParseFlag_Discontinuity);
OSStatus status = AudioFileStreamSeek(audioFileStream, framePacket.mPacket,
&currentOffset, &flags);
NSLog(#"Setting next byte offset to: %qi, flags: %d", (long long)currentOffset, flags);
// then read data from the new offset set by AudioFileStreamSeek
[fileHandle seekToFileOffset:currentOffset];
NSData* data = "" readDataOfLength:4096];
flags = kAudioFileStreamParseFlag_Discontinuity;
status = AudioFileStreamParseBytes( stream, [data length], [data bytes], flags);
if (status != noErr)
{
NSLog(#"Error parsing bytes: %d", status);
}
Unless I'm mistaken, this is only available in the 3.0 SDK, and therefore under NDA. Maybe you should take this to the Apple Beta forums?
I stand corrected. AudioFileStreamSeek doesn't show up if you do a search in the online 2.2.1 documentation. You have to manually dig into the docs to find it.
Don't forget to add the data offset (kAudioFileStreamProperty_DataOffset) to the byte offset returned by AudioFileStreamSeek. The return value is an offset into the audio data and ignores the data offset.
It's also a good idea to stop and then re-start the AudioQueue before/after seeking.
Matt Gallagher uses AudioFileStreamSeek in his example "Streaming and playing an MP3 stream".
Look at Matt's code AudioStreamer.m:
SInt64 seekPacket = floor(newSeekTime / packetDuration);
err = AudioFileStreamSeek(audioFileStream, seekPacket, &packetAlignedByteOffset, &ioFlags);