mirror of
https://github.com/oonyeje/Get-Hip.git
synced 2025-12-25 19:57:42 +00:00
142 lines
4.0 KiB
Objective-C
Executable File
142 lines
4.0 KiB
Objective-C
Executable File
//
|
|
// TDAudioQueue.m
|
|
// TDAudioStreamer
|
|
//
|
|
// Created by Tony DiPasquale on 10/4/13.
|
|
// Copyright (c) 2013 Tony DiPasquale. The MIT License (MIT).
|
|
//
|
|
|
|
#import "TDAudioQueue.h"
|
|
#import "TDAudioQueueBuffer.h"
|
|
#import "TDAudioQueueController.h"
|
|
#import "TDAudioQueueBufferManager.h"
|
|
#import "TDAudioStreamerConstants.h"
|
|
|
|
@interface TDAudioQueue ()
|
|
|
|
@property (assign, nonatomic) AudioQueueRef audioQueue;
|
|
@property (strong, nonatomic) TDAudioQueueBufferManager *bufferManager;
|
|
@property (strong, nonatomic) NSCondition *waitForFreeBufferCondition;
|
|
@property (assign, nonatomic) NSUInteger buffersToFillBeforeStart;
|
|
|
|
- (void)didFreeAudioQueueBuffer:(AudioQueueBufferRef)audioQueueBuffer;
|
|
|
|
@end
|
|
|
|
void TDAudioQueueOutputCallback(void *inUserData, AudioQueueRef inAudioQueue, AudioQueueBufferRef inAudioQueueBuffer)
|
|
{
|
|
TDAudioQueue *audioQueue = (__bridge TDAudioQueue *)inUserData;
|
|
[audioQueue didFreeAudioQueueBuffer:inAudioQueueBuffer];
|
|
}
|
|
|
|
@implementation TDAudioQueue
|
|
|
|
- (instancetype)initWithBasicDescription:(AudioStreamBasicDescription)basicDescription bufferCount:(UInt32)bufferCount bufferSize:(UInt32)bufferSize magicCookieData:(void *)magicCookieData magicCookieSize:(UInt32)magicCookieSize
|
|
{
|
|
self = [self init];
|
|
if (!self) return nil;
|
|
|
|
OSStatus err = AudioQueueNewOutput(&basicDescription, TDAudioQueueOutputCallback, (__bridge void *)self, NULL, NULL, 0, &_audioQueue);
|
|
|
|
if (err) return nil;
|
|
|
|
self.bufferManager = [[TDAudioQueueBufferManager alloc] initWithAudioQueue:self.audioQueue size:bufferSize count:bufferCount];
|
|
|
|
AudioQueueSetProperty(self.audioQueue, kAudioQueueProperty_MagicCookie, magicCookieData, magicCookieSize);
|
|
free(magicCookieData);
|
|
|
|
AudioQueueSetParameter(self.audioQueue, kAudioQueueParam_Volume, 1.0);
|
|
|
|
self.waitForFreeBufferCondition = [[NSCondition alloc] init];
|
|
self.state = TDAudioQueueStateBuffering;
|
|
self.buffersToFillBeforeStart = kTDAudioQueueStartMinimumBuffers;
|
|
|
|
return self;
|
|
}
|
|
|
|
#pragma mark - Audio Queue Events
|
|
|
|
- (void)didFreeAudioQueueBuffer:(AudioQueueBufferRef)audioQueueBuffer
|
|
{
|
|
[self.bufferManager freeAudioQueueBuffer:audioQueueBuffer];
|
|
|
|
[self.waitForFreeBufferCondition lock];
|
|
[self.waitForFreeBufferCondition signal];
|
|
[self.waitForFreeBufferCondition unlock];
|
|
|
|
if (self.state == TDAudioQueueStateStopped && ![self.bufferManager isProcessingAudioQueueBuffer]) {
|
|
[self.delegate audioQueueDidFinishPlaying:self];
|
|
}
|
|
}
|
|
|
|
#pragma mark - Public Methods
|
|
|
|
- (TDAudioQueueBuffer *)nextFreeBuffer
|
|
{
|
|
if (![self.bufferManager hasAvailableAudioQueueBuffer]) {
|
|
[self.waitForFreeBufferCondition lock];
|
|
[self.waitForFreeBufferCondition wait];
|
|
[self.waitForFreeBufferCondition unlock];
|
|
}
|
|
|
|
TDAudioQueueBuffer *nextBuffer = [self.bufferManager nextFreeBuffer];
|
|
|
|
if (!nextBuffer) return [self nextFreeBuffer];
|
|
return nextBuffer;
|
|
}
|
|
|
|
- (void)enqueue
|
|
{
|
|
[self.bufferManager enqueueNextBufferOnAudioQueue:self.audioQueue];
|
|
|
|
if (self.state == TDAudioQueueStateBuffering && --self.buffersToFillBeforeStart == 0) {
|
|
AudioQueuePrime(self.audioQueue, 0, NULL);
|
|
[self play];
|
|
[self.delegate audioQueueDidStartPlaying:self];
|
|
}
|
|
}
|
|
|
|
#pragma mark - Audio Queue Controls
|
|
|
|
- (void)play
|
|
{
|
|
if (self.state == TDAudioQueueStatePlaying) return;
|
|
|
|
[TDAudioQueueController playAudioQueue:self.audioQueue];
|
|
self.state = TDAudioQueueStatePlaying;
|
|
}
|
|
|
|
- (void)pause
|
|
{
|
|
if (self.state == TDAudioQueueStatePaused) return;
|
|
|
|
[TDAudioQueueController pauseAudioQueue:self.audioQueue];
|
|
self.state = TDAudioQueueStatePaused;
|
|
}
|
|
|
|
- (void)stop
|
|
{
|
|
if (self.state == TDAudioQueueStateStopped) return;
|
|
|
|
[TDAudioQueueController stopAudioQueue:self.audioQueue];
|
|
self.state = TDAudioQueueStateStopped;
|
|
}
|
|
|
|
- (void)finish
|
|
{
|
|
if (self.state == TDAudioQueueStateStopped) return;
|
|
|
|
[TDAudioQueueController finishAudioQueue:self.audioQueue];
|
|
self.state = TDAudioQueueStateStopped;
|
|
}
|
|
|
|
#pragma mark - Cleanup
|
|
|
|
- (void)dealloc
|
|
{
|
|
[self.bufferManager freeBufferMemoryFromAudioQueue:self.audioQueue];
|
|
AudioQueueDispose(self.audioQueue, YES);
|
|
}
|
|
|
|
@end
|