计算两个通道的音频level/amplitude/db
Calculate the level/amplitude/db of audio for two channels
我已经阅读了两篇关于从 AudioInputStream 中提取样本并将其转换为 dB 的帖子。
据我了解 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);
希望你能帮助我。提前谢谢你。
立体声信号的保存格式称为 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);
}
我已经阅读了两篇关于从 AudioInputStream 中提取样本并将其转换为 dB 的帖子。
据我了解 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);
希望你能帮助我。提前谢谢你。
立体声信号的保存格式称为 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);
}