Java Android:正弦波生成

Java Android:正弦波生成,java,android,waveform,Java,Android,Waveform,我正在尝试使用AudioTrack生成正弦波、方波和锯齿波。然而,这产生的音频听起来不像一个纯粹的正弦波,而是有一些其他的波叠加。在使用第一个示例中的方法时,如何获得第二个代码示例中的纯正弦波?由于上面的例子只涉及到第二个例子中使用的一些算法,它们不应该产生相同的波形吗 @Override protected Void doInBackground(Void... foo) { short[] buffer = new short[1024];

我正在尝试使用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!

            }           
        }
@覆盖
受保护的Void doInBackground(Void…foo){
short[]buffer=新的short[1024];
this.track=新的AudioTrack(AudioManager.STREAM\u MUSIC,44100,AudioFormat.CHANNEL\u CONFIGURATION\u MONO,AudioFormat.ENCODING\u PCM\u 16位,minBufferSize,AudioTrack.MODE\u STREAM);
浮点数样本[]=新浮点数[1024];
这个。track。play();
while(true){
对于(int i=0;i
注意:这给了我一个纯正弦波:

@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!

            }           
        }
@覆盖
受保护的Void doInBackground(Void…foo){
short[]buffer=新的short[1024];
this.track=新的AudioTrack(AudioManager.STREAM\u MUSIC,44100,AudioFormat.CHANNEL\u CONFIGURATION\u MONO,AudioFormat.ENCODING\u PCM\u 16位,minBufferSize,AudioTrack.MODE\u STREAM);
浮点增量=(浮点)(2*Math.PI)*频率/44100;//每个样本的角度增量
浮动角度=0;
浮点数样本[]=新浮点数[1024];
这个。track。play();
while(true){
对于(int i=0;i

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

我在您的两个代码示例中看到的唯一实质性差异是,第一个示例中的方程包含一个整数(
I
),因此,您可能正在执行整数(而不是浮点)运算。这将导致阶梯效应,给波形增加不必要的谐波

我猜想,如果你简单地将
I
转换为等式中的一个浮点,它将产生一个纯正弦波

samples[i] 
    = (float) Math.sin( (float)i * ((float)(2*Math.PI) * frequency / 44100));

尝试通过以下方式优化代码:

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

  • 为什么??因为我怀疑缓冲区需要很长时间来准备,是什么导致两次缓冲区推送之间的延迟变大,这可能是噪音的原因。

    这些anwers都无法解决问题。缓冲区长度应该是采样率的倍数,或者至少是一次旋转的长度。让我们将其分解为大量变量,以显示我们对事物的理解:

    int sampleRate = 44100;
    int bitsPerChannel = 16;
    int bytesPerChannel = bitsPerChannel / 8;
    int channelCount = 1;
    int bytesPerSample = channelCount * bytesPerChannel;
    int bytesPerRotation = sampleRate * bytesPerSample * (1d / (double) frequency);
    

    然后你可以将这个
    字节旋转
    乘以任何东西,它不会改变一个事实:声音中不会出现小故障。

    听起来你可能听到了一些混叠或剪辑。试着降低你产生的声波的振幅。那么为什么不使用有效的代码呢?我不知道你的问题是什么。罗伯特,我也想创建方波和锯齿波,但在处理更高级别的波函数时,整个角度和增量的想法让我感到困惑。尝试通过1)增加缓冲区大小,2)准备缓冲区一次,并继续将其重写到输出流来优化代码(这将需要一些数学计算来计算缓冲器的完美大小,以确保整个正弦波完全适合它).哦,我现在明白你的意思了。因为在缓冲区中,可能会在一个完整波长之间结束波,导致波在每次缓冲区推压的开始和结束时变形?将I转换为浮点数根本不会影响计算。@you786是的,好的。我想我们已经确定了这一点。