parent
2b465db026
commit
426b478fe1
@ -0,0 +1,81 @@ |
|||||||
|
package com.frank.androidmedia.util |
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream |
||||||
|
import java.io.IOException |
||||||
|
|
||||||
|
/** |
||||||
|
* The header of wave format |
||||||
|
* @author frank |
||||||
|
* @date 2022/3/22 |
||||||
|
*/ |
||||||
|
internal class WavHeader { |
||||||
|
var riffID = charArrayOf('R', 'I', 'F', 'F') |
||||||
|
@JvmField |
||||||
|
var riffSize = 0 |
||||||
|
var riffType = charArrayOf('W', 'A', 'V', 'E') |
||||||
|
var formatID = charArrayOf('f', 'm', 't', ' ') |
||||||
|
@JvmField |
||||||
|
var formatSize = 0 |
||||||
|
@JvmField |
||||||
|
var formatTag: Short = 0 |
||||||
|
@JvmField |
||||||
|
var numChannels: Short = 0 |
||||||
|
@JvmField |
||||||
|
var sampleRate = 0 |
||||||
|
@JvmField |
||||||
|
var avgBytesPerSec = 0 |
||||||
|
@JvmField |
||||||
|
var blockAlign: Short = 0 |
||||||
|
@JvmField |
||||||
|
var bitsPerSample: Short = 0 |
||||||
|
var dataID = charArrayOf('d', 'a', 't', 'a') |
||||||
|
@JvmField |
||||||
|
var dataSize = 0 |
||||||
|
|
||||||
|
@get:Throws(IOException::class) |
||||||
|
val header: ByteArray |
||||||
|
get() { |
||||||
|
val bos = ByteArrayOutputStream() |
||||||
|
writeChar(bos, riffID) |
||||||
|
writeInt(bos, riffSize) |
||||||
|
writeChar(bos, riffType) |
||||||
|
writeChar(bos, formatID) |
||||||
|
writeInt(bos, formatSize) |
||||||
|
writeShort(bos, formatTag.toInt()) |
||||||
|
writeShort(bos, numChannels.toInt()) |
||||||
|
writeInt(bos, sampleRate) |
||||||
|
writeInt(bos, avgBytesPerSec) |
||||||
|
writeShort(bos, blockAlign.toInt()) |
||||||
|
writeShort(bos, bitsPerSample.toInt()) |
||||||
|
writeChar(bos, dataID) |
||||||
|
writeInt(bos, dataSize) |
||||||
|
bos.flush() |
||||||
|
val r = bos.toByteArray() |
||||||
|
bos.close() |
||||||
|
return r |
||||||
|
} |
||||||
|
|
||||||
|
@Throws(IOException::class) |
||||||
|
private fun writeShort(bos: ByteArrayOutputStream, s: Int) { |
||||||
|
val data = ByteArray(2) |
||||||
|
data[1] = (s shl 16 shr 24).toByte() |
||||||
|
data[0] = (s shl 24 shr 24).toByte() |
||||||
|
bos.write(data) |
||||||
|
} |
||||||
|
|
||||||
|
@Throws(IOException::class) |
||||||
|
private fun writeInt(bos: ByteArrayOutputStream, n: Int) { |
||||||
|
val buf = ByteArray(4) |
||||||
|
buf[3] = (n shr 24).toByte() |
||||||
|
buf[2] = (n shl 8 shr 24).toByte() |
||||||
|
buf[1] = (n shl 16 shr 24).toByte() |
||||||
|
buf[0] = (n shl 24 shr 24).toByte() |
||||||
|
bos.write(buf) |
||||||
|
} |
||||||
|
|
||||||
|
private fun writeChar(bos: ByteArrayOutputStream, id: CharArray) { |
||||||
|
for (c in id) { |
||||||
|
bos.write(c.toInt()) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,64 @@ |
|||||||
|
package com.frank.androidmedia.util |
||||||
|
|
||||||
|
import android.util.Log |
||||||
|
import java.io.* |
||||||
|
|
||||||
|
/** |
||||||
|
* Convert pcm to wav |
||||||
|
* |
||||||
|
* @author frank |
||||||
|
* @date 2022/3/22 |
||||||
|
*/ |
||||||
|
object WavUtil { |
||||||
|
|
||||||
|
fun makePCMToWAVFile(pcmPath: String?, wavPath: String?, deletePcmFile: Boolean): Boolean { |
||||||
|
val buffer: ByteArray |
||||||
|
val file = File(pcmPath) |
||||||
|
if (!file.exists()) { |
||||||
|
return false |
||||||
|
} |
||||||
|
val len = file.length().toInt() |
||||||
|
val header = WavHeader() |
||||||
|
header.riffSize = len + (44 - 8) |
||||||
|
header.formatSize = 16 |
||||||
|
header.bitsPerSample = 16 |
||||||
|
header.numChannels = 2 |
||||||
|
header.formatTag = 0x0001 |
||||||
|
header.sampleRate = 44100 |
||||||
|
header.blockAlign = (header.numChannels * header.bitsPerSample / 8).toShort() |
||||||
|
header.avgBytesPerSec = header.blockAlign * header.sampleRate |
||||||
|
header.dataSize = len |
||||||
|
val h: ByteArray = try { |
||||||
|
header.header |
||||||
|
} catch (e1: IOException) { |
||||||
|
Log.e("WavUtil", e1.message) |
||||||
|
return false |
||||||
|
} |
||||||
|
if (h.size != 44) return false |
||||||
|
val dstFile = File(wavPath) |
||||||
|
if (dstFile.exists()) dstFile.delete() |
||||||
|
try { |
||||||
|
buffer = ByteArray(1024 * 4) |
||||||
|
val inStream: InputStream |
||||||
|
val ouStream: OutputStream |
||||||
|
ouStream = BufferedOutputStream(FileOutputStream(wavPath)) |
||||||
|
ouStream.write(h, 0, h.size) |
||||||
|
inStream = BufferedInputStream(FileInputStream(file)) |
||||||
|
var size = inStream.read(buffer) |
||||||
|
while (size != -1) { |
||||||
|
ouStream.write(buffer) |
||||||
|
size = inStream.read(buffer) |
||||||
|
} |
||||||
|
inStream.close() |
||||||
|
ouStream.close() |
||||||
|
} catch (e: IOException) { |
||||||
|
Log.e("WavUtil", e.message) |
||||||
|
return false |
||||||
|
} |
||||||
|
if (deletePcmFile) { |
||||||
|
file.delete() |
||||||
|
} |
||||||
|
Log.i("WavUtil", "makePCMToWAVFile success...") |
||||||
|
return true |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue