Commit 86fa963f authored by banban's avatar banban

环形队列样例,线程数据出入队列

parents
File added
========================================================================
控制台应用程序:queuePThread (环形队列和pthread)项目概述
========================================================================
应用程序向导已为您创建了此 queuePThread 应用程序。
本文件概要介绍组成 queuePThread 应用程序的每个文件的内容。
queuePThread.vcxproj
这是使用应用程序向导生成的 VC++ 项目的主项目文件,其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
queuePThread.vcxproj.filters
这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。
queuePThread.cpp
这是主应用程序源文件。
/////////////////////////////////////////////////////////////////////////////
其他标准文件:
StdAfx.h, StdAfx.cpp
这些文件用于生成名为 queuePThread.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
/////////////////////////////////////////////////////////////////////////////
其他注释:
应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。
/////////////////////////////////////////////////////////////////////////////
#ifndef CLASS_4321B8861C16_CAACENC
#define CLASS_4321B8861C16_CAACENC
#include "faac.h"
class IAacEncListener
{
public:
virtual bool OnData(unsigned char* outAacBuffer, unsigned long outBufferBytes) = 0;//{ return true; }
};
class CAacEnc {
public:
#define SAMPLE_RATE_DEF (44100)
#define SAMPLE_BITS_DEF (16)
#define MAX_COPYRIGHT_STR (260)
CAacEnc(unsigned long nSampleRate, unsigned long nChannels, unsigned int nSampleBitCount);
~CAacEnc();
const char* GetCopyRight();
bool OpenEncoder(unsigned long nSampleRate, unsigned long nChannels, unsigned int nSampleBitCount);
bool Encode(unsigned char* inPcmBuffer, unsigned long inPcmBytes);
/** Flush()的调用示例:
while (true) {
iRet = oAacEnc.Flush(&pbAACBuffer);
if (iRet <= 0)//返回非正值才算结束
break;
printf("Last remaining data.", pbAACBuffer)
}
*/
bool Flush();
void CloseEncoder();
protected:
IAacEncListener* m_IListener;
char m_strCopyRight[MAX_COPYRIGHT_STR];
unsigned long m_nSampleRate; // 设置输出aac采样率
unsigned int m_nChannels; // 设置输出aac声道数
unsigned int m_nSampleBitCount; // 设置输出aac单样本位数
unsigned long m_nInputSamples;
unsigned long m_nMaxOutputBytes;
unsigned char* m_pPcmInBuf;
unsigned long m_nPcmSamples;
unsigned char* m_pAacOutBuf;
faacEncHandle* m_phEnc;
faacEncConfigurationPtr* m_ppConfig;
void ReleaseAll();
public:
void AddEventListener(IAacEncListener* IListener);
};
#endif // !CLASS_4321B8861C16_CAACENC
#ifndef CLASS_4321B8861C16_CMYAACENCLISTENER
#define CLASS_4321B8861C16_CMYAACENCLISTENER
#include "AacEnc.h"
#include <stdio.h>
class CAacEncListener: public IAacEncListener
{
public:
CAacEncListener(const char* strFile);
~CAacEncListener();
bool OnData(unsigned char* outAacBuffer, unsigned long outBufferBytes);
protected:
FILE* m_fp;
};
#endif // !CLASS_4321B8861C16_CMYAACENCLISTENER
#pragma once
#include "pthread.h"
class CAutoLock
{
public:
CAutoLock(pthread_mutex_t& lock);
~CAutoLock();
protected:
pthread_mutex_t& m_lock;
};
#ifndef _PTHREAD_QUEUE_
#define _PTHREAD_QUEUE_
#include <pthread.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include "queue_ring.h"
#include "QueueEventListener.h"
#pragma comment(lib,"pthreadVC2.lib")
class CPThreadQueue {
typedef enum _PROCESSOR_STATUS
{
STOPED
, STOP
, RUNNING
}PROCESSOR_STATUS, *PPROCESSOR_STATUS;
public:
CPThreadQueue(unsigned long iQueueMaxsize);
~CPThreadQueue();
void AddListener(CQueueEventListener* listener);
bool AddData(CQueueNode* p);
static void* processor_thread(void* pParam);
protected:
CRingQueue* m_pRingQueue;
PROCESSOR_STATUS m_iStatus;
pthread_t m_thProcessor;
CQueueEventListener* m_listener;
void doProcessor();
};
#endif // _PTHREAD_QUEUE_
#ifndef CLASS_B29F80E93405_CPCMDATA
#define CLASS_B29F80E93405_CPCMDATA
class CPcmData {
public:
CPcmData(char* pData, unsigned long nBytes);
~CPcmData();
char* audio_data;
unsigned long audio_size;
};
#endif //!CLASS_B29F80E93405_CPCMDATA
#ifndef CLASS_167A00526B23_CPCMRECORDER
#define CLASS_167A00526B23_CPCMRECORDER
#include <stdio.h>
#include "QueueEventListener.h"
#include "PcmData.h"
#include "AacEnc.h"
#include "AacEncListener.h"
#if _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
class CPcmRecorder : public CQueueEventListener
{
public:
CPcmRecorder(const char* fileName, const int bits_per_sample, const int sample_rate, const int number_of_channels, const int number_of_frames);
~CPcmRecorder();
// ͨ IQueueEventListener ̳
virtual void OnData(CQueueNode* pNode);
protected:
FILE* m_fpOut;
int m_bitsPerSample; //16
int m_sampleRate; //48000
int m_numberOfChannels; //2
int m_numberOfFrames; //480
CAacEnc m_oAacEnc;
CAacEncListener oListener;
#if _WIN32
LARGE_INTEGER nFreq;
LARGE_INTEGER nBeginTime;
LARGE_INTEGER nEndTime;
#endif
};
#endif // !CLASS_167A00526B23_CPCMRECORDER
#ifndef CLASS_F37C5E96EF22_IQueueEventListener
#define CLASS_F37C5E96EF22_IQueueEventListener
#include "queue_ring.h"
class IQueueEventListener {
public:
virtual void OnData(CQueueNode* pNode) = 0;
};
class CQueueEventListener: public IQueueEventListener {
public:
CQueueEventListener();
~CQueueEventListener();
// ͨ IQueueEventListener ̳
virtual void OnData(CQueueNode * pNode) override;
};
#endif // !CLASS_F37C5E96EF22_IQueueEventListener
/*
* FAAC - Freeware Advanced Audio Coder
* Copyright (C) 2001 Menno Bakker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: faac.h,v 1.36 2009/01/25 18:50:32 menno Exp $
*/
#ifndef _FAAC_H_
#define _FAAC_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#if defined(_WIN32) && !defined(__MINGW32__)
# ifndef FAACAPI
# define FAACAPI __stdcall
# endif
#else
# ifndef FAACAPI
# define FAACAPI
# endif
#endif
#pragma pack(push, 1)
typedef struct {
void *ptr;
char *name;
}
psymodellist_t;
#include "faaccfg.h"
typedef void *faacEncHandle;
#ifndef HAVE_INT32_T
typedef signed int int32_t;
#endif
/*
Allows an application to get FAAC version info. This is intended
purely for informative purposes.
Returns FAAC_CFG_VERSION.
*/
int FAACAPI faacEncGetVersion(char **faac_id_string,
char **faac_copyright_string);
faacEncConfigurationPtr FAACAPI
faacEncGetCurrentConfiguration(faacEncHandle hEncoder);
int FAACAPI faacEncSetConfiguration(faacEncHandle hEncoder,
faacEncConfigurationPtr config);
faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate,
unsigned int numChannels,
unsigned long *inputSamples,
unsigned long *maxOutputBytes);
int FAACAPI faacEncGetDecoderSpecificInfo(faacEncHandle hEncoder, unsigned char **ppBuffer,
unsigned long *pSizeOfDecoderSpecificInfo);
int FAACAPI faacEncEncode(faacEncHandle hEncoder, int32_t * inputBuffer, unsigned int samplesInput,
unsigned char *outputBuffer,
unsigned int bufferSize);
int FAACAPI faacEncClose(faacEncHandle hEncoder);
#pragma pack(pop)
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _FAAC_H_ */
/*
* FAAC - Freeware Advanced Audio Coder
* Copyright (C) 2001 Menno Bakker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: faaccfg.h,v 1.3 2004/07/04 12:12:05 corrados Exp $
*/
#ifndef _FAACCFG_H_
#define _FAACCFG_H_
#define FAAC_CFG_VERSION 104
/* MPEG ID's */
#define MPEG2 1
#define MPEG4 0
/* AAC object types */
#define MAIN 1
#define LOW 2
#define SSR 3
#define LTP 4
/* Input Formats */
#define FAAC_INPUT_NULL 0
#define FAAC_INPUT_16BIT 1
#define FAAC_INPUT_24BIT 2
#define FAAC_INPUT_32BIT 3
#define FAAC_INPUT_FLOAT 4
#define SHORTCTL_NORMAL 0
#define SHORTCTL_NOSHORT 1
#define SHORTCTL_NOLONG 2
#pragma pack(push, 1)
typedef struct faacEncConfiguration
{
/* config version */
int version;
/* library version */
char *name;
/* copyright string */
char *copyright;
/* MPEG version, 2 or 4 */
unsigned int mpegVersion;
/* AAC object type */
unsigned int aacObjectType;
/* Allow mid/side coding */
unsigned int allowMidside;
/* Use one of the channels as LFE channel */
unsigned int useLfe;
/* Use Temporal Noise Shaping */
unsigned int useTns;
/* bitrate / channel of AAC file */
unsigned long bitRate;
/* AAC file frequency bandwidth */
unsigned int bandWidth;
/* Quantizer quality */
unsigned long quantqual;
/* Bitstream output format (0 = Raw; 1 = ADTS) */
unsigned int outputFormat;
/* psychoacoustic model list */
psymodellist_t *psymodellist;
/* selected index in psymodellist */
unsigned int psymodelidx;
/*
PCM Sample Input Format
0 FAAC_INPUT_NULL invalid, signifies a misconfigured config
1 FAAC_INPUT_16BIT native endian 16bit
2 FAAC_INPUT_24BIT native endian 24bit in 24 bits (not implemented)
3 FAAC_INPUT_32BIT native endian 24bit in 32 bits (DEFAULT)
4 FAAC_INPUT_FLOAT 32bit floating point
*/
unsigned int inputFormat;
/* block type enforcing (SHORTCTL_NORMAL/SHORTCTL_NOSHORT/SHORTCTL_NOLONG) */
int shortctl;
/*
Channel Remapping
Default 0, 1, 2, 3 ... 63 (64 is MAX_CHANNELS in coder.h)
WAVE 4.0 2, 0, 1, 3
WAVE 5.0 2, 0, 1, 3, 4
WAVE 5.1 2, 0, 1, 4, 5, 3
AIFF 5.1 2, 0, 3, 1, 4, 5
*/
int channel_map[64];
} faacEncConfiguration, *faacEncConfigurationPtr;
#pragma pack(pop)
#endif /* _FAACCFG_H_ */
#ifndef CLASS_9B43D69BB4DA_CRINGQUEUE
#define CLASS_9B43D69BB4DA_CRINGQUEUE
#include<stdio.h>
#include<stdlib.h>
#include <pthread.h>
#include <memory.h>
#include "AutoLock.h"
#include "AacEnc.h"
class CQueueNode {
public:
typedef enum _NODETYPE {
TYPE_AUDIO = 8
}NODETYPE, *PNODETYPE;
NODETYPE m_eType;//节点类型
void* m_pData;//节点数据块
unsigned int m_iDataSize;//pData数据大小;
bool m_isClassData;
CQueueNode(NODETYPE eType, void* pData, unsigned long nBytes);
~CQueueNode();
};
class CRingQueue {
public:
CRingQueue(unsigned long iQueueMaxsize);
~CRingQueue();
bool isEmpty(CAutoLock** ppLock/*=NULL*/);
bool isFull(CAutoLock** ppLock/*=NULL*/);
bool enQueue(CQueueNode* pNode);
CQueueNode* deQueue();
void setQueueMax(unsigned long iMaxsize);
protected:
unsigned long m_iQueueMaxsize;
CQueueNode** m_qu;//申明环形队列的物理顺序数组
pthread_mutex_t m_lock;//申明wp的互斥锁
unsigned int m_iFront;//队首指针,即rp
unsigned int m_iRear;//队尾指针,即wp
bool initQueue();
void freeQueue();
inline bool isEmpty();
inline bool isFull();
};
#endif// !CLASS_9B43D69BB4DA_CRINGQUEUE
File added
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include "PThreadQueue.h"
#include "PcmData.h"
#include "PcmRecorder.h"
#define PCMBUF_SIZE (960)
#define BIT_PER_SAMPLE (16)
#define SAMPLE_RATE (44100)
#define NUMBER_OF_CHANNELS (2)
#define NUMBER_OF_FRAMES (480)
int main(int argc, char* argv[])
{
if (argc < 2) {
printf("--s <pcm file name>\n");
getchar();
return E_INVALIDARG;
}
FILE* fp = NULL;
fopen_s(&fp, argv[1], "rb");
if (!fp) {
printf("open file error!\n");
getchar();
return -1;
}
unsigned long ringQueueLenth = 10;
CPThreadQueue nPThreadQueue(ringQueueLenth);
CPcmRecorder pPcmRecorder("./bin/queueAudio.aac", BIT_PER_SAMPLE, SAMPLE_RATE, NUMBER_OF_CHANNELS, NUMBER_OF_FRAMES);
nPThreadQueue.AddListener(&pPcmRecorder);
CQueueNode* pQueueNode = NULL;
CPcmData* pPcmData = NULL;
long number_of_bytes = (long)(NUMBER_OF_CHANNELS * NUMBER_OF_FRAMES * sizeof(short));
char* pcmBuf = new char[number_of_bytes];
if (!pcmBuf)
return -1;
bool bRet = false;
do {
for (int i = 0; !_kbhit(); ++i) {
unsigned long size = (unsigned long)fread(pcmBuf, 1, number_of_bytes, fp);
if (size <= 0)
break;
//printf("%d read file pcm size=%d\n", i, size);
pPcmData = new CPcmData(pcmBuf, size);
if (!pPcmData)
break;
pQueueNode = new CQueueNode(CQueueNode::TYPE_AUDIO, pPcmData, sizeof(CPcmData));
if (pQueueNode) {
bRet = nPThreadQueue.AddData(pQueueNode);
if (!bRet) {
printf("queue is full.\n");
delete pQueueNode;
}
Sleep(5);
}
}
} while (false);
if (fp) {
fclose(fp);
}
if (pcmBuf) {
delete[] pcmBuf;
pcmBuf = NULL;
}
getchar();
return 0;
}
\ No newline at end of file
File added
File added

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "queuePThread", "queuePThread.vcxproj", "{FA49B617-D901-4E57-8DFB-7B6D620692FA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfaac", "libfaac\libfaac.vcxproj", "{9CC48C6E-92EB-4814-AD37-97AB3622AB65}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{FA49B617-D901-4E57-8DFB-7B6D620692FA}.Debug|x64.ActiveCfg = Debug|x64
{FA49B617-D901-4E57-8DFB-7B6D620692FA}.Debug|x64.Build.0 = Debug|x64
{FA49B617-D901-4E57-8DFB-7B6D620692FA}.Debug|x86.ActiveCfg = Debug|Win32
{FA49B617-D901-4E57-8DFB-7B6D620692FA}.Debug|x86.Build.0 = Debug|Win32
{FA49B617-D901-4E57-8DFB-7B6D620692FA}.Release|x64.ActiveCfg = Release|x64
{FA49B617-D901-4E57-8DFB-7B6D620692FA}.Release|x64.Build.0 = Release|x64
{FA49B617-D901-4E57-8DFB-7B6D620692FA}.Release|x86.ActiveCfg = Release|Win32
{FA49B617-D901-4E57-8DFB-7B6D620692FA}.Release|x86.Build.0 = Release|Win32
{9CC48C6E-92EB-4814-AD37-97AB3622AB65}.Debug|x64.ActiveCfg = Debug|x64
{9CC48C6E-92EB-4814-AD37-97AB3622AB65}.Debug|x64.Build.0 = Debug|x64
{9CC48C6E-92EB-4814-AD37-97AB3622AB65}.Debug|x86.ActiveCfg = Debug|Win32
{9CC48C6E-92EB-4814-AD37-97AB3622AB65}.Debug|x86.Build.0 = Debug|Win32
{9CC48C6E-92EB-4814-AD37-97AB3622AB65}.Release|x64.ActiveCfg = Release|x64
{9CC48C6E-92EB-4814-AD37-97AB3622AB65}.Release|x64.Build.0 = Release|x64
{9CC48C6E-92EB-4814-AD37-97AB3622AB65}.Release|x86.ActiveCfg = Release|Win32
{9CC48C6E-92EB-4814-AD37-97AB3622AB65}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{FA49B617-D901-4E57-8DFB-7B6D620692FA}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>queuePThread</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)bin\</OutDir>
<IntDir>$(SolutionDir)obj\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)bin\</OutDir>
<IntDir>$(SolutionDir)obj\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\</OutDir>
<IntDir>$(SolutionDir)obj\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\</OutDir>
<IntDir>$(SolutionDir)obj\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>HAVE_STRUCT_TIMESPEC;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>.\include;.\pthreads-win32\Pre-built.2\include</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<FullProgramDatabaseFile>true</FullProgramDatabaseFile>
<AdditionalLibraryDirectories>.\pthreads-win32\Pre-built.2\lib\x86;.\lib\Win32_Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libfaac.lib;pthreadVC2.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>HAVE_STRUCT_TIMESPEC;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>.\include;.\pthreads-win32\Pre-built.2\include</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<FullProgramDatabaseFile>true</FullProgramDatabaseFile>
<AdditionalLibraryDirectories>.\pthreads-win32\Pre-built.2\lib\x64;.\lib\x64_Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libfaac.lib;pthreadVC2.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>HAVE_STRUCT_TIMESPEC;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>.\include;.\pthreads-win32\Pre-built.2\include</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<FullProgramDatabaseFile>false</FullProgramDatabaseFile>
<AdditionalLibraryDirectories>.\pthreads-win32\Pre-built.2\lib\x86;.\lib\Win32_Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libfaac.lib;pthreadVC2.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>HAVE_STRUCT_TIMESPEC;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>.\include;.\pthreads-win32\Pre-built.2\include</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<FullProgramDatabaseFile>false</FullProgramDatabaseFile>
<AdditionalLibraryDirectories>.\pthreads-win32\Pre-built.2\lib\x64;.\lib\x64_Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libfaac.lib;pthreadVC2.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="include\AacEnc.h" />
<ClInclude Include="include\AacEncListener.h" />
<ClInclude Include="include\AutoLock.h" />
<ClInclude Include="include\faac.h" />
<ClInclude Include="include\faaccfg.h" />
<ClInclude Include="include\PcmData.h" />
<ClInclude Include="include\PcmRecorder.h" />
<ClInclude Include="include\PThreadQueue.h" />
<ClInclude Include="include\QueueEventListener.h" />
<ClInclude Include="include\queue_ring.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="source\AacEnc.cpp" />
<ClCompile Include="source\AacEncListener.cpp" />
<ClCompile Include="source\AutoLock.cpp" />
<ClCompile Include="source\PcmData.cpp" />
<ClCompile Include="source\PcmRecorder.cpp" />
<ClCompile Include="source\PThreadQueue.cpp" />
<ClCompile Include="source\QueueEventListener.cpp" />
<ClCompile Include="source\queue_ring.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="source\AutoLock.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="source\PcmData.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="source\PcmRecorder.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="source\PThreadQueue.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="source\queue_ring.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="source\QueueEventListener.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="source\AacEnc.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="source\AacEncListener.cpp">
<Filter>source</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\AutoLock.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="include\PcmData.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="include\PcmRecorder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="include\PThreadQueue.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="include\queue_ring.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="include\QueueEventListener.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="include\faaccfg.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="include\faac.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="include\AacEncListener.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="include\AacEnc.h">
<Filter>include</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="source">
<UniqueIdentifier>{475b5cf2-199d-4e38-8943-b4f3bcd9d045}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="include">
<UniqueIdentifier>{ebbff8bd-2d80-4224-852e-bde2d9af131b}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
</ItemGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommandArguments>./bin/Faded.pcm</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>
\ No newline at end of file
#include "AacEnc.h"
#include <stdlib.h>
#include <memory.h>
#include <stdio.h>
#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
CAacEnc::CAacEnc(unsigned long nSampleRate = SAMPLE_RATE_DEF, unsigned long nChannels = 2, unsigned int nSampleBitCount = SAMPLE_BITS_DEF)
: m_IListener(NULL)
, m_nSampleRate(max(1, nSampleRate))
, m_nChannels(max(1, nChannels))
, m_nSampleBitCount(max(1, nSampleBitCount))
, m_nInputSamples(0)
, m_nMaxOutputBytes(0)
, m_pPcmInBuf(NULL)
, m_pAacOutBuf(NULL)
, m_phEnc(NULL)
, m_ppConfig(NULL)
, m_nPcmSamples(0)
{
m_strCopyRight[0] = '\0';
m_phEnc = new faacEncHandle;
m_ppConfig = new faacEncConfigurationPtr;
if (!m_phEnc || !m_ppConfig)
return;
*m_phEnc = NULL;
*m_ppConfig = NULL;
OpenEncoder(nSampleRate, nChannels, nSampleBitCount);
}
CAacEnc::~CAacEnc()
{
ReleaseAll();
}
void CAacEnc::ReleaseAll()
{
CloseEncoder();
if (m_phEnc) {
delete m_phEnc;
m_phEnc = NULL;
}
if (m_ppConfig) {
delete m_ppConfig;
m_ppConfig = NULL;
}
}
bool CAacEnc::OpenEncoder(unsigned long nSampleRate = SAMPLE_RATE_DEF, unsigned long nChannels = 2, unsigned int nSampleBitCount = SAMPLE_BITS_DEF)
{
bool bRet = false;
if (m_phEnc&& *m_phEnc)
return bRet;
m_nSampleRate= max(1, nSampleRate);
m_nChannels = max(1, nChannels);
m_nSampleBitCount = max(1, nSampleBitCount);
do {
// (1)Open FAAC engine
*m_phEnc = faacEncOpen(m_nSampleRate, m_nChannels, &m_nInputSamples, &m_nMaxOutputBytes);
if (!*m_phEnc)
break;
const int nPCMBufferSize = m_nInputSamples * m_nSampleBitCount / 8;
m_pPcmInBuf = new unsigned char[nPCMBufferSize];
if (!m_pPcmInBuf)
break;
m_pAacOutBuf = new unsigned char[m_nMaxOutputBytes];
if (!m_pAacOutBuf)
break;
// (2.1) Get current encoding configuration
*m_ppConfig = faacEncGetCurrentConfiguration(*m_phEnc);
if (!*m_ppConfig)
break;
//设置编码配置信息
/* PCM Sample Input Format
0 FAAC_INPUT_NULL invalid, signifies a misconfigured config
1 FAAC_INPUT_16BIT native endian 16bit
2 FAAC_INPUT_24BIT native endian 24bit in 24 bits (not implemented)
3 FAAC_INPUT_32BIT native endian 24bit in 32 bits (DEFAULT)
4 FAAC_INPUT_FLOAT 32bit floating point
*/
(*m_ppConfig)->inputFormat = FAAC_INPUT_16BIT;
// 0 = Raw; 1 = ADTS
(*m_ppConfig)->outputFormat = 1;
(*m_ppConfig)->aacObjectType = LOW; //设置AAC类型
// (*m_ppConfig)->useLfe = 0; //是否允许一个声道为低频通道
// (*m_ppConfig)->useTns = 1; //是否使用瞬时噪声定形滤波器(具体作用不是很清楚)
// (*m_ppConfig)->allowMidside = 0; //是否允许midSide coding (在MPEG-2 AAC 系统中,M/S(Mid/Side) Stereo coding被提供在多声道信号中,每个声道对(channel pair)的组合,也就是每个通道对,是对称地排列在人耳听觉的左右两边,其方式简单,且对位串不会引起较显著的负担。 一般其在左右声道数据相似度大时常被用到,并需记载每一频带的四种能量临界组合,分别为左、右、左右声道音频合并(L+R)及相减(L-R)的两种新的能量。一般,若所转换的Sid声道的能量较小时,M/S Stereo coding 可以节省此通道的位数,而将多余的位应用于另一个所转换的声道,即Mid 声道,进而可提高此编码效率。)
// (2.2) Set encoding configuration
(void)faacEncSetConfiguration(*m_phEnc, *m_ppConfig);
bRet = true;
} while (false);
if (!bRet) {
CloseEncoder();
}
return bRet;
}
void CAacEnc::CloseEncoder()
{
if (!m_phEnc|| !*m_phEnc)
return;
(void)Flush();
(void)faacEncClose(*m_phEnc);
*m_phEnc = NULL;
if (m_pPcmInBuf) {
delete[] m_pPcmInBuf;
m_pPcmInBuf = NULL;
}
if (m_pAacOutBuf) {
delete[] m_pAacOutBuf;
m_pAacOutBuf = NULL;
}
}
// 数据填入缓存,每2048字节送编码,不足2048的暂存于缓存与下次调用或Flush补上的静音数据一起编码。
bool CAacEnc::Encode(unsigned char* inPcmBuffer, unsigned long inPcmBytes/*=441*2*sizeof(short)*/)
{
bool bRet = false;
unsigned long inSamples= inPcmBytes / (m_nSampleBitCount / 8);//2B;
if (inSamples == 0)
return bRet;
unsigned long nAllSample = m_nPcmSamples + inSamples;
if (inSamples == 0 || !m_phEnc || !*m_phEnc)
return bRet;
unsigned long inRemain = inSamples;
int outBytesOfAacBuffer = 0;
bRet = true;
for (; nAllSample >= m_nInputSamples; nAllSample -= m_nInputSamples) {
unsigned long nCopy = min(inRemain, m_nInputSamples - m_nPcmSamples);
memcpy(m_pPcmInBuf + m_nPcmSamples * sizeof(short), inPcmBuffer + (inSamples - inRemain) * sizeof(short), nCopy * sizeof(short));
inRemain -= nCopy;
outBytesOfAacBuffer = faacEncEncode(*m_phEnc, (int*)m_pPcmInBuf, m_nInputSamples, m_pAacOutBuf, m_nMaxOutputBytes);
m_nPcmSamples = 0;
if (0 == outBytesOfAacBuffer) {
continue;
}else if(outBytesOfAacBuffer<0){
bRet = false;
break;
}else{//outBytesOfAacBuffer > 0
if (m_IListener) {
bRet = m_IListener->OnData(m_pAacOutBuf, outBytesOfAacBuffer);
if (!bRet)
break;
}
}
}
if (bRet&& inRemain != 0) {
memcpy(m_pPcmInBuf + m_nPcmSamples * sizeof(short), inPcmBuffer + (inSamples - inRemain) * sizeof(short), inRemain * sizeof(short));
m_nPcmSamples += inRemain;
}
return bRet;//多次编码输出后大于m_nMaxOutputBytes会溢出
}
//编码器起始是会缓存3-4个2048个样本,所以编码结束时用Flush取出尾部剩余的数据,直到返回值<=0才算完成
bool CAacEnc::Flush()
{
int outBytesOfAacBuffer;
if (0 != m_nPcmSamples) {//缓冲中还有不足2048的数据时,用静音包补满2048字节,完成本帧编码。
if (m_nPcmSamples > m_nInputSamples) {
m_nPcmSamples = 0;
return false;
}
//不补静音包,只送剩余数据,不足2048个采样的部分,编码器会自行补齐静音包:
outBytesOfAacBuffer = faacEncEncode(*m_phEnc, (int*)m_pPcmInBuf, m_nPcmSamples, m_pAacOutBuf, m_nMaxOutputBytes);
m_nPcmSamples = 0;
if (outBytesOfAacBuffer < 0) {
return false;
} else if(0==outBytesOfAacBuffer) {
return true;//返回true,不调用OnData()
}
} else {
//输入长度为零的数据,获取解码器的残余数据,直到返回<=0才算结束。
outBytesOfAacBuffer = faacEncEncode(*m_phEnc, NULL, 0, m_pAacOutBuf, m_nMaxOutputBytes);
if (outBytesOfAacBuffer <= 0)
return false;
}
if (m_IListener)
return m_IListener->OnData(m_pAacOutBuf, outBytesOfAacBuffer);
return true;
}
const char* CAacEnc::GetCopyRight()
{
char* verId = NULL;
char* copyRight = NULL;
(void)faacEncGetVersion(&verId, &copyRight);
sprintf(m_strCopyRight, "faac v%s\n%s\n", verId, copyRight);
return m_strCopyRight;
}
void CAacEnc::AddEventListener(IAacEncListener* IListener)
{
m_IListener = IListener;
}
#include "AacEncListener.h"
#include <io.h>
#include <string.h>
CAacEncListener::CAacEncListener(const char* strFile)
: m_fp(NULL)
{
if (strFile && 0 != strlen(strFile))
m_fp = fopen(strFile, "wb");//AAC file for output
}
CAacEncListener::~CAacEncListener()
{
if (m_fp) {
fclose(m_fp);
m_fp = NULL;
}
}
bool CAacEncListener::OnData(unsigned char * outAacBuffer, unsigned long outBufferBytes)
{
static long pkgId = 0;
++pkgId;
if (0 == outBufferBytes || !outAacBuffer) {
printf("%ld: error, 0 bytes\n", pkgId);
return true;
}
if (m_fp) {
(void)fwrite(outAacBuffer, 1, outBufferBytes, m_fp);
//printf("%ld: faac out %d\n", pkgId, outBufferBytes);
}
return true;
}
#include "AutoLock.h"
CAutoLock::CAutoLock(pthread_mutex_t& lock)
:m_lock(lock)
{
pthread_mutex_lock(&m_lock);
}
CAutoLock::~CAutoLock()
{
pthread_mutex_unlock(&m_lock);
}
#include "PThreadQueue.h"
CPThreadQueue::CPThreadQueue(const unsigned long iQueueMaxsize)
: m_pRingQueue(NULL)
, m_iStatus(STOPED)
, m_thProcessor({ 0 })
{
m_pRingQueue = new CRingQueue(iQueueMaxsize);
if (!pthread_create(&m_thProcessor, NULL, processor_thread, (void*)this)) {
//m_iStatus = RUNNING;
}
}
CPThreadQueue::~CPThreadQueue()
{
if (m_iStatus == RUNNING) {
m_iStatus = STOP;
pthread_join(m_thProcessor, NULL);
}
if (m_pRingQueue) {
delete m_pRingQueue;
m_pRingQueue = NULL;
}
}
void CPThreadQueue::AddListener(CQueueEventListener* listener)
{
m_listener = listener;
}
/** audio_data 音频dataBuf
* @audio_size buf字节数
* @bits_per_sample 单样本位数 16
* @sample_rate 采样率 48000/44100
* @number_of_channels 声道 2
* @number_of_frames 采样点数量 480/441
*/
bool CPThreadQueue::AddData(CQueueNode* p)//, int bits_per_sample, int sample_rate, long long number_of_channels, long long number_of_frames)
{
if (!m_pRingQueue)
return false;
return m_pRingQueue->enQueue(p);
}
void* CPThreadQueue::processor_thread(void* pParam)
{
CPThreadQueue* pThis = (CPThreadQueue*)pParam;
if (!pThis)
return NULL;
pThis->doProcessor();
return NULL;
}
void CPThreadQueue::doProcessor()
{
if (!m_pRingQueue)
return;
m_iStatus = RUNNING;
while (m_iStatus == RUNNING) {
CQueueNode* pNode = m_pRingQueue->deQueue();
if (pNode) {
if (m_listener)
m_listener->OnData(pNode);
delete pNode;
}
Sleep(0);
}
m_iStatus = STOPED;
pthread_exit(NULL);
}
\ No newline at end of file
#include "PcmData.h"
#include <stdlib.h>
#include <memory.h>
CPcmData::CPcmData(char* pData, unsigned long nBytes)
: audio_data(NULL)
, audio_size(0)
{
if (!pData || nBytes == 0)
return;
audio_data = new char[nBytes];
if (audio_data)
memcpy(audio_data, pData, nBytes);
audio_size = nBytes;
}
CPcmData::~CPcmData()
{
if (audio_data) {
delete[] audio_data;
//audio_data=NULL;
}
//audio_size=0;
}
#include "PcmRecorder.h"
CPcmRecorder::CPcmRecorder(const char* fileName, const int bits_per_sample = 16, const int sample_rate = 48000, const int number_of_channels = 2, const int number_of_frames = 480)
: m_fpOut(NULL)
, m_bitsPerSample(bits_per_sample)
, m_sampleRate(sample_rate)
, m_numberOfChannels(number_of_channels)
, m_numberOfFrames(number_of_frames)
, m_oAacEnc(sample_rate, number_of_channels, bits_per_sample)
, oListener(fileName)
{
QueryPerformanceFrequency(&nFreq);//ʼʱʱ
m_oAacEnc.AddEventListener(&oListener);
if (fileName) {
m_fpOut = fopen("./bin/pcm.pcm", "wb");
}
}
CPcmRecorder::~CPcmRecorder()
{
if (m_fpOut) {
fclose(m_fpOut);
m_fpOut = NULL;
}
}
//printf("read audio data %d bytes\n", nSamplesRead);
void CPcmRecorder::OnData(CQueueNode* pNode)
{
QueryPerformanceCounter(&nBeginTime);
if (!pNode || !pNode->m_pData || pNode->m_eType != CQueueNode::TYPE_AUDIO || pNode->m_iDataSize != sizeof(CPcmData))
return;
CPcmData* pAudioData = (CPcmData*)pNode->m_pData;
unsigned long number_of_bytes = pAudioData->audio_size;//assuming bits_per_sample is 16
if (!pAudioData->audio_data || number_of_bytes == 0)
return;
if (m_fpOut) {
(void)fwrite(pAudioData->audio_data, number_of_bytes, 1, m_fpOut);
}
m_oAacEnc.Encode((unsigned char*)pAudioData->audio_data, number_of_bytes);
QueryPerformanceCounter(&nEndTime);
double intervalTime = (double)(nEndTime.QuadPart - nBeginTime.QuadPart) / (double)nFreq.QuadPart;
printf_s("time now = %fms\n", intervalTime * 1000);
}
#include "QueueEventListener.h"
CQueueEventListener::CQueueEventListener()
{
}
CQueueEventListener::~CQueueEventListener()
{
}
void CQueueEventListener::OnData(CQueueNode * pNode)
{
}
#include "queue_ring.h"
#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
CQueueNode::CQueueNode(NODETYPE eType, void* pData, unsigned long nBytes)
: m_isClassData(false)
{
m_eType = eType;
m_pData = pData;
m_iDataSize = nBytes;
}
CQueueNode::~CQueueNode()
{
if (m_pData) {
if (m_isClassData)
delete[] m_pData;
else
delete m_pData;
}
}
CRingQueue::CRingQueue(const unsigned long iQueueMaxsize = 50000)
: m_iFront(0)//队首指针,即rp
, m_iRear(0)
, m_iQueueMaxsize(max(2, iQueueMaxsize))//队列长度最短2个
, m_qu(NULL)
{
memset(&m_lock, 0, sizeof(m_lock));
(void)pthread_mutex_init(&m_lock, NULL);
(void)initQueue();
}
CRingQueue::~CRingQueue()
{
freeQueue();
pthread_mutex_destroy(&m_lock);
}
//创建循环队列
bool CRingQueue::initQueue()
{
freeQueue();
m_qu = new CQueueNode*[m_iQueueMaxsize];
if (!m_qu)
return false;
memset(m_qu, 0, sizeof(m_qu[0])*m_iQueueMaxsize);//初始化环形队列的物理顺序数组
m_iRear = m_iFront = 0;//置为初始状态,满足队空条件。
return true;
}
void CRingQueue::freeQueue()
{
if (!m_qu)
return;
//{ //利用CAutoLock的生命周期,实现自旋锁:
CAutoLock al(m_lock);
for (unsigned int i = 0; i < m_iQueueMaxsize; ++i) {
if (m_qu[i]) {
delete m_qu[i];
//m_qu[i]=NULL;
}
}
delete[] m_qu;
m_qu = NULL;
//}//CAutoLock的生命周期到此结束,析构函数被调用,此后才可释放m_pLock。
}
//判队空
bool CRingQueue::isEmpty()
{
return m_iFront == m_iRear;
}
//判队满
bool CRingQueue::isFull()
{
return (m_iRear + 1) % m_iQueueMaxsize == m_iFront;
}
//带锁判队空
bool CRingQueue::isEmpty(CAutoLock** ppLock/*=NULL*/)
{
CAutoLock* p = new CAutoLock(m_lock);//获取自旋锁
if (!p)
return true;
bool bRet = isEmpty();
if (ppLock) {
*ppLock = p;
}
else {
delete p;
//p=NULL;
}
return bRet;
}
//带锁判队满
bool CRingQueue::isFull(CAutoLock** ppLock/*=NULL*/)
{
CAutoLock* p = new CAutoLock(m_lock);//获取自旋锁
if (!p)
return true;
bool bRet = isFull();
if (ppLock) {
*ppLock = p;
}
else {
delete p;
//p=NULL;
}
return bRet;
}
//元素进循环队列
bool CRingQueue::enQueue(CQueueNode* pNode)
{
CAutoLock* pLock = NULL;
bool bRet = !isFull(&pLock);
if (bRet) {
m_qu[m_iRear] = pNode;
m_iRear = (m_iRear + 1) % m_iQueueMaxsize;
//bRet = true;
}
if (pLock) {
delete pLock;
//pLock=NULL;
}
return bRet;
}
//元素出循环队列
CQueueNode* CRingQueue::deQueue()
{
CQueueNode* pNode = NULL;
CAutoLock* pLock = NULL;
if (!isEmpty(&pLock)) {
pNode = m_qu[m_iFront];
m_qu[m_iFront] = NULL;
m_iFront = (m_iFront + 1) % m_iQueueMaxsize;
}
if (pLock) {
delete pLock;
//pLock=NULL;
}
return pNode;
}
void CRingQueue::setQueueMax(unsigned long iMaxsize)
{
if (iMaxsize < 2)
iMaxsize = 2;
m_iQueueMaxsize = iMaxsize;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment