📄 msadpcm.c
字号:
// Return the name of the song // case IOCTL_CODEC_GETTITLE: { unsigned short **ppusName; // // The second parameter is a pointer for the name. // ppusName = (unsigned short **)ulParam2; // // There is no way to store the song title in a MS ADPCM file. // *ppusName = 0; // // Success. // return(1); } // // Return the bitrate at which this file is encoded. // case IOCTL_CODEC_GETBITRATE: { unsigned long *pulBitRate; tMSADPCM *pMSADPCM; // // The first parameter is a pointer to the MS ADPCM persistent // data. // pMSADPCM = (tMSADPCM *)ulParam1; // // The second parameter is a pointer for the bitrate. // pulBitRate = (unsigned long *)ulParam2; // // Return the bitrate of the file. // *pulBitRate = pMSADPCM->ulBitRate; // // Success. // return(1); } // // Return the sample rate at which this file is encoded. // case IOCTL_CODEC_GETSAMPLERATE: { unsigned long *pulSampleRate; tMSADPCM *pMSADPCM; // // The first parameter is a pointer to the MS ADPCM persistent // data. // pMSADPCM = (tMSADPCM *)ulParam1; // // The second parameter is a pointer for the sample rate. // pulSampleRate = (unsigned long *)ulParam2; // // Return the sample rate of the file. // *pulSampleRate = pMSADPCM->usSampleRate; // // Success. // return(1); } // // Return the number of channels in the file. // case IOCTL_CODEC_GETCHANNELS: { unsigned long *pulChannels; tMSADPCM *pMSADPCM; // // The first parameter is a pointer to the MS ADPCM persistent // data. // pMSADPCM = (tMSADPCM *)ulParam1; // // The second parameter is a pointer for the number of channels. // pulChannels = (unsigned long *)ulParam2; // // Return the number of channels in the file. // *pulChannels = pMSADPCM->ucChannels; // // Success. // return(1); } // // Return the length (in milliseconds) of the file. // case IOCTL_CODEC_GETLENGTH: { unsigned long *pulLength; tMSADPCM *pMSADPCM; // // The first parameter is a pointer to the MS ADPCM persistent // data. // pMSADPCM = (tMSADPCM *)ulParam1; // // The second parameter is a pointer for the number of // milliseconds. // pulLength = (unsigned long *)ulParam2; // // Return the length of the file. // *pulLength = pMSADPCM->ulTimeLength; // // Success. // return(1); } // // Return the current position (in milliseconds) within the file. // case IOCTL_CODEC_GETTIME: { unsigned long *pulTime; tMSADPCM *pMSADPCM; // // The first parameter is a pointer to the MS ADPCM persistent // data. // pMSADPCM = (tMSADPCM *)ulParam1; // // The second parameter is a pointer for the number of seconds. // pulTime = (unsigned long *)ulParam2; // // Determine the time based on the sample rate. // *pulTime = ((pMSADPCM->ulTimePos / pMSADPCM->usSampleRate) * 1000) + (((pMSADPCM->ulTimePos % pMSADPCM->usSampleRate) * 1000) / pMSADPCM->usSampleRate); // // Success. // return(1); } // // Determine if the given file can be decoded. // case IOCTL_CODEC_QUERY: { tFile *pFile; unsigned char *pucScratch; unsigned long ulValid, ulOffset, ulLength; ADPCMWaveFormat sWaveFormat; // // 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; // // Read the first 512 bytes of the file. // ulValid = FSRead(pFile, pucScratch, 512); // // Make sure that this is a RIFF WAVE file. // if((ulValid < 12) || (pucScratch[0] != 'R') || (pucScratch[1] != 'I') || (pucScratch[2] != 'F') || (pucScratch[3] != 'F') || (pucScratch[8] != 'W') || (pucScratch[9] != 'A') || (pucScratch[10] != 'V') || (pucScratch[11] != 'E')) { return(0); } // // Find the "fmt " chunk. // ulOffset = CodecFindRIFFChunk(pucScratch, 512, 12, "fmt "); if(ulOffset == -1) { return(0); } // // Make sure that there is enough data in the data buffer. // if((ulOffset + 8) > ulValid) { // // We could not find the "fmt " chunk in the first 512 bytes of // the file, so we can not decode this file. // return(0); } // // Get the length of the "fmt " chunk. // ulLength = ((pucScratch[ulOffset + 7] << 24) | (pucScratch[ulOffset + 6] << 16) | (pucScratch[ulOffset + 5] << 8) | pucScratch[ulOffset + 4]); // // If the length of the "fmt " chunk is not the same as the size of // the MS ADPCM wave format sturcture, then we can not decode this // file. // if(ulLength != sizeof(ADPCMWaveFormat)) { return(0); } // // Make sure that the entire "fmt " chunk is in the data buffer. // if((ulOffset + ulLength + 8) > ulValid) { // // We could not find the entire "fmt " chunk in the first 512 // bytes of the file, so we can not decode this file. // return(0); } // // Copy the wave format structure from the "fmt " chunk into a // local. We do this instead of grabbing the values directly from // the data buffer since the "fmt " chunk can occur with any // alignment, making it a lot easier to simply copy the structure. // memcpy((void *)&sWaveFormat, pucScratch + ulOffset + 8, sizeof(ADPCMWaveFormat)); // // Perform some sanity checks on the wave format structure. // if((sWaveFormat.wFormatTag != 2) || (sWaveFormat.nChannels > 2) || (sWaveFormat.nSamplesPerSec > 48000) || (sWaveFormat.nBlockAlign > 4096) || (sWaveFormat.wBitsPerSample != 4) || (sWaveFormat.cbSize != 32) || (sWaveFormat.wSamplesPerBlock > MSADPCM_MAX_PCM_LENGTH) || (sWaveFormat.wNumCoef != 7)) { // // The wave format does not pass the sanity checks, so we can // not decode this file. // return(0); } // // Make sure that the coefficients match the MS ADPCM coefficients. // for(ulLength = 0; ulLength < 7; ulLength++) { if((sWaveFormat.aCoef[ulLength].iCoef1 != psCoefficient1[ulLength]) || (sWaveFormat.aCoef[ulLength].iCoef2 != psCoefficient2[ulLength])) { // // The coefficients do not match the MS ADPCM coefficients, // so we can not decode this file. // return(0); } } // // We can decode this file. // return(1); } // // Prepare the codec to encode or decode a file. // case IOCTL_CODEC_OPEN: { tMSADPCM *pMSADPCM; // // The first parameter is a pointer to the MS ADPCM persistent // state. // pMSADPCM = (tMSADPCM *)ulParam1; // // Make sure that we have enough memory for this decoder. // if(((unsigned long)pMSADPCM + sizeof(tMSADPCM)) > ulExtentOfRAM) { return(0); } // // Save the pointer to the file structure. // pMSADPCM->pFile = (tFile *)ulParam4; // // See if we are encoding or decoding a file. // if(ulParam3 & CODEC_OPEN_ENCODE) { // // Setup the encoder. // return(MSADPCMSetupEncoder(pMSADPCM)); } else { // // Setup the decoder. // return(MSADPCMSetupDecoder(pMSADPCM)); } } // // Get the capture buffer for the encoder. // case IOCTL_CODEC_GETCAPTUREBUFFER: { tMSADPCM *pMSADPCM; short **ppsBuffer; long *plLength; // // The first parameter is a pointer to the MS ADPCM persistent // state. // pMSADPCM = (tMSADPCM *)ulParam1; // // The second parameter is a pointer to the capture buffer. // ppsBuffer = (short **)ulParam2; // // The third parameter is a pointer to the length of the capture // buffer. // plLength = (long *)ulParam3; // // Return the capture buffer. // *ppsBuffer = pMSADPCM->psRight; *plLength = MSADPCM_MAX_PCM_LENGTH * 2; // // Success. // return(1); } // // Set the output buffer for the decoder. // case IOCTL_CODEC_SETBUFFER: { tMSADPCM *pMSADPCM; // // The first parameter is a pointer to the MS ADPCM persistent // state. // pMSADPCM = (tMSADPCM *)ulParam1; // // The second parameter is a pointer to the buffer object. // pMSADPCM->pBuffer = (BufferState *)ulParam2; // // Provide the buffer object with our data buffers. // if(pMSADPCM->ucChannels == 2) { BufferSetBuffer(pMSADPCM->pBuffer, pMSADPCM->psLeft, pMSADPCM->psRight, pMSADPCM->usSamplesPerBlock + pMSADPCM->usSamplesPerBlock);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -