【问题标题】:how to record .wav format file in android如何在android中录制.wav格式的文件
【发布时间】:2011-03-09 12:05:42
【问题描述】:

我想使用 android 录制 .wav 文件。有没有办法做到这一点?

【问题讨论】:

标签: android


【解决方案1】:

快速谷歌后,我发现直接支持波形录制。最常见的波形格式是 PCM。 android.media.AudioRecord 支持 PCM 输出。您只需将其写入文件即可。

在您创建文件之后,您必须将自己的转换器编程为 wave(或为此寻找在线库)。

如果您喜欢可以随时使用并在 wave 中录制的应用,您可以下载此应用:

额外链接:

【讨论】:

    【解决方案2】:

    有两个类可以录制音频,AudioRecordMediaRecorder

    我现在也在写一个应用程序,就是记录和显示频谱图。所以我使用 AudioRecord

    祝你好运!

    【讨论】:

      【解决方案3】:

      您必须使用 AudioRecord 类并自己编写 wav 标头数据。 此代码应包含您需要的所有内容。

      class WavRecorder(val context: Context) {
          private var recorder: AudioRecord? = null
          private var isRecording = false
      
          private var recordingThread: Thread? = null
      
          fun startRecording(_filename: String? = null, internalStorage: Boolean = false) {
              val filename = _filename ?: "recording-${System.currentTimeMillis()}.wav"
      
              val path = if (internalStorage) context.filesDir?.path + "/$filename"
              else context.externalCacheDir?.path + "/$filename"
      
              recorder = AudioRecord(MediaRecorder.AudioSource.MIC,
                      RECORDER_SAMPLE_RATE, RECORDER_CHANNELS,
                      RECORDER_AUDIO_ENCODING, 512)
      
              recorder?.startRecording()
              isRecording = true
      
              recordingThread = thread(true) {
                  writeAudioDataToFile(path)
              }
          }
      
      
          fun stopRecording() {
              recorder?.run {
                  isRecording = false;
                  stop()
                  release()
                  recordingThread = null
                  recorder = null
              }
          }
      
          private fun short2byte(sData: ShortArray): ByteArray {
              val arrSize = sData.size
              val bytes = ByteArray(arrSize * 2)
              for (i in 0 until arrSize) {
                  bytes[i * 2] = (sData[i] and 0x00FF).toByte()
                  bytes[i * 2 + 1] = (sData[i].toInt() shr 8).toByte()
                  sData[i] = 0
              }
              return bytes
          }
      
          private fun writeAudioDataToFile(path: String) {
              val sData = ShortArray(BufferElements2Rec)
              var os: FileOutputStream? = null
              try {
                  os = FileOutputStream(path)
              } catch (e: FileNotFoundException) {
                  e.printStackTrace()
              }
      
              val data = arrayListOf<Byte>()
      
              for (byte in wavFileHeader()) {
                  data.add(byte)
              }
      
              while (isRecording) {
                  // gets the voice output from microphone to byte format
                  recorder?.read(sData, 0, BufferElements2Rec)
                  try {
                      val bData = short2byte(sData)
                      for (byte in bData)
                          data.add(byte)
                  } catch (e: IOException) {
                      e.printStackTrace()
                  }
              }
      
              updateHeaderInformation(data)
      
              os?.write(data.toByteArray())
      
              try {
                  os?.close()
              } catch (e: IOException) {
                  e.printStackTrace()
              }
          }
      
      
          /**
           * Constructs header for wav file format
           */
          private fun wavFileHeader(): ByteArray {
              val headerSize = 44
              val header = ByteArray(headerSize)
      
              header[0] = 'R'.toByte() // RIFF/WAVE header
              header[1] = 'I'.toByte()
              header[2] = 'F'.toByte()
              header[3] = 'F'.toByte()
      
              header[4] = (0 and 0xff).toByte() // Size of the overall file, 0 because unknown
              header[5] = (0 shr 8 and 0xff).toByte()
              header[6] = (0 shr 16 and 0xff).toByte()
              header[7] = (0 shr 24 and 0xff).toByte()
      
              header[8] = 'W'.toByte()
              header[9] = 'A'.toByte()
              header[10] = 'V'.toByte()
              header[11] = 'E'.toByte()
      
              header[12] = 'f'.toByte() // 'fmt ' chunk
              header[13] = 'm'.toByte()
              header[14] = 't'.toByte()
              header[15] = ' '.toByte()
      
              header[16] = 16 // Length of format data
              header[17] = 0
              header[18] = 0
              header[19] = 0
      
              header[20] = 1 // Type of format (1 is PCM)
              header[21] = 0
      
              header[22] = NUMBER_CHANNELS.toByte()
              header[23] = 0
      
              header[24] = (RECORDER_SAMPLE_RATE and 0xff).toByte() // Sampling rate
              header[25] = (RECORDER_SAMPLE_RATE shr 8 and 0xff).toByte()
              header[26] = (RECORDER_SAMPLE_RATE shr 16 and 0xff).toByte()
              header[27] = (RECORDER_SAMPLE_RATE shr 24 and 0xff).toByte()
      
              header[28] = (BYTE_RATE and 0xff).toByte() // Byte rate = (Sample Rate * BitsPerSample * Channels) / 8
              header[29] = (BYTE_RATE shr 8 and 0xff).toByte()
              header[30] = (BYTE_RATE shr 16 and 0xff).toByte()
              header[31] = (BYTE_RATE shr 24 and 0xff).toByte()
      
              header[32] = (NUMBER_CHANNELS * BITS_PER_SAMPLE / 8).toByte() //  16 Bits stereo
              header[33] = 0
      
              header[34] = BITS_PER_SAMPLE.toByte() // Bits per sample
              header[35] = 0
      
              header[36] = 'd'.toByte()
              header[37] = 'a'.toByte()
              header[38] = 't'.toByte()
              header[39] = 'a'.toByte()
      
              header[40] = (0 and 0xff).toByte() // Size of the data section.
              header[41] = (0 shr 8 and 0xff).toByte()
              header[42] = (0 shr 16 and 0xff).toByte()
              header[43] = (0 shr 24 and 0xff).toByte()
      
              return header
          }
      
          private fun updateHeaderInformation(data: ArrayList<Byte>) {
              val fileSize = data.size
              val contentSize = fileSize - 44
      
              data[4] = (fileSize and 0xff).toByte() // Size of the overall file
              data[5] = (fileSize shr 8 and 0xff).toByte()
              data[6] = (fileSize shr 16 and 0xff).toByte()
              data[7] = (fileSize shr 24 and 0xff).toByte()
      
              data[40] = (contentSize and 0xff).toByte() // Size of the data section.
              data[41] = (contentSize shr 8 and 0xff).toByte()
              data[42] = (contentSize shr 16 and 0xff).toByte()
              data[43] = (contentSize shr 24 and 0xff).toByte()
          }
      
          companion object {
              const val RECORDER_SAMPLE_RATE = 8000
              const val RECORDER_CHANNELS: Int = android.media.AudioFormat.CHANNEL_IN_MONO
              const val RECORDER_AUDIO_ENCODING: Int = android.media.AudioFormat.ENCODING_PCM_16BIT
              const val BITS_PER_SAMPLE: Short = 16
              const val NUMBER_CHANNELS: Short = 1
              const val BYTE_RATE = RECORDER_SAMPLE_RATE * NUMBER_CHANNELS * 16 / 8
      
              var BufferElements2Rec = 1024
          }
      }
      

      【讨论】:

      • 我们可以立即播放保存的文件吗?
      【解决方案4】:

      这对我有用...Picture of results

      private void setUpMediaRec(String path) {
          Log.i(TAG, "[Start]setting up media recoder![Start]");
          mediaRecorder = new MediaRecorder();
          mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
          mediaRecorder.setOutputFormat(AudioFormat.ENCODING_PCM_16BIT);
          mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
          mediaRecorder.setOutputFile(path);
          Log.i(TAG, "[END]setting up media recoder![END]");}
      

      并提供文件地址(您喜欢的任何地方)以保存录制的文件

      mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
          mFileName += "/my_rec_ext_dir.wav";
      

      【讨论】:

      • 我会小心使用“AudioFormat.ENCODING_PCM_16BIT”,因为它与“MediaRecorder.OutputFormat.MPEG_4”的值相同。
      【解决方案5】:

      我最近为此录制目的制作了库。你只需要这样做:-

      recorder = OmRecorder.wav(
      new PullTransport.Default(mic(), new PullTransport.OnAudioChunkPulledListener() {
          @Override public void onAudioChunkPulled(AudioChunk audioChunk) {
            animateVoice((float) (audioChunk.maxAmplitude() / 200.0));
          }
        }), file());
      

      您可以设置频率音源等,然后可以轻松录制wav文件。 你可以找到更多信息:-

      https://github.com/kailash09dabhi/OmRecorder

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多