📄 msadpcm.c
字号:
} else { BufferSetBuffer(pMSADPCM->pBuffer, pMSADPCM->psLeft, pMSADPCM->psLeft, pMSADPCM->usSamplesPerBlock + pMSADPCM->usSamplesPerBlock); } // // Success. // return(1); } // // Determine if the next frame of data can be decoded. // case IOCTL_CODEC_CAN_DECODE: { tMSADPCM *pMSADPCM; // // The first parameter is a pointer to the MS ADPCM persistent // state. // pMSADPCM = (tMSADPCM *)ulParam1; // // See if there is space available for decoding the next frame. // if(BufferSpaceAvailable(pMSADPCM->pBuffer) < pMSADPCM->usSamplesPerBlock) { // // 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: { tMSADPCM *pMSADPCM; short *psLeft, *psRight; long lLength, lBlockSize; // // The first parameter is a pointer to the MS ADPCM persistent // state. // pMSADPCM = (tMSADPCM *)ulParam1; // // Compute the size of the next encoded MS ADPCM block. // if((pMSADPCM->usValid - pMSADPCM->usOffset) > pMSADPCM->usBytesPerBlock) { // // There is a full block in the buffer. // lBlockSize = pMSADPCM->usBytesPerBlock; } else { // // There is a partial block in the buffer, which contains the // end of the file. // lBlockSize = pMSADPCM->usValid - pMSADPCM->usOffset; } // // Wait until there is space in the output buffer. This tells us // when it is OK to write more data into the output buffer. // while(BufferSpaceAvailable(pMSADPCM->pBuffer) < pMSADPCM->usSamplesPerBlock) { // // Busy wait until space is available. // } // // Get a pointer to the available space in the output buffer. // BufferGetWritePointer(pMSADPCM->pBuffer, &psLeft, &psRight, &lLength); // // Decode the next block. // if(adpcmDecode4Bit(pMSADPCM, pMSADPCM->pucEncodedData + pMSADPCM->usOffset, psLeft, psRight, lBlockSize) == 0) { // // We could not decode the block, so return an error. // return(0); } // // Update the output buffer's write pointer. // BufferUpdateWritePointer(pMSADPCM->pBuffer, pMSADPCM->usSamplesPerBlock); // // Increment the encoded data buffer pointer. // pMSADPCM->usOffset += lBlockSize; // // Increment the time based on the number of samples. // pMSADPCM->ulTimePos += pMSADPCM->usSamplesPerBlock; // // See if there is enough data in the encoded data buffer. // if(((pMSADPCM->usOffset + pMSADPCM->usBytesPerBlock) > pMSADPCM->usValid) && (pMSADPCM->usValid < pMSADPCM->ulDataValid)) { // // Copy the tail of the buffer to the beginning. // memcpy(pMSADPCM->pucEncodedData, pMSADPCM->pucEncodedData + (pMSADPCM->usOffset & ~3), pMSADPCM->usValid - (pMSADPCM->usOffset & ~3)); // // Update the number of valid bytes in the buffer. // pMSADPCM->usValid -= (pMSADPCM->usOffset & ~3); // // Update the number of valid byte remaining in the file. // pMSADPCM->ulDataValid -= (pMSADPCM->usOffset & ~3); // // Read more data into the buffer. // pMSADPCM->usValid += FSRead(pMSADPCM->pFile, pMSADPCM->pucEncodedData + pMSADPCM->usValid, (4096 - pMSADPCM->usValid) & ~511); // // Make sure that the number of valid byte in the buffer does // not exceed the number of valid bytes in the "data" chunk. // if(pMSADPCM->usValid > pMSADPCM->ulDataValid) { pMSADPCM->usValid = pMSADPCM->ulDataValid; } // // Set the current offset to the beginning of the buffer. // pMSADPCM->usOffset &= 3; } // // Success. // return(1); } // // Determine if the next frame of data can be encoded. // case IOCTL_CODEC_CAN_ENCODE: { tMSADPCM *pMSADPCM; // // The first parameter is a pointer to the MS ADPCM persistent // state. // pMSADPCM = (tMSADPCM *)ulParam1; // // See if there is enough data in the input buffer. // if(BufferDataAvailable(pMSADPCM->pBuffer) < pMSADPCM->usSamplesPerBlock) { // // There is not enough data available, so we can not encode the // next frame. // return(0); } // // We can encode the next frame. // return(1); } // // Encode a frame of data. // case IOCTL_CODEC_ENCODE: { tMSADPCM *pMSADPCM; short *psLeft, *psRight; long lLength; // // The first parameter is a pointer to the MS ADPCM persistent // state. // pMSADPCM = (tMSADPCM *)ulParam1; // // Wait until there is enough data in the input buffer. // while(BufferDataAvailable(pMSADPCM->pBuffer) < pMSADPCM->usSamplesPerBlock) { // // Busy wait until data is available. // } // // Get the read pointer for the input buffer. // BufferGetReadPointer(pMSADPCM->pBuffer, &psLeft, &psRight, &lLength); // // Compress the samples with MS ADPCM. // adpcmEncode4Bit(pMSADPCM, psLeft, psRight, pMSADPCM->pucEncodedData + pMSADPCM->usValid); pMSADPCM->usValid += pMSADPCM->usBytesPerBlock; pMSADPCM->ulDataValid += pMSADPCM->usBytesPerBlock; // // Update the read pointer for the input buffer. // BufferUpdateReadPointer(pMSADPCM->pBuffer, pMSADPCM->usSamplesPerBlock); // // If there is enough data in the encoded data buffer, then write // it to the file. // if(pMSADPCM->usValid >= 4096) { // // Write 4096 bytes of data to the file. // if(FSWrite(pMSADPCM->pFile, pMSADPCM->pucEncodedData, 4096) == 0) { return(0); } // // There are now 4096 less bytes in the encoded data buffer. // pMSADPCM->usValid -= 4096; // // Copy the valid data from the end of the buffer to the // beginning. // memcpy(pMSADPCM->pucEncodedData, pMSADPCM->pucEncodedData + 4096, pMSADPCM->usValid); } // // Increment the time. // pMSADPCM->ulTimePos += pMSADPCM->usSamplesPerBlock; // // Success. // return(1); } // // Seek to the specified time position. // case IOCTL_CODEC_SEEK: { tMSADPCM *pMSADPCM; unsigned long ulPos; // // The first parameter is a pointer to the MS ADPCM persistent // state. // pMSADPCM = (tMSADPCM *)ulParam1; // // Make sure that the specified time is valid. // if(ulParam2 > pMSADPCM->ulTimeLength) { ulParam2 = pMSADPCM->ulTimeLength; } // // Compute the number of blocks that occur before the requested // time position. // ulPos = (((ulParam2 / 1000) * pMSADPCM->usSampleRate) / pMSADPCM->usSamplesPerBlock) + (((ulParam2 % 1000) * pMSADPCM->usSampleRate) / (pMSADPCM->usSamplesPerBlock * 1000)); // // Compute the time for the computed block number. // pMSADPCM->ulTimePos = ulPos * pMSADPCM->usSamplesPerBlock; // // Compute the file position for the computed block number. // ulPos = (ulPos * pMSADPCM->usBytesPerBlock) + pMSADPCM->ulDataStart; // // Seek to the new position in the file. // FSSeek(pMSADPCM->pFile, ulPos & ~511); // // Read 4K from the file. // pMSADPCM->usValid = FSRead(pMSADPCM->pFile, pMSADPCM->pucEncodedData, 4096); // // Set the current position in the file. // pMSADPCM->usOffset = ulPos & 511; // // Set the number of valid byte remaining in the file. // pMSADPCM->ulDataValid = pMSADPCM->ulLength + pMSADPCM->ulDataStart - (ulPos & ~511); // // Success. // return(1); } // // Cleanup after the codec. // case IOCTL_CODEC_CLOSE: { tMSADPCM *pMSADPCM; // // There is nothing to do if we were not encoding a file. // if(ulParam2 & CODEC_OPEN_ENCODE) { // // The first parameter is a pointer to the MS ADPCM persistent // state. // pMSADPCM = (tMSADPCM *)ulParam1; // // Write the remaining data from the encoded data buffer. // FSWrite(pMSADPCM->pFile, pMSADPCM->pucEncodedData, pMSADPCM->usValid); // // Seek back to the beginning of the file. // FSSeek(pMSADPCM->pFile, 0); // // Read the first 512 bytes from the file. // FSRead(pMSADPCM->pFile, pMSADPCM->pucEncodedData, 512); // // Seek back to the beginning of the file. // FSSeek(pMSADPCM->pFile, 0); // // Fill in the number of samples in the "fact" chunk. // pMSADPCM->pucEncodedData[78] = pMSADPCM->ulTimePos; pMSADPCM->pucEncodedData[79] = pMSADPCM->ulTimePos >> 8; pMSADPCM->pucEncodedData[80] = pMSADPCM->ulTimePos >> 16; pMSADPCM->pucEncodedData[81] = pMSADPCM->ulTimePos >> 24; // // Fill in the number of data bytes in the "data" chunk. // pMSADPCM->pucEncodedData[86] = pMSADPCM->ulDataValid; pMSADPCM->pucEncodedData[87] = pMSADPCM->ulDataValid >> 8; pMSADPCM->pucEncodedData[88] = pMSADPCM->ulDataValid >> 16; pMSADPCM->pucEncodedData[89] = pMSADPCM
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -