Запись.Wav с Android AudioRecorder

Я прочитал много страниц о AudioRecorder Android. Вы можете увидеть их список под вопросом.

Я пытаюсь записать звук с помощью AudioRecorder, но он не работает хорошо.

public class MainActivity extends Activity {

AudioRecord ar = null;
int buffsize = 0;

int blockSize = 256;
boolean isRecording = false;
private Thread recordingThread = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


}

public void baslat(View v)
{
            // when click to START 
    buffsize = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
    ar = new AudioRecord(MediaRecorder.AudioSource.MIC, 44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, buffsize);

    ar.startRecording();

    isRecording = true;
    recordingThread = new Thread(new Runnable() {
        public void run() {
            writeAudioDataToFile();
        }
    }, "AudioRecorder Thread");
    recordingThread.start();
}
public void durdur(View v)
{
            // When click to STOP
    ar.stop();
    isRecording = false;
}

private void writeAudioDataToFile() {
    // Write the output audio in byte

    String filePath = "/sdcard/voice8K16bitmono.wav";
    short sData[] = new short[buffsize/2];

    FileOutputStream os = null;
    try {
        os = new FileOutputStream(filePath);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    while (isRecording) {
        // gets the voice output from microphone to byte format

        ar.read(sData, 0, buffsize/2);
        Log.d("eray","Short wirting to file" + sData.toString());
        try {
            // // writes the data to file from buffer
            // // stores the voice buffer
            byte bData[] = short2byte(sData);
            os.write(bData, 0, buffsize);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    try {
        os.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private byte[] short2byte(short[] sData) {
    int shortArrsize = sData.length;
    byte[] bytes = new byte[shortArrsize * 2];
    for (int i = 0; i < shortArrsize; i++) {
        bytes[i * 2] = (byte) (sData[i] & 0x00FF);
        bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
        sData[i] = 0;
    }
    return bytes;

}

он создает .wav файл, но когда я пытаюсь слушать его, не открывая. Я получаю ошибку" файл не поддерживается". Я попытался воспроизвести файл с помощью нескольких приложений media player.

Примечание: Я должен использовать AudioRecorder вместо MediaRecorder, потому что мое приложение будет делать другой процесс во время записи (отображение эквалайзера) .

здесь находится список страниц, которые я читал об этой теме:

  1. http://developer.android.com/reference/android/media/AudioRecord.html#read(short[],%20int,%20int)
  2. Android AudioRecord пример
  3. http://audiorecordandroid.blogspot.in
  4. объект AudioRecord не инициализируется
  5. запись wav-файла с микрофона в Android-проблемы
  6. http://i-liger.com/article/android-wav-audio-recording
  7. создание WAV-файла из необработанных данных PCM с помощью Android SDK
  8. захват звука для анализа и визуализация частот в Android

есть много разных способов сделать это. Я пробовал их много, но ничего не работает для меня. Я работаю над этой проблемой около 6 часов, поэтому я был бы признателен за окончательный ответ, в идеале некоторый пример кода.

5 ответов


PCMAudioHelper решить мою проблему. Я изменю этот ответ и объясню его, но сначала я должен сделать некоторые тесты над этим классом.


Я написал простой (по которому вы должны читать, а не по профессиональным стандартам) класс, чтобы сделать это вчера, и он работает.

        private class Wave
    {
    private final int LONGINT = 4; 
    private final int SMALLINT = 2;
    private final int INTEGER = 4;
    private final int ID_STRING_SIZE = 4;
    private final int WAV_RIFF_SIZE = LONGINT+ID_STRING_SIZE; 
    private final int WAV_FMT_SIZE = (4*SMALLINT)+(INTEGER*2)+LONGINT+ID_STRING_SIZE; 
    private final int WAV_DATA_SIZE = ID_STRING_SIZE+LONGINT;
    private final int WAV_HDR_SIZE = WAV_RIFF_SIZE+ID_STRING_SIZE+WAV_FMT_SIZE+WAV_DATA_SIZE;
    private final short PCM = 1;
    private final int SAMPLE_SIZE = 2;
    int cursor, nSamples;
    byte[] output;

        public Wave(int sampleRate, short nChannels, short[] data, int start, int end)
        {
            nSamples=end-start+1;
            cursor=0;
            output=new byte[nSamples*SMALLINT+WAV_HDR_SIZE];
            buildHeader(sampleRate,nChannels);
            writeData(data,start,end);
        }
        // ------------------------------------------------------------
        private void buildHeader(int sampleRate, short nChannels)
        {
            write("RIFF");
            write(output.length);
            write("WAVE");
            writeFormat(sampleRate, nChannels);
        }
        // ------------------------------------------------------------
        public void writeFormat(int sampleRate, short nChannels)
        {
            write("fmt ");
            write(WAV_FMT_SIZE-WAV_DATA_SIZE);
            write(PCM);
            write(nChannels);
            write(sampleRate);
            write(nChannels * sampleRate * SAMPLE_SIZE);
            write((short)(nChannels * SAMPLE_SIZE));
            write((short)16);
        }
        // ------------------------------------------------------------
        public void writeData(short[] data, int start, int end)
        {
            write("data");
            write(nSamples*SMALLINT);
            for(int i=start; i<=end; write(data[i++]));
        }
        // ------------------------------------------------------------
        private void write(byte b)
        {
            output[cursor++]=b;
        }
        // ------------------------------------------------------------
        private void write(String id)
        {
            if(id.length()!=ID_STRING_SIZE) Utils.logError("String "+id+" must have four characters.");
            else {
                for(int i=0; i<ID_STRING_SIZE; ++i) write((byte)id.charAt(i));
            }
        }
        // ------------------------------------------------------------
        private void write(int i)
        {
            write((byte) (i&0xFF)); i>>=8;
            write((byte) (i&0xFF)); i>>=8;
            write((byte) (i&0xFF)); i>>=8;
            write((byte) (i&0xFF));
        }
        // ------------------------------------------------------------
        private void write(short i)
        {
            write((byte) (i&0xFF)); i>>=8;
            write((byte) (i&0xFF));
        }
        // ------------------------------------------------------------
        public boolean wroteToFile(String filename)
        {
        boolean ok=false;

            try {
                File path=new File(getFilesDir(),filename);
                FileOutputStream outFile = new FileOutputStream(path);
                outFile.write(output);
                outFile.close();
                ok=true;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                ok=false;
            } catch (IOException e) {
                ok=false;
                e.printStackTrace();
            }
            return ok;
        }
    }

надеюсь, что это помогает


Я бы добавил Это в качестве комментария, но у меня еще недостаточно точек повторения Stackoverflow...

ссылка Opiatefuchs приведет вас к образцу кода, который показывает точное форматирование заголовка, необходимое для создания.WAV-файл. Я сам изучал этот код. Очень полезно.


сначала вам нужно знать, что wav-файл имеет свой формат -- header. таким образом, вы не можете просто записать чистые данные .WAV-файл.

во-вторых, заголовок файла wav включает длину файла . поэтому вам нужно написать заголовок После записи.

мое решение , AudioRecorder записи пользователя файл PCM .

    byte[] audiodata = new byte[bufferSizeInBytes];

    FileOutputStream fos = null;
    int readsize = 0;
    try {
        fos = new FileOutputStream(pcmFileName, true);
    } catch (FileNotFoundException e) {
        Log.e("AudioRecorder", e.getMessage());
    }

    status = Status.STATUS_START;
    while (status == Status.STATUS_START && audioRecord != null) {
        readsize = audioRecord.read(audiodata, 0, bufferSizeInBytes);
        if (AudioRecord.ERROR_INVALID_OPERATION != readsize && fos != null) {

            if (readsize > 0 && readsize <= audiodata.length)
                    fos.write(audiodata, 0, readsize);
            } catch (IOException e) {
                Log.e("AudioRecorder", e.getMessage());
            }
        }
    }
    try {
        if (fos != null) {
            fos.close();
        }
    } catch (IOException e) {
        Log.e("AudioRecorder", e.getMessage());
    }

затем конвертируйте его в wav-файл.

    byte buffer[] = null;
    int TOTAL_SIZE = 0;
    File file = new File(pcmPath);
    if (!file.exists()) {
        return false;
    }
    TOTAL_SIZE = (int) file.length();

    WaveHeader header = new WaveHeader();

    header.fileLength = TOTAL_SIZE + (44 - 8);
    header.FmtHdrLeth = 16;
    header.BitsPerSample = 16;
    header.Channels = 1;
    header.FormatTag = 0x0001;
    header.SamplesPerSec = 8000;
    header.BlockAlign = (short) (header.Channels * header.BitsPerSample / 8);
    header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec;
    header.DataHdrLeth = TOTAL_SIZE;

    byte[] h = null;
    try {
        h = header.getHeader();
    } catch (IOException e1) {
        Log.e("PcmToWav", e1.getMessage());
        return false;
    }

    if (h.length != 44) 
        return false;


    File destfile = new File(destinationPath);
    if (destfile.exists())
        destfile.delete();


    try {
        buffer = new byte[1024 * 4]; // Length of All Files, Total Size
        InputStream inStream = null;
        OutputStream ouStream = null;

        ouStream = new BufferedOutputStream(new FileOutputStream(
                destinationPath));
        ouStream.write(h, 0, h.length);
        inStream = new BufferedInputStream(new FileInputStream(file));
        int size = inStream.read(buffer);
        while (size != -1) {
            ouStream.write(buffer);
            size = inStream.read(buffer);
        }
        inStream.close();
        ouStream.close();
    } catch (FileNotFoundException e) {
        Log.e("PcmToWav", e.getMessage());
        return false;
    } catch (IOException ioe) {
        Log.e("PcmToWav", ioe.getMessage());
        return false;
    }
    if (deletePcmFile) {
        file.delete();
    }
    Log.i("PcmToWav", "makePCMFileToWAVFile  success!" + new SimpleDateFormat("yyyy-MM-dd hh:mm").format(new Date()));
    return true;

вы можете найти это OMRECORDER полезно для записи .

в случае если .aac работает с вами, а затем проверить эту WhatsappAudioRecorder:

на startRecording нажмите кнопку:

  1. запустить новый поток.
  2. создать файл с