本机缓冲音频

问题描述:

这可能是我自己的错误之一,但我似乎无法找到问题所在。在尝试提高我的应用程序的性能之后,我将音频缓冲从Java层移到了本机层。音频处理(录制/播放)已经使用OpenSL ES API本地完成。本机缓冲音频

然而,本机缓冲导致我的应用程序在我启动应用程序时崩溃。我使用一个简单的Queue实现作为我的缓冲区,其中第一个节点是最旧的数据(FIFO)。

struct bufferNode{ 
    struct bufferNode* next; 
    jbyte* data; 
}; 

struct bufferQueue{ 
    struct bufferNode* first; 
    struct bufferNode* last; 
    int size; 
}; 

音频数据由bufferNode中的jbyte *引用。通过这两种方法访问队列,并与互斥锁同步。

void enqueueInBuffer(struct bufferQueue* queue, jbyte* data){ 
    SLresult result; 
    if(queue != NULL){ 
     if(data != NULL){ 
      result = pthread_mutex_lock(&recMutex); 
      if(result != 0){ 
       decodeMutexResult(result); 
       logErr("EnqueueInBuffer", "Unable to acquire recording mutex"); 
      } else { 
       struct bufferNode* node = (struct bufferNode*)malloc(sizeof(struct bufferNode)); 
       if(node == NULL){ 
        logErr("EnqueueInBuffer", "Insufficient memory available to buffer new audio"); 
       } else { 
        node->data = data; 
        if(queue->first == NULL){ 
         queue->first = queue->last = node; 
        } else { 
         queue->last->next = node; 
         queue->last = node; 
        } 
        queue->size = queue->size + 1; 
        node->next = NULL; 
       } 
      } 
      result = pthread_mutex_unlock(&recMutex); 
      if(result != 0){ 
       decodeMutexResult(result); 
       logErr("EnqueueInBuffer", "Unable to release recording mutex"); 
      } 
     } else { 
      logErr("EnqueueInBuffer", "Data is NULL"); 
     } 
    } else { 
     logErr("EnqueueInBuffer", "Queue is NULL"); 
    } 
} 

void dequeueFromBuffer(struct bufferQueue* queue, jbyte* returnData){ 
    SLresult result; 
    result = pthread_mutex_lock(&recMutex); 
    if(result != 0){ 
     decodeMutexResult(result); 
     logErr("DequeueFromBuffer", "Unable to acquire recording mutex"); 
    } else { 
     if(queue->first == NULL){ 
      returnData = NULL; 
     } else { 
      returnData = queue->first->data; 
      struct bufferNode* tmp = queue->first; 
      if(queue->first == queue->last){ 
       queue->first = queue->last = NULL; 
      } else { 
       queue->first = queue->first->next; 
      } 
      free(tmp); 
      queue->size = queue->size - 1; 
     } 
    } 
    result = pthread_mutex_unlock(&recMutex); 
    if(result != 0){ 
     decodeMutexResult(result); 
     logErr("DequeueFromBuffer", "Unable to release recording mutex"); 
    } 
} 
  • 凡日志和解码方法selfdeclared实用方法。日志只是将消息记录到logcat中,而解码方法则“解码”前一个方法调用中可能出现的任何错误号。

但是当我尝试排列音频数据时,我总是收到一个错误。无论何时我调用enqueueInBuffer方法,我都会得到一个SIGSEGV本地错误,并带有代码1(SEGV_MAPERR)。但我似乎无法找到造成错误的原因。当我尝试进行enqueueInBuffer方法调用时(这是在OpenSL ES Recorder回调中完成的,因此是同步),队列和音频数据都存在。

是否还有其他事情会导致分段故障?可能我对它负责,但我似乎无法找到错误。

显然,这是由我的OpenSL ES Recorder回调中的一行代码引起的。

回调原本是这样的:

void recorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context){ 
    SLresult result; 
    enqueueInBuffer(&recordingQueue, (*recorderBuffers[queueIndex])); 
    result = (*bq)->Enqueue(bq, recorderBuffers[queueIndex], RECORDER_FRAMES * sizeof(jbyte)); 
    if(checkError(result, "RecorderCallB", "Unable to enqueue new buffer on recorder") == -1){ 
     return; 
    } 
    queueIndex = queueIndex++ % MAX_RECORDER_BUFFERS; 
} 

然而,似乎回调的最后一行并没有正确地创建新的索引。我使用的缓冲区是一个数组,长度为4。

最后一行更改为

queueIndex = (queueIndex + 1) % MAX_RECORDER_BUFFERS; 

似乎已经解决了这个错误。

+0

现在我再看看它,它可能是'queueIndex = ++ queueIndex%MAX_RECORDER_BUFFERS;'应该也是足够的。全部归因于索引值的后置或前置增量。 – ThaMe90