android - Android应用程序中的采样率不可能超过1兆赫吗?
问题描述
所以,基本上我不仅仅是android开发的初学者。目前,我正在开发一个应用程序,它可以产生不同的声音频率来驱赶不同的动物。
基本思想是,动物可以听到和响应不同的频率,狗和猫响应频率范围为 22-25kHz,大鼠响应频率范围为 60-72kHz,昆虫(38-44kHz)和蜥蜴(52-60kHz)类似。
下面给出了我正在使用的代码,但问题是当我将采样率 (sr) 设置为 44100 作为人类推荐的采样率时,应用程序可以编译并且工作正常,但对于动物我需要将采样率 (sr) 设置为产生 60kHz 的频率需要两倍的频率,即 120kHz 的采样率(以击退大鼠和小鼠)。当我设置如此高的采样率时,应用程序崩溃并且无法运行。
我不知道出了什么问题。看一下代码。
package pk.edu.muet.tl.afm;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
public class Animal extends AppCompatActivity {
Button lizard;
Button petAnimal;
Button insects;
Button rats;
Thread t;
int sr = 44100;
boolean isRunning = true;
double sliderval = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animal);
lizard=(Button)findViewById(R.id.lizard);
petAnimal=(Button)findViewById(R.id.pet_animal);
insects=(Button)findViewById(R.id.insects);
rats=(Button)findViewById(R.id.rats);
lizard.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
lizard.setText("Stop");
}
});
petAnimal.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
sliderval=22000;
}
});
insects.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
sliderval=38000;
}
});
rats.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
sliderval=60000;
}
});
t = new Thread() {
public void run() {
setPriority(Thread.MAX_PRIORITY);
int buffsize = AudioTrack.getMinBufferSize(sr, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sr, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, buffsize, AudioTrack.MODE_STREAM);
short samples[] = new short[buffsize];
int amp = 10000;
double twopi = 8.*Math.atan(1.);
double fr = 440.f;
double ph = 0.0;
audioTrack.play();
while(isRunning){
fr = sliderval;
for(int i=0; i < buffsize; i++){
samples[i] = (short) (amp*Math.sin(ph));
ph += twopi*fr/sr;
}
audioTrack.write(samples, 0, buffsize);
}
audioTrack.stop();
audioTrack.release();
}
};
t.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.animal, menu);
return true;
}
public void onDestroy(){
super.onDestroy();
isRunning = false;
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
t = null;
}
} ```
解决方案
推荐阅读
- flutter - 在颤动中使用用户输入(行和列)创建 Gridview
- javascript - 在外部单击时关闭多个框下拉菜单
- android - 将 Android.mk 转换为 android.bp 时出错
- java - 编译时找不到 Manifest.permission.CAPTURE_VIDEO_OUTPUT,如何解决?
- javascript - 未捕获的类型错误:无法设置未定义的属性“值” // for 和 while 循环的区别?
- reactjs - Webfonts-loader:覆盖同名图标
- java - 使用 s3Client.copyObject 方法复制带有“子目录”的 S3 对象
- c# - Winforms,我可以在这里使用文本框而不是组合框吗?(超过 15k 选项的下拉列表)
- flutter - 如果用户是管理员颤振,则显示一个小部件
- sql - 如何将 SQL 表中的正则表达式匹配到文本