我想创建一个混音器(DJ 音乐曲目)类的应用程序,它可以创建音频歌曲的 Dj 混音器。用户可以选择一个音乐歌曲轨道,该轨道可以与两个或多个单独的节奏、贝司或节拍轨道混合,以创建新的修改后的 Dj 音乐。
我对此进行了大量研究,但找不到任何想法或线索。
如果有人对此有任何想法或参考网址,请分享。
我想创建一个混音器(DJ 音乐曲目)类的应用程序,它可以创建音频歌曲的 Dj 混音器。用户可以选择一个音乐歌曲轨道,该轨道可以与两个或多个单独的节奏、贝司或节拍轨道混合,以创建新的修改后的 Dj 音乐。
我对此进行了大量研究,但找不到任何想法或线索。
如果有人对此有任何想法或参考网址,请分享。
Android 上没有内置库支持音频混合(将两个音频输入流合并为一个输出流)。支持音频混合的 Javajavax.sound
库没有移植到 Android - Google 小组与 Google 工程师 Diane Hackborn 关于不移植到 Android 的决定进行了一次有趣的讨论javax.sound
。
看起来您必须从头开始开发自己的解决方案。关于如何将两个音频流合并为一个的 SO,有几个有用的答案:
听起来最难的部分是一次播放多个曲目,其余的可以通过 UI 完成。一个可能对您有所帮助的链接是如何同时播放多个 ogg 或 mp3 ..?可以在此处找到 SoundPool 的文档,该文档可让您一次播放多个声音。
已经晚了,但如果有人需要,可以使用AudioMixer-android 。
File dir;
dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
dir.mkdirs();
//Audio Mixer for two .raw file into single .wav file...
void AudioMixer() {
File file_play1 = new File(dir, "Neww.raw");
int shortSizeInBytes = Short.SIZE / Byte.SIZE;
int bufferSizeInBytes = (int) (file_play1.length() / shortSizeInBytes);
short[] audioData = new short[bufferSizeInBytes];
try {
InputStream inputStream = new FileInputStream(file_play1);
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
DataInputStream dataInputStream = new DataInputStream(bufferedInputStream);
InputStream inputStream1 = getResources().openRawResource(R.raw.trainss); //Play form raw folder
BufferedInputStream bufferedInputStream1 = new BufferedInputStream(inputStream1);
DataInputStream dataInputStream1 = new DataInputStream(bufferedInputStream1);
int i = 0;
while (dataInputStream.available() > 0 && dataInputStream1.available() > 0) {
audioData[i] = (short) (dataInputStream.readShort() + dataInputStream1.readShort());
i++;
}
dataInputStream.close();
dataInputStream1.close();
AudioTrack audioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC,
11025,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSizeInBytes,
AudioTrack.MODE_STREAM);
audioTrack.write(audioData, 0, bufferSizeInBytes);
//merge two .raw files in single .raw file...
File file_record = new File(dir, "testing.raw");
try {
OutputStream outputStream = new FileOutputStream(file_record);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream);
for (int j = 0; j < audioData.length; j++) {
dataOutputStream.writeShort(audioData[j]);
}
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
//Convert that .raw (testing.raw) file into .wav (testingNew.wav) file
File des = new File(dir, "testingNew.wav");
try {
rawToWave(file_record, des);
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
//convert .raw file to .wav File...
private void rawToWave(final File rawFile, final File waveFile) throws IOException {
byte[] rawData = new byte[(int) rawFile.length()];
DataInputStream input = null;
try {
input = new DataInputStream(new FileInputStream(rawFile));
input.read(rawData);
} finally {
if (input != null) {
input.close();
}
}
DataOutputStream output = null;
try {
output = new DataOutputStream(new FileOutputStream(waveFile));
// WAVE header
writeString(output, "RIFF"); // chunk id
writeInt(output, 36 + rawData.length); // chunk size
writeString(output, "WAVE"); // format
writeString(output, "fmt "); // subchunk 1 id
writeInt(output, 16); // subchunk 1 size
writeShort(output, (short) 1); // audio format (1 = PCM)
writeShort(output, (short) 1); // number of channels
writeInt(output, SAMPLE_RATE); // sample rate
writeInt(output, SAMPLE_RATE * 2); // byte rate
writeShort(output, (short) 2); // block align
writeShort(output, (short) 16); // bits per sample
writeString(output, "data"); // subchunk 2 id
writeInt(output, rawData.length); // subchunk 2 size
// Audio data (conversion big endian -> little endian)
short[] shorts = new short[rawData.length / 2];
ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
ByteBuffer bytes = ByteBuffer.allocate(shorts.length * 2);
for (short s : shorts) {
bytes.putShort(s);
}
output.write(bytes.array());
} finally {
if (output != null) {
output.close();
}
}
}
private void writeInt(final DataOutputStream output, final int value) throws IOException {
output.write(value >> 0);
output.write(value >> 8);
output.write(value >> 16);
output.write(value >> 24);
}
private void writeShort(final DataOutputStream output, final short value) throws IOException {
output.write(value >> 0);
output.write(value >> 8);
}
private void writeString(final DataOutputStream output, final String value) throws IOException {
for (int i = 0; i < value.length(); i++) {
output.write(value.charAt(i));
}
}
//playing merged file...
private void playWavFile() {
MediaPlayer recorded_audio_in_sounds = new MediaPlayer();
String outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/testingNew.wav";
try {
if (recorded_audio_in_sounds != null) {
if (recorded_audio_in_sounds.isPlaying()) {
recorded_audio_in_sounds.pause();
recorded_audio_in_sounds.stop();
recorded_audio_in_sounds.reset();
recorded_audio_in_sounds.setDataSource(outputFile);
recorded_audio_in_sounds.prepare();
recorded_audio_in_sounds.setAudioStreamType(AudioManager.STREAM_MUSIC);
recorded_audio_in_sounds.start();
recorded_audio_in_sounds.start();
} else {
recorded_audio_in_sounds.reset();
recorded_audio_in_sounds.setDataSource(outputFile);
recorded_audio_in_sounds.prepare();
recorded_audio_in_sounds.start();
recorded_audio_in_sounds.setVolume(2.0f, 2.0f);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}