头文件 | 用途 |
---|---|
SBT_WAVFileReadWrite | Wave文件读写(附重采样转换) |
SBT_PCMAdvProcess | PCM数据操作:重采样转换、WAV数据大小计算(整个音频数据长度)、(跳下) |
SBT_PCMAdvProcess2 | SBT_AudioMIX_Param_ST,没用过,从解释感觉是通道增益 待更新 |
SBT_PCMBasicProcess | PCM数据操作:重采样、调节音量、声道分离、声道合并、降噪、采样率过滤、(跳下) |
SBT_PCMBasicProcess2 | 时间计算 |
SBT_MPEGBufferEncode | MPEG编码,视频和音频基带数据编码,只用过YUV、RGB基带数据视频编码其它未尝试待更新 |
SBT_MPGABufferDecode | MPGE(mpga)音频的解码,支持mp1/mp2/mp3解码(帧解码),对应SBT_MPABufferEncode |
SBT_CutlistV2 | 万能代码,把文件名给传给cutlist,让cutlist播,自己去取缓存 |
SBT_MediaDetect | 万能媒体文件读取,读取视音频文件信息,GetClipSampleIcon不知道何用待更新 |
SBT_MediaDetect2 | 同上,增加可读性的文件读取,测试代码见SBT_CutlistV2 |
SBT_WAVFileReadWrite
- writer是自带重采样的(采样率或通道转换)
- readerex才带有重采样功能
测试代码:++ 1234567891011121314151617181920212223242526272829303132333435363738BYTE* bybuffer = NULL;int len = 0;BOOL end;WAVEFORMATEX wavef, *pwave;Init_StanderWave(wavef);pwave = &wavef;SBT_WAVFileReaderEx read;read.Initialize();read.SetInputFile(_T("D:\\tebig.wav"));read.GetOutputWAVEFormat(&pwave);wavef.nChannels = pwave->nChannels;wavef.wBitsPerSample = pwave->wBitsPerSample;Calcute_Block_SamplesPer(wavef);read.SetOutputWAVEFormat(&wavef);read.SetPCMFrameSize(BY_BYTE, wavef.nAvgBytesPerSec/25);//read.EnableInternalBuffer();read.StartRead();SBT_WAVFileWriter wavwrite;int ar = wavwrite.Initialize();ar = wavwrite.SetOutputFile(_T("D:\\wwaw.wav"));ar = wavwrite.SetInputWAVEFormat(&wavef);ar = wavwrite.SetOutputWAVEFormat(&wavef);ar = wavwrite.StartWrite();while (1){read.ReadEx(BY_BYTE, wavef.nAvgBytesPerSec/25, &bybuffer, &len, &pwave, &end);//输出长度依旧不定长不知为何,BY_FRAME我没成功过if (end){break;}ar = wavwrite.SetInputBuffer(bybuffer, len);//这个函数很挑剔,SBT_PCMBasicProcess2的从采样数据输入就不行(不知为何)。}wavwrite.StopWrite();
SBT_PCMAdvProcess
SBT_PCMAdvProcess2
- 这个是通过名和void指针调用
SBT_PCMBasicProcess
SBT_PCMBasicProcess2
- CalResampleParam参数未知,待研究
- ReformatLPCM在按照帧做转换时会出现输出数据不定长(连续写入也有问题),ReformatLPCM2按帧转换输出长度比较正常,但是对WAVEFORMATEX要计算好。
测试代码:++ 123m_SBPcmProcess.ReformatLPCM2(*m_pSrcWave, m_pReadData, inlen, *m_pDstWave, &pOut1, &outlen1);
SBT_MPEGBufferEncode
测试代码:++ 12345678910111213141516171819
SBT_MPEGBufferEncode* m_pBufferEncode;DO(m_pBufferEncode->SetEncodeOperationMode(XH_MPEG_ESBUF_OUT)); XH_MPEG_ENCODE_PARAM paramIn;paramIn.GetDefaultParam(m_nVideoType == SD_TYPE ? XH_MPEG2_422PML : XH_MPEG2_422PHL);paramIn.chroma_format = 1;paramIn.group_I_frame_count = 1;paramIn.group_B_frame_count = 0;paramIn.group_P_frame_count = 0;DO(m_pBufferEncode->SetEncodeParam(¶mIn));DO(m_pBufferEncode->SetEncodeOutputCB(XH_VIDEO_OUTPUT_CB, EncodeOutCB, this));m_bitInfoHead.biCompression = BI_RGB;DO(m_pBufferEncode->SetVideoInputBufferFormat(&m_bitInfoHead));DO(m_pBufferEncode->StartEncode());DO(m_pBufferEncode->SetVideoInputBuffer(m_pBmpDataBuf, m_dwBmpSize));
|
|
SBT_MPGABufferDecode
测试代码:++ 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
//这是mp3解码测试,从MP3里一个个读取帧数据,再放入解码。//对pcm文件写入,要用SBT_WAVFileReadWrite。//自写的pcm文件写入老是有点问题,也没调试;代码不易,暂时放入记录以后修改。#define Calcute_Block_SamplesPer(outhead) outhead.nBlockAlign = (outhead.nChannels * outhead.wBitsPerSample) / 8;\outhead.nAvgBytesPerSec = outhead.nSamplesPerSec * outhead.nBlockAlign;#define Create_DstWave(outhead, inhead) \ outhead.wFormatTag = 1;\ outhead.nSamplesPerSec = 48000;\ outhead.nAvgBytesPerSec = 1152000;\ outhead.nChannels = 8;\ outhead.nBlockAlign = 24;\ outhead.wBitsPerSample = inhead.wBitsPerSample;\ Calcute_Block_SamplesPer(outhead);#define GetID3V2Size(header) (header.Size[0] & 0x7F)<< 21 | (header.Size[1] & 0x7F) << 14 | (header.Size[2] & 0x7F) << 7 | (header.Size[3] & 0x7F); #define BITRATEFREE 0xfffe#define BITRATEBAD 0xffff//// MP3FRAMEHEADER structure//struct MP3FRAMEHEADER //4byte//{// unsigned framesync :11; //同步信息// unsigned MPEGID : 2; //版本// unsigned layer : 2; //层// unsigned protectbit : 1; //CRC 校验// unsigned bitrateindx : 4; //位率// unsigned samplefreq : 2; //采样率// unsigned paddingbit : 1; //帧长调节// unsigned privatebit : 1; //保留字// unsigned channel : 2; //声道模式// unsigned modeext : 2; //扩充模型// unsigned copyright : 1; //Copyright// unsigned original : 1; //原版标志// unsigned emphasis : 2; //强调模式//};// MP3FRAMEHEADER structurestruct MP3FRAMEHEADER{ unsigned emphasis : 2; // M unsigned original : 1; // L unsigned copyright : 1; // K unsigned modeext : 2; // J unsigned channel : 2; // I unsigned privatebit : 1; // H unsigned paddingbit : 1; // G unsigned samplefreq : 2; // F unsigned bitrateindx : 4; // E unsigned protectbit : 1; // D unsigned layer : 2; // C unsigned MPEGID : 2; // B unsigned framesync : 11; // A};struct MP3ID3V2TAG //10byte{ char Header[3];//ID3 char Ver;//3 char Revision; char Flag; char Size[4];};// MP3ID3V1TAG structurestruct MP3ID3V1TAG//128byte{ char ident[3]; // TAG char title[30]; char artist[30]; char album[30]; char year[4]; char comment[28]; BYTE reserved; BYTE tracknum; BYTE genre;};int g_BitRates[] = { BITRATEFREE, BITRATEFREE, BITRATEFREE, BITRATEFREE, BITRATEFREE, 32, 32, 32, 32, 8, 64, 48, 40, 48, 16, 96, 56, 48, 56, 24, 128, 64, 56, 64, 32, 160, 80, 64, 80, 40, 192, 96, 80, 96, 48, 224, 112, 96, 112, 56, 256, 128, 112, 128, 64, 288, 160, 128, 144, 80, 320, 192, 160, 160, 96, 352, 224, 192, 176, 112, 384, 256, 224, 192, 128, 416, 320, 256, 224, 144, 448, 384, 320, 256, 160, BITRATEBAD, BITRATEBAD, BITRATEBAD, BITRATEBAD, BITRATEBAD};int g_SampleCountMap[4][4] = { 0, 0, 0, 0, 576, 0, 576, 1152, //l3 1152, 0, 1152, 1152, //l2 384, 0, 384, 384, //l1};int g_SampleRate[4][4] = { 11025, 0, 22050, 44100,//0 12000, 0, 24000, 48000,//1 8000, 0, 16000, 32000,//2 0, 0, 0, 0,};int GetBitRate(INT nlayer, INT nversion, int nbitindex){ if (nversion == 3) { return g_BitRates[nbitindex * 5 + (3 - nlayer)]; } else if (nversion == 2)// { if (nlayer == 3) return g_BitRates[nbitindex * 5 + 3]; else return g_BitRates[nbitindex * 5 + 4]; } return 0;}bool Is_Mp3FrameHead(const unsigned char * pHead) { if (pHead[0] == 0xff && (pHead[1] & 0xe0) == 0xe0) { if (((pHead[1] & 0x06) >> 1) == 0) return 0; /* no layer 4 */ if (((pHead[2] & 0xf0) >> 4) == 15) return 0; /* bitrate can't be 1111 */ if (((pHead[2] & 0x0c) >> 2) == 3) return 0; /* samplerate can't be 11 */ return 1; } return 0;}bool Is_Mp3V1Head(const unsigned char* pHead){ if (pHead[0] == 0x00 && pHead[1] == 0x00 && pHead[2] == 0x01 && pHead[3] == 0xba) { return 1; } return 0;}void ChangeEndian(void* pBuffer, int nBufSize){ if (!pBuffer || !nBufSize) return; char temp; for (int i = 0; i < nBufSize / 2; i++) { temp = ((char*)pBuffer)[i]; ((char*)pBuffer)[i] = ((char*)pBuffer)[nBufSize - i - 1]; ((char*)pBuffer)[nBufSize - i - 1] = temp; }}void writefilehead(WAVEFORMATEX& head, int sz, FILE* pwrite){ int bits = head.wBitsPerSample; char *data = (char*)"RIFF"; short short_temp; int long_temp; int fileSize; int size = sz; fileSize = size + 36; data = (char*)"RIFF"; fwrite(data, sizeof(char), 4, pwrite); fwrite(&fileSize, sizeof(int), 1, pwrite); data = (char*)"WAVE"; fwrite(data,sizeof(char),4,pwrite); data = (char*)"fmt "; fwrite(data,sizeof(char),4,pwrite); long_temp = 16; fwrite(&long_temp, sizeof(int), 1, pwrite); short_temp = 0x01; fwrite(&short_temp,sizeof(int),1,pwrite); short_temp = (head.nChannels); fwrite(&short_temp, sizeof(short), 1,pwrite); long_temp=(head.nSamplesPerSec); fwrite(&long_temp,sizeof(int),1,pwrite); long_temp=(bits/8)*(head.nChannels)*(head.nSamplesPerSec); fwrite(&long_temp,sizeof(int),1,pwrite); short_temp=(bits/8)*(head.nChannels); fwrite(&short_temp,sizeof(short),1,pwrite); short_temp=(bits); fwrite(&short_temp,sizeof(short),1,pwrite); data=(char*)"data"; fwrite(data,sizeof(char),4,pwrite); fwrite(&size,sizeof(int),1,pwrite); fseek(pwrite,44,SEEK_SET);}int CBmp2Video::ReadMP3(int lengh){ #define Release_And_Return() { fclose(m_pAudioInfo->pFile);\ delete m_pAudioInfo;\ m_pAudioInfo = NULL;\ return 0;}\ if (m_pAudioInfo->pFile == NULL) return 0; int nReadPos = 0; int v2headsz = 0; SBT_MPGABufferDecode decode; MP3FRAMEHEADER frameHead = {0}; MP3ID3V2TAG v2tag = {0}; int rd = fread_s(&v2tag, sizeof(MP3ID3V2TAG), sizeof(MP3ID3V2TAG), 1, m_pAudioInfo->pFile); if (rd < 1) Release_And_Return(); if (v2tag.Header[0] == 'I' &&// v2tag.Header[1] == 'D' && v2tag.Header[2] == '3') { if (v2tag.Ver != 3) Release_And_Return(); v2headsz = GetID3V2Size(v2tag); rd = fseek(m_pAudioInfo->pFile, v2headsz, SEEK_CUR); bool bfind = false; int nBlockPos = 0; BYTE headbuffer[10] = {0}; while (true)//部分MP3,会对标签到第一帧进行多余填充,此时长度无法定位第一帧,只能一个一个读取寻找 { if (bfind) break; rd = fread_s(&headbuffer, sizeof(headbuffer) * sizeof(BYTE), sizeof(headbuffer) * sizeof(BYTE), 1, m_pAudioInfo->pFile); for (int i = 0; i < 10; i++) { if (headbuffer[i] == 255) { bfind = true; break; } nBlockPos++; } } nReadPos = v2headsz + nBlockPos + 10; rd = fseek(m_pAudioInfo->pFile, nReadPos, SEEK_SET); } else//当没有标签头时 { rd = fseek(m_pAudioInfo->pFile, 0-sizeof(MP3ID3V2TAG), SEEK_CUR); nReadPos = 0; } if (rd == 0) { m_pAudioInfo->nDataType = MP3_TYPE; } SBT_MPGABufferDecode decode; FILE* writewave = NULL; int allsize = 0; int nsamplerate = 0; int outlen = 0; int nbitrate = 0; int nframebyte = 0; bool bhavehead = false; WAVEFORMATEX writeformat = {0}; MP3FRAMEHEADER frameHead = {0}; decode.Initialize(); decode.StartDecode(); fopen_s(&writewave, "www.wav", "wb"); rd = fread_s(&frameHead, sizeof(MP3FRAMEHEADER), sizeof(MP3FRAMEHEADER), 1, m_pAudioInfo->pFile); while (rd > 0) { if (rd < 1) return -1; else if (Is_Mp3FrameHead((const unsigned char*)&frameHead)) { fseek(m_pAudioInfo->pFile, 0-sizeof(MP3FRAMEHEADER), SEEK_CUR); ChangeEndian(&frameHead, 4); nsamplerate = g_SampleRate[frameHead.samplefreq][frameHead.MPEGID]; nbitrate = GetBitRate(frameHead.layer, frameHead.MPEGID, frameHead.bitrateindx); if (frameHead.layer == 3) nframebyte = (12000 * nbitrate / nsamplerate + frameHead.paddingbit) * 4; else nframebyte = 144000 * nbitrate / nsamplerate + frameHead.paddingbit; int noutDecodelen = 0; BYTE* poutDecodebuffer = NULL; BYTE* pReadbuffer = new BYTE[nframebyte]; rd = fread_s(pReadbuffer, nframebyte, nframebyte, 1, m_pAudioInfo->pFile); //解码 nReadPos += nframebyte; MPEG_AUDIO_FRAME_INFO mpginfo = {0}; decode.GetAudioFrameInfo(pReadbuffer, nframebyte, mpginfo); rd = decode.SetInputBuffer(pReadbuffer, nframebyte); rd = decode.GetOutputBufferFormat(&noutDecodelen, &writeformat); rd = decode.GetOutputBuffer(&poutDecodebuffer, &noutDecodelen); allsize += noutDecodelen; if (!bhavehead) { bhavehead = true; writefilehead(writeformat, noutDecodelen, writewave); } fwrite(poutDecodebuffer, noutDecodelen, 1, writewave); delete pReadbuffer; if (nReadPos >= lengh) { break; } } else if (Is_Mp3V1Head((const unsigned char*)&frameHead)) { return -1; } rd = fread_s(&frameHead, sizeof(MP3FRAMEHEADER), sizeof(MP3FRAMEHEADER), 1, m_pAudioInfo->pFile); } fseek(writewave, 40, SEEK_SET); fwrite(&allsize, 1, sizeof(int), writewave); allsize += 36; fseek(writewave, 4, SEEK_SET); fwrite(&allsize, 1, sizeof(int), writewave); fclose(writewave); return 0;}
|
|
SBT_CutlistV2
测试代码:++ 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
////////////////////////////////////////////////////////////////////////////////////int allsize = 0;*FILE* writewave = NULL;fopen_s(&writewave, "D:\\wwq.wav", "wb");*/SBT_WAVFileWriter wavewrite;SBT_MEDIA_INFO2 info2;SBT_MediaDetect2 detect2;detect2.SetInputFile(lpPath);detect2.GetMediaInfo2(&info2);WAVEFORMATEX outhead = info2.AudioInfo(0).stWavFormat;outhead.nSamplesPerSec = 48000;Calcute_Block_SamplesPer(outhead);AM_MEDIA_TYPE meditype = {0};meditype.majortype = MEDIATYPE_Audio;meditype.formattype = FORMAT_WaveFormatEx;meditype.cbFormat = sizeof(WAVEFORMATEX);meditype.pbFormat = new BYTE[meditype.cbFormat];memcpy_s(meditype.pbFormat, sizeof(WAVEFORMATEX), &outhead, sizeof(WAVEFORMATEX));ST_CUTLIST_ITEM* pItemList = new ST_CUTLIST_ITEM[1];int nFrameNum = (int)((info2.AudioInfo(0).llDuration*25/(1000*10*1000))+0.001);pItemList[0].llMediaOut = nFrameNum;pItemList[0].llTimelineIn = 0;pItemList[0].llTimelineOut = pItemList[0].llMediaOut;pItemList[0].bstrFileName = strPath;pItemList[0].dwFileFormatID = info2.FileFormatID();pItemList[0].dwMediaTypeID = info2.AudioInfo(0).nMediaID;pItemList[0].dwItemType = SBT_CUTLIST_ITEM_AUDIO;pItemList[0].dwReserved1 = pItemList[0].dwReserved2 = 0;//////////////////函数执行//////////////////设置参数wavewrite.Initialize();wavewrite.SetOutputFile(_T("D:\\qqw.wav"));wavewrite.SetInputWAVEFormat(&outhead);wavewrite.SetOutputWAVEFormat(&outhead);wavewrite.StartWrite();//writefilehead(outhead, 22, writewave);int rd = m_pSbCutList->Initialize(SBT_CUTLIST_ITEM_AUDIO);rd = m_pSbCutList->SetBufferingMode(TRUE);rd = m_pSbCutList->SetBufferPoolSize(25, 100);rd = m_pSbCutList->SetFPS(0L);rd = m_pSbCutList->SetOutputFormat(SBT_CUTLIST_ITEM_AUDIO, &meditype);rd = m_pSbCutList->SetItemList(pItemList, 1);rd = m_pSbCutList->SetStatus(SBT_CUTLIST_STATUS_PLAY);/////////////////////获取数据ST_CUTLISTV2_DECODE_OUT stDecout;ST_CUTLISTV2_DECODE_IN stDecIn;stDecIn.llTimelinePos = 0;stDecIn.pUserBuffer = NULL;stDecIn.pUserBuffer2 = NULL;stDecIn.nUserBufSize = 0;stDecIn.nUserBufStride = 0;stDecIn.dwMask = 0xFFFF;stDecIn.dwReserved = 0x00;stDecIn.dwParameter = 0x01;ErrorInfo errinfo;ST_CUTLIST_PROCESS_INFO proinfo;while ((rd = m_pSbCutList->GetOutputBuffer(&stDecIn, stDecout)) > 0){ rd = m_pSbCutList->GetCutlistProInfo(proinfo); rd = m_pSbCutList->GerLastErrorCodeInfo(errinfo); if (proinfo.nDecodedBufferNum == 0) break; if (stDecout.pDestBuffer == NULL) break; if (stDecIn.llTimelinePos == nFrameNum) break; stDecIn.llTimelinePos++; allsize += stDecout.nActualDataSize; wavewrite.SetInputBuffer(stDecout.pDestBuffer, stDecout.nActualDataSize); //fwrite(stDecout.pDestBuffer, stDecout.nActualDataSize, 1, writewave);}wavewrite.StopWrite();fseek(writewave, 40, SEEK_SET);fwrite(&allsize, 1, sizeof(int), writewave);allsize += 36;fseek(writewave, 4, SEEK_SET);fwrite(&allsize, 1, sizeof(int), writewave);fclose(writewave);delete meditype.pbFormat;//delete pItemList;////////////////////////////////////////////////////////////////////////////////////
|
|