【发布时间】:2014-03-25 23:13:39
【问题描述】:
我试图从两个或两个以上相同长度的音频文件创建一个同步音频输出文件。 我做了一些研究,发现这可以通过以下步骤来实现:
- 只有未压缩的音频文件可以用于此目的。即将 mp3 音频文件转换为 WAV 格式。
- 混合 2 个新的 wav 文件;我遵循了这种方法: Mix audio in android
但同样的问题出现了,混合的音频文件无法播放。
我一直在尝试按照这个答案 Writing PCM recorded data into a .wav file (java android) 向输出文件添加一个有效的标题。
这是我的混音器类:
public class SongMixer2
{
private Context mContext;
public SongMixer2(Context context)
{
mContext = context;
}
public void onCreate()
{
try
{
mixSound();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void mixSound() throws IOException
{
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
44100, AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT, 44100, AudioTrack.MODE_STREAM);
InputStream in1 = mContext.getResources().openRawResource(R.raw.brokaw);
InputStream in2 = mContext.getResources().openRawResource(R.raw.brokaw);
byte[] arrayMusic1 = null;
arrayMusic1 = new byte[in1.available()];
arrayMusic1 = createMusicArray(in1);
in1.close();
byte[] arrayMusic2 = null;
arrayMusic2 = new byte[in2.available()];
arrayMusic2 = createMusicArray(in2);
in2.close();
byte[] output = new byte[arrayMusic1.length];
audioTrack.play();
for (int i = 0; i < output.length - 1; i++)
{
float samplef1 = arrayMusic1[i] / 128.0f;
float samplef2 = arrayMusic2[i] / 128.0f;
float mixed = samplef1 + samplef2;
// reduce the volume a bit:
mixed *= 0.8;
// hard clipping
if (mixed > 1.0f)
mixed = 1.0f;
if (mixed < -1.0f)
mixed = -1.0f;
byte outputSample = (byte) (mixed * 128.0f);
output[i] = outputSample;
}
audioTrack.write(output, 0, output.length);
convertByteToFile(output);
}
public static byte[] createMusicArray(InputStream is) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buff = new byte[10240];
int i = Integer.MAX_VALUE;
while ((i = is.read(buff, 0, buff.length)) > 0)
{
baos.write(buff, 0, i);
}
return baos.toByteArray(); // be sure to close InputStream in calling
// function
}
public static void convertByteToFile(byte[] fileBytes)
throws FileNotFoundException
{
String path = Environment.getExternalStorageDirectory().getPath() + "/mixed.wav";
File f=new File(path);
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(f));
try
{
bos.write(writeHeader(fileBytes.length), 0, 44);
bos.write(fileBytes);
bos.flush();
bos.close();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static byte[] writeHeader(int totalDataLen)
{
byte[] header = new byte[44];
header[0] = 'R'; // RIFF/WAVE header
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
header[4] = (byte) (totalDataLen & 0xff);
header[5] = (byte) ((totalDataLen >> 8) & 0xff);
header[6] = (byte) ((totalDataLen >> 16) & 0xff);
header[7] = (byte) ((totalDataLen >> 24) & 0xff);
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
header[12] = 'f'; // 'fmt ' chunk
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
header[16] = 16; // 4 bytes: size of 'fmt ' chunk
header[17] = 0;
/* header[18] = 0;
header[19] = 0;
header[20] = 1; // format = 1
header[21] = 0;
header[22] = (byte) channels;
header[23] = 0;
header[24] = (byte) (longSampleRate & 0xff);
header[25] = (byte) ((longSampleRate >> 8) & 0xff);
header[26] = (byte) ((longSampleRate >> 16) & 0xff);
header[27] = (byte) ((longSampleRate >> 24) & 0xff);
header[28] = (byte) (byteRate & 0xff);
header[29] = (byte) ((byteRate >> 8) & 0xff);
header[30] = (byte) ((byteRate >> 16) & 0xff);
header[31] = (byte) ((byteRate >> 24) & 0xff);
header[32] = (byte) (2 * 16 / 8); // block align
header[33] = 0;
header[34] = RECORDER_BPP; // bits per sample
header[35] = 0;*/
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
/* header[40] = (byte) (totalAudioLen & 0xff);
header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
*/
return header;
}
}
还有活动:
public class SoundMixerActivity extends Activity
{
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
new SongMixer2(this).onCreate();
}
}
在 SD 卡中创建了一个文件 'mixed.wav',但无法播放...请大家帮忙!!
【问题讨论】:
-
@Vnay:你找到解决办法了吗?
-
@Vinay 到目前为止你找到解决方案了吗?请帮帮我...我也在做同样的事情