Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Алгоритм программы на языке SDL




 

 

Листинг программы

 

//---------------------------------------------------------------------------

//подключение необходимых библиотек

#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 Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...