Android音频:改变音调

时间:2011-10-29 14:10:50

标签: android audio signal-processing soundpool

SoundPool的Android文档说“应用程序还可以通过实时调整多普勒或合成效果的播放速率来改变音高”。所以我尝试这样做,使用setRate方法从一个音符平滑地变化到另一个音符,但结果很糟糕:声音变化非常粗糙。这是我试过的代码。请告诉我是否有更好的方法。

int streamId = soundPool.play (soundId, 1, 1, 1, 0, 1.0f);
for (float x = 0; x < 1; x += 0.005) {
  SystemClock.sleep (10);
  soundPool.setRate (streamId, 1 + x);
}

2 个答案:

答案 0 :(得分:13)

尽管Androids文档建议您可以使用setRate()来产生多普勒效应,但我不会依赖每个Android设备上的快速或足够好的实现。

经济实惠的音频IC需要44kHz或48kHz的固定采样率。因此,采样率转换(即音调修改)必须在软件中完成。因为这包括低级数字运算,我确信这是由设备制造商实现的,而不是由Google实现的。鉴于各种Android设备制造商和通常使用的低成本硬件,当然有很多采样率转换实现。有些更快,有些更慢。有些光滑,有些衣衫褴褛。

在播放期间更改转换率时会发生什么?如果算法不能精确匹配各个部分,则音频播放可能会出现短暂的裂缝。您每10毫秒更改一次转换率。如果每10ms有一个裂缝,那就相当于100Hz的频率,这是一个音调本身。这可能是你听到的“衣衫褴褛的”。

总而言之,我认为使用高级Android API在各种Android设备上实时模拟乐器是不可能的。本机应用程序可能足够快。

答案 1 :(得分:0)

尝试完所有后,我决定使用SoundPool来改变音高,播放速率为2.0会使声音以高于其原始频率的频率播放,而播放速率为0.5会使其以原始音量的一半播放频率。播放速率范围为0.5到2.0。 但它确实适用于较低且高于0.5和2.0的频率。

我发布了我的工作代码,

但是因为它仅用于演示目的,每次安装应用程序时,您需要手动更改“播放速率”,例如:“sp.play(explosion,1,1,0,0,1.5f)”这里“1.5f”是播放速率。可以轻松创建EditView或类似的东西,以便在运行时设置播放速率的值。

在这个应用程序中,您只需点击应用程序的屏幕即可以设定的播放速率播放音乐。

import java.io.IOException;

import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class SoundPoolActivity extends Activity implements OnClickListener {

    SoundPool sp;
    int explosion = 0;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

       View v = new View(this);
       v.setOnClickListener(this);
       setContentView(v);
       sp = new SoundPool(1,AudioManager.STREAM_MUSIC,0);
       //explosion = sp.load(this, R.raw.hh,0);
       explosion = sp.load("/sdcard/hh.m4a",0);


    }


    public void onClick(View v){
         if (explosion!=0){

             sp.play(explosion, 1,1,0,0,2.3f);
         }

    }
}