2011-10-24 37 views
12

Tôi đang làm việc để nhận âm thanh vào iPhone dưới dạng tôi có thể chuyển nó sang thuật toán phân tích (C++). Có, tất nhiên, nhiều tùy chọn: hướng dẫn AudioQueue at trailsinthesand giúp mọi thứ bắt đầu.Làm thế nào để lấy mảng dữ liệu âm thanh nổi từ AudioQueueRef trong iOS?

Cuộc gọi lại âm thanh, mặc dù, cung cấp cho AudioQueueRef và tôi đang tìm tài liệu của Apple mỏng về mặt này của sự vật. Các phương thức tích hợp để ghi vào một tệp, nhưng không có gì bạn thực sự nằm trong các gói để xem dữ liệu.

Tôi cần dữ liệu. Tôi không muốn viết bất cứ điều gì vào một tập tin, đó là những gì tất cả các hướng dẫn - và thậm chí cả các đối tượng I/O tiện lợi của Apple - dường như đang nhắm đến. Của Apple AVAudioRecorder (tức giận) sẽ cung cấp cho bạn mức độ và ghi dữ liệu, nhưng không thực sự cung cấp cho bạn truy cập vào nó. Trừ khi tôi bỏ lỡ điều gì đó ...

Làm cách nào để thực hiện việc này? Trong đoạn mã dưới đây có inBuffer->mAudioData gần giống nhưng tôi không thể tìm thấy thông tin nào về định dạng 'dữ liệu' này hoặc cách truy cập nó.

AudioQueue Callback:

void AudioInputCallback(void *inUserData, 
    AudioQueueRef inAQ, 
    AudioQueueBufferRef inBuffer, 
    const AudioTimeStamp *inStartTime, 
    UInt32 inNumberPacketDescriptions, 
    const AudioStreamPacketDescription *inPacketDescs) 
{ 
    static int count = 0; 
    RecordState* recordState = (RecordState*)inUserData;  
    AudioQueueEnqueueBuffer(recordState->queue, inBuffer, 0, NULL); 

    ++count; 
    printf("Got buffer %d\n", count); 
} 

và mã để viết các âm thanh vào một tập tin:

OSStatus status = AudioFileWritePackets(recordState->audioFile, 
       false, 
       inBuffer->mAudioDataByteSize, 
       inPacketDescs, 
       recordState->currentPacket, 
       &inNumberPacketDescriptions, 
       inBuffer->mAudioData); // THIS! This is what I want to look inside of. 
if(status == 0) 
{ 
    recordState->currentPacket += inNumberPacketDescriptions; 
} 

Trả lời

10
// so you don't have to hunt them all down when you decide to switch to float: 
    #define AUDIO_DATA_TYPE_FORMAT SInt16 

    // the actual sample-grabbing code: 
    int sampleCount = inBuffer->mAudioDataBytesCapacity/sizeof(AUDIO_DATA_TYPE_FORMAT); 
    AUDIO_DATA_TYPE_FORMAT *samples = (AUDIO_DATA_TYPE_FORMAT*)inBuffer->mAudioData; 

Sau đó, bạn có của bạn (trong trường hợp này SInt16) mảng samples mà bạn có thể truy cập từ samples[0] đến samples[sampleCount-1]. .

+0

mảng "mẫu" này, bao nhiêu giây lấy mẫu chứa? đây là biểu diễn nhị phân của âm thanh đã ghi? –

+0

"mẫu" chứa một giá trị mẫu của bộ đệm. Độ dài là giây phụ thuộc vào kích thước bộ đệm và tốc độ lấy mẫu: 512 mẫu tại 44.1kHz là 512/44100 = 0,011609977 giây. – buildsucceeded

0

Các giải pháp trên không làm việc cho tôi, tôi đã nhận được dữ liệu mẫu sai bản thân (một vấn đề endian) Nếu trong trường hợp ai đó đang nhận dữ liệu mẫu sai trong thời gian tới, tôi hy vọng điều này sẽ giúp bạn:

- (void) feedSamplesToEngine: (UInt32) audioDataBytesDữ liệu âm thanh: (void *) audioData { int sampleCount = audioDataBytesCapacity/sizeof (SAMPLE_TYPE);

SAMPLE_TYPE *samples = (SAMPLE_TYPE*)audioData; 
//SAMPLE_TYPE *sample_le = (SAMPLE_TYPE *)malloc(sizeof(SAMPLE_TYPE)*sampleCount);//for swapping endians 

std::string shorts; 
double power = pow(2,10); 
for(int i = 0; i < sampleCount; i++) 
{ 
    SAMPLE_TYPE sample_le = (0xff00 & (samples[i] << 8)) | (0x00ff & (samples[i] >> 8)) ; //Endianess issue 
    char dataInterim[30]; 
    sprintf(dataInterim,"%f ", sample_le/power); // normalize it. 
    shorts.append(dataInterim); 
} 
Các vấn đề liên quan