【问题标题】:Calculate the level/amplitude/db of audio for two channels计算两个通道的音频电平/幅度/db
【发布时间】:2020-07-23 17:19:06
【问题描述】:

我已经阅读了两篇关于从 AudioInputStream 中提取样本并将其转换为 dB 的文章。

https://stackoverflow.com/a/26576548/8428414

https://stackoverflow.com/a/26824664/8428414

据我了解byte[] bytes; 的结构如下:

Index 0: Sample 0 (Left Channel)
Index 1: Sample 0 (Right Channel)
Index 2: Sample 1 (Left Channel)
Index 3: Sample 1 (Right Channel)
Index 4: Sample 2 (Left Channel)
Index 5: Sample 2 (Right Channel)

在第一篇文章中,它展示了如何从一个通道(单声道)获取样本。

所以,我的问题是我想分别为右声道和左声道分别获取样本,以便计算左右声道的 dB。

这里是代码。如何更改以分别获取右声道和左声道? 我无法理解索引i 的变化...

final byte[] buffer = new byte[2048];

float[] samples = new float[buffer.length / 2];

for (int n = 0; n != -1; n = in.read(buffer, 0, buffer.length)) {
    line.write(buffer, 0, n);

    for (int i = 0, sampleIndex = 0; i < n; ) {
        int sample = 0;

        sample |= buffer[i++] & 0xFF; // (reverse these two lines
        sample |= buffer[i++] << 8;   //  if the format is big endian)

        // normalize to range of +/-1.0f
        samples[sampleIndex++] = sample / 32768f;
    }

    float rms = 0f;
    for (float sample : samples) {
        rms += sample * sample;
    }

    rms = (float) Math.sqrt(rms / samples.length);

希望你能帮助我。提前谢谢你。

【问题讨论】:

    标签: java audio javasound audio-processing javax.sound.sampled


    【解决方案1】:

    立体声信号保存的格式称为interleaved。即,正如您正确描述的那样,它是LLRRLLRRLLRR...。因此,您首先需要读取左侧样本,然后读取右侧样本,依此类推。

    我已编辑您的代码以反映这一点。不过,refactoring 有一些改进的空间。

    注意:代码更改仅处理交错。我还没有检查你的其余代码。

    final byte[] buffer = new byte[2048];
    
    // create two buffers. One for the left, one for the right channel.
    float[] leftSamples = new float[buffer.length / 4];
    float[] rightSamples = new float[buffer.length / 4];
    
    for (int n = 0; n != -1; n = in.read(buffer, 0, buffer.length)) {
        line.write(buffer, 0, n);
    
        for (int i = 0, sampleIndex = 0; i < n; ) {
            int sample = 0;
    
            leftSample |= buffer[i++] & 0xFF; // (reverse these two lines
            leftSample |= buffer[i++] << 8;   //  if the format is big endian)
    
            rightSample |= buffer[i++] & 0xFF; // (reverse these two lines
            rightSample |= buffer[i++] << 8;   //  if the format is big endian)
    
            // normalize to range of +/-1.0f
            leftSamples[sampleIndex] = leftSample / 32768f;
            rightSamples[sampleIndex] = rightSample / 32768f;
    
            sampleIndex++;
        }
    
        // now compute RMS for left
        float leftRMS = 0f;
        for (float sample : leftSamples) {
            leftRMS += sample * sample;
        }
    
        leftRMS = (float) Math.sqrt(leftRMS / leftSamples.length);
    
        // ...and right
        float rightRMS = 0f;
        for (float sample : rightSamples) {
            rightRMS += sample * sample;
        }
    
        rightRMS = (float) Math.sqrt(rightRMS / rightSamples.length);
    }
    

    【讨论】:

      猜你喜欢
      • 2014-12-21
      • 1970-01-01
      • 2020-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-18
      相关资源
      最近更新 更多