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芯片

以下代码片段 C++ 的说明

*** Bool 编码为数字属性列表片段。属性列表编码器

Sublime Text自定制代码片段(Code Snippets)

通过 findById 访问活动布局中的硬编码片段