代码之家  ›  专栏  ›  技术社区  ›  Glenncito

用LAME将原始PCM文件转换为MP3会返回失真的音频

  •  0
  • Glenncito  · 技术社区  · 6 年前

    Here is the link to the API response that returns in. .

    然后我用这个字符串创建一个PCM文件,然后用LAME库把它转换成MP3。

        companion object {
      init {
          System.loadLibrary("mp3lame")
      }
      }
    
    
    private external fun initEncoder(numChannels: Int, sampleRate: Int, bitRate: Int, mode: Int, quality: Int)
    private external fun destroyEncoder()
    private external fun encodeFile(sourcePath: String, targetPath: String): Int
    val NUM_CHANNELS = 1
    val SAMPLE_RATE = 16000
    val BITRATE = 128
    val MODE = 3
    val QUALITY = 0
    
    fun createAudioFromBase64AndGetPath(inputBase64: String, outputFileName: String) {
        initEncoder(NUM_CHANNELS, SAMPLE_RATE, BITRATE, MODE, QUALITY)
    
        val path: String = "newFile.wav"
    
        try {
            val decoded = Base64.decode(inputBase64, Base64.NO_WRAP)
            try {
                val fileRaw = File(Environment.getExternalStorageDirectory().toString() + "/$outputFileName.pcm")
                val fileEncoded = File(Environment.getExternalStorageDirectory().toString() + "/$outputFileName.mp3")
    
    
                    val os = FileOutputStream(fileRaw, true)
                    os.write(decoded)
                    os.close()
    
                val result = encodeFile(fileRaw!!.absolutePath, fileEncoded!!.absolutePath)
                if (result == 0) {
                    Log.d ("encoded to ", fileEncoded!!.name)
                }
                destroyEncoder()
    
            } catch (e: Exception) {
                Log.e ("decode ", "first catch", e)
                e.printStackTrace()
            }
    
        } catch (e: Exception) {
            e.printStackTrace()
            Log.d ("decode ", "2nd catch", e)
        }
    }
    

    this.

    我尝试过浏览C库文件,这些文件解释了不同的变量选项的用途 初始化编码器 我的意思是,我到处摆弄,但什么都没变。

    为了避免每次编译应用程序时出现延迟,我使用base64字符串并使用在线转换器(Motobit)将其转换为PCM文件。然后,我使用了一个非常漂亮的(免费的)mac转换器XLD来测试这些转换,而不必每次编译应用程序,看看我是否能弄清楚发生了什么,也许我只是在initEncoder中使用了错误的变量组合。

    我注意到的第一件事是,为了打开从motobit下载的PCM文件,我必须选择“Open raw PCM(bin+cue)…”选项。

    这是选择窗口。 The selection window

    下一个难题,这似乎是关键的一块,是我只能正确地转换音频(没有噪音)时,选择“小”在Endian框。问题是,回到我的应用程序中,我无法找到如何或是否可以访问和更改LAME库中的此属性。

    为了清楚起见,我在这里使用包装器: https://developer.samsung.com/technical-doc/view.do?v=T000000090

    1 回复  |  直到 6 年前
        1
  •  1
  •   greeble31    6 年前

    如果你走投无路了,你可以自己改变结局:

    for (i in decoded.indices step 2)
    {
        val swap = decoded[i]
        decoded[i] = decoded[i + 1]
        decoded[i + 1] = swap
    }
    

    Base64.decode() 返回一个字节数组,我假设您使用的是16位音频。

    initEncoder() 医生,我自己。