📄 maipcmdec.c
字号:
2/3 - unknown (16 bits) 4 - emphasis (1 bit) 4 - mute (1 bit) 4 - reserved (1 bit) 4 - current frame (5 bits) 5 - quantization (2 bits) 5 - frequency (2 bits) 0 == 48 kHz, 1 == 96 kHz, 2 == 44100, 3 == 32000 5 - reserved (1 bit) 5 - number of channels - 1 (3 bits) 1 == 2 channels 6 - dynamic range control (8 bits) 0x80 == off */ pPInfo->ci.channels = (temp_str[5] & 7) + 1; switch ((temp_str[5] >> 4) & 3) { default: case 0: pPInfo->ci.sampling_rate = 48000; break; case 1: pPInfo->ci.sampling_rate = 96000; break; case 2: pPInfo->ci.sampling_rate = 44100; break; case 3: pPInfo->ci.sampling_rate = 32000; break; } if ((pPInfo->ci.channels > 8) || (pPInfo->ci.channels < 1)) pPInfo->ci.channels = 2; /* default */ pPInfo->ci.sampling_rate = check_rate(pPInfo->ci.sampling_rate); set_no_header_wav_decode(); pPInfo->m_bUncompressedPCM = UNCOMPRESSED_MPEG_LPCM; pAudioInfo->MediaTypeInfo.uiSize=sizeof(MAIMediaTypeAudio_t); pAudioInfo->MediaTypeInfo.eMType=MAI_MTYPE_AUDIO; pAudioInfo->MediaTypeInfo.eMSubtype=MAI_MSUBTYPE_PCM; pAudioInfo->MediaTypeInfo.uiFlags=0; pAudioInfo->uiFlags = 0; pAudioInfo->uiModeFlags = 0; //if ((pAudioInfo->uiBitsPerSample != 16) && (pAudioInfo->uiBitsPerSample != 8) && (pAudioInfo->uiBitsPerSample != 24)) pAudioInfo->uiBitsPerSample = 16; // default pPInfo->ci.bits_per_sample = pAudioInfo->uiBitsPerSample; pAudioInfo->uiMaxBufSize = MAX_PCM_OUTBUF_SIZE; pAudioInfo->uiChannels = pPInfo->ci.channels; pAudioInfo->uiSamplesPerSec = pPInfo->ci.sampling_rate; APIPRINTF((M_TEXT("PCMDEC: _processbuffer() NEWFORMAT: %d ch, %d rate, %d bits, %d bufsize\n"), pAudioInfo->uiChannels, pAudioInfo->uiSamplesPerSec, pAudioInfo->uiBitsPerSample, pAudioInfo->uiMaxBufSize)); wavheader.iSamplesPerSec = pAudioInfo->uiSamplesPerSec; wavheader.iBitsPerSample = pAudioInfo->uiBitsPerSample; wavheader.iChannels = pAudioInfo->uiChannels; wavheader.iBitrate = pAudioInfo->uiBitrate = pAudioInfo->uiBitsPerSample * pAudioInfo->uiSamplesPerSec * pAudioInfo->uiChannels; wavheader.iFramesize = pAudioInfo->uiFramesize = pInBufferInfo->uiDataSize - 7; wavheader.iDuration = pAudioInfo->uiDuration; wavheader.iEmphasis = pAudioInfo->uiEmphasis = 0; wavheader.iLayer = pAudioInfo->uiLayer = 1; BufferInfo.dwFlags = MAICOMPBUF_FLAG_NEWFORMAT|MAICOMPBUF_FLAG_AUDIO; BufferInfo.tTimeStamp = 0; BufferInfo.pBuffer = (unsigned char *)pAudioInfo; BufferInfo.uiBufSize = 0; BufferInfo.uiDataSize = sizeof(MAIMediaTypeAudio_t); #if DO_RATECONVERSION_AND_DOWNMIX setup_pcm_conversions(&pAudioInfo->uiChannels, &pAudioInfo->uiSamplesPerSec, pAudioInfo->uiMaxBufSize); #endif MAICompBase_OutputPutBuf(hComp, 0, &BufferInfo); pPInfo->m_bNewFormat = 0; } else // treat as raw PCM with our header { /* see if prescan already has the info that we need */ DPRINTF((M_TEXT("PCMDEC: treat as raw PCM with our header, pcm type %x, srate %d, channels %d\n"), pAudioInfo->uiLayer, pAudioInfo->uiSamplesPerSec, pAudioInfo->uiChannels));//printf("%x %x %x %x %x %x %x %x\n", temp_str[0], temp_str[1], temp_str[2], temp_str[3], temp_str[4], temp_str[5], temp_str[6], temp_str[7]); pPInfo->ci.channels = pAudioInfo->uiChannels; pPInfo->ci.sampling_rate = pAudioInfo->uiSamplesPerSec; set_no_header_wav_decode(); if ((pPInfo->ci.channels > 8) || (pPInfo->ci.channels < 1)) pPInfo->ci.channels = 2; // default pPInfo->ci.sampling_rate = check_rate(pPInfo->ci.sampling_rate); pPInfo->m_bUncompressedPCM = UNCOMPRESSED_PCM; pAudioInfo->MediaTypeInfo.uiSize=sizeof(MAIMediaTypeAudio_t); pAudioInfo->MediaTypeInfo.eMType=MAI_MTYPE_AUDIO; pAudioInfo->MediaTypeInfo.eMSubtype=MAI_MSUBTYPE_PCM; pAudioInfo->MediaTypeInfo.uiFlags=0; pAudioInfo->uiFlags = 0; pAudioInfo->uiModeFlags = 0; if ((pAudioInfo->uiBitsPerSample != 16) && (pAudioInfo->uiBitsPerSample != 8) && (pAudioInfo->uiBitsPerSample != 24)) pAudioInfo->uiBitsPerSample = 16; // defualt pPInfo->ci.bits_per_sample = pAudioInfo->uiBitsPerSample; pAudioInfo->uiMaxBufSize = MAX_PCM_OUTBUF_SIZE; pAudioInfo->uiChannels = pPInfo->ci.channels; pAudioInfo->uiSamplesPerSec = pPInfo->ci.sampling_rate; APIPRINTF((M_TEXT("PCMDEC: _processbuffer() NEWFORMAT: %d ch, %d rate, %d bits, %d bufsize\n"), pAudioInfo->uiChannels, pAudioInfo->uiSamplesPerSec, pAudioInfo->uiBitsPerSample, pAudioInfo->uiMaxBufSize)); wavheader.iSamplesPerSec = pAudioInfo->uiSamplesPerSec; wavheader.iBitsPerSample = pAudioInfo->uiBitsPerSample; wavheader.iChannels = pAudioInfo->uiChannels; wavheader.iBitrate = pAudioInfo->uiBitrate; wavheader.iFramesize = pAudioInfo->uiFramesize; wavheader.iDuration = pAudioInfo->uiDuration; wavheader.iEmphasis = pAudioInfo->uiEmphasis; wavheader.iLayer = pAudioInfo->uiLayer; BufferInfo.dwFlags = MAICOMPBUF_FLAG_NEWFORMAT|MAICOMPBUF_FLAG_AUDIO; BufferInfo.tTimeStamp = 0; BufferInfo.pBuffer = (unsigned char *)pAudioInfo; BufferInfo.uiBufSize = 0; BufferInfo.uiDataSize = sizeof(MAIMediaTypeAudio_t); if ((pAudioInfo->uiLayer == WAVE_FORMAT_MULAW) || (pAudioInfo->uiLayer == WAVE_FORMAT_ALAW)) { wavheader.iLayer = pAudioInfo->uiLayer; pPInfo->m_bUncompressedPCM = UNCOMPRESSED_NONE; /* Since it decompresses to 16 bits, tell the renderer. */ wavheader.iBitsPerSample = pAudioInfo->uiBitsPerSample = 16; APIPRINTF((M_TEXT("PCMDEC: _processbuffer() PCM ULAW\n"))); } else if ((pAudioInfo->uiLayer == 0xffff) || (pAudioInfo->uiLayer == 0)) wavheader.iLayer = WAVE_FORMAT_PCM; #if DO_RATECONVERSION_AND_DOWNMIX setup_pcm_conversions(&pAudioInfo->uiChannels, &pAudioInfo->uiSamplesPerSec, pAudioInfo->uiMaxBufSize); #endif MAICompBase_OutputPutBuf(hComp, 0, &BufferInfo); pPInfo->m_bNewFormat = 0; APIPRINTF((M_TEXT("PCMDEC: _processbuffer() end (special init) layer %x %x\n"), pAudioInfo->uiLayer, pPInfo->m_bUncompressedPCM)); return MAI_STATUS_OK; // This input buffer will only have rates, channels, flags, etc., no data. } } if ((uiBufFlags&MAICOMPBUF_FLAG_EOS)!=0) { APIPRINTF((M_TEXT("PCMDEC EOS flag found. Shortening buf_pad\n"))); buf_pad = 16; /* Try to play the end of the file. */ last_frame = 1; } if (pPInfo->m_bUncompressedPCM == UNCOMPRESSED_MPEG_LPCM) /* there is a header on each buffer */ { BufferInfo.dwFlags = 0; if (pInBufferInfo && (uiBufFlags&MAICOMPBUF_FLAG_PTS)!=0) /* input buffer was timestamped */ { MAITIME_ASSIGN(BufferInfo.tTimeStamp, pInBufferInfo->tTimeStamp); MAICompBase_UpdateTime(hComp, 0, BufferInfo.tTimeStamp); DPRINTF((M_TEXT("PCMDEC: _processbuffer() pass PTS=%u\n"), (unsigned int)(BufferInfo.tTimeStamp))); BufferInfo.dwFlags |= MAICOMPBUF_FLAG_PTS; MAICompBase_ReportTime(hComp, 0); uiBufFlags&=~MAICOMPBUF_FLAG_PTS; /* clear PTS flag, report only once for this buffer */ } if ((uiBufFlags&MAICOMPBUF_FLAG_DATADISCON)!=0) /* check for discontinuity */ { APIPRINTF((M_TEXT("PCMDEC: _processbuffer() pass DATADISCON\n"))); BufferInfo.dwFlags |= MAICOMPBUF_FLAG_DATADISCON; uiBufFlags&=~MAICOMPBUF_FLAG_DATADISCON; /* clear DATADISCON flag, report only once for this buffer */ } if ((uiBufFlags&MAICOMPBUF_FLAG_EOS)!=0) /* last buffer to output, check for EOS */ { APIPRINTF((M_TEXT("PCMDEC: _processbuffer() pass EOS\n"))); BufferInfo.dwFlags|=MAICOMPBUF_FLAG_EOS; uiBufFlags&=~MAICOMPBUF_FLAG_EOS; /* clear EOS flag, report only once for this buffer */ } BufferInfo.pBuffer = pInBufferInfo->pBuffer + 7; BufferInfo.uiDataSize = pInBufferInfo->uiDataSize - 7; if (pInBufferInfo->pBuffer[6] != 0x80) {// unsigned char *inbuf = pInBufferInfo->pBuffer;//printf("MPEG LPCM missing header\n");//printf("%4x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n", pInBufferInfo->uiDataSize, inbuf[0], inbuf[1], inbuf[2], inbuf[3], inbuf[4], inbuf[5], inbuf[6], inbuf[7], inbuf[8], inbuf[9], inbuf[10], inbuf[11], inbuf[12], inbuf[13], inbuf[14], inbuf[15], inbuf[16], inbuf[17], inbuf[18], inbuf[19], inbuf[20], inbuf[21], inbuf[22], inbuf[23], inbuf[24], inbuf[25], inbuf[26], inbuf[27], inbuf[28], inbuf[29], inbuf[30]); } else if (BufferInfo.uiDataSize > MAX_PCM_OUTBUF_SIZE) {printf("ERROR MPEG LPCM Buffer too big %x\n", BufferInfo.uiDataSize); } else { /* Note that LPCM is BIG Endian */ flip_byte_order((unsigned short *)BufferInfo.pBuffer, BufferInfo.uiDataSize); MAICompBase_OutputPutBuf(hComp, 0, &BufferInfo); } pPInfo->m_uiProcessLoops++; return 0; } if (pPInfo->m_LeftOverInput > 0) { if (pPInfo->m_uiMaxInBufferSize < pInBufferInfo->uiDataSize) { if (pPInfo->m_pucAudioInBuf != NULL) free(pPInfo->m_pucAudioInBuf); pPInfo->m_pucAudioInBuf = NULL; } if (pPInfo->m_pucAudioInBuf == NULL) { pPInfo->m_uiMaxInBufferSize = pInBufferInfo->uiBufSize; pPInfo->m_pucAudioInBuf = (unsigned char *)malloc(pPInfo->m_uiMaxInBufferSize + PCM_BUF_PAD); if (pPInfo->m_pucAudioInBuf == NULL) return MAI_STATUS_MEMORY; } memcpy(pPInfo->m_pucAudioInBuf, pPInfo->m_pucLeftOver, pPInfo->m_LeftOverInput); if (pPInfo->m_bUncompressedPCM == UNCOMPRESSED_MPEG_LPCM) /* there is a header on each buffer */ { memcpy(pPInfo->m_pucAudioInBuf + pPInfo->m_LeftOverInput, inbuf + 7, pInBufferInfo->uiDataSize - 7); insize = pInBufferInfo->uiDataSize - 7 + pPInfo->m_LeftOverInput; } else { memcpy(pPInfo->m_pucAudioInBuf + pPInfo->m_LeftOverInput, inbuf, pInBufferInfo->uiDataSize); insize = pInBufferInfo->uiDataSize + pPInfo->m_LeftOverInput; } inbuf_ptr = pPInfo->m_pucAudioInBuf; } else { if (pPInfo->m_bUncompressedPCM == UNCOMPRESSED_MPEG_LPCM) /* there is a header on each buffer */ { inbuf_ptr = inbuf + 7; insize = pInBufferInfo->uiDataSize - 7; } else inbuf_ptr = inbuf; } while (insize >= buf_pad) { int out_size; int len; if (pPInfo->m_bUncompressedPCM == UNCOMPRESSED_MPEG_LPCM) len = decode_pcm_audio(&pPInfo->ci, pPInfo->m_pAudioOutBuf, &out_size, inbuf_ptr, insize, pPInfo->ci.bits_per_sample>>3 /* size in bytes */, 1);// else if (pPInfo->m_bUncompressedPCM == UNCOMPRESSED_PCM)// len = decode_pcm_audio(&pPInfo->ci, pPInfo->m_pAudioOutBuf, &out_size, inbuf_ptr, insize, pPInfo->ci.bits_per_sample>>3 /* size in bytes */, 0); else len = decode_wav_audio(&pPInfo->ci, pPInfo->m_pAudioOutBuf, &out_size, inbuf_ptr, insize); if (len < 0) { ERRORPRINTF((M_TEXT("Error while decoding length %d."), len)); return MAI_STATUS_ERROR; } if (out_size > 0) { if (pPInfo->m_uiPrevSRate != (unsigned int)pPInfo->ci.sampling_rate) { pPInfo->m_uiPrevSRate = pPInfo->ci.sampling_rate; pPInfo->m_bNewFormat = 1; } if (pPInfo->m_nPrevChannels != (unsigned int)pPInfo->ci.channels) { pPInfo->m_nPrevChannels = (unsigned int)pPInfo->ci.channels; pPInfo->m_bNewFormat = 1; } if (pPInfo->m_bNewFormat) { MAIMediaTypeAudio_t AudioInfo; MAIMediaTypeAudio_t *pAudioInfo=&AudioInfo; pPInfo->m_bNewFormat = 0; memset(pAudioInfo, 0, sizeof(MAIMediaTypeAudio_t)); pAudioInfo->MediaTypeInfo.uiSize=sizeof(MAIMediaTypeAudio_t); pAudioInfo->MediaTypeInfo.eMType=MAI_MTYPE_AUDIO; pAudioInfo->MediaTypeInfo.eMSubtype=MAI_MSUBTYPE_PCM; pAudioInfo->MediaTypeInfo.uiFlags=0; pAudioInfo->uiFlags = 0; pAudioInfo->uiModeFlags = 0; pAudioInfo->uiBitsPerSample = 16; pPInfo->ci.bits_per_sample = pAudioInfo->uiBitsPerSample; pAudioInfo->uiMaxBufSize = MAX_PCM_OUTBUF_SIZE; pAudioInfo->uiChannels = pPInfo->ci.channels; pAudioInfo->uiSamplesPerSec = pPInfo->ci.sampling_rate; APIPRINTF((M_TEXT("PCMDEC: _processbuffer() NEWFORMAT: %d ch, %d rate, %d bits, %d bufsize\n"), pAudioInfo->uiChannels, pAudioInfo->uiSamplesPerSec, pAudioInfo->uiBitsPerSample, pAudioInfo->uiMaxBufSize)); BufferInfo.dwFlags = MAICOMPBUF_FLAG_NEWFORMAT|MAICOMPBUF_FLAG_AUDIO; BufferInfo.tTimeStamp = 0; BufferInfo.pBuffer = (unsigned char *)pAudioInfo; BufferInfo.uiBufSize = 0; BufferInfo.uiDataSize = sizeof(MAIMediaTypeAudio_t); #if DO_RATECONVERSION_AND_DOWNMIX setup_pcm_conversions(&pAudioInfo->uiChannels, &pAudioInfo->uiSamplesPerSec, pAudioInfo->uiMaxBufSize); #endif MAICompBase_OutputPutBuf(hComp, 0, &BufferInfo); } if (out_size > 0) { /* if a frame has been decoded, output it */ DUMPAUDIO(pPInfo->m_pAudioOutBuf, out_size); DPRINTF((M_TEXT("PCMDEC: _processbuffer() OutputPutBuf(%d)\n"), out_size)); BufferInfo.dwFlags = 0; /* default - no special flags */ BufferInfo.tTimeStamp = 0; if (pInBufferInfo && (uiBufFlags&MAICOMPBUF_FLAG_PTS)!=0) /* input buffer was timestamped */ { MAITIME_ASSIGN(BufferInfo.tTimeStamp, pInBufferInfo->tTimeStamp); MAICompBase_UpdateTime(hComp, 0, BufferInfo.tTimeStamp); DPRINTF((M_TEXT("PCMDEC: _processbuffer() pass PTS=%u\n"), (unsigned int)(BufferInfo.tTimeStamp))); BufferInfo.dwFlags |= MAICOMPBUF_FLAG_PTS; MAICompBase_ReportTime(hComp, 0); uiBufFlags&=~MAICOMPBUF_FLAG_PTS; /* clear PTS flag, report only once for this buffer */ } if ((uiBufFlags&MAICOMPBUF_FLAG_DATADISCON)!=0) /* check for discontinuity */ { APIPRINTF((M_TEXT("PCMDEC: _processbuffer() pass DATADISCON\n"))); BufferInfo.dwFlags |= MAICOMPBUF_FLAG_DATADISCON; uiBufFlags&=~MAICOMPBUF_FLAG_DATADISCON; /* clear DATADISCON flag, report only once for this buffer */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -