2012-05-29 3 views
1

그래서 모든 것을 설정하고 입력 콜백에서 오디오 데이터를받는 평범한 과정을 거침으로써 입력 대기열에 녹음하고 싶다고합시다. 이 파일을 작성하는 대신 간단히 어딘가에 버퍼링을 시작한 다음 입력 대기열 바로 다음에 실행되도록 출력 대기열에 공급하고 싶습니다. 입력 대기열에서 버퍼링 할 데이터를 사용하고 재생 중입니다. 내가 녹음 할 때의 오디오. 이것이 가능한가? 이 구현을 시도했지만 내 출력 대기열을 시작하는 문제가 발생합니다. 초기화하고 아무 오류도보고하지 않지만 AudioQueueStart 함수를 호출 한 후에는 제공된 출력 콜백이 호출되지 않습니다. 아마도 이것이 내 구현의 문제이지만, 막 다른 골목에 먼저 들어가는 일이 없도록하려는 것입니다. 명령 줄 응용 프로그램에서이 POC를 실행하는 코드 추가두 개의 AudioQueue를 동시에 실행하는 Core Audio

임 :

감사

편집

.

static void *buffer[1000]; 

:

Recorder recorder = {0}; 

    AudioStreamBasicDescription asbd; 
    memset(&asbd, 0, sizeof(asbd)); 

    asbd.mFormatID = kAudioFormatLinearPCM; 
    asbd.mSampleRate = SAMPLE_RATE; 
    asbd.mBytesPerPacket = 4; 
    asbd.mBytesPerFrame = 4; 
    asbd.mChannelsPerFrame = 2; 
    asbd.mBitsPerChannel = 16; 
    asbd.mFramesPerPacket = 1; 
    asbd.mFormatFlags = kAudioFormatFlagIsBigEndian | 
    kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; 

    AudioQueueRef queue = {0}; 


    reportError(AudioQueueNewInput(&asbd, MyAQInputCallback, &recorder, NULL, NULL, 0, &queue), "AudioQueue Input Create"); 

    int bufferSize = 88200; 

    for (int i = 0; i < BUFFER_COUNT; i++) { 

     AudioQueueBufferRef retBuffer; 
     reportError(AudioQueueAllocateBuffer(queue, bufferSize, &retBuffer), "Error Allocating Buffer"); 
     reportError(AudioQueueEnqueueBuffer(queue, retBuffer, 0, NULL), "Error enqueuing buffer"); 


    } 

    recorder.running = YES; 
    reportError(AudioQueueStart(queue, NULL), "Start Failed"); 
    CFRunLoopRunInMode(kCFRunLoopDefaultMode, 3, false); 

내가,이 내가 그냥가 실행 얻을 수 있는지보고 싶어 변경됩니다 들어오는 데이터를 보유하는 글로벌 무효 포인터 배열을 선언 주에서 나는 레코더를 초기화 내 입력 콜백. 레코더 내가이 전에 파일에 기록하며 한 나를 위해 벌금을 실행하고있다, 그래서 이것은 특정 지점의 부름을받을 않습니다

기본적으로
static void MyAQInputCallback(void *inUserData, 
          AudioQueueRef inQueue, 
          AudioQueueBufferRef inBuffer, 
          const AudioTimeStamp *inStartTime, 
          UInt32 inNumPackets, 
          const AudioStreamPacketDescription *inPacketDesc) 
{ 

Recorder *recorder = (Recorder *) inUserData; 

buffer[globalBufferIndex] = (short *)inBuffer->mAudioData; 
++globalBufferIndex; 

if (globalBufferIndex == 1000) { 
    globalBufferIndex = 0; 
    clearBuffer(); 
} 
if (recorder->running) { 
    reportError(AudioQueueEnqueueBuffer(inQueue, inBuffer, 0, NULL), "CallbackEnqueue Failed"); 
} 
} 

단지 덩어리를 끌어에 저장하는 것입니다 여기에 목표 버퍼 나는 이것이 꼭해야한다고 생각한다.

플레이어가 초기화된다

Player player = {0}; 
AudioQueueRef que = {0}; 

reportError(AudioQueueNewOutput(&asbd, MyAQOutputCallback, &player, NULL, NULL, 0, &que), "New Output Error"); 

AudioQueueBufferRef buffers[BUFFER_COUNT]; 

for (int i = 0; i < BUFFER_COUNT; ++i) { 

     reportError(AudioQueueAllocateBuffer(que, bufferSize, &buffers[i]), "Error Buffer Allocating"); 

     MyAQOutputCallback(&player, que, buffers[i]); 

    } 

reportError(AudioQueueStart(que, NULL), "Start Failed"); 

플레이어 콜백 :

static void MyAQOutputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inCompleteAQBuffer) 
{ 

Player *player; 

player = (Player *) inUserData; 

short *chunk = (short *) inCompleteAQBuffer->mAudioData; 
chunk = buffer[globalOutputBufferIndex]; 
globalOutputBufferIndex++; 

AudioQueueEnqueueBuffer(inAQ, inCompleteAQBuffer, sizeof(chunk)/4, player->packetDescs); 

} 

뭐죠 큐에 글로벌 버퍼에 저장하고를 보낼 수있는 목표.

그래서 이건 훌륭한 구조는 아니지만 내가 실행할 때 얻는 동작은 레코더가 입력 콜백에 대한 호출을 실행하고 데이터를 저장하지만 그 다음에 플레이어 초기화 및 출력 콜백이 실행된다는 것입니다. 3 회 (my for 루프 호출) 호출하고 결코 다시 호출되지 않습니다. getchar()을 호출하여 마지막에 앱 종료를 차단합니다. 나는 플레이어가 파일을 읽고 그것을 읽도록 노력하도록 만들었다. 분명히 이것은 매우 다르다. 레코더는 계속 작동하지만 플레이어 콜백은 호출되지 않습니다. 나는 아마 내 설명에 문제가 있다고 생각했으나 할당하는 동안 오류는 절대로 나에게보고되지 않는다. 여기에 어떤 지침이라도 좋을 것입니다.

+0

https://github.com/alexbw/novocaine이 코드를 표시 :

감사 –

답변

2

아무도이 모르는 것 같다 없기 때문에

, 여기에이 작업을 수행 꽤 좋은 샘플 프로젝트에 대한 링크입니다.
+0

이것은 슈퍼 포스트 맨입니다. 그 도서관은 상어처럼 일합니다! – doozMen

관련 문제