So, I would like to get a sound file and convert it in packets, and send it to another computer. I would like that the other computer be able to play the packets as they arr
Here is simplest class to play files with AQ Note that you can play it from any point (just set currentPacketNumber)
#import
#import
@interface AudioFile : NSObject {
AudioFileID fileID; // the identifier for the audio file to play
AudioStreamBasicDescription format;
UInt64 packetsCount;
UInt32 maxPacketSize;
}
@property (readwrite) AudioFileID fileID;
@property (readwrite) UInt64 packetsCount;
@property (readwrite) UInt32 maxPacketSize;
- (id) initWithURL: (CFURLRef) url;
- (AudioStreamBasicDescription *)audioFormatRef;
@end
// AudioFile.m
#import "AudioFile.h"
@implementation AudioFile
@synthesize fileID;
@synthesize format;
@synthesize maxPacketSize;
@synthesize packetsCount;
- (id)initWithURL:(CFURLRef)url{
if (self = [super init]){
AudioFileOpenURL(
url,
0x01, //fsRdPerm, read only
0, //no hint
&fileID
);
UInt32 sizeOfPlaybackFormatASBDStruct = sizeof format;
AudioFileGetProperty (
fileID,
kAudioFilePropertyDataFormat,
&sizeOfPlaybackFormatASBDStruct,
&format
);
UInt32 propertySize = sizeof (maxPacketSize);
AudioFileGetProperty (
fileID,
kAudioFilePropertyMaximumPacketSize,
&propertySize,
&maxPacketSize
);
propertySize = sizeof(packetsCount);
AudioFileGetProperty(fileID, kAudioFilePropertyAudioDataPacketCount, &propertySize, &packetsCount);
}
return self;
}
-(AudioStreamBasicDescription *)audioFormatRef{
return &format;
}
- (void) dealloc {
AudioFileClose(fileID);
[super dealloc];
}
// AQPlayer.h
#import
#import "AudioFile.h"
#define AUDIOBUFFERS_NUMBER 3
#define MAX_PACKET_COUNT 4096
@interface AQPlayer : NSObject {
@public
AudioQueueRef queue;
AudioQueueBufferRef buffers[AUDIOBUFFERS_NUMBER];
NSInteger bufferByteSize;
AudioStreamPacketDescription packetDescriptions[MAX_PACKET_COUNT];
AudioFile * audioFile;
SInt64 currentPacketNumber;
UInt32 numPacketsToRead;
}
@property (nonatomic) SInt64 currentPacketNumber;
@property (nonatomic, retain) AudioFile * audioFile;
-(id)initWithFile:(NSString *)file;
-(NSInteger)fillBuffer:(AudioQueueBufferRef)buffer;
-(void)play;
@end
// AQPlayer.m
#import "AQPlayer.h"
static void AQOutputCallback(void * inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) {
AQPlayer * aqp = (AQPlayer *)inUserData;
[aqp fillBuffer:(AudioQueueBufferRef)inBuffer];
}
@implementation AQPlayer
@synthesize currentPacketNumber;
@synthesize audioFile;
-(id)initWithFile:(NSString *)file{
if ([self init]){
audioFile = [[AudioFile alloc] initWithURL:[NSURL fileURLWithPath:file]];
currentPacketNumber = 0;
AudioQueueNewOutput ([audioFile audioFormatRef], AQOutputCallback, self, CFRunLoopGetCurrent (), kCFRunLoopCommonModes, 0, &queue);
bufferByteSize = 4096;
if (bufferByteSize < audioFile.maxPacketSize) bufferByteSize = audioFile.maxPacketSize;
numPacketsToRead = bufferByteSize/audioFile.maxPacketSize;
for(int i=0; imBytesPerPacket == 0 ? YES : NO;
AudioFileReadPackets(
audioFile.fileID,
NO,
&numBytes,
isVBR ? packetDescriptions : 0,
currentPacketNumber,
&numPackets,
buffer->mAudioData
);
if (numPackets > 0) {
buffer->mAudioDataByteSize = numBytes;
AudioQueueEnqueueBuffer (
queue,
buffer,
isVBR ? numPackets : 0,
isVBR ? packetDescriptions : 0
);
}
else{
// end of present data, check if all packets are played
// if yes, stop play and dispose queue
// if no, pause queue till new data arrive then start it again
}
return numPackets;
}