📄 wma.c
字号:
// *pulTime = ((pWMA->dwTimePos / pWMA->dwSampleRate) * 1000) + (((pWMA->dwTimePos % pWMA->dwSampleRate) * 1000) / pWMA->dwSampleRate); // // Success. // return(1); } // // Determine if the given file can be decoded. // case IOCTL_CODEC_QUERY: { tFile *pFile; unsigned char *pucScratch; // // The second parameter is the file to be checked. // pFile = (tFile *)ulParam2; // // The third parameter is a 512 byte scratch buffer. // pucScratch = (unsigned char *)ulParam3; // // See if this is an ASF file. // if(CodecIsASFFile(pFile, pucScratch) == 0) { // // This is not an ASF file, so we will not be able to decode // it. // return(0); } // // See if the security chunk is in the file. // if(CodecFindASFChunk(pFile, pucScratch, pucSecurityGUID) == -1) { // // This file is not protected by DRM, so we will be able to // decode it. // return(1); } // // This file is protectedby DRM, and we can not determine if we // will be able to decode it. So, just assume that we can not. // This really isn't correct... // return(0); } // // Prepare the codec to encode or decode a file. // case IOCTL_CODEC_OPEN: { tWMA *pWMA; tWMAFileLicParams sDeviceID; unsigned char ucID[32]; unsigned long ulIDLength; // // If we are being asked to encode a WMA file, then return a // failure since we can only decode WMA. // if(ulParam2 & CODEC_OPEN_ENCODE) { return(0); } // // The first parameter is a pointer to the WMA persistent state. // pWMA = (tWMA *)ulParam1; // // Make sure that we have enough memory for this decoder. // if((ulParam1 + sizeof(tWMA)) > ulExtentOfRAM) { return(0); } // // Clear the internal structure. // memset((void *)&pWMA->sWMAState, 0, sizeof(pWMA->sWMAState)); // // Save the pointer to the file structure. // pWMA->pFile = (tFile *)ulParam4; // // Indicate that there is no file data in the internal read buffer. // pWMA->dwOffset = 0; pWMA->dwLength = 0; // // Initialize the WMA decoder. // if(WMAFileDecodeInit(&pWMA->sWMAState) != cWMA_NoErr) { return(0); } // // Decode the file header. // if(WMAFileDecodeInfo(&pWMA->sWMAState, &pWMA->sWMAHeader) != cWMA_NoErr) { return(0); } // // If the file is protected by DRM, then we can not play it (at // this time). // if(pWMA->sWMAHeader.has_DRM) { // // If the license is not part of the file, then we can not // play the file. // if(pWMA->sWMAHeader.LicenseLength == 0) { return(0); } // // Get the unique media ID for the drive on which this file // resides. // ulIDLength = 32 * 8; if(FSGetMediaID(FSDriveNum(pWMA->pFile), ucID, &ulIDLength) == 0) { return(0); } // // The ID supplied to the Microsoft DRM must be a multiple of // 8 bits in length. // if(ulIDLength & 7) { return(0); } // // Supply the unique media ID to the DRM. // sDeviceID.pPMID = ucID; sDeviceID.cbPMID = ulIDLength / 8; // // Provide our device ID to the DRM library and if the license // does now allow the file to be played on this device then we // can not play the file. // if(WMAFileLicenseInit(&pWMA->sWMAState, &sDeviceID, CHECK_ALL_LICENSE) != cWMA_NoErr) { return(0); } } // // Get the file content description. // pWMA->sWMADesc.title_len = 128; pWMA->sWMADesc.author_len = 128; pWMA->sWMADesc.copyright_len = 0; pWMA->sWMADesc.description_len = 0; pWMA->sWMADesc.rating_len = 0; pWMA->sWMADesc.pTitle = (unsigned char *)pWMA->pusTitle; pWMA->sWMADesc.pAuthor = (unsigned char *)pWMA->pusAuthor; pWMA->pusTitle[0] = '\0'; pWMA->pusAuthor[0] = '\0'; if(WMAFileContentDesc(&pWMA->sWMAState, &pWMA->sWMADesc) != cWMA_NoErr) { pWMA->sWMADesc.title_len = 0; pWMA->sWMADesc.author_len = 0; } // // The initial time position is zero. // pWMA->dwTimePos = 0; // // Get the sample rate of the file. // switch(pWMA->sWMAHeader.sample_rate) { // // The sample rate is 22.05kHz. // case cWMA_SR_22_05kHz: { pWMA->dwSampleRate = 22050; break; } // // The sample rate is 32kHz. // case cWMA_SR_32kHz: { pWMA->dwSampleRate = 32000; break; } // // The sample rate is 44.1kHz. // case cWMA_SR_44_1kHz: { pWMA->dwSampleRate = 44100; break; } // // This file has an unknown sample rate. // default: { return(0); } } // // Initially, there is not any PCM data to be generated. // pWMA->bMorePCMToGenerate = 0; // // There is no output buffer. // pWMA->pOutput = 0; // // Success. // return(1); } // // Set the output buffer for the decoder. // case IOCTL_CODEC_SETBUFFER: { tWMA *pWMA; // // The first parameter is a pointer to the WMA persistent state. // pWMA = (tWMA *)ulParam1; // // The second parameter is a pointer to the output buffer. // pWMA->pOutput = (BufferState *)ulParam2; // // Provide the output buffer with our data buffers. // if(pWMA->sWMAHeader.num_channels == cWMA_C_Stereo) { BufferSetBuffer(pWMA->pOutput, pWMA->psLeft, pWMA->psRight, WMA_MAX_PCM_LENGTH); } else { BufferSetBuffer(pWMA->pOutput, pWMA->psLeft, pWMA->psLeft, WMA_MAX_PCM_LENGTH); } // // Success. // return(1); } // // Determine if the next frame of data can be decoded. // case IOCTL_CODEC_CAN_DECODE: { tWMA *pWMA; // // The first parameter is a pointer to the WMA persistent state // pWMA = (tWMA *)ulParam1; // // See if there is space available for decoding the next frame. // if(BufferSpaceAvailable(pWMA->pOutput) < 256) { // // There is not enough space available, so we can not decode // the next frame. // return(0); } // // We can decode the next frame. // return(1); } // // Decode a frame of data. // case IOCTL_CODEC_DECODE: { tWMA *pWMA; short *psLeft, *psRight; long lSamples; // // The first parameter is a pointer to the WMA persistent state // pWMA = (tWMA *)ulParam1; // // The loop will only return in case of an error or when it // generated an output. // while(1) { // // See if there is more PCM data to be generated. // if(!pWMA->bMorePCMToGenerate) { // // There is no more PCM data available, so decode the next // frame of the WMA file. // if(WMAFileDecodeData(&pWMA->sWMAState) != cWMA_NoErr) { // // Either there was a file error or we've reached the // end of the file. // return(0); } // // There should be more PCM to be generated. // pWMA->bMorePCMToGenerate = 1; } // // Wait until there is an adequate amount of space available // in the output buffer. // while(BufferSpaceAvailable(pWMA->pOutput) < 256) { // // Busy wait until space is available. // } // // Get a pointer to the output buffer // BufferGetWritePointer(pWMA->pOutput, &psLeft, &psRight, &lSamples); // // Generate PCM data into the output buffer. // lSamples = WMAFileGetPCM(&pWMA->sWMAState, psLeft, psRight, lSamples); // // See if we actually generated any samples. // if(lSamples > 0) { // // Advance the write pointer of the output buffer by the // number of samples we produced. // BufferUpdateWritePointer(pWMA->pOutput, lSamples); // // Increment the time position by the number of samples // we produced. // pWMA->dwTimePos += lSamples; // // Success // return(1); } else { // // There is no more PCM data, so indicate that we must // decode the next frame. // pWMA->bMorePCMToGenerate = 0; } } // // We should never get here, but just in case... // break; } // // Encode a frame of data. // case IOCTL_CODEC_CAN_ENCODE: case IOCTL_CODEC_ENCODE: { // // We don't support encode, so return an error. // return(0); } // /// Seek to the specified time position. // case IOCTL_CODEC_SEEK: { tWMA *pWMA; // // The first parameter is a pointer to the WMA persistent state // pWMA = (tWMA *)ulParam1; // // Seek to the specified position. // ulParam2 = WMAFileSeek(&pWMA->sWMAState, ulParam2); // // Set the time position correctly. // pWMA->dwTimePos = ((ulParam2 / 1000) * pWMA->dwSampleRate) + (((ulParam2 % 1000) * pWMA->dwSampleRate) / 1000); // // Success. // return(1); } // // Cleanup after the codec. // case IOCTL_CODEC_CLOSE: { // // There's nothing to do, so return success. // return(1); } // // We should never get here, but just in case... // default: { // // Return a failure. // return(0); } }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -