简单的音量放大

花满楼原创

小白:音量设置?按几下音量按键就好啦!

花满楼:这种办法是全局的音量控制方式,现在是直接改音频数据,来做到音量的变化控制。

本文介绍直接更改pcm值,以达到能量控制。

大体的思路是这样的,先解码音频文件,得到pcm文件,再运算pcm文件,最后把pcm文件编码成aac。

重点讲解的部分是pcm文件的运算,解码与编码部分可以参考之前的文章来写代码完成,这里直接用ffmpeg的命令行来完成编解码。

先看整体代码,再做解释:

#include <stdio.h>
#include <stdlib.h>

const char* FFMPEGEXE = "ffmpeg";
const int BUF_LEN = 1024;
const int SAMPLE_RATE = 44100;
const int CHANNELS = 2;
const int BITRATE = 128;

void decode(const char* srcfile, const char* outfile) {
    char buf[BUF_LEN] = {0};
    sprintf(buf, "%s -i %s -f s16le -ar %d -ac %d -y %s", FFMPEGEXE, srcfile, SAMPLE_RATE, CHANNELS, outfile);
    system(buf);
}

void encode(const char* srcfile, const char* outfile) {
    char buf[BUF_LEN] = {0};
    sprintf(buf, "%s -ar %d -ac %d -f s16le -i %s -ar %d -ac %d -b:a %dK -y %s", FFMPEGEXE, SAMPLE_RATE, CHANNELS, srcfile, SAMPLE_RATE, CHANNELS, BITRATE, outfile);
    system(buf);
}

void change_volume(const char* pcmfile, double volume_factor, const char* outfile) {
    const int sample_count =1024;
    short samples[sample_count];
    FILE* src = fopen(pcmfile, "rb");
    FILE* out = fopen(outfile, "wb");
    if (src && out) {
        int cnt = 0;
        while (cnt = fread(samples, sizeof(short), sample_count, src)) {
            for (int i = 0; i < cnt; i ++) {
                samples[i] = (short)(samples[i] * volume_factor);
            }
            fwrite(samples, sizeof(short), cnt, out);
        }
        fclose(src);
        fclose(out);
    }
}

int main(int argc, char *argv[])
{
    const char* srcfile = "test.mp3";
    const char* pcmfile = "test.pcm";
    const char* pcmvolfile = "test_vol.pcm";
    const char* outfile = "test.aac";
    decode(srcfile, pcmfile);
    change_volume(pcmfile, 1.1, pcmvolfile);
    encode(pcmvolfile, outfile);

    return 0;
}

解码,decode函数,解码为pcm中的s16le的格式,也就是一个short为一个样本。参数ar与ac分别指定采样率与声道数。

小白:pcm不就是未压缩的格式吗,为什么还有s16le这样的格式?

花满楼:pcm是没有未压缩,但还会细化出多种格式,你可以看下avcodec.h里面的定义,比如AV_CODEC_ID_PCM_F32BE、AV_CODEC_ID_PCM_F32LE等等,也可以看下之前讲的“音频之岁月留声”。

改变音量,这里很暴力地,直接把每个样本乘以一个系数。当这个系数超过1之后,削顶失真的问题就会出现。

这里给出一个演示效果。

小于1倍音量时,声音很小,没有问题(1倍音量时跟原文件一样):
![音量对比1]()

1.5倍音量时,声音变大,感觉还可以;3倍音量时,开始失真明显了:
![音量对比2]()

10倍音量的部分波形图是这样的,削顶失真很明显:
![10倍音量时的部分能量图]()

小白:你这些都是图片,我要的声音呢?

花满楼:好吧,我看下有没有上传音频的功能。

可以看出,让声音变小是没有问题的,但如果想放大声音而又避免明显失真,用这个办法的话,就要考虑一个合适的系数,比如不要超过3之类。

小白:你说这是一个简单直接的办法?难道还有不直接的办法能避免失真?

花满楼:还有其它办法来放大音量,比如动态范围控制(DRC)等,这些在以后再作介绍。

编码,把pcm编码成aac,可以使用FFmpeg自带的编码器(FFmpeg3.x才支持),也可以使用faac或fdk-aac等,这里使用的是fdk-aac,先要保证FFmpeg使用了fdk-aac:
![打开fdk-aac]()

在使用命令时,需要指定输入的pcm的格式如ar/ac/f等参数。

原文地址:http://blog.51cto.com/13136504/2058747

时间: 2024-10-09 15:09:28

简单的音量放大的相关文章

wav转amr以及简单调整音量

说一下wav转amr的方式.wav是PC上录制音频最容易生成的方式,但是缺点是生成的音频体积比较大.amr是手机上音频播放比较主流的格式,优点是音频体积小,易于传输. 转换的方式很简单,amr分两种,这里以nb为例.首先需要下载opencore-amr,将静态库和文件导入工程里.然后输入以下代码 int wav2Amr( const char *infile, const char *outfile) { enum Mode mode = MR122; int ch, dtx = 0; FILE

Android 4.4 音量调节流程分析(一)

最近在做Android Audio方面的工作,有需求是在调节Volume_Up_Key & Volume_Down_key时,Spearker or Headset每音阶的衰减变为3db左右.所以利用Source Insight分析Android源码中音量控制的流程,如有错误,欢迎指正,谢谢! 以下是调节音量的流程: Step_1.首先在调节机台Volume_Up_Key & Volume_Down_Key操作时,系统会调用到AudioManager.java中handleKeyUp &a

调节音量的流程

以下是调节音量的流程: Step_1.首先在调节机台Volume_Up_Key & Volume_Down_Key操作时,系统会调用到AudioManager.java中handleKeyUp & handleKeyDown函数,以 handleKeyDown函数为例: 1 public void handleKeyDown(KeyEvent event, int stream) { 2 int keyCode = event.getKeyCode(); 3 switch (keyCode

语音放大缩小

1: public class SpeakLouder 2: { 3: private WavFormat _wavFormat=new WavFormat(); //文件格式 4: private byte[] _audioData; //语音数据 5: private SpeechSynthesizer _speech; //文本转语音 6: private string _pb;//文本转语音参数 7:   8: /// <summary> 9: /// 文本转语音的说话器 10: //

DoTween学习笔记(二) UGUI结合使用(实现一些简单效果)

UGUI官方实例中是使用Animation来控制UI的移动,放大缩小动画等等, Animation来控制UI的动画工作量实在是太多了, 所以我们一般使用itween,DoTween. 来控制动画, 这样工作量大大减少. 那今天我们来学习下UGUI + DoTween吧   UGUI进行简单的移动,放大,旋转 public class MyClass : MonoBehaviour { void Start () { Image image = transform.GetComponent<Ima

WPF动画制作简单的按钮动画

主界面的代码 <StackPanel ButtonBase.Click="Grid_Click"> <Button Content="逐渐变大缩小"/> <Button Content="鼠标移动特效" /> </StackPanel> cs : //这事件不做过多的解释有基础的一看就会明白 private void Grid_Click(object sender, RoutedEventArgs

(四)双击放大与缩小图片

自定义ZoomImageView实现到这里,基本上完成一大半了.在上一篇又给它添加了自由移动的功能.如果你没读过,可以点击下面的链接:http://www.cnblogs.com/fuly550871915/p/4940103.html 在这篇文章中,就来实现双击放大或者缩小图片.用到的知识点就是GestureDetector,用它来监测双击事件.至于双击后怎么缩放图片,相信在前面几篇文章中,你都已经很熟悉了.但是难点是,我们要求双击后缓慢的放大或者缩小,而不是一下子就放大到或者缩小到目标值.这

Viper4Android使用教程-ViPER4Android简单设置手册

[FX版设置] V4A FX版主要针对音频效果的渲染,通过调节各个参数以达到音频效果调整的目的. <耳机效果> 1.效果总开关.该选项定义了是否启用V4A的耳机音效,是总开关. 2.回放增益控制 回放增益控制主要用于动态控制音频的音量,放大或衰减. (1).启用.是否启用该效果. (2).效果强度.效果强度代表音量放大或衰减的速度,越强则速度越快,最终音量也越大,越弱则速度越慢,最终音量越接近音频原始音量.推荐中等. (3).最大增益倍数.当音频的音量过小时,回放增益为了将音量放大到设定的水准

如何识别JPG图片转文字,简单的方法讲解

相信办公中的小伙伴们经常会遇到图片转文字的问题,需要将图片上的文字应用到别的地方去,但是图中的文字又不可以直接进行复制粘贴,接下来小编就来给大家分享一种识别JPG图片转文字的简单操作方法,大家可以以此来参考下. 辅助工具:迅捷OCR文字识别软件 操作步骤: 1:在电脑中打开接下来使用到的OCR文字识别软件,点击图片局部识别板块. 2:进入图片局部识别板块后,点击添加文件按钮选择一张所需转换的文字图片并打开. 3:图片打开后可以通过下方一排小工具来简单对图片进行"移动""放大&