directshow-faac编码
Posted qianbo_insist
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了directshow-faac编码相关的知识,希望对你有一定的参考价值。
目的
建立一个简单的windows下的工具,采集音频后可以进行算法分析,简单来说:制作工具
1、 portaudio
2、directshow audio
2、libfaac
3、ffmpeg
其实要选择,我们肯定会选择portaudio, 因为该工具是跨平台的,但是我们制作的是工具,因此依赖越少越好,使用directshow 和libfaac的依赖很少,计划直接使用,ffmpeg强大的工具,我们在编译开关中关掉,使用libfaac。
后续算法
1、去噪算法
2、静音检测
静音检测二
3、回声消除
下载
简单使用libfaac进行编码
#if !USE_FAAC
#include "TPictureInfo.h"
extern "C"{
#include "libavcodec/avcodec.h"
#include "libswresample/swresample.h"
#include "libavutil/opt.h"
}
#endif
#if(USE_FAAC)
#include "faac.h"
class FFSimpleEncoder
{
public:
FFSimpleEncoder();
~FFSimpleEncoder();
void Init(
unsigned int bitrate,
unsigned int samRate,
unsigned int channels,
int bitsPerSample);
void Encode(unsigned char* inputBuf,
unsigned int samCount,
unsigned char* outBuf,
unsigned int& bufSize);
unsigned long InputSamples() { return input_sams_; }
unsigned int GetsamRate(){return samRate_;}
unsigned int Getchannels(){return channels_;}
int GetbitsPerSample(){return bitsPerSample_;}
unsigned long MaxOutBytes() { return max_output_bytes_; }
private:
void Destroy();
faacEncHandle faac_handle_ = NULL;
unsigned long input_sams_ = 0;
unsigned int samRate_ = 0;
unsigned int channels_ = 0;
int bitsPerSample_ = 0;
unsigned long max_output_bytes_ =0;
};
#include "FAACEncoder.h"
#if(USE_FAAC)
FFSimpleEncoder::FFSimpleEncoder()
{
input_sams_ = 0;
max_output_bytes_ = 0;
faac_handle_ = NULL;
}
FFSimpleEncoder::~FFSimpleEncoder()
{
Destroy();
}
void FFSimpleEncoder::Init(unsigned int bitrate,
unsigned int samRate,
unsigned int channels,
int bitsPerSample)
{
//先销毁
Destroy();
samRate_ = samRate;
channels_ = channels;
bitsPerSample_ = bitsPerSample;
//Destroy();
faac_handle_ = faacEncOpen(samRate, channels, &input_sams_, &max_output_bytes_);
faacEncConfigurationPtr enc_cfg = faacEncGetCurrentConfiguration(faac_handle_);
switch (bitsPerSample)
{
case 16:
enc_cfg->inputFormat = FAAC_INPUT_16BIT;
break;
case 24:
enc_cfg->inputFormat = FAAC_INPUT_24BIT;
break;
case 32:
enc_cfg->inputFormat = FAAC_INPUT_32BIT;
break;
default:
enc_cfg->inputFormat = FAAC_INPUT_NULL;
break;
}
enc_cfg->mpegVersion = MPEG4;
enc_cfg->aacObjectType = LOW;
enc_cfg->allowMidside = 1;
enc_cfg->useLfe = 0;
enc_cfg->useTns = 0; //可以设置为true 曝音处理
enc_cfg->bitRate = bitrate;// 64000;
enc_cfg->quantqual = 100;
enc_cfg->bandWidth = 0;
//输出ATDS
enc_cfg->outputFormat = 1;
faacEncSetConfiguration(faac_handle_, enc_cfg);
}
void FFSimpleEncoder::Encode(unsigned char* inputBuf, unsigned int samCount, unsigned char* outBuf, unsigned int& bufSize)
{
bufSize = faacEncEncode(faac_handle_, (int*)inputBuf, samCount, outBuf, max_output_bytes_);
}
void FFSimpleEncoder::Destroy()
{
if (faac_handle_ != NULL)
{
faacEncClose(faac_handle_);
faac_handle_ = NULL;
}
}
使用directshow 进行音频采集
#include "../DSAudio/General.h"
#include "../DSAudio/dscapture.h"
#include<iostream>
#include<cstring>
#include<windows.h>
#include<conio.h>
#include "FAACEncoder.h"
#pragma comment(lib,"STRMBASE.lib")
unsigned char fBitsPerSample, fNumChannels;
unsigned fSamplingFrequency;
unsigned fGranularityInMS;
DSCapture* _ds_capture;
FFSimpleEncoder* _faac_encoder;
unsigned long max_out_bytes;
unsigned char* outbuf;
FILE* f_aac_;
int main()
{
fBitsPerSample = 16; //单个采样音频信息位数(一个样本有多少位)
fNumChannels = 2; //通道数
fSamplingFrequency = 44100;//采样率
//faac_encoder_->Init(fSamplingFrequency,fNumChannels,fBitsPerSample); //初始化AAC编码器
_ds_capture = new DSCapture();//捕获麦克风设备
std::map<CString, CString> a_devices = _ds_capture->DShowGraph()->AudioCapDevices();
if(a_devices.size() == 0 ) ::exit(0);
DSAudioFormat audio_fmt;
audio_fmt.samples_per_sec = fSamplingFrequency;
audio_fmt.channels = fNumChannels;
audio_fmt.bits_per_sample = fBitsPerSample;
// 枚举音频采样设备,选择最后一个
CString audio_device_id;
for (std::map<CString, CString>::iterator it = a_devices.begin(); it != a_devices.end(); ++it)
{
audio_device_id = it->first;
}
_ds_capture->Create(audio_device_id, audio_fmt, NULL);
// 开始采集音频数据
_ds_capture->StartAudio();
::Sleep(10);
//max_out_bytes = faac_encoder_->MaxOutBytes();
outbuf = (unsigned char*)malloc(max_out_bytes);
// 编码后存文件
f_aac_ = fopen("./audio1.aac","wb");
printf("Recording...");
while(1)
{
int pcmLen = 0;
// 采集音频pcm数据
char* pcmBuf = _ds_capture->GetBuffer(pcmLen);
if(pcmLen > 0)
{
unsigned int sample_count = (pcmLen << 3)/fBitsPerSample;
unsigned int buf_size = 0;
// 编码AAC
_faac_encoder->Encode((unsigned char*)pcmBuf, sample_count, (unsigned char*)outbuf, buf_size);
if(buf_size > 0)
{
printf(".");
// 存文件或者自定义
fwrite(outbuf,1,buf_size,f_aac_);
}
}
// 释放采集的pcm数据
_ds_capture->ReleaseBuffer(pcmBuf);
::Sleep(10);
}
free(outbuf);
}
以上是关于directshow-faac编码的主要内容,如果未能解决你的问题,请参考以下文章
从 XML 声明片段获取 XML 编码:部分内容解析不支持 XmlDeclaration
《安富莱嵌入式周报》第279期:强劲的代码片段搜索工具,卡内基梅隆大学安全可靠C编码标准,Nordic发布双频WiFi6 nRF7002芯片