session-ios/Signal/src/audio/incall_audio/AudioPacker.m

73 lines
2.5 KiB
Objective-C

#import "AudioPacker.h"
#import "CryptoTools.h"
#import "Conversions.h"
#import "Util.h"
@implementation AudioPacker
+(AudioPacker*) audioPacker {
AudioPacker* newAudioPackerInstance = [AudioPacker new];
newAudioPackerInstance->audioFrameToReceiveQueue = [Queue new];
newAudioPackerInstance->framesToSend = [NSMutableArray array];
newAudioPackerInstance->nextSequenceNumber = [CryptoTools generateSecureRandomUInt16];
// interop fix:
// cut off the high bit (the sign bit), to avoid confusion over signed-ness when peer receives the initial number
// also cut off the next bit, so that at least 2^14 packets (instead of 1) must fail to arrive before confusion can be caused
newAudioPackerInstance->nextSequenceNumber &= 0x3FFF;
return newAudioPackerInstance;
}
-(void)packFrame:(EncodedAudioFrame*)frame{
require(frame != nil);
require(![frame isMissingAudioData]);
[framesToSend addObject:[frame tryGetAudioData]];
}
-(EncodedAudioPacket*) tryGetFinishedAudioPacket{
if (framesToSend.count < AUDIO_FRAMES_PER_PACKET) return nil;
uint16_t sequenceNumber = nextSequenceNumber++;
NSData* payload = [framesToSend concatDatas];
[framesToSend removeAllObjects];
return [EncodedAudioPacket encodedAudioPacketWithAudioData:payload
andSequenceNumber:sequenceNumber];
}
-(void)unpackPotentiallyMissingAudioPacket:(EncodedAudioPacket*)potentiallyMissingPacket{
if (potentiallyMissingPacket != nil) {
[self enqueueFramesForPacket:potentiallyMissingPacket];
} else {
[self enqueueFramesForMissingPacket];
}
}
-(EncodedAudioFrame*) tryGetReceivedFrame{
return [audioFrameToReceiveQueue tryDequeue];
}
#pragma mark -
#pragma mark Private Methods
-(void) enqueueFramesForPacket:(EncodedAudioPacket*)packet {
require(packet != nil);
NSData* audioData = [packet audioData];
requireState(audioData.length % AUDIO_FRAMES_PER_PACKET == 0);
NSUInteger frameSize = audioData.length / AUDIO_FRAMES_PER_PACKET;
for (NSUInteger i = 0; i < AUDIO_FRAMES_PER_PACKET; i++) {
NSData* frameData = [audioData subdataWithRange:NSMakeRange(frameSize*i, frameSize)];
[audioFrameToReceiveQueue enqueue:[EncodedAudioFrame encodedAudioFrameWithData:frameData]];
}
}
-(void) enqueueFramesForMissingPacket {
for (NSUInteger i = 0; i < AUDIO_FRAMES_PER_PACKET; i++) {
[audioFrameToReceiveQueue enqueue:[EncodedAudioFrame encodedAudioFrameWithoutData]];
}
}
@end