当前位置:网站首页>Player practice 18 xresample
Player practice 18 xresample
2022-06-12 14:09:00 【Sister Suo】
Sampling rate :
That is, the number of samples per second .
An infinite number of sampling points form the original analog signal curve . So what kind of sampling rate is more appropriate ?
Recording must ultimately be for playback . Sampling coding for storage, processing and transmission , Finally, the analog signal should be restored to play .
according to “ Nyquist sampling theory ”: When the sampled analog signal is restored , Its highest frequency is only half of the sampling frequency .
let me put it another way : To reconstruct a complete analog signal , The sampling rate should be more than twice the frequency of the analog signal .
Human auditory range :20 Hz -20 KHz. So for audio that people listen to , The sampling rate should be greater than 40 KHz When the digital signal is converted into an analog signal for playback, the sound quality will not be damaged . therefore , Appropriate sampling rate Generally greater than 40 KHz, The mainstream sampling rates are 44100HZ perhaps 48000HZ
Sampling depth ( Sampling format ):
Namely, the quantization granularity of the vertical coordinate during quantization .
In the analog signal in the figure above , The ordinate represents the loudness of the sound , Volume .
From the above figure, we can see that , When the granularity of quantification is finer , The value of the discrete point is closer to the actual value of the analog signal , If quantification , The sampling depth is 1bit, That is, quantification can only be 1 and 0, Or play the loudest sound , Or no sound .
Only the deeper the sampling depth , That is, the finer the quantization granularity , Sampled data , To get closer to the actual volume .
Now it's commonly used 16 Bit to represent the volume of a sample data .(S16)
You can see the audio format information in this media file :
format=8
audio: the sample format, the value corresponds to enum AVSampleFormat.
Corresponding table lookup :
enum AVSampleFormat {
AV_SAMPLE_FMT_NONE = -1,
AV_SAMPLE_FMT_U8, ///< unsigned 8 bits
AV_SAMPLE_FMT_S16, ///< signed 16 bits
AV_SAMPLE_FMT_S32, ///< signed 32 bits
AV_SAMPLE_FMT_FLT, ///< float
AV_SAMPLE_FMT_DBL, ///< double
AV_SAMPLE_FMT_U8P, ///< unsigned 8 bits, planar
AV_SAMPLE_FMT_S16P, ///< signed 16 bits, planar
AV_SAMPLE_FMT_S32P, ///< signed 32 bits, planar
AV_SAMPLE_FMT_FLTP, ///< float, planar
AV_SAMPLE_FMT_DBLP, ///< double, planar
AV_SAMPLE_FMT_S64, ///< signed 64 bits
AV_SAMPLE_FMT_S64P, ///< signed 64 bits, planar
AV_SAMPLE_FMT_NB
by AV_SAMPLE_FMT_S32P, ///< signed 32 bits, planar
32 Bit compact format , Because the task here is to transform it into 16 Bit for easy playback
1.xresample.h
#pragma once
struct AVCodecParameters;
struct AVFrame;
struct SwrContext;
#include <mutex>
class xresample
{
public:
// The output parameters are consistent with the input parameters except for the sampling format , Output is S16
virtual bool Open(AVCodecParameters* para);
virtual void Close();
// Returns the size after resampling , Whether successful or not, release AVFrame
virtual int Resample(AVFrame* indata, unsigned char* outdata);
xresample();
~xresample();
protected:
std::mutex mux;
SwrContext* actx = NULL;
int outformat = 1;//S16
};
The sampling rate and the number of channels remain unchanged , What you need to change is the output format , Put the output format to be changed in the header file protect in (outformat)
2.xresample.cpp
#include "xresample.h"
extern "C" {
#include <libswresample/swresample.h>
#include <libavcodec/avcodec.h>
}
#pragma comment(lib,"swresample.lib")
#include <iostream>
using namespace std;
// The output parameters are consistent with the input parameters except for the sampling format , Output is S16
bool xresample::Open(AVCodecParameters* para)
{
if (!para)return false;
mux.lock();
// Audio resampling Context initialization
//if(!actx)
// actx = swr_alloc();
// If actx by NULL Will allocate space
actx = swr_alloc_set_opts(actx,
av_get_default_channel_layout(2), // Output format
(AVSampleFormat)outformat, // Output sample format
para->sample_rate, // Output sample rate
av_get_default_channel_layout(para->channels),// Input format
(AVSampleFormat)para->format,
para->sample_rate,
0, 0
);
avcodec_parameters_free(¶);
int re = swr_init(actx);
mux.unlock();
if (re != 0)
{
char buf[1024] = {
0 };
av_strerror(re, buf, sizeof(buf) - 1);
cout << "swr_init failed! :" << buf << endl;
return false;
}
//unsigned char *pcm = NULL;
cout << "swr_int success!:" << endl;
return true;
}
void xresample::Close()
{
mux.lock();
if (actx)
swr_free(&actx);
mux.unlock();
}
xresample::xresample()
{
}
xresample::~xresample()
{
}
int xresample::Resample(AVFrame* indata, unsigned char* outdata)
{
if (!indata)return 0;
if (!outdata)
{
av_frame_free(&indata);
return 0;
}
uint8_t* data[2] = {
0 };
data[0] = outdata;
int re = swr_convert(actx, data, indata->nb_samples
, (const uint8_t**)indata->data, indata->nb_samples);
if (re <= 0)return re;
int outSize = re * indata->channels * av_get_bytes_per_sample((AVSampleFormat)outformat);
cout << "re :" << re << endl;
cout << "indata->channels:" << indata->channels << endl;
cout << "av_get_bytes_per_sample:" << av_get_bytes_per_sample((AVSampleFormat)outformat) << endl;
return outSize;
}
re by swr_convert The return value of : Number of samples per channel
return number of samples output per channel, negative value
indata->channels: Is the number of channels
av_get_bytes_per_sample: Number of bits sampled for each , That is, the format (S16) The amount of space taken up (16 Bits are two bits )
Their multiplication is the number of bits sampled for each audio channel
Use the result of this multiplication in audio playback ( Determine whether the result is larger than the remaining cache space , If the remaining cache space is large, you can play )
边栏推荐
- Go language functions as parameters of functions
- Program analysis and Optimization - 6 loop optimization
- 十四周作业
- QA of some high frequency problems in oauth2 learning
- 通过loganalyzer展示数据库中的日志
- IAT hook hijacking process API call
- 阿里云开发板HaaS510将串口获取数据发送到物联网平台
- 基于Profibus-DP协议的PLC智能从站设计
- Alibaba Cloud Development Board haas510 submission Device Properties
- Shell脚本到底是什么高大上的技术吗?
猜你喜欢

Now you must know the pointer

简述CGI与FASTCGI区别

Axi4 increase burst / wrap burst/ fix burst and narrow transfer

肝了一个月的原创小袁个人博客项目开源啦(博客基本功能都有,还包含后台管理)

Acwing: topology sequence

Alibaba Cloud Development Board haas510 submission Device Properties

Shell脚本到底是什么高大上的技术吗?

Transmission and response of events and use cases

Communication flow analysis

Why do Chinese programmers change jobs?
随机推荐
Remote code injection
【mysql进阶】mysql索引数据结构的演变(四)
chrome://tracing Performance analysis artifact
2022版Redis数据删除策略
OAuth2学习中的一些高频问题的QA
肝了一个月的原创小袁个人博客项目开源啦(博客基本功能都有,还包含后台管理)
Interview question 17.14 Minimum number of K (almost double hundreds)
Convert the string to hexadecimal string and display it
Notepad common settings
[advanced MySQL] evolution of MySQL index data structure (IV)
Alicloud development board vscode development environment setup
Cmake basic tutorial - 01 a-hello-cmake
Transmission and response of events and use cases
Is Shell Scripting really a big technology?
Go zero micro Service Practice Series (II. Service splitting)
阿里云开发板vscode开发环境搭建
动态搜索广告智能查找匹配关键字
编译安装基于fastcgi模式的多虚拟主机的wordpress和discuz的LAMP架构
【视频课】android studio物联网APP设计制作全套教程--国庆期间全掌握
Backtracking: Prime Rings