我如何编码一个任意的声音相当于一个频率值在搜索栏上播放android



当我在android手机或模拟器上运行这个类时,应用程序甚至没有启动。我将非常感谢任何改进:)

public class Whistly extends Activity implements OnClickListener,
    OnSeekBarChangeListener {
private SeekBar seekBar;
private Button k5;
private Button k10;
private Button k15;
private Button k20;
private ToggleButton whistle;
private TextView frequency;
private Integer intToneFreq = Integer.parseInt(String.valueOf(seekBar.getProgress()));
private final int duration = 2; // seconds
private final int sampleRate = 8000;
private final int numSamples = duration * sampleRate;
private final double sample[] = new double[numSamples];
private  int freqOfTone = intToneFreq * 1000; // hz
private final byte generatedSnd[] = new byte[2 * numSamples];

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_whistly);
    seekBar = (SeekBar) findViewById(R.id.seekBar);
    k5 = (Button) findViewById(R.id.k5);
    k10 = (Button) findViewById(R.id.k10);
    k15 = (Button) findViewById(R.id.k15);
    k20 = (Button) findViewById(R.id.k20);
    whistle = (ToggleButton) findViewById(R.id.toggleButton1);
    frequency = (TextView) findViewById(R.id.textView1);
    seekBar.setMax(25);
    seekBar.setOnSeekBarChangeListener(this);
    k5.setOnClickListener(this);
    k10.setOnClickListener(this);
    k15.setOnClickListener(this);
    k20.setOnClickListener(this);
    whistle.setOnClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.whistly, menu);
    return true;
}

@Override
public void onClick(View v) {
    if (v == k5) {
        frequency.setText(R.string.k5);
        seekBar.setProgress(5);
    }
    if (v == k10) {
        frequency.setText(R.string.k10);
        seekBar.setProgress(10);
    }
    if (v == k15) {
        frequency.setText(R.string.k15);
        seekBar.setProgress(15);
    }
    if (v == k20) {
        frequency.setText(R.string.k20);
        seekBar.setProgress(20);
    }
    if (v == whistle) {
        if(whistle.isChecked()){
            playSound();
        }
    }
}

@Override
protected void onResume() {
    super.onResume();
    // Use a new tread as this can take a while
    final Thread thread = new Thread(new Runnable() {
        public void run() {
            genTone();
        }
    });
    thread.start();
}
void genTone() {
    // fill out the array
    for (int i = 0; i < numSamples; ++i) {
        sample[i] =  Math.sin(2 * Math.PI * i / (sampleRate / freqOfTone));
    }
    // 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() {
    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();
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
        boolean fromUser) {
       String progress1 = String.valueOf(progress);
       frequency.setText(progress1 + " kHz");
   }
   @Override
   public void onStartTrackingTouch(SeekBar seekBar) {
   }
   @Override
   public void onStopTrackingTouch(SeekBar seekBar) {
   }
}

你不能这么做

private Integer intToneFreq = Integer.parseInt(String.valueOf(seekBar.getProgress()));

在静态初始化式中;在执行的早期,当它运行时,您还没有任何内容视图来包含膨胀的SeekBar,并且您还没有将SeekBar变量指向它。

你可以简单地通过初始化intToneFreq为一些安全的默认值来解决你的直接问题,并且只有当你的应用程序完全启动时才尝试读取进度条。但很可能你也会发现其他问题。正如在注释中提到的,您需要学习使用logcat工具和/或源代码调试器。

最新更新