Audio song mixer in android programmatically

前端 未结 4 1521
梦谈多话
梦谈多话 2020-12-23 18:25

I want to create an audio mixer (DJ music track) kind of app which can create Dj mixer of an audio song. User can select a music song track that can be mixed with two or mo

相关标签:
4条回答
  • 2020-12-23 18:58

    There is no build-in library on Android that supports audio mixing (combining two audio input streams into one output stream). The Java javax.sound library which supports audio mixing was not ported to Android - there's an interesting discussion on Google Groups with Google engineer Diane Hackborn about the decision to not port javax.sound to Android.

    It looks like you have to develop your own solution from scratch. There are several helpful answers on SO on how to combine two audio streams into one:

    Mixing Audio Files

    Audio editing in Android

    Android - Mixing multiple static waveforms into a single AudioTrack

    0 讨论(0)
  • 2020-12-23 19:07
    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();
        }
    }
    
    0 讨论(0)
  • 2020-12-23 19:10

    It is late but if someone needs, AudioMixer-android can be used.

    0 讨论(0)
  • 2020-12-23 19:12

    It sounds like the hardest part of this would be playing multiple tracks at once, and that the rest can be done with the UI. One link that might help you is How to play multiple ogg or mp3 at the same time..? The documentation for SoundPool, which lets you play multiple sounds at once, can be found here.

    0 讨论(0)
提交回复
热议问题