2011-09-06 109 views
1

這可能是我自己的錯誤之一,但我似乎無法找到問題所在。在嘗試提高我的應用程序的性能之後,我將音頻緩衝從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回調中完成的,因此是同步),隊列和音頻數據都存在。

是否還有其他事情會導致分段故障?可能我對它負責,但我似乎無法找到錯誤。

回答

1

顯然,這是由我的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