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

📄 main.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 <winsock2.h>
#include <windows.h>
#include <mmsystem.h>
#include <mmreg.h>
#include <msacm.h>
#include <stdio.h>
#include "defines.h"
#include "resource.h"



// external functions
char init_sockets (void);
void close_sockets (void);
char init_sound (void);
void close_sound (void);
DWORD WINAPI sender (LPVOID);
DWORD WINAPI receiver (LPVOID);
DWORD WINAPI player (LPVOID);
BOOL CALLBACK addr_dialog (HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK talk_dialog (HWND, UINT, WPARAM, LPARAM);



int               queue_size;
sound_sec         sqq[MAX_QUEUE];
int               index_put, index_take;

bool              dbl;
HANDLE            heap;   // maybe will use this for allocating memory dynamically for the ACM
int               band;   // stupid name
bool              stereo, use_primary;
bool              blocks_got[16];
unsigned char     total_blocks;

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

CRITICAL_SECTION  cs;
char              my_addr_txt [16], dst_addr_txt [16];
unsigned long     my_addr, dst_addr;
unsigned short    next_send_id, next_receive_id;
SOCKET            ssin, sout;
HACMSTREAM        has, hasd;
HANDLE            hPlay, hRec[10], hTerminate, hData;
int               segments, lock_size, input_buffer_size, output_buf_size;
HANDLE            Thread [3];
DWORD             id [3];
ACMSTREAMHEADER   ahc, ahd;
WAVEFORMATEX      wfx;
MPEG_WFX          mwfx;
char              listen_mode;
HWND              talker_dlg;





void ErrB (char *msg, int x=0, HWND hwnd=0)
{
   char str[128];


   if (x) sprintf(str, "%s, code: %X", msg, x);
   else sprintf(str, "%s", msg);
   MessageBox(hwnd, str, 0, 0);
}



void release_vars (void)
{
   DeleteCriticalSection (&cs);
   CloseHandle (hPlay);
   CloseHandle (hTerminate);
   CloseHandle (hData);
}



char init_vars (void)
{
   hPlay = CreateEvent (0, 0, 0, 0);
   if (hPlay)
   {
      for (int i=0;i<10;i++) hRec[i] = CreateEvent (0, 0, 0, 0);
      if (hRec[0]&&hRec[1]&&hRec[2]&&hRec[3]&&hRec[4]&&hRec[5]&&hRec[6]&&hRec[7]&&hRec[8]&&hRec[9])
      {
         hTerminate = CreateEvent (0, 1, 0, 0);
         if (hTerminate)
         {
            hData = CreateSemaphore(0, 0, 63, 0);
            if (hData)
            {
               next_receive_id = 0;
               next_send_id = 1;

               my_addr = 0;

               memset (&mwfx, 0, sizeof (MPEG_WFX));
               mwfx.wfx.wFormatTag = 85;
               mwfx.wfx.nChannels = (stereo) ? 2 : 1;
               mwfx.wfx.nSamplesPerSec = 11025;
               mwfx.wfx.nAvgBytesPerSec = (band==0) ? 1000 : ((band==1) ? 2000 : 2500);
               mwfx.wfx.nBlockAlign = 1;
               mwfx.wfx.wBitsPerSample = 0;
               mwfx.wfx.cbSize = 12;
               // only 11025hz; adjust channels for number of channels
               // for 20kbit: data[6]=4,data[7]=1,data[8]=2, avgbytespersec=2500
               // THE 18kbit is not good since it requires 5 packets which is exactly as the 20kbit which is better
               // for 18kbit: data[6]=0xD4,data[7]=1,data[8]=4,avg=2250
               // for 16kbit: data[6]=0x68,avg=2000
               // for 8kbit: data[6]=0x34,data[8]=1, avg=1000
               mwfx.data[0] = 1;
               mwfx.data[2] = 2;
               mwfx.data[10] = 0x71;
               mwfx.data[11] = 5;
               switch (band)
               {
                  case 0:
                     mwfx.data[6] = 0x34;
                     mwfx.data[8] = 1;
                     break;

                  case 1:
                     mwfx.data[6] = 0x68;
                     mwfx.data[8] = 1;
                     break;

                  case 2:
                     mwfx.data[6] = 4;
                     mwfx.data[7] = 1;
                     mwfx.data[8] = 2;
                     break;
               }



               wfx.wFormatTag = WAVE_FORMAT_PCM;
               wfx.nChannels = (stereo) ? 2 : 1;
               wfx.nSamplesPerSec = 11025;
               wfx.nAvgBytesPerSec = (stereo) ? 44100 : 22050;
               wfx.nBlockAlign = (stereo) ? 4 : 2;
               wfx.wBitsPerSample = 16;
               wfx.cbSize = 0;


               InitializeCriticalSection (&cs);
               index_put = 0;
               index_take = -1;
               queue_size = 0;
               dbl = false;
               segments = 4;
               input_buffer_size = (stereo)?44100:22050;
               lock_size = (stereo)?11024:5512;

               return (1);
            }
            //CloseHandle (hTerminate);
         }
         //CloseHandle (hRec);
      }
      //CloseHandle (hPlay);
   }
   return (0);
}







char init_threads (void)
{
   Thread[0] = CreateThread (0, 0, sender, 0, 0, &id[0]);
   if (Thread[0])
   {
      Thread[1] = CreateThread (0, 0, player, 0, CREATE_SUSPENDED, &id[1]);
      if (Thread[1])
      {
         Thread[2] = CreateThread (0, 0, receiver, 0, CREATE_SUSPENDED, &id[2]);
         if (Thread[2]) return (1);
      }
   }

   SetEvent (hTerminate);
   return (0);
}



void close_threads (void)
{
   SetEvent (hTerminate);
   ResumeThread (Thread[1]);
   ResumeThread (Thread[2]);
   WaitForMultipleObjects (3, Thread, 1, INFINITE);
}


char init_all (void)
{
   if (init_vars ())
   {
      if (init_sound ())
      {
         if (init_sockets ())
         {
            if (init_threads ()) return (1);
         }

         else ErrB ("socket problem");
         close_sound ();
      }
      else ErrB ("sound problem");
      release_vars ();
   }
   else ErrB ("varialbe problem");

   return (0);
}


void close_all (void)
{
   close_threads ();
   close_sound ();
   close_sockets ();
}








int WINAPI WinMain (HINSTANCE h1, HINSTANCE h2, LPSTR cmd, int show)
{

   int  r;



   // after much thought, it seems just right to give ourselves a boost
   // and anyway, we don't waste that much cycles
   SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
   band = 0;
   r = DialogBox (h1, MAKEINTRESOURCE (IDD_ADDRESS), 0, (DLGPROC) addr_dialog);
   switch (r)
   {
      case 0 :
         ErrB ("operation canceled");
         break;

      case 1:
         if (init_all ())
         {
            r = DialogBox (h1, MAKEINTRESOURCE (IDD_TALK), 0, (DLGPROC) talk_dialog);
            if (r) ErrB ("failed to create dialog box, aborting");
            close_all ();
         }
         else ErrB ("init failed");
         break;

      case -1 :
         ErrB ("failed to create first dialog box, aborting");
         break;
   }


   ExitProcess (0);
   return (0);
}

⌨️ 快捷键说明

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