Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 在音频应用程序中使用奴佛卡因_Iphone_Objective C_Ios_Avaudioplayer - Fatal编程技术网

Iphone 在音频应用程序中使用奴佛卡因

Iphone 在音频应用程序中使用奴佛卡因,iphone,objective-c,ios,avaudioplayer,Iphone,Objective C,Ios,Avaudioplayer,我正在构建一个iPhone应用程序,通过以“caf”格式播放单独录制的吉他音符来生成随机吉他音乐。这些音符的持续时间从3秒到11秒不等,这取决于持续的时间 我最初使用AVAudioPlayer进行播放,在模拟器中以120 bpm的速度播放16个音符,它唱得很好听,但在我的手机上,当我 将速度提高到60 bpm多一点,只播放1/4个音符,它像狗一样跑,无法跟上时间。我的兴高采烈是短暂的 为了减少延迟,我尝试使用Apple MixerHost项目作为音频引擎的模板,通过音频单元实现播放,但在我将其连

我正在构建一个iPhone应用程序,通过以“caf”格式播放单独录制的吉他音符来生成随机吉他音乐。这些音符的持续时间从3秒到11秒不等,这取决于持续的时间

我最初使用AVAudioPlayer进行播放,在模拟器中以120 bpm的速度播放16个音符,它唱得很好听,但在我的手机上,当我 将速度提高到60 bpm多一点,只播放1/4个音符,它像狗一样跑,无法跟上时间。我的兴高采烈是短暂的

为了减少延迟,我尝试使用Apple MixerHost项目作为音频引擎的模板,通过音频单元实现播放,但在我将其连接并将所有内容连接起来后,一直出现严重的访问错误

经过几个小时的努力,我放弃了思考,转而使用Novocaine音频引擎

我现在遇到一堵砖墙,试图把它和我的模型连接起来

在最基本的层面上,我的模型是一个Neck对象,其中包含一个Notes对象字典

每个音符对象都知道它所在的吉他琴颈的弦和弦,并包含自己的AVAudioPlayer

我制作了一个半音吉他琴颈,它包含122个音符(6弦22格)或144个音符(6弦24格),具体取决于用户偏好中选择的琴颈大小

我使用这些音符作为我的单一真理点,所以音乐引擎生成的所有标量音符都是指向这个彩色音符桶的指针

@interface Note : NSObject <NSCopying>
{
    NSString *name;
    AVAudioPlayer *soundFilePlayer;
    int stringNumber;
    int fretNumber; 
}
每个便笺的AVAudioPlayer加载如下:

- (AVAudioPlayer *)buildStringNotePlayer:(NSString *)nameOfNote
{
    NSString *soundFileName = @"S";
    soundFileName = [soundFileName stringByAppendingString:[NSString stringWithFormat:@"%d", stringNumber]];
    soundFileName = [soundFileName stringByAppendingString:@"F"];

    if (fretNumber < 10) {
        soundFileName = [soundFileName stringByAppendingString:@"0"];
    }
    soundFileName = [soundFileName stringByAppendingString:[NSString stringWithFormat:@"%d", fretNumber]];

    NSString *soundPath = [[NSBundle mainBundle] pathForResource:soundFileName ofType:@"caf"];
    NSURL *fileURL = [NSURL fileURLWithPath:soundPath];
    AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];

    return notePlayer;
}
但在下载的项目中,您使用以下代码加载音频

// AUDIO FILE READING OHHH YEAHHHH
// ========================================
NSURL *inputFileURL = [[NSBundle mainBundle] URLForResource:@"TLC" withExtension:@"mp3"];

fileReader = [[AudioFileReader alloc]
              initWithAudioFileURL:inputFileURL
              samplingRate:audioManager.samplingRate
              numChannels:audioManager.numOutputChannels];

[fileReader play];
fileReader.currentTime = 30.0;

[audioManager setOutputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels)
{
    [fileReader retrieveFreshAudio:data numFrames:numFrames numChannels:numChannels];
    NSLog(@"Time: %f", fileReader.currentTime);
}];
这里是我真正开始感到困惑的地方,因为第一个方法使用浮点,第二个方法使用URL

如何将“caf”文件传递给浮点?我不知道如何使用奴佛卡因,我的脑子里还不清楚

我的问题,我希望有人能帮助我如下

  • Novocaine对象是否与AVAudioPlayer对象类似,只是更通用,并且调整到最大值以减少延迟?i、 e.独立音频播放(/录制/生成)装置

  • 我可以在我的模型中使用奴佛卡因吗?i、 e.每个彩色音符1个奴佛卡因对象,还是我应该有一个包含所有彩色音符的奴佛卡因对象?或者我只是将URL存储在便笺中,然后将其传递给Novocaine播放器

  • 当我的音频是“caf”文件且“audioToPlay”处于浮动状态时,如何将我的音频放入“audioToPlay”中

  • 如果我在Note.m中包含并声明Novocaine属性,那么我是否必须将该类重命名为Note.mm才能使用Novocaine对象

  • 如何同时播放多个奴佛卡因对象以再现和弦和音程

  • 我可以循环Novocaine对象的播放吗

  • 我可以设置音符的播放长度吗?i、 e.播放10秒的音符,只持续1秒

  • 我可以修改上述代码以使用奴佛卡因吗

  • 我在runMusicGenerator中使用的方法是否正确,以保持符合专业标准的节奏


  • 无需手动设置RemoteIO AudioUnit,Novocaine使您的生活更加轻松。这包括必须痛苦地填充一堆CoreAudio结构,并提供一堆回调,比如这个音频进程回调

    静态OSStatus PerformThru(void*inRefCon,AudioUnitRenderActionFlags*ioActionFlags,const AudioTimeStamp*inTimeStamp,UInt32 inbunsumber,UInt32 inNumberFrames,AudioBufferList*ioData)

    取而代之的是,Novocaine在它的实现中处理这个问题,然后调用你的块,你可以通过这样做来设置它

    [audioManager设置输出块:^(浮点*AudioTopPlay,UInt32 numSamples,UInt32 numChannel){}

    无论你写什么
    audioToPlay
    都会播放

  • Novocaine为您设置RemoteIO AudioUnit。这是一个低级别的CoreAudio API,不同于高级别的AVFoundation,并且正如预期的那样,延迟非常低。你说得对,奴佛卡因是自给自足的。您可以实时录制、生成和处理音频

  • 奴佛卡因是单例,不能有多个奴佛卡因实例。一种方法是将吉他声音存储在一个单独的类或数组中,然后编写一系列方法,使用Novocaine来播放它们

  • 你有很多选择。您可以使用Novocaine的AudioFileReader为您播放.caf文件。您可以通过分配一个AudioFileReader,然后传递要播放的.caf文件的URL来实现这一点,如示例代码所示。然后在块中粘贴
    [fileReader retrieveFreshAudio:data numFrames:numFrames numChannels:numChannels]
    ,如示例代码所示。每次调用块时,AudioFileReader都会从磁盘抓取并缓冲一块音频,并将其放入
    audioToPlay
    ,然后播放。这有一些缺点。对于短音(比如我假设的吉他音),反复调用
    retrieveFreshAudio
    是一种性能上的成功。通常最好(对于短声音)执行同步、顺序地将整个文件读入内存。奴佛卡因还没有提供一种方法来做到这一点。您必须使用ExtAudioFileServices来执行此操作。Apple示例项目MixerHost详细介绍了如何实现这一点

  • 如果您使用的是AudioFileReader是。当您是C++时,您只重命名为.m.代码>导入/ <代码> ING,从Obj-C++标题或<代码>包含< <代码> ING C++头。< /P>
  • 如前所述,仅允许使用1个奴佛卡因实例。您可以通过混合多个音频源来实现复调。这只是简单地将缓冲区添加到一起。如果你用不同的音高弹奏了多个版本的相同吉他声音,只要把它们都读到记忆中,
    Novocaine *audioManager = [Novocaine audioManager];
    [audioManager setOutputBlock:^(float *audioToPlay, UInt32 numSamples, UInt32 numChannels) {
        // All you have to do is put your audio into "audioToPlay".
    }];
    
    // AUDIO FILE READING OHHH YEAHHHH
    // ========================================
    NSURL *inputFileURL = [[NSBundle mainBundle] URLForResource:@"TLC" withExtension:@"mp3"];
    
    fileReader = [[AudioFileReader alloc]
                  initWithAudioFileURL:inputFileURL
                  samplingRate:audioManager.samplingRate
                  numChannels:audioManager.numOutputChannels];
    
    [fileReader play];
    fileReader.currentTime = 30.0;
    
    [audioManager setOutputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels)
    {
        [fileReader retrieveFreshAudio:data numFrames:numFrames numChannels:numChannels];
        NSLog(@"Time: %f", fileReader.currentTime);
    }];
    
    [audioManager setOutputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels){
        static int count = 0;
        for(int i=0; i<numFrames; ++i){
            //Mono mix each sample of each sound together. Since result can be 4x louder, divide the total amp by 4. 
            //You should be using `vDSP_vadd` from the accelerate framework for added performance.
            data[count] = (guitarC[count] + guitarE[count] + guitarG[count] + guitarB[count]) * 0.25;
            if(++count >= 44100) count = 0;    //Plays the mix for 1 sec
        }
    }];