如何在android中录制.wav格式的文件
Posted
技术标签:
【中文标题】如何在android中录制.wav格式的文件【英文标题】:how to record .wav format file in android 【发布时间】:2011-03-09 12:05:42 【问题描述】:我想使用 android 录制 .wav 文件。有没有办法做到这一点?
【问题讨论】:
你已经问过这个问题了。不要问不止一次。 How to record voice in "wav" format in Android的可能重复 【参考方案1】:快速谷歌后,我发现直接支持波形录制。最常见的波形格式是 PCM。 android.media.AudioRecord 支持 PCM 输出。您只需将其写入文件即可。
AudioRecord在您创建文件之后,您必须将自己的转换器编程为 wave(或为此寻找在线库)。
如果您喜欢可以随时使用并在 wave 中录制的应用,您可以下载此应用:
uk.ac.cam.cl.dtg.android.audionetworking.hertz额外链接:
Subject: [android-developers] Re: How to record audio in WAV format?【讨论】:
【参考方案2】:有两个类可以录制音频,AudioRecord和MediaRecorder。
http://developer.android.com/reference/android/media/MediaRecorder.html http://developer.android.com/reference/android/media/AudioRecord.html我现在也在写一个应用程序,就是记录和显示频谱图。所以我使用 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
【讨论】:
以上是关于如何在android中录制.wav格式的文件的主要内容,如果未能解决你的问题,请参考以下文章
android上的qt5不使用QAudioRecorder录制PCM wav文件