Алгоритм программы на языке SDL
⇐ ПредыдущаяСтр 2 из 2
Листинг программы
//--------------------------------------------------------------------------- //подключение необходимых библиотек #include <vcl.h> #include <MMSystem.h> #include <winsock2.h>
//включение информации из файла #include "Unit1.h"
#pragma package(smart_init) #pragma resource "*.dfm"
TForm1 *Form1; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //необходимые переменные и константы const int SIZE_OF_SOUND=192; //размер области аудиоданных пакета
//параметры циклического буфера для принятых аудиоданных int fst; //указатель на первый элемент буфера int lst; //указатель на следующий за последним элемент буфера const int SIZE_OF_BUF=14; //максимальное число элементов буфера char QUEUE[SIZE_OF_BUF][SIZE_OF_SOUND]; //буфер
//буфер для воспроизведения char PlayBuf[SIZE_OF_SOUND];
bool EnableReceive=false; //индикатор разрешения приёма трансляции bool StreamOpen=false; //индикатор создания потока bool Timer2Enable=false; //индикатор запуска таймера на воспроизведение char WaveBuf[SIZE_OF_SOUND]; //буфер для считанных из файла данных HANDLE Soc_id; //дескриптор потока DWORD S_id; //идентификатор потока
WAVEHDR pwhPlay; //структура, описывающая буфер на проигрывание звука HWAVEOUT hwo; //идентификатор аудиоустройства WAVEFORMATEX CurrentFormatFile; //структура с описанием формата звуковых данных MMRESULT mres; //переменная для хранения результата выполнения функции HMMIO hmmio; //идентификатор файла
//функция записи принятых аудиоданных в циклический буфер void In(char* SoundBuff); //--------------------------------------------------------------------------- //структура с описанием формата пакета struct Sound
{ char NameFile[10]; //имя файла int Number; //номер кадра char SoundData[SIZE_OF_SOUND]; //аудиоданные }; //--------------------------------------------------------------------------- //функция записи принятых аудиоданных в циклический буфер
void In(char* Buf) { //запись в буфер memcpy(QUEUE[lst],Buf,SIZE_OF_SOUND); lst=(lst+1)%SIZE_OF_BUF;
//разрешить срабатывание таймера на воспроизведение принятых данных //если он ещё не запущен if (Timer2Enable==false) { Form1->Timer2->Enabled=true; Timer2Enable=true; }; } //--------------------------------------------------------------------------- //описание класса TSoc class TSoc { public: int i, j; //число отправленных/принятых пакетов int prevNumber; //номер предыдущего принятого пакета SOCKET s; //идентификатор сокета SOCKADDR_IN to; //структура с описанием адреса получателя SOCKADDR_IN from; //структура с описанием адреса отправителя char RecvBuffer[SIZE_OF_SOUND+58]; //буфер для принятого пакета Sound sSound; //объект класса Sound
TSoc(); //конструктор bool Create(); //функция создания и настройки сокета void Receive(); //функция приёма пакетов void Send(char* SendVoiceBuf); //функция отправки пакетов }; //--------------------------------------------------------------------------- //конструктор класса TSoc TSoc::TSoc() { i=1; //число приняных пакетов j=1; //число переданных пакетов prevNumber=0; //номер предыдущего принятого пакета } //--------------------------------------------------------------------------- //функция создания и настройки сокета bool TSoc::Create() { //инициализация сокета WSADATA wsadata; WORD wVersionRequested; wVersionRequested = MAKEWORD(2,0); if (WSAStartup(wVersionRequested,&wsadata)==SOCKET_ERROR) { MessageBox(0,"Error: WSAStartup",0,MB_OK); return false; };
//создание сокета и присвоение идентификатора s=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if(s==INVALID_SOCKET) { MessageBox(0,"Error: Create socket",0,MB_OK); return false; };
//создание структуры адреса отправителя from.sin_addr.S_un.S_addr=ADDR_ANY; from.sin_family=PF_INET; from.sin_port=5000;
//подключение сокета к коммуникационной среде int errSer=bind(s,(LPSOCKADDR)&from,sizeof(from)); if(errSer!=0) { MessageBox(0,"Error: Bind", 0, MB_OK); closesocket(s); //закрытие сокета return false; };
return true; } //--------------------------------------------------------------------------- //функция формирования и передачи пакетов void TSoc::Send(char* SendVoiceBuf) { //заполнение заголовка пакета //имя файла берётся из поля "nameFile" memcpy(sSound.NameFile,Form1->nameFile->Text.c_str(),15); //номер пакета
sSound.Number=j; //заполнение поля данных memcpy(sSound.SoundData,SendVoiceBuf,SIZE_OF_SOUND);
//формирование структуры с IP-адресом получателя to.sin_family=PF_INET; to.sin_addr.S_un.S_addr=inet_addr(Form1->To->Text.c_str()); to.sin_port=5000;
//отправка пакета int err=sendto(s,(char*)(&sSound),sizeof(Sound),0,(struct sockaddr*)&to,sizeof(to)); if (err==SOCKET_ERROR) MessageBox(0,"Error: Send sound",0,MB_OK); //число переданных пакетов else { Form1->lSend->Caption="Послано пакетов: "+IntToStr(j); j++; }; } //--------------------------------------------------------------------------- //функция приёма пакетов void TSoc::Receive() { //определение наличия пришедших данных unsigned long lSize; ioctlsocket(s,FIONREAD,&lSize); if (lSize==0) return;
//приём данных int cadr=sizeof(from); recvfrom(s,RecvBuffer,SIZE_OF_SOUND+58,0,(struct sockaddr*)&from,&cadr);
//указатель на буфер с принятыми данными Sound* pointSound; pointSound=(Sound*) RecvBuffer;
//анализ номера пакета //если нумерация нарушается, то пакет не воспроизводится if (pointSound->Number>prevNumber) { //вывод числа принятых пакетов и имени файла AnsiString st=pointSound->NameFile; Form1->lReceive->Caption="Имя файла: "+st+"\nПринято пакетов: "+IntToStr(i); i++;
//отправка данных в буфер для накопления In(pointSound->SoundData); }; return; } //--------------------------------------------------------------------------- TSoc Soc; //объект класса TSoc //--------------------------------------------------------------------------- //функция потока для контроля данных пришедших на сокет DWORD WINAPI ThreadSoc(LPVOID) { while(true) { //индикатор разрешения приёма трансляции if (EnableReceive) { //вызов функции обработки принятых данных Soc.Receive(); }; }; } //--------------------------------------------------------------------------- //запуск программы __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { //вызов функции создания и настройки сокета if (Soc.Create()) btSend->Enabled=true; else return;
//инициализация формата звуковых данных CurrentFormatFile.wFormatTag=WAVE_FORMAT_PCM; CurrentFormatFile.nChannels=1; CurrentFormatFile.nSamplesPerSec=8000; CurrentFormatFile.nAvgBytesPerSec=8000; CurrentFormatFile.nBlockAlign=1; CurrentFormatFile.wBitsPerSample=8;
//открытие устройства воспроизведения UINT uDeviceID=WAVE_MAPPER; mres=waveOutOpen(&hwo,uDeviceID,&CurrentFormatFile,0,0,0); if (mres!=0) MessageBox(0,"Error: WaveOutOpen",0,MB_OK); else btReceive->Enabled=true; } //--------------------------------------------------------------------------- //нажатие кнопки Начать передачу void __fastcall TForm1::btSendClick(TObject *Sender) { //открытие файла для чтения //char sfile[15]; //memcpy(sfile,Form1->nameFile->Text.c_str(),15); hmmio=mmioOpen("pesnya.wav",0,MMIO_READ); if (hmmio==0) { MessageBox(0,"Error: mmioOpen",0,MB_OK); btSend->Enabled=false; return; };
btSend->Enabled=false; //деактивация кнопки "Начать передачу"
btStopSend->Enabled=true; //активация кнопки "Остановить" nameFile->Enabled=false; //запрещение редктирования поля "Имя файла" To->Enabled=false; //запрещение редктирования поля "Кому"
//разрешить срабатывание таймера на отправку пакетов Timer1->Enabled=true; } //--------------------------------------------------------------------------- //срабатывание таймера на отправку пакетов void __fastcall TForm1::Timer1Timer(TObject *Sender) { //прочитать данные из открытого блока mmioRead(hmmio,WaveBuf,SIZE_OF_SOUND);
//вызов функции отправки пакета Soc.Send(WaveBuf); } //-------------------------------------------------------------------------- //нажатие кнопки Остановить void __fastcall TForm1::btStopSendClick(TObject *Sender) { btStopSend->Enabled=false; //деактивация кнопки "Остановить" btSend->Enabled=true; //активация кнопки "Начать передачу" nameFile->Enabled=true; //разрешение редактирования поля "Имя файла" To->Enabled=true; //разрешение редактирования поля "Кому"
Timer1->Enabled=false; //запретить срабатывание таймера на отправку пакетов } //--------------------------------------------------------------------------- //нажатие кнопки Принимать void __fastcall TForm1::btReceiveClick(TObject *Sender) { EnableReceive=true; //индикатор разрешения приёма трансляции
//создание потока для контроля пришедших данных if (StreamOpen==false) { //создание потока Soc_id=CreateThread(0,0,ThreadSoc,0,0,&S_id); StreamOpen=true; //индикатор создания потока };
btReceive->Enabled=false; //деактивация кнопки "Принимать" btStopReceive->Enabled=true; //активация кнопки "Прекратить" } //--------------------------------------------------------------------------- //срабатывание таймера на воспроизведение принятых данных void __fastcall TForm1::Timer2Timer(TObject *Sender)
{ //взять блок данных из начала очереди memcpy(PlayBuf,QUEUE[(fst+1)%SIZE_OF_BUF],SIZE_OF_SOUND); fst=(fst+1)%SIZE_OF_BUF;
//подготовка буфера для воспроизведения pwhPlay.lpData=PlayBuf; pwhPlay.dwBufferLength=SIZE_OF_SOUND; pwhPlay.dwFlags=0;
//подготовка блока аудиоданных для воспроизведения mres=waveOutPrepareHeader(hwo,&pwhPlay,sizeof(pwhPlay)); if (mres!=0) MessageBox(0,"Error: OutPrepareHeader",0,MB_OK);
//отправка блока аудиоданных заданному устройству вывода mres=waveOutWrite(hwo,&pwhPlay,sizeof(pwhPlay)); if (mres!=0) MessageBox(0,"Error: waveOutWrite",0,MB_OK); } //---------------------------------------------------------------------------
//нажатие кнопки Прекратить void __fastcall TForm1::btStopReceiveClick(TObject *Sender) { EnableReceive=false; //индикатор разрешения приёма трансляции //запретить срабатывание таймера на воспроизведение принятых данных Timer2->Enabled=false; Timer2Enable=false; //инликатор запуска таймера на воспроизведение
btReceive->Enabled=true; //активация кнопки "Принимать" btStopReceive->Enabled=false; //деактивация кнопки "Прекратить" } //-------------------------------------------------------------------------- //выход из программы void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) { mmioClose(hmmio, 0); //закрытие файла waveOutClose(hwo); //закрытие звукового устройства closesocket(Soc.s); //закрытие сокета при выходе из программы //---------------------------------------------------------------------------
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|