AudioRecord with Gain Adjustment not working on Samsung Device

前端 未结 2 1074
小蘑菇
小蘑菇 2021-02-10 08:34

I have written code for recording audio file using AudioRecord and while writing file on SD card i am making two version.

Version 1 Recorde

2条回答
  •  一整个雨季
    2021-02-10 09:16

    Audio gain conrol To increase the amplitude of the audio u need to calculate the gain factor and multiply calculated gain factor with every sample captured. The following code does that. P.S. Ignore the unrelated code

    public class MainActivity extends Activity {
    
    public static final int SAMPLE_RATE = 16000;
    
    private AudioRecord mRecorder;
    private File mRecording;
    private short[] mBuffer;
    private final String startRecordingLabel = "Start recording";
    private final String stopRecordingLabel = "Stop recording";
    private boolean mIsRecording = false;
    private ProgressBar mProgressBar;
    float iGain = 1.0f;
    CheckBox gain;
    
    protected int bitsPerSamples = 16;
    
    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_main);
    
        initRecorder();
    
        Button bluetooth = (Button)findViewById(R.id.blue);
        gain = (CheckBox) findViewById(R.id.checkBox1);
        mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
    
        final Button button = (Button) findViewById(R.id.start);
        button.setText(startRecordingLabel);
    
        bluetooth.setOnClickListener(new View.OnClickListener() {
    
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent i = new Intent("");
            }
        });
        gain.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    
            @Override
            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
    
                if (gain.isChecked()) {
                    iGain = 5.0f;
    
                } else {
                    iGain = 2.0f;
                }
            }
        });
    
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View v) {
                if (!mIsRecording) {
                    button.setText(stopRecordingLabel);
                    mIsRecording = true;
                    mRecorder.startRecording();
                    mRecording = getFile("raw");
                    startBufferedWrite(mRecording);
                } else {
                    button.setText(startRecordingLabel);
                    mIsRecording = false;
                    mRecorder.stop();
                    File waveFile = getFile("wav");
                    try {
                        rawToWave(mRecording, waveFile);
                    } catch (IOException e) {
                        Toast.makeText(MainActivity.this, e.getMessage(),
                                Toast.LENGTH_SHORT).show();
                    }
                    Toast.makeText(MainActivity.this,
                            "Recorded to " + waveFile.getName(),
                            Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
    
    @Override
    public void onDestroy() {
        mRecorder.release();
        super.onDestroy();
    }
    
    private void initRecorder() {
        int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
                AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
        mBuffer = new short[bufferSize];
        mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE,
                AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
                bufferSize);
    }
    
    private void startBufferedWrite(final File file) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                DataOutputStream output = null;
                try {
                    output = new DataOutputStream(new BufferedOutputStream(
                            new FileOutputStream(file)));
                    while (mIsRecording) {
                        double sum = 0;
    
                        int readSize = mRecorder.read(mBuffer, 0,
                                mBuffer.length);
    
                        final int bytesPerSample = bitsPerSamples / 8;
                        final int emptySpace = 64 - bitsPerSamples;
                        int byteIndex = 0;
                        int byteIndex2 = 0;
                        int temp = 0;
                        int mLeftTemp = 0;
                        int mRightTemp = 0;
                        int a = 0;
                        int x = 0;
    
                        for (int frameIndex = 0; frameIndex < readSize; frameIndex++) {
    
                            for (int c = 0; c < 1; c++) {
    
                                if (iGain != 1) {
    
                                    long accumulator = 0;
                                    for (int b = 0; b < bytesPerSample; b++) {
    
                                        accumulator += ((long) (mBuffer[byteIndex++] & 0xFF)) << (b * 8 + emptySpace);
                                    }
    
                                    double sample = ((double) accumulator / (double) Long.MAX_VALUE);
                                    sample *= iGain;
                                    int intValue = (int) ((double) sample * (double) Integer.MAX_VALUE);
    
                                    for (int i = 0; i < bytesPerSample; i++) {
                                        mBuffer[i + byteIndex2] = (byte) (intValue >>> ((i + 2) * 8) & 0xff);
                                    }
                                    byteIndex2 += bytesPerSample;
    
                                }
                            }// end for(channel)
    
                            // mBuffer[frameIndex] *=iGain;
                            if (mBuffer[frameIndex] > 32765) {
                                mBuffer[frameIndex] = 32767;
    
                            } else if (mBuffer[frameIndex] < -32767) {
                                mBuffer[frameIndex] = -32767;
                            }
                            output.writeShort(mBuffer[frameIndex]);
                            sum += mBuffer[frameIndex] * mBuffer[frameIndex];
    
                        }
    
                        if (readSize > 0) {
                            final double amplitude = sum / readSize;
                            mProgressBar.setProgress((int) Math.sqrt(amplitude));
                        }
                    }
                } catch (IOException e) {
                    Toast.makeText(MainActivity.this, e.getMessage(),
                            Toast.LENGTH_SHORT).show();
                } finally {
                    mProgressBar.setProgress(0);
                    if (output != null) {
                        try {
                            output.flush();
                        } catch (IOException e) {
                            Toast.makeText(MainActivity.this, e.getMessage(),
                                    Toast.LENGTH_SHORT).show();
                        } finally {
                            try {
                                output.close();
                            } catch (IOException e) {
                                Toast.makeText(MainActivity.this, e.getMessage(),
                                        Toast.LENGTH_SHORT).show();
                            }
                        }
                    }
                }
            }
        }).start();
    }
    
    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
            // see http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
            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) {
    
                // Apply Gain
                /*
                 * s *= iGain; if(s>32767) { s=32767; } else if(s<-32768) {
                 * s=-32768; }
                 */
                bytes.putShort(s);
            }
            output.write(bytes.array());
        } finally {
            if (output != null) {
                output.close();
            }
        }
    }
    
    private File getFile(final String suffix) {
        Time time = new Time();
        time.setToNow();
        return new File(Environment.getExternalStorageDirectory(),
                time.format("%Y%m%d%H%M%S") + "." + suffix);
    }
    
    
    
    
    
    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));
        }
    }
    }
    

提交回复
热议问题