首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么iOS AudioQueue内存不断增加?

为什么iOS AudioQueue内存不断增加?
EN

Stack Overflow用户
提问于 2015-01-27 00:59:56
回答 1查看 446关注 0票数 0

我有一个播放音频类使用AudioToolBox.frameworkAudioQueue

我遇到一个问题,每一段音频数据回放,内存都会增加,回放完成后,内存不会减少。如果进行批量测试,它会被添加到几百兆字节的内存中,我想知道是什么原因导致内存一直在增加,音频数据对每个对象的每一次传递都是释放还是其他原因。

下面是我的playThread类代码:

代码语言:javascript
复制
@interface PlayThread()
{
    BOOL transferDataComplete; // if thers is no data transfer to   playthread set transferDataComplete = yes;
    NSMutableArray *receiveDataArray;// audio data array
    BOOL isPlay;// if audioqueue start,isPlay = yes,
}
@end
#pragma mark class implementation
@implementation PlayThread
- (instancetype)init
{
    if (self = [super init]) {
        receiveDataArray = [[NSMutableArray alloc]init];
        isPlay = NO;
        transferDataComplete = false;
        bufferOverCount = QUEUE_BUFFER_SIZE;
        audioQueue = nil;
    }
    return self;
}

// audio queue callback function
static void BufferCallback(void *inUserData,AudioQueueRef    inAQ,AudioQueueBufferRef buffer)
{
    USCPlayThread* player=(__bridge USCPlayThread*)inUserData;
    [player fillBuffer:inAQ queueBuffer:buffer];
}
// fill buffer
-(void)fillBuffer:(AudioQueueRef)queue queueBuffer:(AudioQueueBufferRef)buffer
{
    while (true){
        NSData *audioData = [self getAudioData];
        if( transferDataComplete && audioData == nil) {
           bufferOverCount --;
           break;
        }
        else if(audioData != nil){
            memcpy(buffer->mAudioData, [audioData bytes] , audioData.length);
                buffer->mAudioDataByteSize = (UInt32)audioData.length;
                AudioQueueEnqueueBuffer(queue, buffer, 0, NULL);
                break;
            }
            else
                break;
        } // while
        if(bufferOverCount == 0){
            // stop audioqueue
            [self stopAudioQueue];
             dispatch_async(dispatch_get_main_queue(), ^{
                if ([self.delegate respondsToSelector:@selector(playComplete)])     {
                    [self.delegate playComplete];
                }
            });
        }
    }

-(void)addPlayData:(NSData *)data
{
    NSUInteger count = 0;
     @synchronized(receiveDataArray){
        [receiveDataArray addObject:data];
    }
 }
 /**
 *  get data from receiveDataArray
 */
-(NSData*)getAudioData
{
    NSData *headData = nil;
    @synchronized(receiveDataArray){
        if(receiveDataArray.count > 0){
            headData = [receiveDataArray objectAtIndex:0];
            [receiveDataArray removeObjectAtIndex:0];
        }
    }
    return headData;
}

- (void)startPlay // start audioqueue to play audio data
{
    [self reset];
    [self open];
    for(int i=0; i<QUEUE_BUFFER_SIZE; i++)
    {
        [self fillBuffer:audioQueue queueBuffer:audioQueueBuffers[i]];
    }
    // audioqueuestart
    AudioQueueStart(audioQueue, NULL);

    @synchronized(self){
        isPlay = YES;
    }
    if ([self.delegate respondsToSelector:@selector(playBegin)]) {
        [self.delegate playBegin];
    }
}
-(void)createAudioQueue
{
    if (audioQueue) {
        return;
    }
    AudioQueueNewOutput(&audioDescription, BufferCallback, (__bridge void *)(self), nil, nil, 0, &audioQueue);
    if(audioQueue){
        for(int i=0;i<QUEUE_BUFFER_SIZE;i++){
            AudioQueueAllocateBufferWithPacketDescriptions(audioQueue, EVERY_READ_LENGTH, 0, &audioQueueBuffers[i]);
        }
    }
}
-(void)stopAudioQueue
{
    if(audioQueue == nil){
        return;
    }
    @synchronized(self){
        if(isPlay){
            isPlay = NO;
        }
    }
    AudioQueueStop(audioQueue, TRUE);
}
-(void)setAudioFormat
{
    audioDescription.mSampleRate = 16000;
    audioDescription.mFormatID = kAudioFormatLinearPCM;
    audioDescription.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
    audioDescription.mChannelsPerFrame = 1;
    audioDescription.mFramesPerPacket = 1;
    audioDescription.mBitsPerChannel = 16;
    audioDescription.mBytesPerFrame = (audioDescription.mBitsPerChannel/8) *      audioDescription.mChannelsPerFrame;
    audioDescription.mBytesPerPacket = audioDescription.mBytesPerFrame ;
  }

  -(void)close
    {
       if (audioQueue) {
        AudioQueueStop(audioQueue, true);
        AudioQueueDispose(audioQueue, true);
        audioQueue = nil;
        isPlay = NO;
    }
}

-(BOOL)open {
    if([self isOpen]){
        return YES;
    }
    [self close];
    [self setAudioFormat];
    [self createAudioQueue];
    return YES;
}

-(BOOL)isOpen
{
    return (audioQueue != nil);
}

- (void)reset
{
    bufferOverCount = QUEUE_BUFFER_SIZE;
    transferDataComplete = NO;
}

- (BOOL)isPlaying
{
    return isPlay;
}

- (void)disposeQueue
{
    if (audioQueue) {
        AudioQueueDispose(audioQueue, YES);
    }
    audioQueue = nil;
}
 - (void)dealloc
{
    [self disposeQueue];
}

这里是ViewContrller.m:

代码语言:javascript
复制
- (void)viewDidLoad {
[super viewDidLoad];

PlayThread *playThread = [[PlayThread alloc]init];
playThread.delegate = self;
self.playThread = playThread;

for (int  i = 0; i < 10; i++)
{   // create empth audio data to simulate
    NSMutableData *data = [[NSMutableData alloc]initWithLength:10000];
    [self.playThread addPlayData:data];
}
    [self.playThread startPlay]; 
}

以下是PlayThread的委托方法:

代码语言:javascript
复制
// When the play completely,then play once again,memory will continue to increase
- (void)playComplete
{
    dispatch_async(dispatch_get_main_queue(), ^{
        for (int  i = 0; i < 10; i++)
        {
            NSMutableData *data = [[NSMutableData alloc]initWithLength:10000];
            [self.playThread addPlayData:data];
        }
        [self.playThread startPlay];
    });
}

Why memory has continued to increase, how can promptly release memory?

EN

回答 1

Stack Overflow用户

发布于 2016-08-23 12:09:33

AudioQueueNewOutput(&audioDescription,BufferCallback,(__bridge空*)(self),nil,nil,0,&audioQueue);此处参数不能为nil

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28154952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档