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

📄 sound.cpp

📁 a file about net phone based on IP,write by VC++.
💻 CPP
字号:
/*
   Talker - A small program which utilizes the Layer-3 codec (ACM) in windows for voice-over-IP
   Copyright (C) 1999 Dino Klein

   This program is free software; you can redistribute it and/or modify it under the terms of
   the GNU General Public License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version. 

   This program is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or
   FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
   more details. 

   You should have received a copy of the GNU General Public License along with this
   program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
   MA 02139, USA.

   email: dinoklein@hotmail.com
*/


#define  WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <mmsystem.h>
#include <dsound.h>
#include <mmreg.h>
#include <msacm.h>
#include "defines.h"


void ErrB (char*, int=0, HWND=0);


extern bool             stereo, use_primary;
extern HACMSTREAM       has, hasd;
extern HANDLE           hPlay, hRec[10];
extern ACMSTREAMHEADER  ahc, ahd;
extern WAVEFORMATEX     wfx;
extern MPEG_WFX         mwfx;
extern int              input_buffer_size, segments, output_buf_size;

extern char             decomp_buf[44100];
extern char             comped_buf[4096];
extern char             acmbuf[44100];
extern char             output_buffer[4096];






LPDIRECTSOUND lpds;
LPDIRECTSOUNDBUFFER lpdsb;
LPDIRECTSOUNDNOTIFY lpdsn;

LPDIRECTSOUNDCAPTURE lpdsc;
LPDIRECTSOUNDCAPTUREBUFFER lpdscb;
LPDIRECTSOUNDNOTIFY lpdsnc;







bool zero_output_buffer (void)
{
   HRESULT  hr;
   LPVOID   pv1, pv2;
   DWORD    cb1, cb2;


   hr = lpdsb->Lock(0, 0, &pv1, &cb1, &pv2, &cb2, DSBLOCK_ENTIREBUFFER);
   if (hr==DS_OK)
   {
      memset(pv1, 0, cb1);
      if (pv2) memset(pv2, 0, cb2);
      lpdsb->Unlock(pv1, cb1, pv2, cb2);
   }
   return (hr==DS_OK);
}


bool set_capture_events (int segs)
{
   DSBPOSITIONNOTIFY  dsbnn[10];
   HRESULT            hr;
   int                i;

   for (i=0; i<segs; i++) dsbnn[i].hEventNotify = hRec[i];
   switch (segs)
   {
      case 2:
         dsbnn[0].dwOffset = input_buffer_size/2 - ((stereo)?3:1);
         dsbnn[1].dwOffset = input_buffer_size-1;
         break;

      case 3:
         for (i=0; i<3; i++) dsbnn[i].dwOffset = (input_buffer_size/3)*(i+1)-1;
         break;

      case 4:
         dsbnn[0].dwOffset = (stereo) ? 11023 : 5511;
         dsbnn[1].dwOffset = (stereo) ? 22047 : 11023;
         dsbnn[2].dwOffset = (stereo) ? 33071 : 16535;
         dsbnn[3].dwOffset = input_buffer_size-1;
         break;

      case 10:
         dsbnn[0].dwOffset = (stereo) ? 4407 : 2203;
         for (i=1; i<9; i++) dsbnn[i].dwOffset = dsbnn[i-1].dwOffset+((stereo)?4408:2204);
         dsbnn[9].dwOffset = input_buffer_size-1;
         break;
   }
   hr = lpdsnc->SetNotificationPositions(segs, dsbnn);
   return (hr==DS_OK);
}



bool init_primary_buffer (void)
{
   HRESULT  hr;
   DSBUFFERDESC  dsbd;


   dsbd.dwSize = sizeof(dsbd);
   dsbd.dwFlags = DSBCAPS_STICKYFOCUS|DSBCAPS_PRIMARYBUFFER;
   dsbd.dwBufferBytes = 0;
   dsbd.dwReserved = 0;
   dsbd.lpwfxFormat = 0;
   hr = lpds->CreateSoundBuffer(&dsbd, &lpdsb, 0);
   if (hr==DS_OK)
   {
      hr = lpdsb->SetFormat(&wfx);
      if (hr==DS_OK)
      {
         DSBCAPS  dsbc;


         dsbc.dwSize = sizeof(dsbc);
         lpdsb->GetCaps(&dsbc);
         output_buf_size = dsbc.dwBufferBytes;
         return true;
      }
      lpdsb->Release();
   }
   lpdsb = 0;
   return false;
}



bool set_primary_buffer_format (void)
{
   LPDIRECTSOUNDBUFFER  primary;
   DSBUFFERDESC         dsbd;
   HRESULT              hr;


   dsbd.dwSize = sizeof(dsbd);
   dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
   dsbd.dwBufferBytes = 0;
   dsbd.dwReserved = 0;
   dsbd.lpwfxFormat = 0;
   hr = lpds->CreateSoundBuffer(&dsbd, &primary, 0);
   if (hr==DS_OK)
   {
      hr = primary->SetFormat(&wfx);
      primary->Release();
   }
   return (hr==DS_OK);
}


bool init_secondary_buffer (void)
{
#define BUFFER_SIZE 20*1024
   HRESULT  hr;
   DSBUFFERDESC  dsbd;


   if (set_primary_buffer_format())
   {
      dsbd.dwSize = sizeof(dsbd);
      dsbd.dwFlags = DSBCAPS_GLOBALFOCUS|DSBCAPS_STICKYFOCUS|DSBCAPS_GETCURRENTPOSITION2;
      dsbd.dwBufferBytes = BUFFER_SIZE;
      dsbd.dwReserved = 0;
      dsbd.lpwfxFormat = &wfx;
      hr = lpds->CreateSoundBuffer(&dsbd, &lpdsb, 0);
      if (hr==DS_OK)
      {
         output_buf_size = BUFFER_SIZE;
         //zero_output_buffer();

         DSBCAPS  dsbc;


         dsbc.dwSize = sizeof(dsbc);
         lpdsb->GetCaps(&dsbc);
         //lpdsb->Play(0, 0, DSBPLAY_LOOPING);
         return true;
      }
   }
   lpdsb = 0;
   return false;
#undef BUFFER_SIZE
}




bool init_wave_out_ds (HWND hwnd)
{
   HRESULT  hr;


   hr = DirectSoundCreate(0, &lpds, 0);
   if (hr==DS_OK)
   {
      ShowWindow(hwnd, SW_SHOW);
      hr = lpds->SetCooperativeLevel(hwnd, (use_primary)?DSSCL_WRITEPRIMARY:DSSCL_PRIORITY);
      if (hr==DS_OK)
      {
         if (use_primary)
         if (init_primary_buffer()) return true;
         else MessageBox(hwnd, "err init using primary buf", 0, 0);
         else if (init_secondary_buffer()) return true;
              else MessageBox(hwnd, "err using secondary buffer", 0, 0);
      }
      else MessageBox(hwnd, "unable to set cooperative level", 0, 0);
      lpds->Release();
   }
   else MessageBox(hwnd, "open sound device failed", 0, 0);
   lpdsb=0;
   lpds=0;
   return false;
}


void close_wave_out_ds (void)
{
   if (lpdsb) lpdsb->Release();
   if (lpds) lpds->Release();
   lpdsb = 0;
   lpds = 0;
}



bool init_wave_in_ds (HWND hwnd)
{
   HRESULT  hr;


   hr = DirectSoundCaptureCreate(0, &lpdsc, 0);
   if (hr==DS_OK)
   {
      DSCBUFFERDESC  dsbcd;


      dsbcd.dwSize = sizeof(dsbcd);
      dsbcd.dwFlags = 0;
      dsbcd.dwBufferBytes = input_buffer_size;
      dsbcd.dwReserved = 0;
      dsbcd.lpwfxFormat = &wfx;
      hr = lpdsc->CreateCaptureBuffer(&dsbcd, &lpdscb, 0);
      if (hr==DS_OK)
      {
         lpdscb->QueryInterface(IID_IDirectSoundNotify, (LPVOID*)&lpdsnc);
         if (hr==S_OK)
         {
            if (set_capture_events(segments)) return true;
            else ErrB("err setting points", hr, hwnd);
            lpdsnc->Release();
         }
         else ErrB("query notify", hr, hwnd);
         lpdscb->Release();
      }
      else ErrB("capture buffer", hr, hwnd);
      lpdsc->Release();
   }
   else ErrB("capture device", hr, hwnd);

   lpdsnc = 0;
   lpdscb = 0;
   lpdsc = 0;   
   return false;
}


void close_wave_in_ds (void)
{
   if (lpdscb)
   {
      lpdscb->Stop();
      lpdscb->Release();
   }
   if (lpdsnc) lpdsnc->Release();
   if (lpdsc) lpdsc->Release();

   lpdscb = 0;
   lpdsnc = 0;
   lpdsc = 0;
}


char init_acm_stream (void)
{
   long  r;


   r = acmStreamOpen (&has, NULL, &wfx, &mwfx.wfx, 0, 0, 0, 0);
   if (!r)
   {

      memset (&ahc, 0, sizeof (ACMSTREAMHEADER));
      ahc.cbStruct = sizeof (ACMSTREAMHEADER);
      ahc.pbSrc = (BYTE *) acmbuf;
      ahc.cbSrcLength = 44100;
      ahc.pbDst = (BYTE *) output_buffer;
      ahc.cbDstLength = 4096;
      r = acmStreamPrepareHeader (has, &ahc, 0);
      if (!r) return 1;

      acmStreamClose (has, 0);
   }

   return (0);
}


void close_acm_stream (void)
{
   ahc.cbSrcLength =  44100;
   ahc.cbDstLength = 4096;
   acmStreamUnprepareHeader (has, &ahc, 0);
   acmStreamClose (has, 0);
}


char init_acm_stream_decomp (void)
{
   long  r;


   r = acmStreamOpen (&hasd, NULL, &mwfx.wfx, &wfx, 0, 0, 0, 0);
   if (!r)
   {

      memset (&ahd, 0, sizeof (ACMSTREAMHEADER));
      ahd.cbStruct = sizeof (ACMSTREAMHEADER);
      ahd.pbSrc = (BYTE *) comped_buf;
      ahd.cbSrcLength = 4096;
      ahd.pbDst = (BYTE *) decomp_buf;
      ahd.cbDstLength = 44100;
      r = acmStreamPrepareHeader (hasd, &ahd, 0);
      if (!r) return 1;

      acmStreamClose (hasd, 0);
   }

   return (0);
}

void close_acm_stream_decomp (void)
{
   ahd.cbSrcLength = 4096;
   ahd.cbDstLength = 44100;
   acmStreamUnprepareHeader (hasd, &ahd, 0);
   acmStreamClose (hasd, 0);
}


void close_sound (void)
{
   close_acm_stream_decomp();
   close_acm_stream ();
   close_wave_in_ds ();
   close_wave_out_ds ();
}



char init_sound (void)
{
   if (init_acm_stream_decomp ())
   {
      if (init_acm_stream()) return (1);
      else ErrB("init acm decomp stream");
      close_acm_stream_decomp();
   }
   else ErrB ("error initializing acm stream");
   return (0);
}

⌨️ 快捷键说明

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