在Java/Android中添加两个音频信号
我在试着做我自己的回声垫,事实上在回声部分之前一切都很顺利 起初我从声音创作开始,它很棒,但当我开始添加回声效果时,它听起来很愚蠢 代码在Java/Android中添加两个音频信号,java,audio,echo,Java,Audio,Echo,我在试着做我自己的回声垫,事实上在回声部分之前一切都很顺利 起初我从声音创作开始,它很棒,但当我开始添加回声效果时,它听起来很愚蠢 代码 package com.echo; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.A
package com.echo;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
public class WavePlay {
private final static float duration = 1f; // seconds
private final static int sampleRate = 44100;
private final static int numSamples = (int) (duration * sampleRate);
private final static double sample[] = new double[numSamples];
private static SourceDataLine line = null;
private static int freqOfTone = 30;
private static byte[] original;
public static void main(String[] args) {
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
sampleRate, 8, 1, 1, sampleRate, true);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
try {
line = (SourceDataLine) AudioSystem.getLine(info);
line.open(format);
} catch (LineUnavailableException e) {
e.printStackTrace();
}
for (int i = 0; i < numSamples; ++i) {
sample[i] = 255 * Math.sin(2 * Math.PI * i
/ (sampleRate / freqOfTone));
}
final byte generatedSnd[] = new byte[100000];
original = new byte[generatedSnd.length];
for (int i = 0; i < 20000; i++) {
generatedSnd[i] = (byte) (sample[i % sample.length] + 1);
original[i] = generatedSnd[i];
}
// Echo
int delaySamples = 10000;
float decay = 0.3f;
for (int j = 0; j < 5; j++) {
for (int i = 0; i < generatedSnd.length; i++) {
if (i < delaySamples * (j + 1)) {
continue;
}
generatedSnd[i] += (byte) (original[i - delaySamples * (j + 1)] * decay);
}
decay *= 0.4;
}
// play
InputStream source = new ByteArrayInputStream(generatedSnd);
int numRead = 0;
byte[] buf = new byte[line.getBufferSize()];
line.start();
// read and play chunks of the audio
try {
while ((numRead = source.read(buf, 0, buf.length)) >= 0) {
int offset = 0;
while (offset < numRead)
offset += line.write(buf, offset, numRead - offset);
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
line.drain();
line.stop();
line.close();
System.exit(0);
}
}
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
public class WavePlay {
public static void main(String[] args) {
float duration = 1f; // seconds
int sampleRate = 44100;
int numSamples = (int) (duration * sampleRate);
double sample[] = new double[numSamples];
SourceDataLine line = null;
int freqOfTone = 300;
double[] original;
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
sampleRate, 8, 1, 1, sampleRate, true);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
try {
line = (SourceDataLine) AudioSystem.getLine(info);
line.open(format);
} catch (LineUnavailableException e) {
e.printStackTrace();
}
double increment = 2 * Math.PI * freqOfTone / sampleRate;
double angle = 0;
for (int i = 0; i < numSamples; ++i) {
sample[i] = (Math.sin(angle)) * Byte.MAX_VALUE;
angle += increment;
}
final double generatedSnd[] = new double[200000];
original = new double[generatedSnd.length];
for (int i = 0; i < 20000; i++) {
generatedSnd[i] = sample[i % sample.length];
original[i] = generatedSnd[i];
}
// Echo
int delaySamples = 20000;
float decay = 0.8f;
double maxValue = Byte.MAX_VALUE;
for (int j = 0; j < 10; j++) {
for (int i = 0; i < generatedSnd.length; i++) {
if (i < delaySamples * (j + 1)) {
continue;
}
generatedSnd[i] += original[i - delaySamples * (j + 1)] * decay;
if(generatedSnd[i] > maxValue){
maxValue = generatedSnd[i];
}
}
decay *= 0.5;
}
//scale to fit byte length (8 bit)
byte[] out = new byte[generatedSnd.length];
for (int i = 0; i < out.length; i++) {
out[i] = (byte)(Byte.MAX_VALUE * generatedSnd[i] / maxValue);
}
// play
InputStream source = new ByteArrayInputStream(out);
int numRead = 0;
byte[] buf = new byte[line.getBufferSize()];
line.start();
// read and play chunks of the audio
try {
while ((numRead = source.read(buf, 0, buf.length)) >= 0) {
int offset = 0;
while (offset < numRead)
offset += line.write(buf, offset, numRead - offset);
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
line.drain();
line.stop();
line.close();
System.exit(0);
}
}
package com.echo;
导入java.io.ByteArrayInputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入javax.sound.sampled.AudioFormat;
导入javax.sound.sampled.AudioSystem;
导入javax.sound.sampled.DataLine;
导入javax.sound.sampled.LineUnavailableException;
导入javax.sound.sampled.SourceDataLine;
公共类波浪游戏{
私有最终静态浮动持续时间=1f;//秒
私人最终静态int采样器=44100;
私有最终静态int numSamples=(int)(持续时间*采样器);
私有最终静态双样本[]=新双样本[numSamples];
私有静态SourceDataLine=null;
专用静态int频率=30;
私有静态字节[]原始;
公共静态void main(字符串[]args){
AudioFormat格式=新的AudioFormat(AudioFormat.Encoding.PCM_签名,
采样器,8,1,1,采样器,真);
DataLine.Info=newdataline.Info(SourceDataLine.class,格式);
试一试{
line=(SourceDataLine)AudioSystem.getLine(info);
行。打开(格式);
}捕获(LineUnavailableException e){
e、 printStackTrace();
}
对于(int i=0;i=0){
整数偏移=0;
while(偏移量
请运行代码并告诉我是否有任何问题
提前多谢了事实上有几个错误,下面的代码通过这些更改生成了更清晰的结果:
- 写入缓冲区中的值必须小于Byte.MAX_值(如果在支持短数组的android上写入,则偏移量将短于.MAX_值)
- 示例创建是以更简洁的方式实现的
package com.echo;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
public class WavePlay {
private final static float duration = 1f; // seconds
private final static int sampleRate = 44100;
private final static int numSamples = (int) (duration * sampleRate);
private final static double sample[] = new double[numSamples];
private static SourceDataLine line = null;
private static int freqOfTone = 30;
private static byte[] original;
public static void main(String[] args) {
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
sampleRate, 8, 1, 1, sampleRate, true);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
try {
line = (SourceDataLine) AudioSystem.getLine(info);
line.open(format);
} catch (LineUnavailableException e) {
e.printStackTrace();
}
for (int i = 0; i < numSamples; ++i) {
sample[i] = 255 * Math.sin(2 * Math.PI * i
/ (sampleRate / freqOfTone));
}
final byte generatedSnd[] = new byte[100000];
original = new byte[generatedSnd.length];
for (int i = 0; i < 20000; i++) {
generatedSnd[i] = (byte) (sample[i % sample.length] + 1);
original[i] = generatedSnd[i];
}
// Echo
int delaySamples = 10000;
float decay = 0.3f;
for (int j = 0; j < 5; j++) {
for (int i = 0; i < generatedSnd.length; i++) {
if (i < delaySamples * (j + 1)) {
continue;
}
generatedSnd[i] += (byte) (original[i - delaySamples * (j + 1)] * decay);
}
decay *= 0.4;
}
// play
InputStream source = new ByteArrayInputStream(generatedSnd);
int numRead = 0;
byte[] buf = new byte[line.getBufferSize()];
line.start();
// read and play chunks of the audio
try {
while ((numRead = source.read(buf, 0, buf.length)) >= 0) {
int offset = 0;
while (offset < numRead)
offset += line.write(buf, offset, numRead - offset);
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
line.drain();
line.stop();
line.close();
System.exit(0);
}
}
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
public class WavePlay {
public static void main(String[] args) {
float duration = 1f; // seconds
int sampleRate = 44100;
int numSamples = (int) (duration * sampleRate);
double sample[] = new double[numSamples];
SourceDataLine line = null;
int freqOfTone = 300;
double[] original;
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
sampleRate, 8, 1, 1, sampleRate, true);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
try {
line = (SourceDataLine) AudioSystem.getLine(info);
line.open(format);
} catch (LineUnavailableException e) {
e.printStackTrace();
}
double increment = 2 * Math.PI * freqOfTone / sampleRate;
double angle = 0;
for (int i = 0; i < numSamples; ++i) {
sample[i] = (Math.sin(angle)) * Byte.MAX_VALUE;
angle += increment;
}
final double generatedSnd[] = new double[200000];
original = new double[generatedSnd.length];
for (int i = 0; i < 20000; i++) {
generatedSnd[i] = sample[i % sample.length];
original[i] = generatedSnd[i];
}
// Echo
int delaySamples = 20000;
float decay = 0.8f;
double maxValue = Byte.MAX_VALUE;
for (int j = 0; j < 10; j++) {
for (int i = 0; i < generatedSnd.length; i++) {
if (i < delaySamples * (j + 1)) {
continue;
}
generatedSnd[i] += original[i - delaySamples * (j + 1)] * decay;
if(generatedSnd[i] > maxValue){
maxValue = generatedSnd[i];
}
}
decay *= 0.5;
}
//scale to fit byte length (8 bit)
byte[] out = new byte[generatedSnd.length];
for (int i = 0; i < out.length; i++) {
out[i] = (byte)(Byte.MAX_VALUE * generatedSnd[i] / maxValue);
}
// play
InputStream source = new ByteArrayInputStream(out);
int numRead = 0;
byte[] buf = new byte[line.getBufferSize()];
line.start();
// read and play chunks of the audio
try {
while ((numRead = source.read(buf, 0, buf.length)) >= 0) {
int offset = 0;
while (offset < numRead)
offset += line.write(buf, offset, numRead - offset);
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
line.drain();
line.stop();
line.close();
System.exit(0);
}
}
import java.io.ByteArrayInputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入javax.sound.sampled.AudioFormat;
导入javax.sound.sampled.AudioSystem;
导入javax.sound.sampled.DataLine;
导入javax.sound.sampled.LineUnavailableException;
导入javax.sound.sampled.SourceDataLine;
公共类波浪游戏{
公共静态void main(字符串[]args){
浮动持续时间=1f;//秒
int-sampleRate=44100;
int numSamples=(int)(持续时间*取样器);
双样本[]=新的双样本[numSamples];
SourceDataLine=null;
int频率=300;
双[]原件;
AudioFormat格式=新的AudioFormat(AudioFormat.Encoding.PCM_签名,
采样器,8,1,1,采样器,真);
DataLine.Info=newdataline.Info(SourceDataLine.class,格式);
试一试{
line=(SourceDataLine)AudioSystem.getLine(info);
行。打开(格式);
}捕获(LineUnavailableException e){
e、 printStackTrace();
}
双增量=2*Math.PI*频率/采样器;
双角度=0;
对于(int i=0;imaxValue){
maxValue=generatedSnd[i];
}
}
衰减*=0.5;
}
//缩放以适应字节长度(8位)
byte[]out=新字节[generatedSnd.length];
for(int i=0;i