玩android系统中的活动重复AudioTrack [英] Playing repeated AudioTrack in android activity
问题描述
我想打在指定的速度,例如重复脉冲音3次。它的工作原理约20次,然后如下崩溃。
无效playSound(){
最后AudioTrack audioTrack =新AudioTrack(AudioManager.STREAM_MUSIC,采样率,AudioFormat.CHANNEL_CONFIGURATION_MONO,AudioFormat.ENCODING_PCM_16BIT,generatedSnd.length,AudioTrack.MODE_STATIC);
audioTrack.write(generatedSnd,0,generatedSnd.length);
audioTrack.play();
}
在一个AsyncTask的我运行一个不断循环,检查时间并在需要时调用playSound。它的工作原理了几秒钟,然后得到这个错误,
01-02 18:24:45.035:E / AndroidRuntime(6599):java.lang.IllegalStateException:通过打造成()呼吁未初始化AudioTrack。
即使轨道每次初始化。
什么我做错了任何指示?或者可以做的更好?
这里的code:
公共类DisplayBowieActivity延伸活动{私人最终诠释持续时间= 200; //秒
私人最终诠释采样率= 8000;
私人最终诠释NUMSAMPLES =持续时间*采样率/ 1000;
私人双样本[]; // =新的双[NUMSAMPLES]
私人最终双freqOfTone = 1440; //赫兹
私人诠释脉冲长度;
专用字节generatedSnd []; // =新的字节[2 * NUMSAMPLES]。
私人诠释周期= 4; //赫兹
私人AudioTrack audioTrack;
处理程序处理程序=新的处理程序();@覆盖
保护无效的onCreate(捆绑savedInstanceState){
super.onCreate(savedInstanceState);
的setContentView(R.layout.activity_display_bowie); 意向意图= getIntent();
字符串smessage = intent.getStringExtra(MainActivity.SOUND_MESSAGE);
周期=的Integer.parseInt(smessage);
脉冲长度=持续时间*采样率/ 1000;
System.out.print(+++期+周期);
System.out.print(+++脉冲+脉冲长度); genTone(); 查看查看= this.getWindow()getDecorView()。
view.setBackgroundColor(Color.parseColor(#8E8E38));}@覆盖
公共布尔onCreateOptionsMenu(菜单菜单){
//充气菜单;如果是present这增加了项目操作栏。
。getMenuInflater()膨胀(R.menu.display_bowie,菜单);
返回true;
}@覆盖
保护无效onResume(){
super.onResume(); 新SoundGen()执行(期);}私有类SoundGen扩展的AsyncTask<整数,太虚,太虚> {
@覆盖
保护无效doInBackground(整数...赫兹){
长密耳=(int)的(1000.0 /赫兹[0]);
长启动= System.currentTimeMillis的();
在下长=启动+密耳; 而(真){
长今= System.currentTimeMillis的();
如果(现>下面){
接下来= NOW +密耳;
播放声音();
} }
}}无效genTone(){
样品=新的双[NUMSAMPLES]
generatedSnd =新的字节[2 * NUMSAMPLES]。
INT率= NUMSAMPLES /期; 的for(int i = 0; I< NUMSAMPLES ++我){
如果(I%率== 0){
的System.out.println(+++创建音+ I); INT J = 0;
为(J = 0; J<脉冲长度; J ++){ 样本[I + J] = Math.sin(2 * Math.PI *(I + J)
/(采样率/ freqOfTone));
的System.out.println(+++ SAMPLE+(I + J)+
+样本[I + J]);
}
I = I + J;
}
} //转换成16位PCM阵列声音
//假设样品缓冲液是标准化。
INT IDX = 0;
对于(最终双DVAL:样品){
//规模最大振幅
最终短VAL =(短)((* DVAL 32767));
//在16位WAV PCM,第一个字节是低位字节
generatedSnd [IDX +] =(字节)(VAL&安培;设为0x00FF);
generatedSnd [IDX ++] =(字节)((VAL&放大器;为0xFF00)GT;>→8); }}
无效playSound(){
的System.out.println(+++ PLAY);
//audioTrack.stop();
//audioTrack.setPlaybackHeadPosition(0);
最后AudioTrack audioTrack =新AudioTrack(AudioManager.STREAM_MUSIC,采样率,AudioFormat.CHANNEL_CONFIGURATION_MONO,AudioFormat.ENCODING_PCM_16BIT,generatedSnd.length,AudioTrack.MODE_STATIC);
audioTrack.write(generatedSnd,0,generatedSnd.length);
audioTrack.play();
}
和这里的完整的错误:
01-02 18:24:45.035:E / AndroidRuntime(6599):致命异常:AsyncTask的#1
01-02 18:24:45.035:E / AndroidRuntime(6599):了java.lang.RuntimeException:执行doInBackground发生错误()
01-02 18:24:45.035:E / AndroidRuntime(6599):在android.os.AsyncTask $ 3.done(AsyncTask.java:200)
01-02 18:24:45.035:E / AndroidRuntime(6599):在java.util.concurrent.FutureTask中$ Sync.innerSetException(FutureTask.java:274)
01-02 18:24:45.035:E / AndroidRuntime(6599):在java.util.concurrent.FutureTask.setException(FutureTask.java:125)
01-02 18:24:45.035:E / AndroidRuntime(6599):在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:308)
01-02 18:24:45.035:E / AndroidRuntime(6599):在java.util.concurrent.FutureTask.run(FutureTask.java:138)
01-02 18:24:45.035:E / AndroidRuntime(6599):在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
01-02 18:24:45.035:E / AndroidRuntime(6599):在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:581)
01-02 18:24:45.035:E / AndroidRuntime(6599):在java.lang.Thread.run(Thread.java:1019)
01-02 18:24:45.035:E / AndroidRuntime(6599):java.lang.IllegalStateException:通过打造成()呼吁未初始化AudioTrack。
01-02 18:24:45.035:E / AndroidRuntime(6599):在android.media.AudioTrack.play(AudioTrack.java:824)
01-02 18:24:45.035:E / AndroidRuntime(6599):在uk.co.moonsit.signals.DisplayBowieActivity.playSound(DisplayBowieActivity.java:164)
01-02 18:24:45.035:E / AndroidRuntime(6599):在uk.co.moonsit.signals.DisplayBowieActivity $ SoundGen.doInBackground(DisplayBowieActivity.java:90)
01-02 18:24:45.035:E / AndroidRuntime(6599):在uk.co.moonsit.signals.DisplayBowieActivity $ SoundGen.doInBackground(DisplayBowieActivity.java:1)
01-02 18:24:45.035:E / AndroidRuntime(6599):在android.os.AsyncTask $ 2.call(AsyncTask.java:185)
01-02 18:24:45.035:E / AndroidRuntime(6599):在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:306)
01-02 18:24:45.035:E / AndroidRuntime(6599):... 4个
您正在运行了AudioTracks的,你的情况20,30日我的Nexus4,这给了我:
175-5975 /? E / AudioFlinger:可用没有更多的曲目名称
一个解决方案 - 使用你已经拥有全球audioTrack对象,为null,并在每场比赛创造:
无效playSound(){
的System.out.println(+++ PLAY); //如果audioTrack已经初始化,第一,释放所有资源
//那么它空
如果(audioTrack!= NULL){
audioTrack.release();
audioTrack = NULL;
} //现在又创建它,注意事项:使用全局audioTrack,
//这意味着删除最终AudioTrack在这里
audioTrack =新AudioTrack(AudioManager.STREAM_MUSIC,采样率,AudioFormat.CHANNEL_CONFIGURATION_MONO,AudioFormat.ENCODING_PCM_16BIT,generatedSnd.length,AudioTrack.MODE_STATIC); audioTrack.write(generatedSnd,0,generatedSnd.length);
audioTrack.play();
}
I want to play a tone pulse repeated at a specified rate, e.g. 3 times a second. It works about 20 times and then crashes as below.
void playSound() {
final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, AudioTrack.MODE_STATIC);
audioTrack.write(generatedSnd, 0, generatedSnd.length);
audioTrack.play();
}
In an asynctask I run a continuous loop that checks the time and calls playSound when required. It works for a few seconds and then get this error,
01-02 18:24:45.035: E/AndroidRuntime(6599): Caused by: java.lang.IllegalStateException: play() called on uninitialized AudioTrack.
even though the track is initialised each time.
Any indication of what I am doing wrong? Or could do better?
Here's the code:
public class DisplayBowieActivity extends Activity {
private final int duration = 200; // seconds
private final int sampleRate = 8000;
private final int numSamples = duration * sampleRate / 1000;
private double sample[];// =new double[numSamples];
private final double freqOfTone = 1440; // hz
private int pulseLength;
private byte generatedSnd[];// = new byte[2 * numSamples];
private int period = 4; // hz
private AudioTrack audioTrack;
Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_bowie);
Intent intent = getIntent();
String smessage = intent.getStringExtra(MainActivity.SOUND_MESSAGE);
period = Integer.parseInt(smessage);
pulseLength = duration * sampleRate / 1000;
System.out.print("+++ Period " + period);
System.out.print("+++ Pulse " + pulseLength);
genTone();
View view = this.getWindow().getDecorView();
view.setBackgroundColor(Color.parseColor("#8E8E38"));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.display_bowie, menu);
return true;
}
@Override
protected void onResume() {
super.onResume();
new SoundGen().execute(period);
}
private class SoundGen extends AsyncTask<Integer, Void, Void> {
@Override
protected Void doInBackground(Integer... hz) {
long mils = (int) (1000.0 / hz[0]);
long start = System.currentTimeMillis();
long next = start + mils;
while (true) {
long now = System.currentTimeMillis();
if (now > next) {
next = now + mils;
playSound();
}
}
}
}
void genTone() {
sample = new double[numSamples];
generatedSnd = new byte[2 * numSamples];
int rate = numSamples / period;
for (int i = 0; i < numSamples; ++i) {
if (i % rate == 0) {
System.out.println("+++ Create tone " + i);
int j = 0;
for (j = 0; j < pulseLength; j++) {
sample[i + j] = Math.sin(2 * Math.PI * (i + j)
/ (sampleRate / freqOfTone));
System.out.println("+++ SAMPLE " + (i + j) + " "
+ sample[i + j]);
}
i = i + j;
}
}
// convert to 16 bit pcm sound array
// assumes the sample buffer is normalised.
int idx = 0;
for (final double dVal : sample) {
// scale to maximum amplitude
final short val = (short) ((dVal * 32767));
// in 16 bit wav PCM, first byte is the low order byte
generatedSnd[idx++] = (byte) (val & 0x00ff);
generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
}
}
void playSound() {
System.out.println("+++ PLAY " );
//audioTrack.stop();
//audioTrack.setPlaybackHeadPosition(0);
final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, AudioTrack.MODE_STATIC);
audioTrack.write(generatedSnd, 0, generatedSnd.length);
audioTrack.play();
}
And here's the full error:
01-02 18:24:45.035: E/AndroidRuntime(6599): FATAL EXCEPTION: AsyncTask #1
01-02 18:24:45.035: E/AndroidRuntime(6599): java.lang.RuntimeException: An error occured while executing doInBackground()
01-02 18:24:45.035: E/AndroidRuntime(6599): at android.os.AsyncTask$3.done(AsyncTask.java:200)
01-02 18:24:45.035: E/AndroidRuntime(6599): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
01-02 18:24:45.035: E/AndroidRuntime(6599): at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
01-02 18:24:45.035: E/AndroidRuntime(6599): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
01-02 18:24:45.035: E/AndroidRuntime(6599): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
01-02 18:24:45.035: E/AndroidRuntime(6599): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
01-02 18:24:45.035: E/AndroidRuntime(6599): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
01-02 18:24:45.035: E/AndroidRuntime(6599): at java.lang.Thread.run(Thread.java:1019)
01-02 18:24:45.035: E/AndroidRuntime(6599): Caused by: java.lang.IllegalStateException: play() called on uninitialized AudioTrack.
01-02 18:24:45.035: E/AndroidRuntime(6599): at android.media.AudioTrack.play(AudioTrack.java:824)
01-02 18:24:45.035: E/AndroidRuntime(6599): at uk.co.moonsit.signals.DisplayBowieActivity.playSound(DisplayBowieActivity.java:164)
01-02 18:24:45.035: E/AndroidRuntime(6599): at uk.co.moonsit.signals.DisplayBowieActivity$SoundGen.doInBackground(DisplayBowieActivity.java:90)
01-02 18:24:45.035: E/AndroidRuntime(6599): at uk.co.moonsit.signals.DisplayBowieActivity$SoundGen.doInBackground(DisplayBowieActivity.java:1)
01-02 18:24:45.035: E/AndroidRuntime(6599): at android.os.AsyncTask$2.call(AsyncTask.java:185)
01-02 18:24:45.035: E/AndroidRuntime(6599): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
01-02 18:24:45.035: E/AndroidRuntime(6599): ... 4 more
You're running out of AudioTracks, 20 in your case, 30 on my Nexus4, which gives me:
175-5975/? E/AudioFlinger﹕ no more track names available
A solution - use global audioTrack object that you already have, and null it and create on every play:
void playSound() {
System.out.println("+++ PLAY ");
//if audioTrack has been initialised, first, release any resources
//then null it
if (audioTrack != null) {
audioTrack.release();
audioTrack = null;
}
//now create it again, note: use global audioTrack,
//that means remove "final AudioTrack" here
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, AudioTrack.MODE_STATIC);
audioTrack.write(generatedSnd, 0, generatedSnd.length);
audioTrack.play();
}
这篇关于玩android系统中的活动重复AudioTrack的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!