void QTapeView::doRewind() { if (!m_okTapeInserted) return; WavPcmFile_SetPosition((HWAVPCMFILE)m_hTapeWavPcmFile, 0); updatePosition(); }
void TapeView_DoRewind() { if (!m_okTapeInserted) return; WavPcmFile_SetPosition(m_hTapeWavPcmFile, 0); TapeView_UpdatePosition(); }
HWAVPCMFILE WavPcmFile_Create(LPCTSTR filename, int sampleRate) { const int bitsPerSample = 8; const int channels = 1; const int blockAlign = channels * bitsPerSample / 8; FILE* fpFileNew = ::_tfopen(filename, _T("w+b")); if (fpFileNew == NULL) return (HWAVPCMFILE) INVALID_HANDLE_VALUE; // Failed to create file // Prepare and write file header uint8_t consolidated_header[12 + 8 + 16 + 8]; ::memset(consolidated_header, 0, sizeof(consolidated_header)); uint32_t bytesWritten; memcpy(&consolidated_header[0], magic1, 4); // RIFF memcpy(&consolidated_header[8], magic2, 4); // WAVE memcpy(&consolidated_header[12], format_tag_id, 4); // fmt *((uint32_t*)(consolidated_header + 16)) = 16; // Size of "fmt" chunk *((uint16_t*)(consolidated_header + 20)) = WAV_FORMAT_PCM; // AudioFormat = PCM *((uint16_t*)(consolidated_header + 22)) = channels; // NumChannels = mono *((uint32_t*)(consolidated_header + 24)) = sampleRate; // SampleRate *((uint32_t*)(consolidated_header + 28)) = sampleRate * channels * bitsPerSample / 8; // ByteRate *((uint16_t*)(consolidated_header + 32)) = blockAlign; *((uint16_t*)(consolidated_header + 34)) = bitsPerSample; memcpy(&consolidated_header[36], data_tag_id, 4); // data // Write consolidated header bytesWritten = ::fwrite(consolidated_header, 1, sizeof(consolidated_header), fpFileNew); if (bytesWritten != sizeof(consolidated_header)) { ::fclose(fpFileNew); return (HWAVPCMFILE) INVALID_HANDLE_VALUE; // Failed to write consolidated header } WAVPCMFILE* pWavPcm = (WAVPCMFILE*) ::malloc(sizeof(WAVPCMFILE)); if (pWavPcm == NULL) { ::fclose(fpFileNew); return (HWAVPCMFILE) INVALID_HANDLE_VALUE; // Failed to allocate memory } memset(pWavPcm, 0, sizeof(WAVPCMFILE)); pWavPcm->fpFile = fpFileNew; pWavPcm->nChannels = channels; pWavPcm->nSampleFrequency = sampleRate; pWavPcm->nBitsPerSample = bitsPerSample; pWavPcm->nBlockAlign = blockAlign; pWavPcm->dwDataOffset = sizeof(consolidated_header); pWavPcm->dwDataSize = 0; pWavPcm->okWriting = true; WavPcmFile_SetPosition((HWAVPCMFILE) pWavPcm, 0); return (HWAVPCMFILE) pWavPcm; }
HWAVPCMFILE WavPcmFile_Open(LPCTSTR filename) { FILE* fpFileOpen = ::_tfopen(filename, _T("rb")); if (fpFileOpen == NULL) return (HWAVPCMFILE) INVALID_HANDLE_VALUE; // Failed to open file uint32_t offset = 0; uint32_t bytesRead; ::fseek(fpFileOpen, 0, SEEK_END); uint32_t fileSize = ::ftell(fpFileOpen); ::fseek(fpFileOpen, 0, SEEK_SET); uint8_t fileHeader[12]; bytesRead = ::fread(fileHeader, 1, sizeof(fileHeader), fpFileOpen); if (bytesRead != sizeof(fileHeader) || memcmp(&fileHeader[0], magic1, 4) != 0 || memcmp(&fileHeader[8], magic2, 4) != 0) { ::fclose(fpFileOpen); return (HWAVPCMFILE) INVALID_HANDLE_VALUE; // Failed to read file header OR invalid 'RIFF' tag OR invalid 'WAVE' tag } offset += bytesRead; uint32_t statedSize = *((uint32_t*)(fileHeader + 4)) + 8; if (statedSize > fileSize) statedSize = fileSize; uint8_t tagHeader[8]; uint16_t formatTag[8]; bool formatSpecified = false; uint16_t formatType = 1, channels = 1, bitsPerSample = 1, blockAlign = 0; uint32_t sampleFrequency = 22050, bytesPerSecond, dataOffset = 0, dataSize = 0; while (offset < statedSize) { bytesRead = ::fread(tagHeader, 1, sizeof(tagHeader), fpFileOpen); if (bytesRead != sizeof(tagHeader)) { ::fclose(fpFileOpen); return (HWAVPCMFILE) INVALID_HANDLE_VALUE; // Failed to read tag header } offset += bytesRead; uint32_t tagSize = *(uint32_t*)(tagHeader + 4); if (!memcmp(tagHeader, format_tag_id, 4)) { if (formatSpecified || tagSize < sizeof(formatTag)) { ::fclose(fpFileOpen); return (HWAVPCMFILE) INVALID_HANDLE_VALUE; // Wrong tag header } formatSpecified = true; bytesRead = ::fread(formatTag, 1, sizeof(formatTag), fpFileOpen); if (bytesRead != sizeof(formatTag)) { ::fclose(fpFileOpen); return (HWAVPCMFILE) INVALID_HANDLE_VALUE; // Failed to read format tag } formatType = formatTag[0]; channels = formatTag[1]; sampleFrequency = formatTag[2]; bytesPerSecond = formatTag[4]; blockAlign = formatTag[6]; bitsPerSample = formatTag[7]; if (formatType != WAV_FORMAT_PCM) { ::fclose(fpFileOpen); return (HWAVPCMFILE) INVALID_HANDLE_VALUE; // Unsupported format } if (sampleFrequency * bitsPerSample * channels / 8 != bytesPerSecond || (bitsPerSample != 8 && bitsPerSample != 16 && bitsPerSample != 32)) { ::fclose(fpFileOpen); return (HWAVPCMFILE) INVALID_HANDLE_VALUE; // Wrong format tag } } else if (!memcmp(tagHeader, data_tag_id, 4)) { if (!formatSpecified) { ::fclose(fpFileOpen); return (HWAVPCMFILE) INVALID_HANDLE_VALUE; // Wrong tag } dataOffset = offset; dataSize = tagSize; } else // Ignore all other tags { } offset += tagSize; ::fseek(fpFileOpen, offset, SEEK_SET); } WAVPCMFILE* pWavPcm = (WAVPCMFILE*) ::malloc(sizeof(WAVPCMFILE)); if (pWavPcm == NULL) { ::fclose(fpFileOpen); return (HWAVPCMFILE) INVALID_HANDLE_VALUE; // Failed to allocate memory } ::memset(pWavPcm, 0, sizeof(WAVPCMFILE)); pWavPcm->fpFile = fpFileOpen; pWavPcm->nChannels = channels; pWavPcm->nSampleFrequency = sampleFrequency; pWavPcm->nBitsPerSample = bitsPerSample; pWavPcm->nBlockAlign = blockAlign; pWavPcm->dwDataOffset = dataOffset; pWavPcm->dwDataSize = dataSize; pWavPcm->okWriting = false; WavPcmFile_SetPosition((HWAVPCMFILE) pWavPcm, 0); return (HWAVPCMFILE) pWavPcm; }