Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.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/7/neo4j/3.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
Objective c 如何更改声音的非实时音高/采样?_Objective C_Macos_Cocoa_Audio_Avfoundation - Fatal编程技术网

Objective c 如何更改声音的非实时音高/采样?

Objective c 如何更改声音的非实时音高/采样?,objective-c,macos,cocoa,audio,avfoundation,Objective C,Macos,Cocoa,Audio,Avfoundation,我有一个mp3声音,我想用pan、音高/采样和音量控制来播放一次(不会实时改变)。 我现在使用的是AVAudioPlayer,它可以工作,但是rate设置会执行时间拉伸,而不是执行samplerate更改,其中较低的值会导致声音变慢和变低,较高的值会导致声音变快和变高(有点像磁带速度)。 例如,当您的声音实际为44100时,将samplerate设置为88200 HZ将导致它以200%的速度/音高播放。 AVAudioPlayer是否可以实现类似的功能,或者是否有其他方法可以实现? 以下是我目前

我有一个mp3声音,我想用pan、音高/采样和音量控制来播放一次(不会实时改变)。 我现在使用的是AVAudioPlayer,它可以工作,但是rate设置会执行时间拉伸,而不是执行samplerate更改,其中较低的值会导致声音变慢和变低,较高的值会导致声音变快和变高(有点像磁带速度)。 例如,当您的声音实际为44100时,将samplerate设置为88200 HZ将导致它以200%的速度/音高播放。 AVAudioPlayer是否可以实现类似的功能,或者是否有其他方法可以实现? 以下是我目前掌握的情况:

player=[[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath: @"sound.mp3"] error: nil];
player.volume=0.4f;
player.pan=-1f;
player.enableRate=YES;
player.rate=2.0f;
[player play];

注意:我不是指结合使用时间拉伸来保持声音长度大致相同的音高方法,也不是指任何“高级”算法。

AVAudioEngine
可以为您提供音高、速率、平移和音量控制:

self.engine = [[AVAudioEngine alloc] init];

NSError *error;

AVAudioPlayerNode *playerNode = [[AVAudioPlayerNode alloc] init];
AVAudioMixerNode *mixer = [[AVAudioMixerNode alloc] init];
AVAudioUnitVarispeed *varispeed = [[AVAudioUnitVarispeed alloc] init];

[self.engine attachNode:playerNode];
[self.engine attachNode:varispeed];
[self.engine attachNode:mixer];

[self.engine connect:playerNode to:varispeed format:nil];
[self.engine connect:varispeed to:mixer format:nil];
[self.engine connect:mixer to:self.engine.mainMixerNode format:nil];

BOOL result = [self.engine startAndReturnError: &error];
assert(result);

AVAudioFile *audioFile = [[AVAudioFile alloc] initForReading:url error:&error];
assert(audioFile);

// rate & pitch (fused), pan and volume controls
varispeed.rate = 0.5; // half pitch & rate
mixer.pan = -1;       // left speaker
mixer.volume = 0.5;   // half volume

[playerNode scheduleFile:audioFile atTime:nil completionHandler:nil];
[playerNode play];

如果需要单独的速率和音高控制,请将
avaudionitVariSpeed
节点替换为
avaudionitTimePitch
节点。

它看起来不像AvAudioPlayer提供了那种功能改变播放速度不一定像改变采样率那么简单。支持的采样率有一定数量,因此您可能需要采取不同的方法。我能想到的最明显的方法是使用一个音频单元,在采样值之间进行插值,可以是删除值,也可以是添加值accordingly@fdcpp那我还有别的办法吗?也许是另一门课?另一个框架?如果是非实时的,你可以摄取音频文件,获取样本,应用插值,保存一个新的音频文件,然后播放出来。对于框架:JUCE可能是个笨手笨脚的人。OpenAL可以做到这一点,但已经过时了。音频单元似乎是最有可能的竞争者。这绝对是达到预期效果的最佳方式。我唯一能建议的补充是用
pitch.pitch=1200*log2(pitch.rate)
Thank you@fdcpp将音高与速率联系起来,我太懒了,没法接受step@RhythmicFistman非常感谢你!这是完美的,除了改变音高会导致时间延长,即音频不会随着音高的变化而变慢或变快,即使保持默认速率。我预计-1200音高大约是原来音高的两倍,等等。这就是1200*log2(音高速率)公式应该做的吗?是的!试试那个。啊,等等,你可能想要
avaudionunitvarispeed
。一秒钟,更新答案。