SoundFile.cpp
上传用户:zjb_0001
上传日期:2007-01-11
资源大小:154k
文件大小:5k
源码类别:

Audio

开发平台:

Visual C++

  1. // SoundFile.cpp: implementation of the CSoundFile class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "SoundFile.h"
  6. #ifdef _DEBUG
  7. #undef THIS_FILE
  8. static char THIS_FILE[]=__FILE__;
  9. #define new DEBUG_NEW
  10. #endif
  11. //////////////////////////////////////////////////////////////////////
  12. // Construction/Destruction
  13. //////////////////////////////////////////////////////////////////////
  14. CSoundFile::CSoundFile(CString FileName, WAVEFORMATEX* format)
  15. {
  16. m_hFile = NULL;
  17. m_FileName = FileName;
  18. ZeroMemory(&m_MMCKInfoParent,sizeof(MMCKINFO));
  19. ZeroMemory(&m_MMCKInfoChild,sizeof(MMCKINFO));
  20. ZeroMemory(&m_MMCKInfoData,sizeof(MMCKINFO));
  21. if(format == NULL)
  22. {
  23. m_Mode = READ;
  24. OpenWaveFile();
  25. }
  26. else
  27. {
  28. m_Mode = WRITE;
  29. m_Format = *format;
  30. CreateWaveFile();
  31. }
  32. if(m_Mode == ERROR) Close();
  33. }
  34. CSoundFile::~CSoundFile()
  35. {
  36. Close();
  37. }
  38. void CSoundFile::Close()
  39. {
  40. if(m_hFile)
  41. {
  42. if(m_Mode == WRITE)
  43. {
  44. ::mmioAscend(m_hFile, &m_MMCKInfoChild, 0);
  45. ::mmioAscend(m_hFile, &m_MMCKInfoParent, 0);
  46. }
  47. ::mmioClose(m_hFile, 0);
  48. m_hFile = NULL;
  49. }
  50. }
  51. bool CSoundFile::Write(CBuffer *buffer)
  52. {
  53. if(m_Mode == WRITE)
  54. {
  55. int length = mmioWrite(m_hFile, buffer->ptr.c, buffer->ByteLen);
  56. if(length == buffer->ByteLen)
  57. return true;
  58. }
  59. return false;
  60. }
  61. CBuffer* CSoundFile::Read()
  62. {
  63. // create a new buffer
  64. CBuffer* buf = new CBuffer(m_Format.nBlockAlign*m_BufferSize);
  65. if(buf == NULL) 
  66. return NULL;
  67. if(Read(buf))
  68. return buf;
  69. // if we reach here there was an error
  70. delete buf;
  71. return NULL;
  72. }
  73. bool CSoundFile::Read(CBuffer *buffer)
  74. {
  75. if(m_Mode == READ)
  76. {
  77. buffer->ByteLen = ::mmioRead(m_hFile, buffer->ptr.c, buffer->ByteLen);
  78. if(buffer->ByteLen > 0)
  79. return true;
  80. }
  81. return false;
  82. }
  83. bool CSoundFile::CreateWaveFile()
  84. {
  85. // check if file is already open
  86. if(m_hFile) 
  87. return FALSE;
  88. // open file
  89. m_hFile = ::mmioOpen(m_FileName.GetBuffer(0),NULL, MMIO_CREATE|MMIO_WRITE|MMIO_EXCLUSIVE | MMIO_ALLOCBUF);
  90. if(m_hFile == NULL) 
  91. {
  92. m_Mode = FILE_ERROR;
  93. return FALSE;
  94. }
  95. ZeroMemory(&m_MMCKInfoParent, sizeof(MMCKINFO));
  96. m_MMCKInfoParent.fccType = mmioFOURCC('W','A','V','E');
  97. MMRESULT mmResult = ::mmioCreateChunk( m_hFile,&m_MMCKInfoParent, MMIO_CREATERIFF);
  98. ZeroMemory(&m_MMCKInfoChild, sizeof(MMCKINFO));
  99. m_MMCKInfoChild.ckid = mmioFOURCC('f','m','t',' ');
  100. m_MMCKInfoChild.cksize = sizeof(WAVEFORMATEX) + m_Format.cbSize;
  101. mmResult = ::mmioCreateChunk(m_hFile, &m_MMCKInfoChild, 0);
  102. mmResult = ::mmioWrite(m_hFile, (char*)&m_Format, sizeof(WAVEFORMATEX) + m_Format.cbSize); 
  103. mmResult = ::mmioAscend(m_hFile, &m_MMCKInfoChild, 0);
  104. m_MMCKInfoChild.ckid = mmioFOURCC('d', 'a', 't', 'a');
  105. mmResult = ::mmioCreateChunk(m_hFile, &m_MMCKInfoChild, 0);
  106. return TRUE;
  107. }
  108. bool CSoundFile::OpenWaveFile()
  109. {
  110. // code taken from Visual C++ Multimedia -- Aitken and Jarol p 122
  111. // check if file is already open
  112. if(m_hFile) 
  113. return FALSE; 
  114. m_hFile = mmioOpen(m_FileName.GetBuffer(0),NULL,MMIO_READ);
  115. if(m_hFile == NULL) 
  116. {
  117. m_Mode = FILE_ERROR;
  118. return FALSE;
  119. }
  120. m_MMCKInfoParent.fccType = mmioFOURCC('W','A','V','E');
  121. MMRESULT mmResult = ::mmioDescend(m_hFile, &m_MMCKInfoParent,NULL,MMIO_FINDRIFF);
  122. if(mmResult)
  123. {
  124. AfxMessageBox("Error descending into file");
  125. mmioClose(m_hFile,0);
  126. m_hFile = NULL;
  127. m_Mode = FILE_ERROR;
  128. return FALSE;
  129. }
  130. m_MMCKInfoChild.ckid = mmioFOURCC('f','m','t',' ');
  131. mmResult = mmioDescend(m_hFile,&m_MMCKInfoChild,&m_MMCKInfoParent,MMIO_FINDCHUNK);
  132. if(mmResult)
  133. {
  134. AfxMessageBox("Error descending in wave file");
  135. mmioClose(m_hFile,0);
  136. m_Mode = FILE_ERROR;
  137. m_hFile = NULL;
  138. return FALSE;
  139. }
  140. DWORD bytesRead = mmioRead(m_hFile,(LPSTR)&m_Format,m_MMCKInfoChild.cksize);
  141. if(bytesRead < 0)
  142. {
  143. AfxMessageBox("Error reading PCM wave format record");
  144. mmioClose(m_hFile,0);
  145. m_Mode = FILE_ERROR;
  146. return FALSE;
  147. }
  148. // open output sound file
  149. mmResult = mmioAscend(m_hFile,&m_MMCKInfoChild,0);
  150. if(mmResult)
  151. {
  152. AfxMessageBox("Error ascending in File");
  153. mmioClose(m_hFile,0);
  154. m_hFile = NULL;
  155. m_Mode = FILE_ERROR;
  156. return FALSE;
  157. }
  158. m_MMCKInfoChild.ckid = mmioFOURCC('d','a','t','a');
  159. mmResult = mmioDescend(m_hFile,&m_MMCKInfoChild,
  160. &m_MMCKInfoParent,MMIO_FINDCHUNK);
  161. if(mmResult)
  162. {
  163. AfxMessageBox("error reading data chunk");
  164. mmioClose(m_hFile,0);
  165. m_hFile = NULL;
  166. m_Mode = FILE_ERROR;
  167. return FALSE;
  168. }
  169. return TRUE;
  170. }
  171. EREADWRITE CSoundFile::GetMode()
  172. {
  173. return m_Mode;
  174. }
  175. bool CSoundFile::IsOK()
  176. {
  177. if(m_Mode == FILE_ERROR)
  178. return false;
  179. else
  180. return true;
  181. }