0

我知道现在可以从用户的音乐库中获取一首歌曲并通过更改速度、音高等方式对其进行编辑,但我似乎无法找到有关如何访问歌曲原始数据的有用教程的链接. 有人可以指导我这样做吗,或者是否有这样的图书馆?谢谢!

4

1 回答 1

2

以下是您可以开始使用的一些源代码:

- (void) doSomethingWithAssett:(AVURLAsset *)songAsset {

NSError * error = nil;


AVAssetReader * reader = [[AVAssetReader alloc] initWithAsset:songAsset error:&error];

if (error) {
    NSLog(@"%@", [error description]);
}

AVAssetTrack * songTrack = [songAsset.tracks objectAtIndex:0];

NSDictionary* outputSettingsDict = [[NSDictionary alloc] initWithObjectsAndKeys:

                                    [NSNumber numberWithInt:kAudioFormatLinearPCM],AVFormatIDKey,
                                    //     [NSNumber numberWithInt:44100.0],AVSampleRateKey, /*Not Supported*/
                                    //     [NSNumber numberWithInt: 2],AVNumberOfChannelsKey,    /*Not Supported*/

                                    [NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,
                                    [NSNumber numberWithBool:NO],AVLinearPCMIsBigEndianKey,
                                    [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,
                                    [NSNumber numberWithBool:NO],AVLinearPCMIsNonInterleaved,

                                    nil];


AVAssetReaderTrackOutput* output = [[AVAssetReaderTrackOutput alloc] initWithTrack:songTrack outputSettings:outputSettingsDict];

[reader addOutput:output];

UInt32 sampleRate,channelCount;

NSArray* formatDesc = songTrack.formatDescriptions;
for(unsigned int i = 0; i < [formatDesc count]; ++i) {
    CMAudioFormatDescriptionRef item = (__bridge CMAudioFormatDescriptionRef)[formatDesc objectAtIndex:i];
    const AudioStreamBasicDescription* fmtDesc = CMAudioFormatDescriptionGetStreamBasicDescription (item);
    if(fmtDesc ) {

        sampleRate = fmtDesc->mSampleRate;
        channelCount = fmtDesc->mChannelsPerFrame;

        //    NSLog(@"channels:%u, bytes/packet: %u, sampleRate %f",fmtDesc->mChannelsPerFrame, fmtDesc->mBytesPerPacket,fmtDesc->mSampleRate);
    }
}


UInt32 bytesPerSample = 2 * channelCount;
SInt16 normalizeMax = 0;

NSMutableData * fullSongData = [[NSMutableData alloc] init];
[reader startReading];


UInt64 totalBytes = 0; 


SInt64 totalLeft = 0;
SInt64 totalRight = 0;
NSInteger sampleTally = 0;

NSInteger samplesPerPixel = sampleRate / 50;


while (reader.status == AVAssetReaderStatusReading){

    AVAssetReaderTrackOutput * trackOutput = (AVAssetReaderTrackOutput *)[reader.outputs objectAtIndex:0];
    CMSampleBufferRef sampleBufferRef = [trackOutput copyNextSampleBuffer];

    if (sampleBufferRef){
        CMBlockBufferRef blockBufferRef = CMSampleBufferGetDataBuffer(sampleBufferRef);

        size_t length = CMBlockBufferGetDataLength(blockBufferRef);
        totalBytes += length;


        @autoreleasepool {
            NSMutableData * data = [NSMutableData dataWithLength:length];
            CMBlockBufferCopyDataBytes(blockBufferRef, 0, length, data.mutableBytes);


            SInt16 * samples = (SInt16 *) data.mutableBytes;

你有样品,用它们做点什么......

于 2012-07-14T10:56:28.140 回答