현재 IOS에서 TCP 소켓을 통해 IMA-ADPCM 오디오 데이터를 읽고 PCM으로 변환 한 다음 스트림을 재생하는 앱을 개발 중입니다. 이 단계에서 스트림에서 데이터를 가져와 (또는 푸시에 반응해야한다고 말하는) 클래스를 완성하고이를 PCM으로 디코딩했습니다. Audio Queue 클래스를 설정하고 테스트 톤을 재생하도록했습니다. 데이터 큐를 오디오 큐에 전달하는 가장 좋은 방법은 도움이 필요한 곳입니다.Objective-C - 스트리밍 된 데이터를 오디오 큐로 전달
오디오 데이터는 청크 640 바이트에서 8Khz 16 비트 LPCM으로 ADPCM 디코더에서 출력됩니다. (160 바이트의 ADPCM 데이터로 시작하지만 640으로 압축을 푸십시오). uint_8t 배열로 함수에 들어오고 NSData 객체를 전달합니다. 스트림은 '푸시 (push)'스트림이므로 오디오가 전송 될 때마다 객체를 작성/플러시합니다.
-(NSData*)convertADPCM:(uint8_t[]) adpcmdata {
물론 오디오 큐 콜백 각 패스에서 실행 루프의 각 패스에 대한 자료를 찾고 간다 끌어 오기 함수가 실행 :이 작업을했습니다
-(OSStatus) fillBuffer: (AudioQueueBufferRef) buffer {
며칠 동안 PCM 변환은 상당히 과세되어 있었고 두 가지 사이에서 데이터를 연결하는 가장 좋은 방법은 내 머리 속에 모으는 데 약간의 어려움이 있습니다. 데이터를 생성하는 것과 같지 않고 데이터 작성을 필 버퍼 루틴에 간단하게 통합 할 수 있습니다. 데이터가 푸시되고 있습니다.
uint16_t [] ~에서 순환 버퍼를 0.5 초 설정했지만 뇌가 닳아서 버퍼에서 밀고 당기는 깔끔한 방법을 찾을 수 없어 결국 스냅 딱딱 소리가 튀다.
주로 Android에서 프로젝트를 완료했지만 AudioTrack은 Core-Audio Queues와 매우 다른 짐승입니다.
이 단계에서 저는 Adamson과 Avila가 Learning Core Audio를 한 권 가져 왔으며 핵심 오디오를 잘 모르는 사람들에게 훌륭한 자료라고 생각합니다.
업데이트 : 내가 말했듯이 내가 쓴 때
-(OSStatus) fillBuffer: (AudioQueueBufferRef) buffer {
int frame = 0;
double frameCount = bufferSize/self.streamFormat.mBytesPerFrame;
// buffersize = framecount = 8000/2 = 4000
//
// incoming buffer uint16_t[] convAudio holds 64400 bytes (big I know - 100 x 644 bytes)
// playedHead is set by the function to say where in the buffer the
// next starting point should be
if (playHead > 99) {
playHead = 0;
}
// Playstep factors playhead to get starting position
int playStep = playHead * 644;
// filling the buffer
for (frame = 0; frame < frameCount; ++frame)
// framecount = 4000
{
// pointer to buffer
SInt16 *data = (SInt16*)buffer->mAudioData;
// load data from uint16_t[] convAudio array into frame
(data)[frame] = convAudio[(frame + playStep)];
}
// set buffersize
buffer->mAudioDataByteSize = bufferSize;
// return no Error - Osstatus will return an error otherwise if there is one. (I think)
return noErr;
}
, 내 뇌가 퍼지, 그리고 내가 놓친 거지 눈부시게 분명 뭔가 거기에 아마 : 여기 버퍼 관리 코드입니다. 내가 로그인 할을 덤프하고 그것을 채워 순환 방식으로 채워지고 사물의 convAudio 배열 측면에서
static void MyAQOutputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inCompleteAQBuffer)
{
soundHandler *sHandler = (__bridge soundHandler*)inUserData;
CheckError([sHandler fillBuffer: inCompleteAQBuffer],
"can't refill buffer",
"buffer refilled");
CheckError(AudioQueueEnqueueBuffer(inAQ,
inCompleteAQBuffer,
0,
NULL),
"Couldn't enqueue buffer (refill)",
"buffer enqued (refill)");
}
, 그래서 나는 적어도 알고 코드 위
는 콜백에 의해 호출된다 그 비트가 작동합니다.
버퍼 관리 코드를 게시하십시오. 문제가있는 것으로 보입니다. – hotpaw2
버퍼 코드가 추가되었습니다. – DoctorDbx