2012-06-14 38 views
0

我正在使用文本到語音,開始音頻工作正常,但我不能阻止它。這裏是如何我做的啓動聲音:如何停止AudioQueue?

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) { 
     [[self view] setNeedsDisplay]; 
     [self synthesizeInBackground]; 
     [queue waitUntilAllOperationsAreFinished]; 
     [self setIsSpeaking: false]; 
     [[self view] setNeedsDisplay]; 

    }); 

synthesizeInBackground

- (void) synthesizeInBackground { 
XLog(@"-----------------------------------entered"); 


queue = [[NSOperationQueue alloc] init]; 
XLog(@"queue: %@", queue); 

operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(synthesize) object:nil]; 
XLog(@"operation: %@", operation); 

[queue addOperation: operation]; 

} 

合成

- (void)synthesize { 
XLog(@"-----------------------------------entered"); 



NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

callback_userdata userdata; 

NSError *error = nil; 

self.paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
self.documentsDirectory = [self.paths objectAtIndex:0]; 
self.path = [self.documentsDirectory stringByAppendingPathComponent:@"readSearchresults.txt"]; 
IvonaStreamer *streamer = [[IvonaStreamer alloc] initWithVoice:voice withText:[NSString stringWithContentsOfFile:self.path encoding:NSUTF8StringEncoding error:&error] atSpeed:[NSNumber numberWithFloat:-1]]; 
//IvonaStreamer *streamer = [[IvonaStreamer alloc] initWithVoice:voice withText:@"Dies ist ein Testtext." atSpeed:[NSNumber numberWithFloat:-1]]; 




if (streamer == nil) { 
    XLog(@"Cannot start streamer"); 
    [self setTtsError: @"Cannot start streamer"]; 
    return; 
} 


userdata.speak = &(self->isSpeaking); 
userdata.streamer = streamer; 


#define NUM_BUFFERS 3 
#define BUFFER_SIZE 22050 
OSStatus err; 

AudioQueueRef audioQueue; 
//XLog(@"audioQueue: %d", audioQueue); 
XLog(@"[voice getSampleRate]: %i", [voice getSampleRate]); 

AudioStreamBasicDescription deviceFormat; 
deviceFormat.mSampleRate = [voice getSampleRate]; 
deviceFormat.mFormatID = kAudioFormatLinearPCM; 
deviceFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger; 
deviceFormat.mBytesPerPacket = 2; 
deviceFormat.mFramesPerPacket = 1; 
deviceFormat.mBytesPerFrame = 2; 
deviceFormat.mChannelsPerFrame = 1; 
deviceFormat.mBitsPerChannel = 16; 
deviceFormat.mReserved = 0; 

XLog(@"deviceFormat.mSampleRate: %f", deviceFormat.mSampleRate); 
/* 
XLog(@"deviceFormat.mSampleRate: %f", deviceFormat.mSampleRate); 
XLog(@"deviceFormat.mFormatID: %lu", deviceFormat.mFormatID); 
XLog(@"deviceFormat.mFormatFlags: %lu", deviceFormat.mFormatFlags); 
XLog(@"deviceFormat.mBytesPerPacket %lu", deviceFormat.mBytesPerPacket); 
XLog(@"deviceFormat.mFramesPerPacket %lu", deviceFormat.mFramesPerPacket); 
XLog(@"deviceFormat.mBytesPerFrame %lu", deviceFormat.mBytesPerFrame); 
XLog(@"deviceFormat.mChannelsPerFrame %lu", deviceFormat.mChannelsPerFrame); 
XLog(@"deviceFormat.mBitsPerChannel %lu", deviceFormat.mBitsPerChannel); 
XLog(@"deviceFormat.mReserved %lu", deviceFormat.mReserved); 
*/ 

err = AudioQueueNewOutput(&deviceFormat, 
          AudioQueueCallback, 
          &userdata, 
          CFRunLoopGetCurrent(), 
          kCFRunLoopCommonModes, 
          0, 
          &audioQueue); 
if (err != noErr) { 
    XLog(@"Cannot create audio output"); 
    [self setTtsError: @"Cannot create audio output"]; 
    [streamer stop]; 
    return; 
} 

AudioQueueAddPropertyListener(audioQueue, kAudioQueueProperty_IsRunning, 
           AudioQueuePropertyListener, NULL); 

for (int i = 0; i < NUM_BUFFERS; i++) { 
    AudioQueueBufferRef buffer; 

    err = AudioQueueAllocateBuffer(audioQueue, BUFFER_SIZE, &buffer); 
    if (err != noErr) { 
     XLog(@"Cannot allocate audio buffer"); 
     [self setTtsError: @"Cannot allocate audio buffer"]; 
     [streamer stop]; 
     return; 
    } 

    AudioQueueCallback(&userdata, audioQueue, buffer); 
} 

err = AudioQueueStart(audioQueue, NULL); 
if (err != noErr) { 
    XLog(@"Cannot start audio"); 
    [self setTtsError: @"Cannot start audio"]; 
    [streamer stop]; 
    return; 
} 

CFRunLoopRun(); 

[streamer stop]; 
[pool release]; 
} 

AudioQueueCallback

void AudioQueueCallback(void *userData, AudioQueueRef audioQueue, 
        AudioQueueBufferRef buffer) 
{ 
//XLog(@"-----------------------------------entered"); 


void *data = buffer->mAudioData; 

UInt32 num_bytes = buffer->mAudioDataBytesCapacity; 
//XLog(@"num_bytes: %lu", num_bytes); 

UInt32 to_write = num_bytes/sizeof(short); 
//XLog(@"to_write: %lu", to_write); 

NSInteger num_samples; 
//XLog(@"num_samples: %i", num_samples); 

IvonaStreamer *streamer = ((callback_userdata*) userData)->streamer; 
bool *enabled = ((callback_userdata*) userData)->speak; 

//XLog(@"streamer.getWarnings: %@", streamer.getWarnings); 


if(!*enabled) { 
    XLog(@"!*enabled"); 
    AudioQueueStop(audioQueue, false);   
} 

num_samples = [streamer synthSamples:to_write toCArray:data]; 
//XLog(@"num_samples: %i", num_samples); 

if (num_samples > 0) { 
    //XLog(@"num_samples > 0"); 
    buffer->mAudioDataByteSize = num_samples * sizeof(short); 

    AudioQueueEnqueueBuffer(audioQueue, buffer, 0, NULL); 

} else { 
    //XLog(@"! (num_samples > 0)"); 
    AudioQueueStop(audioQueue, false); 
    } 
} 

AudioQueuePropertyListener

void AudioQueuePropertyListener(void *userData, AudioQueueRef audioQueue, 
          AudioQueuePropertyID id) 
{ 

    XLog(@"-----------------------------------entered"); 

UInt32 isRunning, size = sizeof(isRunning); 
AudioQueueGetProperty(audioQueue, kAudioQueueProperty_IsRunning, &isRunning, &size); 
if (isRunning == 0) { 
    XLog(@"isRunning == 0"); 
    CFRunLoopStop(CFRunLoopGetCurrent()); 
} 

if (isRunning != 0) { 
    XLog(@"nicht null#######"); 

} 

} 

我試圖阻止其他方法(UIAlertView中的委託方法):

if (alertView.tag == 997) { 
    if (buttonIndex == 0) { 
     XLog(@"vorlesen abbrechen geklickt."); 
     [queue cancelAllOperations]; 
     AudioQueueRef audioQueue; 
     //AudioQueueDispose(audioQueue, false); 
     AudioQueueStop(audioQueue, false); 
    } 

我正在取消所有操作並調用AudioQueueDispose,也試圖與AudioQueueStop,但沒有在這裏工作。

所以我的問題是,如何在這裏停止音頻?

回答

1

我相信你在調用AudioQueueStop之前需要調用AudioQueueReset。

AudioQueueReset (audioQueue); 
AudioQueueStop (audioQueue, YES); 
AudioQueueDispose (audioQueue, YES); 
+2

正如@Oliver提到的,AudioQueueReset來自AudioQueueStop,所以這不是必須的。 –

6

AudioQueueStop應該可以工作並且充足。從Apple文檔中,AudioQueueReset從AudioQueueStop調用。 如果您想稍後再次啓動,AudioQueueDispose有點太多了。