【问题标题】:How to use an Audio Unit on the iPhone如何在 iPhone 上使用音频单元
【发布时间】:2009-06-25 15:09:24
【问题描述】:

我正在寻找一种方法来更改录制的音频的音高,因为它被保存到磁盘或回放(实时)。我了解音频单元可用于此目的。 iPhone 对音频单元的支持有限(例如,据我所知,无法创建/使用自定义音频单元),但有几个开箱即用的音频单元可用,其中之一是 AUPitch。

我将如何使用音频单元(特别是 AUPitch)?您是否以某种方式将其连接到音频队列中?是否可以将音频单元链接在一起(例如,同时添加回声效果和音高变化)?

编辑:检查 iPhone SDK 标头后(我认为 AudioUnit.h,我现在不在 Mac 前),我注意到 AUPitch 已被注释掉。所以看起来 AUPitch 毕竟不能在 iPhone 上使用。

Apple 最近似乎在 developer.apple.com 上更好地组织了他们的 iPhone SDK 文档 - 现在更难找到对 AUPitch 等的引用。

也就是说,我仍然对在 iPhone 上使用音频单元(通常)的高质量答案感兴趣。

【问题讨论】:

    标签: iphone objective-c ios audio core-audio


    【解决方案1】:

    这里有一些非常好的资源 (http://michael.tyson.id.au/2008/11/04/using-remoteio-audio-unit/) 用于使用 RemoteIO 音频单元。根据我在 iPhone 上使用音频单元的经验,我发现我可以在回调函数中手动实现转换。这样做,您可能会发现这可以解决您的问题。

    【讨论】:

      【解决方案2】:

      关于在 iPhone 上改变音调,OpenAL 是要走的路。查看 www.71squared.com 上的 SoundManager 类,了解支持音高的 OpenAL 声音引擎的一个很好的示例。

      【讨论】:

      • 请记住,OpenAL 只支持实时音频音高变化,意味着您无法保存更改后的音频
      【解决方案3】:
      - (void)modifySpeedOf:(CFURLRef)inputURL byFactor:(float)factor andWriteTo:(CFURLRef)outputURL {
      
          ExtAudioFileRef inputFile = NULL;
          ExtAudioFileRef outputFile = NULL;
      
          AudioStreamBasicDescription destFormat;
      
          destFormat.mFormatID = kAudioFormatLinearPCM;
          destFormat.mFormatFlags = kAudioFormatFlagsCanonical;
          destFormat.mSampleRate = 44100 * factor;
          destFormat.mBytesPerPacket = 2;
          destFormat.mFramesPerPacket = 1;
          destFormat.mBytesPerFrame = 2;
          destFormat.mChannelsPerFrame = 1;
          destFormat.mBitsPerChannel = 16;
          destFormat.mReserved = 0;
      
          ExtAudioFileCreateWithURL(outputURL, kAudioFileCAFType,
                                    &destFormat, NULL, kAudioFileFlags_EraseFile, &outputFile);
      
          ExtAudioFileOpenURL(inputURL, &inputFile);
      
          //find out how many frames is this file long
          SInt64 length = 0;
          UInt32 dataSize2 = (UInt32)sizeof(length);
          ExtAudioFileGetProperty(inputFile,
                                  kExtAudioFileProperty_FileLengthFrames, &dataSize2, &length);
      
          SInt16 *buffer = (SInt16*)malloc(kBufferSize * sizeof(SInt16));
      
          UInt32 totalFramecount = 0;
      
          AudioBufferList bufferList;
          bufferList.mNumberBuffers = 1;
          bufferList.mBuffers[0].mNumberChannels = 1;
          bufferList.mBuffers[0].mData = buffer; // pointer to buffer of audio data
          bufferList.mBuffers[0].mDataByteSize = kBufferSize *
          sizeof(SInt16); // number of bytes in the buffer
      
          while(true) {
      
              UInt32 frameCount = kBufferSize * sizeof(SInt16) / 2;
              // Read a chunk of input
              ExtAudioFileRead(inputFile, &frameCount, &bufferList);
              totalFramecount += frameCount;
      
              if (!frameCount || totalFramecount >= length) {
                  //termination condition
                  break;
              }
              ExtAudioFileWrite(outputFile, frameCount, &bufferList);
          }
      
          free(buffer);
      
          ExtAudioFileDispose(inputFile);
          ExtAudioFileDispose(outputFile);
      
      }
      

      它将根据因素改变音高

      【讨论】:

        【解决方案4】:

        我之前用过 NewTimePitch 音频单元,音频组件描述是

        var newTimePitchDesc = AudioComponentDescription(componentType: kAudioUnitType_FormatConverter,
                componentSubType: kAudioUnitSubType_NewTimePitch,
                componentManufacturer: kAudioUnitManufacturer_Apple,
                componentFlags: 0,
                componentFlagsMask: 0)
        

        然后您可以通过调用 AudioUnitSetParamater 来更改音高参数。例如,这会将音高更改 -1000 美分

        err = AudioUnitSetParameter(newTimePitchAudioUnit,
                kNewTimePitchParam_Pitch,
                kAudioUnitScope_Global,
                0,
                -1000,
                0)
        

        此音频单元的参数如下

            // Parameters for AUNewTimePitch
        enum {
              // Global, rate, 1/32 -> 32.0, 1.0
          kNewTimePitchParam_Rate                         = 0,
              // Global, Cents, -2400 -> 2400, 1.0
          kNewTimePitchParam_Pitch                        = 1,
              // Global, generic, 3.0 -> 32.0, 8.0
          kNewTimePitchParam_Overlap                      = 4,
              // Global, Boolean, 0->1, 1
          kNewTimePitchParam_EnablePeakLocking            = 6
        };
        

        但您只需要更改音高参数即可。有关如何实现此功能的指南,请参阅贾斯汀的回答

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-01-13
          • 2010-11-03
          • 2010-09-28
          • 1970-01-01
          • 2011-03-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多