我需要实时播放iPod音乐的音频样本。
应用程序EQu(http://itunes.apple.com/us/app/equ-the-quality-equalizer/id403704212?mt=8)已达到此目的,或者我认为它无法应用其过滤器。< / p>
我尝试了一些方法但都徒劳无功。
我能做的就是使用AVAssetReader和Writer来保存iPod音乐的本地转换文件并使用AudioUnit等低级技术播放吗?我认为这个本地文件可能非常大。
谢谢你们。
答案 0 :(得分:1)
几个步骤:
予。创建本地缓冲区,如下例所示,您必须确保
a:写入缓冲区时有足够的空白区域
b:从缓冲区读取时有足够的数据
通过查看读/写idx
typedef struct
{
//suppose non-interleaved LEI16 LPCM format
SInt16 data[MUSIC_RING_BUFFER_NUM_CHANNEL][MUSIC_RING_BUFFER_SIZE];
UInt16 readIdx;
UInt16 writeIdx;
} MyRingBuffer;
typedef struct
{
//suppose non-interleaved LEI16 LPCM format
SInt16 data[MUSIC_RING_BUFFER_NUM_CHANNEL][MUSIC_RING_BUFFER_SIZE];
UInt16 readIdx;
UInt16 writeIdx;
} MyRingBuffer;
II。每次都从AVAssetTrackOuput获取一些原始数据,比如
CMSampleBufferRef nextBuffer = [self.trackOutput copyNextSampleBuffer];
CMBlockBufferRef buffer = CMSampleBufferGetDataBuffer( nextBuffer );
size_t lengthAtOffset;
size_t totalLength;
char* data;
if( CMBlockBufferGetDataPointer( buffer, 0, &lengthAtOffset, &totalLength, &data ) != noErr )
{
NSLog( @"error!" );
return;
}
//raw audio sample data now in (char*) data
III。然后将数据复制到本地缓冲区
非交错16位LPCM的原始数据将类似于
[2 bytes data x N, from left channel][2 bytes data x N from right channel]
使用memcpy复制到本地缓冲区并更新writeIdx
CMSampleBufferRef nextBuffer = [self.trackOutput copyNextSampleBuffer];
CMBlockBufferRef buffer = CMSampleBufferGetDataBuffer( nextBuffer );
size_t lengthAtOffset;
size_t totalLength;
char* data;
if( CMBlockBufferGetDataPointer( buffer, 0, &lengthAtOffset, &totalLength, &data ) != noErr )
{
NSLog( @"error!" );
return;
}
//raw audio sample data now in (char*) data
BTW,始终检查音频格式设置是否相同。从CMSampleBufferRef获取ASBD信息,并与AudioUnit输入设置进行比较
[self performSelectorOnMainThread:@selector(fillMusicBuffer:) withObject:Nil waitUntilDone:NO];
[self performSelectorOnMainThread:@selector(fillMusicBuffer:) withObject:Nil waitUntilDone:NO];