java - Android:正弦波生成

标签 java android waveform

我正在尝试使用 AudioTrack 生成正弦波、方波和锯齿波。然而,这样创建的音频听起来不像是纯正弦波,而是叠加了某种其他波形。在使用第一个示例中的方法的同时,我将如何像第二个代码示例中那样获得纯正弦波?由于上面的例子只围绕第二个中使用的一些算法移动,它们不应该产生相同的波吗?

@Override
        protected Void doInBackground(Void... foo) {
            short[] buffer = new short[1024];
            this.track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
            float samples[] = new float[1024];

            this.track.play();

            while (true) {
                for (int i = 0; i < samples.length; i++) {
                    samples[i] = (float) Math.sin( (float)i * ((float)(2*Math.PI) * frequency / 44100));    //the part that makes this a sine wave....
                    buffer[i] = (short) (samples[i] * Short.MAX_VALUE);
                }
                this.track.write( buffer, 0, samples.length );  //write to the audio buffer.... and start all over again!

            }           
        }

注意:这确实给了我一个纯正弦波:

@Override
        protected Void doInBackground(Void... foo) {
            short[] buffer = new short[1024];
            this.track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
            float increment = (float)(2*Math.PI) * frequency / 44100; // angular increment for each sample
            float angle = 0;
            float samples[] = new float[1024];

            this.track.play();

            while (true) {
                for (int i = 0; i < samples.length; i++) {
                    samples[i] = (float) Math.sin(angle);   //the part that makes this a sine wave....
                    buffer[i] = (short) (samples[i] * Short.MAX_VALUE);
                    angle += increment;
                }
                this.track.write( buffer, 0, samples.length );  //write to the audio buffer.... and start all over again!

            }           
        }

感谢 Martijn:问题是波在缓冲区中的波长之间被切断。增加缓冲区大小解决了第二个示例中的问题。看来 Math.PI * 2 算术是循环中最密集的,因此将该值移动到仅计算一次的外部变量可以解决所有问题。

最佳答案

尝试优化你的代码

  1. 增加缓冲区大小
  2. 一次准备好缓冲区,并不断将其重写到输出流(这将需要一些数学计算缓冲区的完美大小,以确保整个正弦波完全适合它)。

为什么?因为我怀疑缓冲区需要很长时间才能准备好,所以导致两次缓冲区推送之间的滞后很大,这可能会导致噪音。

关于java - Android:正弦波生成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11436472/

相关文章:

java - 将 xml 转换为 json 而不转换字符串/整数?

java - 在字符串化 Double 时,如何抑制整数情况下自动添加 ".0"后缀?

java - 以编程方式添加后无法从 JPanel 中删除 JLabel

android - Retrofit 2 没有 json 的请求体,只是一个普通的形式?

java - 自动更新平板电脑上的 Android 应用程序(即没有市场!)

java - 如何创建一个公式从另一个公式中的值中查找 D 的值

javascript - 如何根据高度过滤元素以适合容器

java - 打印返回值

android - 如何从 Android Studio 打开模拟器

python - 在 Python 中生成音频波形图