Reputation: 812
I have found 3-4 examples which show usage of Remote IO Audio Units. like here, here etc. They covert the analog audio data from iPhone microphone and digitize them and then play them back. Upto this point everything works fine and now I have a good understanding of Audio Units.
Now, rather then playing back the recorded audio stored in AudioBufferList on the same device, I want to stream it to another device.
Below is how I'm converting AudioBufferList to nsdata and send it to another device.
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObject:@(bufferList->mNumberBuffers) forKey:@"buffersCount"];
NSMutableArray *buffers = [NSMutableArray array];
for ( int i=0; i< bufferList->mNumberBuffers; i++ ) {
NSData *data = [NSData dataWithBytes:bufferList->mBuffers[i].mData length:bufferList->mBuffers[i].mDataByteSize];
NSDictionary *obj = @{@"data":data, @"channels":@(bufferList->mBuffers[i].mNumberChannels)};
[buffers addObject:obj];
}
[dict setValue:buffers forKey:@"buffers"];
NSData *packet = [NSKeyedArchiver archivedDataWithRootObject:dict];
Below is how I'm converting nsdata back to AudioBufferList on the receiving device and copying it to tempBuffer which is then played.
NSDictionary *dict = (NSDictionary*) [NSKeyedUnarchiver unarchiveObjectWithData:voiceData];
int numberOfBuffers = [dict[@"buffersCount"] intValue];
AudioBufferList *audio = malloc(sizeof(AudioBufferList) + (numberOfBuffers-1)*sizeof(AudioBuffer));
if ( !audio ) {
return;
}
for (int i=0; i < audio->mNumberBuffers; i++) { // in practice we will only ever have 1 buffer, since audio format is mono
AudioBuffer buffer = audio->mBuffers[i];
NSLog(@"Buffer %d has %d channels and wants %d bytes of data.", i, (unsigned int)buffer.mNumberChannels, buffer.mDataByteSize);
// copy temporary buffer data to output buffer
UInt32 size = min(buffer.mDataByteSize, [iosAudio tempBuffer].mDataByteSize); // dont copy more data then we have, or then fits
memcpy(buffer.mData, [iosAudio tempBuffer].mData, size);
buffer.mDataByteSize = size; // indicate how much data we wrote in the buffer
}
But on the other device I'm not able to hear anything.
Please guide as to what might be wrong.
Upvotes: 1
Views: 771
Reputation: 5990
You didn't retrieve any data from the dictionary, just the number of buffers.
NSDictionary *dict = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLog(@"%@", dict);
int numberOfBuffers = [dict[@"buffersCount"] intValue];
NSLog(@"%d", numberOfBuffers);
AudioBufferList *audioBufferList = (AudioBufferList *)malloc(sizeof(AudioBufferList));
if (NULL == audioBufferList) {
NSLog(@"*** malloc failure for allocating audioBufferList memory");
return;
}
audioBufferList->mNumberBuffers = (int)dict[@"buffersCount"];
for(NSDictionary *obj in dict[@"buffers"]){
NSMutableData *data = [NSMutableData dataWithData:obj[@"data"]];
audioBufferList->mBuffers[0].mNumberChannels = (int)obj[@"channels"];
audioBufferList->mBuffers[0].mDataByteSize = (int)[data length];
audioBufferList->mBuffers[0].mData = (AudioBuffer *)malloc([data length]);
if (NULL == audioBufferList->mBuffers[0].mData) {
NSLog(@"*** malloc failure for allocating mData memory");
return;
}
memcpy(audioBufferList->mBuffers[0].mData, [data mutableBytes], [data length]);
NSLog(@"Buffer has %d channels and wants %d bytes of data.", (unsigned int)audioBufferList->mBuffers[0].mNumberChannels, (unsigned int)audioBufferList->mBuffers[0].mDataByteSize);
}
Upvotes: 1
Reputation: 364
There are a number of ways to open a network connection between two devices. You want to do this and simply package up the data in whatever format you desire to get it from device A to device B.
Start here: http://nshipster.com/multipeer-connectivity/
Upvotes: 0