⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tapiwave.c

📁 演示使用tapi通过语音modem进行拨号并播放和录制wav文件的例子
💻 C
📖 第 1 页 / 共 3 页
字号:

   if (MMSYSERR_NOERROR == waveInGetDevCaps(WaveInID, &in, sizeof(in)))
   {
      MyPrintf(
         TEXT("WaveInDevCaps:\r\n")
         TEXT("  wMid: 0x%04X\r\n")
         TEXT("  wPid: 0x%04X\r\n")
         TEXT("  vDriverVersion: 0x%04X\r\n")
         TEXT("  pszPname: %s\r\n")
         TEXT("  dwFormats: 0x%08X\r\n")
         TEXT("  dwChannels: 0x%04X\r\n")
         ,
         in.wMid, in.wPid, in.vDriverVersion, in.szPname, in.dwFormats, in.wChannels);
   }
   else
      MyPrintf(TEXT("waveInGetDevCaps failed.\r\n"));

   if (MMSYSERR_NOERROR == waveOutGetDevCaps(WaveOutID, &out, sizeof(out)))
   {
      MyPrintf(
         TEXT("WaveOutDevCaps:\r\n")
         TEXT("  wMid: 0x%04X\r\n")
         TEXT("  wPid: 0x%04X\r\n")
         TEXT("  vDriverVersion: 0x%04X\r\n")
         TEXT("  pszPname: %s\r\n")
         TEXT("  dwFormats: 0x%08X\r\n")
         TEXT("  dwChannels: 0x%04X\r\n")
         ,
         out.wMid, out.wPid, out.vDriverVersion, out.szPname, out.dwFormats, out.wChannels);
   }
   else
      MyPrintf(TEXT("waveInGetDevCaps failed.\r\n"));

   // TODO Find out if its capable of simultaneous recording and playing
}


PMYWAVEDATA LoadWaveInfo(WAVEFORMATEX* pFormat)
{
   MMRESULT       mmResult;
   HMMIO          hmmio = {0};
   MMCKINFO       mmckinfoParent;
   MMCKINFO       mmckinfoSubchunk;
   DWORD          dwFmtSize;
   DWORD          dwChunkSize;
   PMYWAVEDATA    pWaveHead = NULL, 
                  pWaveCurr = NULL,
                  pWavePrev = NULL;
   BOOL bLooping = TRUE;
   DWORD dwBuffers = 0;

   // Open the given file for reading using buffered I/O.
   if(!(hmmio = mmioOpen(szFileName, NULL, MMIO_READ | MMIO_ALLOCBUF)))
   {
      MyPrintf(TEXT("mmioOpen failed to open file.\r\n"));
      return NULL;
   }

   // Locate a 'RIFF' chunk with a 'WAVE' form type to make sure it's a WAVE file.
   mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
   if (mmResult = mmioDescend(hmmio, &mmckinfoParent, NULL, MMIO_FINDRIFF))
   {
      MyPrintf(TEXT("mmioDescend RIFF WAVE returned %s\r\n"), FormatWaveOutError(mmResult));
      goto end;
   }

   //  Now, find the format chunk (form type 'fmt '). It should be
   //  a subchunk of the 'RIFF' parent chunk.
   mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' ');
   if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent,
      MMIO_FINDCHUNK))
   {
      MyPrintf(TEXT("Wave file corrupt.\r\n"));
      goto end;
   }

   // Get the size of the format chunk, allocate and lock memory for it.
   dwFmtSize = mmckinfoSubchunk.cksize;
   if (pFormat->cbSize < dwFmtSize)
   {
      MyPrintf(TEXT("Format chunk not big enough.\r\n"));
      goto end;
   }

   // Read the format chunk.
   if (mmioRead(hmmio, (HPSTR) pFormat, dwFmtSize) != (LONG) dwFmtSize)
   {
      MyPrintf(TEXT("mmioRead: failed to read FMT chunk.\r\n"));
      goto end;
   }

   MyPrintf(TEXT("wFormatTag = %lu\r\n"),        (DWORD) pFormat->wFormatTag);
   MyPrintf(TEXT("nChannels = %lu\r\n"),         (DWORD) pFormat->nChannels );
   MyPrintf(TEXT("nSamplesPerSec = %lu\r\n"),    (DWORD) pFormat->nSamplesPerSec);
   MyPrintf(TEXT("nAvgBytesPerSec = %lu\r\n"),   (DWORD) pFormat->nAvgBytesPerSec);
   MyPrintf(TEXT("nBlockAlign = %lu\r\n"),       (DWORD) pFormat->nBlockAlign);
   MyPrintf(TEXT("wBitsPerSample = %lu\r\n"),    (DWORD) pFormat->wBitsPerSample);
   MyPrintf(TEXT("cbSize = %lu\r\n"),            (DWORD) pFormat->cbSize);

   // Ascend out of the format subchunk.
   mmioAscend(hmmio, &mmckinfoSubchunk, 0);

   // Find the data subchunk.
   mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
   if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent,
      MMIO_FINDCHUNK))
   {
      MyPrintf(TEXT("mmioDescend: No DATA chunk.\r\n"));
      goto end;
   }

   //  Get the size of the data subchunk.
   if (mmckinfoSubchunk.cksize == 0L)
   {
      MyPrintf(TEXT("Data chunk actually has no data.\r\n"));
      goto end;
   }
   MyPrintf(TEXT("Size of data is %lu\r\n"),mmckinfoSubchunk.cksize);

   // Now read the data and allocate MYWAVEDATA buffers
   dwChunkSize = (pFormat->nAvgBytesPerSec/4);
   dwChunkSize -= dwChunkSize % pFormat->nBlockAlign;
   if (dwChunkSize < pFormat->nBlockAlign)
   {
      MyPrintf(TEXT("Couldn't calculate a good block size\r\n"));
      goto end;
   }

   while(bLooping)
   {
      LONG lRead;

      pWaveCurr = (PMYWAVEDATA) LocalAlloc(LPTR, dwChunkSize + sizeof(MYWAVEDATA));
      pWaveCurr->wavehdr.lpData = pWaveCurr->data;

      if (pWaveHead == NULL)
         pWaveHead = pWaveCurr;

      // Read the waveform data subchunk.
      lRead = mmioRead(hmmio, pWaveCurr->data, dwChunkSize);
      pWaveCurr->wavehdr.dwBufferLength = lRead;
      if (lRead == -1)
      {
         MyPrintf(TEXT("Error reading from file.\r\n"));
         pWaveHead = NULL; // Leak leak
         goto end;
      }

      if (lRead == 0)
      {
         LocalFree(pWaveCurr);
         break;
      }

      if ((DWORD)lRead != dwChunkSize)
      {
         bLooping = FALSE;
      }

      if (pWavePrev != NULL)
         pWavePrev->pNext = pWaveCurr;
      pWavePrev = pWaveCurr;
      dwBuffers++;
   }

   MyPrintf(TEXT("There were %lu buffers read from %s\r\n"), dwBuffers, szFileName);

  end:

   mmioClose(hmmio, 0);

   return pWaveHead;
}



 
/*=== Printing routines =============================================================*/

/*
  This is easily used to do error messages like this:

  MyPrintf(TEXT("API blah failed with error: %s\r\n"), FormatError(GetLastError()));
*/

#define MAX_PRINT_STRING 1024

//#define MSG_BOX_PRINT

#ifdef _DEBUG
#define MSG_DEBUG_PRINT
#endif

#define MSG_CONSOLE_PRINT

//#define MSG_FILE_PRINT 

#ifdef MSG_FILE_PRINT
TCHAR szFilePrint[MAX_PATH] = TEXT(".\\out.txt");
BOOL bZeroFile = FALSE;
#endif

LPTSTR FormatWaveError(MMRESULT mmrError, MMRESULT (WINAPI *pfn) (MMRESULT, LPTSTR, UINT), LPTSTR szErr)
{
   _declspec(thread) static TCHAR szOutput[MAX_PRINT_STRING];
   MMRESULT mmResult2;
   mmResult2 = pfn(mmrError, szOutput, MAX_PRINT_STRING);
   if (mmResult2 != MMSYSERR_NOERROR)
   {
      TCHAR szTmp[256];
      MMRESULT mmResult3;

      mmResult3 = pfn(mmResult2, szOutput, 256);
      if (mmResult2 != MMSYSERR_NOERROR)
         wsprintf(szOutput, TEXT("%s returned an %lu on %lu"), szErr, mmResult2, mmrError);
      else
         wsprintf(szOutput, TEXT("%s on error %lu"), szTmp, mmrError);
   }
   return szOutput;
}

LPTSTR FormatWaveOutError(MMRESULT mmrError)
{
   return FormatWaveError(mmrError, waveOutGetErrorText, TEXT("waveOutGetError"));
}

LPTSTR FormatWaveInError(MMRESULT mmrError)
{
   return FormatWaveError(mmrError, waveInGetErrorText, TEXT("waveInGetError"));
}


// Turn a TAPI Line error into a printable string.
LPTSTR FormatTapiError (long lError)
{
   static LPTSTR pszLineError[] = 
   {
     TEXT("LINEERR No Error"),
     TEXT("LINEERR_ALLOCATED"),
     TEXT("LINEERR_BADDEVICEID"),
     TEXT("LINEERR_BEARERMODEUNAVAIL"),
     TEXT("LINEERR Unused constant, ERROR!!"),
     TEXT("LINEERR_CALLUNAVAIL"),
     TEXT("LINEERR_COMPLETIONOVERRUN"),
     TEXT("LINEERR_CONFERENCEFULL"),
     TEXT("LINEERR_DIALBILLING"),
     TEXT("LINEERR_DIALDIALTONE"),
     TEXT("LINEERR_DIALPROMPT"),
     TEXT("LINEERR_DIALQUIET"),
     TEXT("LINEERR_INCOMPATIBLEAPIVERSION"),
     TEXT("LINEERR_INCOMPATIBLEEXTVERSION"),
     TEXT("LINEERR_INIFILECORRUPT"),
     TEXT("LINEERR_INUSE"),
     TEXT("LINEERR_INVALADDRESS"),
     TEXT("LINEERR_INVALADDRESSID"),
     TEXT("LINEERR_INVALADDRESSMODE"),
     TEXT("LINEERR_INVALADDRESSSTATE"),
     TEXT("LINEERR_INVALAPPHANDLE"),
     TEXT("LINEERR_INVALAPPNAME"),
     TEXT("LINEERR_INVALBEARERMODE"),
     TEXT("LINEERR_INVALCALLCOMPLMODE"),
     TEXT("LINEERR_INVALCALLHANDLE"),
     TEXT("LINEERR_INVALCALLPARAMS"),
     TEXT("LINEERR_INVALCALLPRIVILEGE"),
     TEXT("LINEERR_INVALCALLSELECT"),
     TEXT("LINEERR_INVALCALLSTATE"),
     TEXT("LINEERR_INVALCALLSTATELIST"),
     TEXT("LINEERR_INVALCARD"),
     TEXT("LINEERR_INVALCOMPLETIONID"),
     TEXT("LINEERR_INVALCONFCALLHANDLE"),
     TEXT("LINEERR_INVALCONSULTCALLHANDLE"),
     TEXT("LINEERR_INVALCOUNTRYCODE"),
     TEXT("LINEERR_INVALDEVICECLASS"),
     TEXT("LINEERR_INVALDEVICEHANDLE"),
     TEXT("LINEERR_INVALDIALPARAMS"),
     TEXT("LINEERR_INVALDIGITLIST"),
     TEXT("LINEERR_INVALDIGITMODE"),
     TEXT("LINEERR_INVALDIGITS"),
     TEXT("LINEERR_INVALEXTVERSION"),
     TEXT("LINEERR_INVALGROUPID"),
     TEXT("LINEERR_INVALLINEHANDLE"),
     TEXT("LINEERR_INVALLINESTATE"),
     TEXT("LINEERR_INVALLOCATION"),
     TEXT("LINEERR_INVALMEDIALIST"),
     TEXT("LINEERR_INVALMEDIAMODE"),
     TEXT("LINEERR_INVALMESSAGEID"),
     TEXT("LINEERR Unused constant, ERROR!!"),
     TEXT("LINEERR_INVALPARAM"),
     TEXT("LINEERR_INVALPARKID"),
     TEXT("LINEERR_INVALPARKMODE"),
     TEXT("LINEERR_INVALPOINTER"),
     TEXT("LINEERR_INVALPRIVSELECT"),
     TEXT("LINEERR_INVALRATE"),
     TEXT("LINEERR_INVALREQUESTMODE"),
     TEXT("LINEERR_INVALTERMINALID"),
     TEXT("LINEERR_INVALTERMINALMODE"),
     TEXT("LINEERR_INVALTIMEOUT"),
     TEXT("LINEERR_INVALTONE"),
     TEXT("LINEERR_INVALTONELIST"),
     TEXT("LINEERR_INVALTONEMODE"),
     TEXT("LINEERR_INVALTRANSFERMODE"),
     TEXT("LINEERR_LINEMAPPERFAILED"),
     TEXT("LINEERR_NOCONFERENCE"),
     TEXT("LINEERR_NODEVICE"),
     TEXT("LINEERR_NODRIVER"),
     TEXT("LINEERR_NOMEM"),
     TEXT("LINEERR_NOREQUEST"),
     TEXT("LINEERR_NOTOWNER"),
     TEXT("LINEERR_NOTREGISTERED"),
     TEXT("LINEERR_OPERATIONFAILED"),
     TEXT("LINEERR_OPERATIONUNAVAIL"),
     TEXT("LINEERR_RATEUNAVAIL"),
     TEXT("LINEERR_RESOURCEUNAVAIL"),
     TEXT("LINEERR_REQUESTOVERRUN"),
     TEXT("LINEERR_STRUCTURETOOSMALL"),
     TEXT("LINEERR_TARGETNOTFOUND"),
     TEXT("LINEERR_TARGETSELF"),
     TEXT("LINEERR_UNINITIALIZED"),
     TEXT("LINEERR_USERUSERINFOTOOBIG"),
     TEXT("LINEERR_REINIT"),
     TEXT("LINEERR_ADDRESSBLOCKED"),
     TEXT("LINEERR_BILLINGREJECTED"),
     TEXT("LINEERR_INVALFEATURE"),
     TEXT("LINEERR_NOMULTIPLEINSTANCE")
   };

   _declspec(thread) static TCHAR szError[512];
   DWORD dwError;
   HMODULE hTapiUIMod = GetModuleHandle(TEXT("TAPIUI.DLL"));

   if (hTapiUIMod)
   {
      dwError = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE,
                    (LPCVOID)hTapiUIMod, TAPIERROR_FORMATMESSAGE(lError),
                    0, szError, sizeof(szError)/sizeof(TCHAR), NULL);
      if (dwError)
         return szError;
   }

   // Strip off the high bit to make the error code positive.
   dwError = (DWORD)lError & 0x7FFFFFFF;

   if ((lError > 0) || (dwError > sizeof(pszLineError)/sizeof(pszLineError[0])))
   {
      wsprintf(szError, TEXT("Unknown TAPI error code: 0x%lx"), lError);
      return szError;
   }

   return pszLineError[dwError];
}



void __cdecl MyPrintf(LPCTSTR pszFormat, ...)
{
   _declspec(thread) static TCHAR szOutput[MAX_PRINT_STRING]; // max printable string length
   va_list v1;
   DWORD dwSize;

   va_start(v1, pszFormat);

   dwSize = wvsprintf(szOutput, pszFormat, v1); 

#ifdef MSG_DEBUG_PRINT
   OutputDebugString(szOutput);
#endif

#ifdef MSG_CONSOLE_PRINT
   _tprintf(szOutput);
#endif

#ifdef MSG_BOX_PRINT
   MessageBox(NULL, szOutput,TEXT("MyPrintf Output"), MB_OK);
#endif

#ifdef MSG_FILE_PRINT
   {
	   static HANDLE hFile = NULL;
	   DWORD dwNumWritten;
	   if (hFile == NULL)
	   {
		   hFile = CreateFile(szFilePrint, GENERIC_WRITE, FILE_SHARE_READ, NULL, 
			   bZeroFile ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

		   if (hFile == INVALID_HANDLE_VALUE)
			   MyPrintf(TEXT("CreateFile output log file %s failed with %s\r\n"), szFilePrint, FormatError(GetLastError()));
		   else
            SetFilePointer(hFile, 0, NULL, FILE_END);
	   }
	   if (hFile != INVALID_HANDLE_VALUE)
      {
         OVERLAPPED ol = {0};
         LockFileEx(hFile, 0, 0, 1, 0, &ol);
		   WriteFile(hFile, szOutput, dwSize*sizeof(TCHAR), &dwNumWritten, NULL);
         UnlockFileEx(hFile, 0, 1, 0, &ol);
      }
   }
#endif
}

LPCTSTR FormatError(DWORD dwError)
{
   _declspec(thread) static TCHAR szBuff[MAX_PRINT_STRING];
   return FormatErrorBuffer(dwError, szBuff, MAX_PRINT_STRING);
}

LPCTSTR FormatErrorBuffer(DWORD dwError, LPTSTR pszBuff, DWORD dwNumChars)
{
   DWORD dwRetFM = 0;

   dwRetFM = wsprintf(pszBuff, TEXT("%lu - "), dwError);
   dwRetFM = FormatMessage(
      FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, 0,
      &pszBuff[dwRetFM], dwNumChars - dwRetFM, NULL);

   if (dwRetFM == 0)
   {
      wsprintf(pszBuff, TEXT("FormatMessage failed on %lu with %lu"),
         dwError, GetLastError());
   }

   return pszBuff;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -