是否有android的任何声音过滤库

是否有android的任何声音过滤库

本文介绍了是否有android的任何声音过滤库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想捕捉的音频并将其转换成字节数组。结果
但是,当我录制的声音,噪音被添加到它。

I want to capture an audio and convert it into byte array.
But when I record the audio, noise gets added to it.

有没有android的任何过滤库,这样我可以在里面去除噪声。

Is there any filtering library in android so that I can remove noise in it.

问候,结果
Sneha

Regards,
Sneha

推荐答案

使用下面的类来分析音频,我在这里为您提供三类。我已经使用这个类来确定信号电平(音频分贝水平)。我认为你可以知道如何在音频过滤噪音。下面的类使用AudioRe codeR录制音频,并将其转换为字节,并测量信号强度。

Use Following classes to analyze Audio, Here I am providing you three classes. I have use this classes to identify Signal Level (Audio Db level). I think you can get idea how to filter noise in Audio. Following Classes use AudioRecoder to record audio and convert it in Bytes and measure signal intensity.

AudioAnalyser.java

AudioAnalyser.java

package com.indianic.audioanalyzer;

import android.util.Log;





/**
 * An {@link Instrument} which analyses an audio stream in various ways.
 *
 * <p>To use this class, your application must have permission RECORD_AUDIO.
 */
public class AudioAnalyser
{

    // ******************************************************************** //
    // Constructor.
    // ******************************************************************** //

    /**
     * Create a WindMeter instance.
     *
     * @param   parent          Parent surface.
     */
    public AudioAnalyser() {

        audioReader = new AudioReader();


        biasRange = new float[2];
    }


    // ******************************************************************** //
    // Configuration.
    // ******************************************************************** //

    /**
     * Set the sample rate for this instrument.
     *
     * @param   rate        The desired rate, in samples/sec.
     */
    public void setSampleRate(int rate) {
        sampleRate = rate;
    }


    /**
     * Set the input block size for this instrument.
     *
     * @param   size        The desired block size, in samples.  Typical
     *                      values would be 256, 512, or 1024.  Larger block
     *                      sizes will mean more work to analyse the spectrum.
     */
    public void setBlockSize(int size) {
        inputBlockSize = size;


        // Allocate the spectrum data.
        spectrumData = new float[inputBlockSize / 2];
        spectrumHist = new float[inputBlockSize / 2][historyLen];
    }




    /**
     * Set the decimation rate for this instrument.
     *
     * @param   rate        The desired decimation.  Only 1 in rate blocks
     *                      will actually be processed.
     */
    public void setDecimation(int rate) {
        sampleDecimate = rate;
    }


    /**
     * Set the histogram averaging window for this instrument.
     *
     * @param   len         The averaging interval.  1 means no averaging.
     */
    public void setAverageLen(int len) {
        historyLen = len;

        // Set up the history buffer.
        spectrumHist = new float[inputBlockSize / 2][historyLen];
        spectrumIndex = 0;
    }


    // ******************************************************************** //
    // Run Control.
    // ******************************************************************** //

    /**
     * The application is starting.  Perform any initial set-up prior to
     * starting the application.  We may not have a screen size yet,
     * so this is not a good place to allocate resources which depend on
     * that.
     */
    public void appStart() {
    }


    /**
     * We are starting the main run; start measurements.
     */
    public void measureStart() {
        audioProcessed = audioSequence = 0;
        readError = AudioReader.Listener.ERR_OK;

        audioReader.startReader(sampleRate, inputBlockSize * sampleDecimate, new AudioReader.Listener() {
            @Override
            public final void onReadComplete(short[] buffer) {
                receiveAudio(buffer);
            }
            @Override
            public void onReadError(int error) {
                handleError(error);
            }
        });
    }


    /**
     * We are stopping / pausing the run; stop measurements.
     */
    public void measureStop() {
        audioReader.stopReader();
    }


    /**
     * The application is closing down.  Clean up any resources.
     */
    public void appStop() {
    }








    // ******************************************************************** //
    // Audio Processing.
    // ******************************************************************** //

    /**
     * Handle audio input.  This is called on the thread of the audio
     * reader.
     *
     * @param   buffer      Audio data that was just read.
     */
    private final void receiveAudio(short[] buffer) {
        // Lock to protect updates to these local variables.  See run().
        synchronized (this) {
            audioData = buffer;
            ++audioSequence;
        }
    }


    /**
     * An error has occurred.  The reader has been terminated.
     *
     * @param   error       ERR_XXX code describing the error.
     */
    private void handleError(int error) {
        synchronized (this) {
            readError = error;
        }
    }


    // ******************************************************************** //
    // Main Loop.
    // ******************************************************************** //

    /**
     * Update the state of the instrument for the current frame.
     * This method must be invoked from the doUpdate() method of the
     * application's {@link SurfaceRunner}.
     *
     * <p>Since this is called frequently, we first check whether new
     * audio data has actually arrived.
     *
     * @param   now         Nominal time of the current frame in ms.
     */
    public final void doUpdate() {
        short[] buffer = null;
        synchronized (this) {
            if (audioData != null && audioSequence > audioProcessed) {
                audioProcessed = audioSequence;
                buffer = audioData;
            }
        }

        // If we got data, process it without the lock.
        if (buffer != null)
            processAudio(buffer);

        if (readError != AudioReader.Listener.ERR_OK)
            processError(readError);
    }


    /**
     * Handle audio input.  This is called on the thread of the
     * parent surface.
     *
     * @param   buffer      Audio data that was just read.
     */
    private final void processAudio(short[] buffer) {
        // Process the buffer.  While reading it, it needs to be locked.
        synchronized (buffer) {
            // Calculate the power now, while we have the input
            // buffer; this is pretty cheap.
            final int len = buffer.length;


            // If we have a power gauge, calculate the signal power.

                setCurrentPower(SignalPower.calculatePowerDb(buffer, 0, len));

            // If we have a spectrum analyser, set up the FFT input data.
          Log.i(this.getClass().getSimpleName(), "dB = " + getCurrentPower() + "\t\t" + Math.round(getCurrentPower()));

            // Tell the reader we're done with the buffer.
            buffer.notify();
        }




    }


    /**
     * Handle an audio input error.
     *
     * @param   error       ERR_XXX code describing the error.
     */
    private final void processError(int error) {

    }





    // ******************************************************************** //
    // Class Data.
    // ******************************************************************** //

    public void setCurrentPower(double currentPower) {
        this.currentPower = currentPower;
    }


    public double getCurrentPower() {
        return currentPower;
    }





    // Debugging tag.
    @SuppressWarnings("unused")
    private static final String TAG = "instrument";




    // The desired sampling rate for this analyser, in samples/sec.
    private int sampleRate = 8000;

    // Audio input block size, in samples.
    private int inputBlockSize = 256;


    // The desired decimation rate for this analyser.  Only 1 in
    // sampleDecimate blocks will actually be processed.
    private int sampleDecimate = 1;

    // The desired histogram averaging window.  1 means no averaging.
    private int historyLen = 4;

    // Our audio input device.
    private final AudioReader audioReader;


    // Buffered audio data, and sequence number of the latest block.
    private short[] audioData;
    private long audioSequence = 0;

    // If we got a read error, the error code.
    private int readError = AudioReader.Listener.ERR_OK;

    // Sequence number of the last block we processed.
    private long audioProcessed = 0;

    // Analysed audio spectrum data; history data for each frequency
    // in the spectrum; index into the history data; and buffer for
    // peak frequencies.
    private float[] spectrumData;
    private float[][] spectrumHist;
    private int spectrumIndex;

    // Current signal power level, in dB relative to max. input power.
    private double currentPower = 0f;

    // Temp. buffer for calculated bias and range.
    private float[] biasRange = null;

}

==================
AudioReader.java

==================AudioReader.java

    package com.indianic.audioanalyzer;


    import android.media.AudioFormat;
    import android.media.AudioRecord;
    import android.media.MediaRecorder;
    import android.util.Log;


    /**
     * A class which reads audio input from the mic in a background thread and
     * passes it to the caller when ready.
     *
     * <p>To use this class, your application must have permission RECORD_AUDIO.
     */
    public class AudioReader
    {

        // ******************************************************************** //
        // Public Classes.
        // ******************************************************************** //

        /**
         * Listener for audio reads.
         */
        public static abstract class Listener {
            /**
             * Audio read error code: no error.
             */
            public static final int ERR_OK = 0;

            /**
             * Audio read error code: the audio reader failed to initialise.
             */
            public static final int ERR_INIT_FAILED = 1;

            /**
             * Audio read error code: an audio read failed.
             */
            public static final int ERR_READ_FAILED = 2;

            /**
             * An audio read has completed.
             * @param   buffer      Buffer containing the data.
             */
            public abstract void onReadComplete(short[] buffer);

            /**
             * An error has occurred.  The reader has been terminated.
             * @param   error       ERR_XXX code describing the error.
             */
            public abstract void onReadError(int error);
        }


        // ******************************************************************** //
        // Constructor.
        // ******************************************************************** //

        /**
         * Create an AudioReader instance.
         */
        public AudioReader() {
    //        audioManager = (AudioManager) app.getSystemService(Context.AUDIO_SERVICE);
        }


        // ******************************************************************** //
        // Run Control.
        // ******************************************************************** //

        /**
         * Start this reader.
         *
         * @param   rate        The audio sampling rate, in samples / sec.
         * @param   block       Number of samples of input to read at a time.
         *                      This is different from the system audio
         *                      buffer size.
         * @param   listener    Listener to be notified on each completed read.
         */
        public void startReader(int rate, int block, Listener listener) {
            Log.i(TAG, "Reader: Start Thread");
            synchronized (this) {
                // Calculate the required I/O buffer size.
                int audioBuf = AudioRecord.getMinBufferSize(rate,
                                             AudioFormat.CHANNEL_CONFIGURATION_MONO,
                                             AudioFormat.ENCODING_PCM_16BIT) * 2;

                // Set up the audio input.
                audioInput = new AudioRecord(MediaRecorder.AudioSource.MIC,
                                             rate,
                                             AudioFormat.CHANNEL_CONFIGURATION_MONO,
                                             AudioFormat.ENCODING_PCM_16BIT,
                                             audioBuf);
                inputBlockSize = block;
                sleepTime = (long) (1000f / ((float) rate / (float) block));
                inputBuffer = new short[2][inputBlockSize];
                inputBufferWhich = 0;
                inputBufferIndex = 0;
                inputListener = listener;
                running = true;
                readerThread = new Thread(new Runnable() {
                    public void run() { readerRun(); }
                }, "Audio Reader");
                readerThread.start();
            }
        }


        /**
         * Stop this reader.
         */
        public void stopReader() {
            Log.i(TAG, "Reader: Signal Stop");
            synchronized (this) {
                running = false;
            }
            try {
                if (readerThread != null)
                    readerThread.join();
            } catch (InterruptedException e) {
                ;
            }
            readerThread = null;

            // Kill the audio input.
            synchronized (this) {
                if (audioInput != null) {
                    audioInput.release();
                    audioInput = null;
                }
            }

            Log.i(TAG, "Reader: Thread Stopped");
        }


        // ******************************************************************** //
        // Main Loop.
        // ******************************************************************** //

        /**
         * Main loop of the audio reader.  This runs in our own thread.
         */
        private void readerRun() {
            short[] buffer;
            int index, readSize;

            int timeout = 200;
            try {
                while (timeout > 0 && audioInput.getState() != AudioRecord.STATE_INITIALIZED) {
                    Thread.sleep(50);
                    timeout -= 50;
                }
            } catch (InterruptedException e) { }

            if (audioInput.getState() != AudioRecord.STATE_INITIALIZED) {
                Log.e(TAG, "Audio reader failed to initialize");
                readError(Listener.ERR_INIT_FAILED);
                running = false;
                return;
            }

            try {
                Log.i(TAG, "Reader: Start Recording");
                audioInput.startRecording();
                while (running) {
                    long stime = System.currentTimeMillis();

                    if (!running)
                        break;

                    readSize = inputBlockSize;
                    int space = inputBlockSize - inputBufferIndex;
                    if (readSize > space)
                        readSize = space;
                    buffer = inputBuffer[inputBufferWhich];
                    index = inputBufferIndex;

                    synchronized (buffer) {
                        int nread = audioInput.read(buffer, index, readSize);

                        boolean done = false;
                        if (!running)
                            break;

                        if (nread < 0) {
                            Log.e(TAG, "Audio read failed: error " + nread);
                            readError(Listener.ERR_READ_FAILED);
                            running = false;
                            break;
                        }
                        int end = inputBufferIndex + nread;
                        if (end >= inputBlockSize) {
                            inputBufferWhich = (inputBufferWhich + 1) % 2;
                            inputBufferIndex = 0;
                            done = true;
                        } else
                            inputBufferIndex = end;

                        if (done) {
                            readDone(buffer);

                            // Because our block size is way smaller than the audio
                            // buffer, we get blocks in bursts, which messes up
                            // the audio analyzer.  We don't want to be forced to
                            // wait until the analysis is done, because if
                            // the analysis is slow, lag will build up.  Instead
                            // wait, but with a timeout which lets us keep the
                            // input serviced.
                            long etime = System.currentTimeMillis();
                            long sleep = sleepTime - (etime - stime);
                            if (sleep < 5)
                                sleep = 5;
                            try {
                                buffer.wait(sleep);
                            } catch (InterruptedException e) { }
                        }
                    }
                }
            } finally {
                Log.i(TAG, "Reader: Stop Recording");
                if (audioInput.getState() == AudioRecord.RECORDSTATE_RECORDING)
                    audioInput.stop();
            }
        }


        /**
         * Notify the client that a read has completed.
         *
         * @param   buffer      Buffer containing the data.
         */
        private void readDone(short[] buffer) {
            inputListener.onReadComplete(buffer);
        }


        /**
         * Notify the client that an error has occurred.  The reader has been
         * terminated.
         *
         * @param   error       ERR_XXX code describing the error.
         */
        private void readError(int code) {
            inputListener.onReadError(code);
        }


        // ******************************************************************** //
        // Class Data.
        // ******************************************************************** //

        // Debugging tag.
        @SuppressWarnings("unused")
        private static final String TAG = "WindMeter";


        // ******************************************************************** //
        // Private Data.
        // ******************************************************************** //

        // Our audio input device.
        private AudioRecord audioInput;

        // Our audio input buffer, and the index of the next item to go in.
        private short[][] inputBuffer = null;
        private int inputBufferWhich = 0;
        private int inputBufferIndex = 0;

        // Size of the block to read each time.
        private int inputBlockSize = 0;

        // Time in ms to sleep between blocks, to meter the supply rate.
        private long sleepTime = 0;

        // Listener for input.
        private Listener inputListener = null;

        // Flag whether the thread should be running.
        private boolean running = false;

        // The thread, if any, which is currently reading.  Null if not running.
        private Thread readerThread = null;

    }


===================

SignalPower.java

SignalPower.java

/**
 * dsp: various digital signal processing algorithms
 * <br>Copyright 2009 Ian Cameron Smith
 *
 * <p>This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation (see COPYING).
 *
 * <p>This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */


package com.indianic.audioanalyzer;


/**
 * A power metering algorithm.
 */
public final class SignalPower {

    // ******************************************************************** //
    // Constructor.
    // ******************************************************************** //

    /**
     * Only static methods are provided in this class.
     */
    private SignalPower() {
    }


    // ******************************************************************** //
    // Algorithm.
    // ******************************************************************** //

    /**
     * Calculate the bias and range of the given input signal.
     *
     * @param   sdata       Buffer containing the input samples to process.
     * @param   off         Offset in sdata of the data of interest.
     * @param   samples     Number of data samples to process.
     * @param   out         A float array in which the results will be placed
     *                      Must have space for two entries, which will be
     *                      set to:
     *                      <ul>
     *                      <li>The bias, i.e. the offset of the average
     *                      signal value from zero.
     *                      <li>The range, i.e. the absolute value of the largest
     *                      departure from the bias level.
     *                      </ul>
     * @throws  NullPointerException    Null output array reference.
     * @throws  ArrayIndexOutOfBoundsException  Output array too small.
     */
    public final static void biasAndRange(short[] sdata, int off, int samples,
                                          float[] out)
    {
        // Find the max and min signal values, and calculate the bias.
        short min =  32767;
        short max = -32768;
        int total = 0;
        for (int i = off; i < off + samples; ++i) {
            final short val = sdata[i];
            total += val;
            if (val < min)
                min = val;
            if (val > max)
                max = val;
        }
        final float bias = (float) total / (float) samples;
        final float bmin = min + bias;
        final float bmax = max - bias;
        final float range = Math.abs(bmax - bmin) / 2f;

        out[0] = bias;
        out[1] = range;
    }


    /**
     * Calculate the power of the given input signal.
     *
     * @param   sdata       Buffer containing the input samples to process.
     * @param   off         Offset in sdata of the data of interest.
     * @param   samples     Number of data samples to process.
     * @return              The calculated power in dB relative to the maximum
     *                      input level; hence 0dB represents maximum power,
     *                      and minimum power is about -95dB.  Particular
     *                      cases of interest:
     *                      <ul>
     *                      <li>A non-clipping full-range sine wave input is
     *                          about -2.41dB.
     *                      <li>Saturated input (heavily clipped) approaches
     *                          0dB.
     *                      <li>A low-frequency fully saturated input can
     *                          get above 0dB, but this would be pretty
     *                          artificial.
     *                      <li>A really tiny signal, which only occasionally
     *                          deviates from zero, can get below -100dB.
     *                      <li>A completely zero input will produce an
     *                          output of -Infinity.
     *                      </ul>
     *                      <b>You must be prepared to handle this infinite
     *                      result and results greater than zero,</b> although
     *                      clipping them off would be quite acceptable in
     *                      most cases.
     */
    public final static double calculatePowerDb(short[] sdata, int off, int samples) {
        // Calculate the sum of the values, and the sum of the squared values.
        // We need longs to avoid running out of bits.
        double sum = 0;
        double sqsum = 0;
        for (int i = 0; i < samples; i++) {
            final long v = sdata[off + i];
            sum += v;
            sqsum += v * v;
        }

        // sqsum is the sum of all (signal+bias)², so
        //     sqsum = sum(signal²) + samples * bias²
        // hence
        //     sum(signal²) = sqsum - samples * bias²
        // Bias is simply the average value, i.e.
        //     bias = sum / samples
        // Since power = sum(signal²) / samples, we have
        //     power = (sqsum - samples * sum² / samples²) / samples
        // so
        //     power = (sqsum - sum² / samples) / samples
        double power = (sqsum - sum * sum / samples) / samples;

        // Scale to the range 0 - 1.
        power /= MAX_16_BIT * MAX_16_BIT;

        // Convert to dB, with 0 being max power.  Add a fudge factor to make
        // a "real" fully saturated input come to 0 dB.
        return Math.log10(power) * 10f + FUDGE;
    }


    // ******************************************************************** //
    // Constants.
    // ******************************************************************** //

    // Maximum signal amplitude for 16-bit data.
    private static final float MAX_16_BIT = 32768;

    // This fudge factor is added to the output to make a realistically
    // fully-saturated signal come to 0dB.  Without it, the signal would
    // have to be solid samples of -32768 to read zero, which is not
    // realistic.  This really is a fudge, because the best value depends
    // on the input frequency and sampling rate.  We optimise here for
    // a 1kHz signal at 16,000 samples/sec.
    private static final float FUDGE = 0.6f;

}

==============================

==============================

这篇关于是否有android的任何声音过滤库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 04:02