音频变速 | libsonic 开源库的介绍与实践

在做音视频编辑的时候,大家关注更多的是视频开发,热衷于 FFmpeg、OpenGL 这些技巧,实际上音频开发也是很重要的,甚至可以说音频开发比视频开发更难一点。

对音频的常见处理就是变速、变调、混音这些,一般都是用开源库来搞定,常见的就是 libsonic 和 libsoundtouch 两个,当然有实力的公司会自己研发音频算法。

本篇文章会简单介绍 libsonic 的使用。

libsonic 获取

libsonic 是一个支持音频倍速播放的开源库,并且支持大于 2 倍速的播放,它的主页地址如下:

https://android.googlesource.com/platform/external/sonic/+/refs/heads/master/doc/index.md

可以通过该链接下载 libsonic 库:

git clone git://github.com/waywardgeek/sonic.git

这个仓库里面内容还挺全的,包含了 Java 和 C 版本的实现和使用演示,很方便做移植。

c1fa16a59ab1c1c60cb888555d89a6be.png

如果你只需要用到变速和音量调整,那么使用 sonic_lite.h 和 sonic_lite.c 两个文件就行了,这里面对功能做了裁剪。

libsonic 主页上还提供了一个 Android NDK 版本的仓库,通过该链接可下载:

git clone git://github.com/waywardgeek/sonic-ndk.git

不过这个版本有的太老旧了,还是 Android.mk 的接入方式,现在都换成 CMake 接入了。

有兴趣的同学可以写一个 sonic-ndk CMake 版本的封装库,说不定能在 Github 上刷一波 star 呢。

libsonic 使用

libsonic 的调用接口不多,具体使用完全可以参考给的代码演示。

以下是一个音频倍速的使用代码:

/* Run sonic_lite. */
static void runSonic(char* inFileName, char* outFileName, float speed, float volume) {
  waveFile inFile, outFile = NULL;
  // 定义输入和输出的 buffer 
  short inBuffer[SONIC_INPUT_SAMPLES], outBuffer[SONIC_INPUT_SAMPLES];
  int samplesRead, samplesWritten, sampleRate, numChannels;
  // 打开输入文件,并且获取输入文件的相关信息
  inFile = openInputWaveFile(inFileName, &sampleRate, &numChannels);
  if (numChannels != 1) {
    fprintf(stderr, "sonic_lite only processes mono wave files.  This file has %d channels.\n",
        numChannels);
    exit(1);
  }
  if (sampleRate != SONIC_SAMPLE_RATE) {
    fprintf(stderr,
        "sonic_lite only processes wave files with a sample rate of %d Hz.  This file uses %d\n",
        SONIC_SAMPLE_RATE, sampleRate);
    exit(1);
  }
  if (inFile == NULL) {
    fprintf(stderr, "Unable to read wave file %s\n", inFileName);
    exit(1);
  }
  // 打开输出文件
  outFile = openOutputWaveFile(outFileName, sampleRate, 1);
  if (outFile == NULL) {
    closeWaveFile(inFile);
    fprintf(stderr, "Unable to open wave file %s for writing\n", outFileName);
    exit(1);
  }
  // 初始化 sonic 并且设置速度 speed 和音量 volume 
  sonicInit();
  sonicSetSpeed(speed);
  sonicSetVolume(volume);
  do {
   // 从输入文件中读取 sample
    samplesRead = readFromWaveFile(inFile, inBuffer, SONIC_INPUT_SAMPLES);
    if (samplesRead == 0) {
      sonicFlushStream();
    } else {
      // 将读取的 sample 给到 sonic 中的 sonicStream
      // sonicStream 会根据 speed 和 volume 做相应处理
      sonicWriteShortToStream(inBuffer, samplesRead);
    }
    // 将 sonic 中 sonicStream 处理后的数据给到 outBuffer
    // 并将 outBuffer 写入到输出文件中
    do {
      samplesWritten = sonicReadShortFromStream(outBuffer, SONIC_INPUT_SAMPLES);
      if (samplesWritten > 0) {
        writeToWaveFile(outFile, outBuffer, samplesWritten);
      }
    } while (samplesWritten > 0);
  } while (samplesRead > 0);
  closeWaveFile(inFile);
  closeWaveFile(outFile);
}

这个代码示例还是比较简单易懂的。

首先是检查输入和输出文件是不是有问题,这一点很基础但也非常重要。

代码中用到的示例文件是 wav 格式的,libsonic 仓库中有对应的资源可以下载,不用自己满世界找文件了。

wav 文件的读取可以用仓库中的 wave.c 和 wave.h 文件操作。

接下来就是从输入文件中读取 sample ,并交由 libsonic 处理,最后将处理好 sample 写入到输出文件中。

这有个概念就是:视频的处理,我们都是说一帧一帧的,音频就没有帧的概念,一般都是说采样点,比如要处理多少个采样点之类的说法。

代码示例中,readFromWaveFile 方法从文件中读取 sample ,sonicWriteShortToStream 方法将 sample 交由 libsonic 处理。

libsonic 中有个 sonicStream 的结构,它用来存储变换后的数据,这里面会根据设置的 speed 和 volume 做处理。

最后再通过 sonicReadShortFromStream 将数据从 libsonic 读出,然后通过 writeToWaveFile 方法写入到输出文件中。

经过测试,以上方法确实可以实现音量调节和变速的效果,并且在变速的同时保持着原来的音调。

小结

以上就是关于 libsonic 的介绍与实践,除了 wav 格式文件,pcm 格式数据也同样可以做变速的。

公众号在后续还会进行更新源码分析等更多内容,敬请期待~~~

09d8e8994a1193d6af06ea66eb54f652.png

技术交流,欢迎加我微信:ezglumes ,拉你入技术交流群。

1b2b3ae2825cc5b847565c576610d8e9.png

私信领取相关资料

推荐阅读:

音视频开发工作经验分享 || 视频版

OpenGL ES 学习资源分享

开通专辑 | 细数那些年写过的技术文章专辑

NDK 学习进阶免费视频来了

你想要的音视频开发资料库来了

推荐几个堪称教科书级别的 Android 音视频入门项目

觉得不错,点个在看呗~

019d77e78219ee44f692d301c777078e.gif

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FFmpeg是一个开源音视频处理工具,可以用于音频变速处理。通过FFmpeg提供的API或命令行工具,可以实现将音频文件进行加速或减速的操作。 要实现音频变速,首先需要安装FFmpeg插件,可以使用命令`pip install ffmpeg`进行安装。然后,可以使用Python中的FFmpeg进行操作。 使用FFmpeg进行音频变速的方法是使用`audio.a_speed()`函数。这个函数接受多个参数,包括输入文件路径、输出文件路径以及变速比例。通过设置变速比例,可以实现音频的加速或减速。 除了使用Python中的FFmpeg,也可以使用FFmpeg命令行工具进行音频变速处理。通过在命令行中执行相应的命令,可以实现对音频文件的变速操作。 综上所述,FFmpeg是一个强大的音视频处理工具,可以用于音频变速处理。可以使用Python中的FFmpeg或者命令行工具来实现音频的加速或减速。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [python音频进行变速的操作方法](https://download.csdn.net/download/weixin_38632146/14910476)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [FFmpeg 音视频倍速控制](https://blog.csdn.net/zhying719/article/details/123059209)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值