Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СТАРИКОВ_ ДИПЛОМ_ПЕЧАТЬ.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
3.42 Mб
Скачать

Приложения

Приложение А

Исходный код

Переменные для хранения звуковых волн и контейнеров:

const int NUMPTS = 44100 * 2 * 5;

int sampleRate = 44100;

short int waveIn[NUMPTS];

short int bWave[NUMPTS];

string names[1024];

int uCount = 0;

bool newUser = false;

char buf[7910] = "";

WAVEHDR wavehdr;

HWAVEIN in;

#define FREQUENCY 44100

int size = (FREQUENCY*3);

char *data = (char*)malloc(sizeof(char)*size);

Событие загрузки окна и чтение файла:

private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {

chart1->Visible = false;

chart2->Visible = false;

std::ifstream file("Read.txt");

std::string str;

while (std::getline(file, str))

{

names[uCount] = str;

uCount ++;

}

}

Считывание звука / регистрация данных о звуке:

WAVEFORMATEX pFormat;

pFormat.wFormatTag = WAVE_FORMAT_PCM;

pFormat.nChannels = 2;

pFormat.wBitsPerSample = 16;

pFormat.nSamplesPerSec = sampleRate;

pFormat.nAvgBytesPerSec = sampleRate * pFormat.nChannels * pFormat.wBitsPerSample / 8;

pFormat.nBlockAlign = pFormat.nChannels * pFormat.wBitsPerSample / 8;

pFormat.cbSize = 0;

HWAVEIN hWaveIn;

WAVEHDR waveInHdr;

waveInOpen(&hWaveIn, WAVE_MAPPER, &pFormat, 0L, 0L, WAVE_FORMAT_DIRECT);

waveInHdr.lpData = (LPSTR)waveIn;

waveInHdr.dwBufferLength = NUMPTS * 2;

waveInHdr.dwBytesRecorded = 0;

waveInHdr.dwUser = 0L;

waveInHdr.dwFlags = 0L;

waveInHdr.dwLoops = 0L;

waveInPrepareHeader(hWaveIn, &waveInHdr, sizeof(WAVEHDR));

waveInAddBuffer(hWaveIn, &waveInHdr, sizeof(WAVEHDR));

Случай идентификации:

if(!newUser)

{

//получаем имя пользователя

//создаем вспомагательные переменные

bool ok = false;

msclr::interop::marshal_context context;

std::string standardString = context.marshal_as<std::string>(textBox1->Text);

char name[255];

char fileToOpen[1024] = "";

strcat(fileToOpen, "users\\");

strcat(fileToOpen, standardString.c_str());

strcat(fileToOpen, ".raw");

//считываем файл с уже имеющимися данными

FILE *f2 = fopen(fileToOpen, "r");

if(f2 == NULL)

{

textBox1->Text = "ПОЛЬЗОВАТЕЛЬ НЕ НАЙДЕН!";

return;

}

//строим спекрограмму

chart1->Visible = true;

chart2->Visible = true;

linkLabel1->Visible = false;

button1->Visible = false;

label1->Visible = false;

chart1->Series[0]->LegendText = "Записанный голос";

chart2->Series[0]->LegendText = "Голос из БД";

chart2->Series[0]->Color = Color::Green;

for(int i = 0; i < NUMPTS; i ++)

{

chart1->Series[0]->Points->AddY(waveIn[i]);

}

//проводим сравнение с захваченным голосом

int cnt = 0;

char buf[128];

while (fgets(buf, sizeof(buf), f2) != NULL )

{

bWave[cnt] = atoi(buf);

chart2->Series[0]->Points->AddY(bWave[cnt]);

cnt ++;

}

int fcnt = 0;

for(int i = 0; i < cnt; i ++)

{

if(abs(abs(waveIn[i]) - abs(bWave[i])) > 3000)

fcnt ++;

}

if(fcnt > 1000)

label2->Text = "НЕ СОВПАДЕНИЕ!";

else

label2->Text = "СОВПАДЕНИЕ!";

}

Случай регистрации:

else // если регистрация нового пользователя

{

// записываем имя в базу имен пользователей

msclr::interop::marshal_context context;

std::string standardString = context.marshal_as<std::string>(textBox1->Text);

FILE *f = fopen("users\\usrs.dat", "a");

fprintf(f, "%s\n", standardString.c_str());

fclose(f);

//записываем звуковые данные в файл

System::String ^ str = textBox1->Text;

char users[1024] = "";

strcat(users, "users\\");

strcat(users, standardString.c_str());

strcat(users, ".raw");

FILE * f2 = fopen(users, "w");

for(int i = 0; i < NUMPTS; i ++)

{

fprintf(f2, "%d\n", waveIn[i]);

}

fclose(f2);

MessageBox::Show("Пользователь добавлен!");

button1->Text = "Идентификация";

newUser = false;

}

Запись аудио:

void WriteAudio(string name)

{

ofstream f( name, ios::binary );

f << "RIFF----WAVEfmt ";

write_word( f, 16, 4 );

write_word( f, 1, 2 );

write_word( f, 2, 2 );

write_word( f, 44100, 4 );

write_word( f, 176400, 4 );

write_word( f, 4, 2 );

write_word( f, 16, 2 );

size_t data_chunk_pos = f.tellp();

f << "data----";

double two_pi = 6.283185307179586476925286766559;

double max_amplitude = 32760;

double hz = 44100;

double frequency = 261.626;

double seconds = 5;

int N = hz * seconds;

for (int n = 0; n < N; n++)

{

double amplitude = (double)n / N * max_amplitude;

double value = sin( (two_pi * n * frequency) / hz );

write_word( f, (int)( amplitude * value), 2 );

write_word( f, (int)((max_amplitude - amplitude) * value), 2 );

}

size_t file_length = f.tellp();

f.seekp( data_chunk_pos + 4 );

write_word( f, file_length - data_chunk_pos + 8 );

f.seekp( 0 + 4 );

write_word( f, file_length - 8, 4 );

}

Захват аудио:

int StartRecord(char * data,int length)

{

int sampleRate = FREQUENCY;

HWAVEIN hWaveIn;

WAVEHDR WaveInHdr;

WAVEFORMATEX pFormat;

pFormat.wFormatTag=WAVE_FORMAT_PCM;

pFormat.nChannels=1;

pFormat.nSamplesPerSec=sampleRate;

pFormat.nAvgBytesPerSec=sampleRate;

pFormat.nBlockAlign=1;

pFormat.wBitsPerSample=8;

pFormat.cbSize=0;

if(waveInOpen(&hWaveIn, WAVE_MAPPER,&pFormat,0L, 0L, WAVE_FORMAT_DIRECT)) return 1;

WaveInHdr.lpData = (LPSTR)data;

WaveInHdr.dwBufferLength = length;

WaveInHdr.dwBytesRecorded=0;

WaveInHdr.dwUser = 0L;

WaveInHdr.dwFlags = 0L;

WaveInHdr.dwLoops = 0L;

waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));

if(waveInAddBuffer(hWaveIn, &WaveInHdr, sizeof(WAVEHDR))) return 2;

if(waveInStart(hWaveIn)) return 3;

while(waveInUnprepareHeader(hWaveIn,&WaveInHdr,sizeof(WAVEHDR)) == WAVERR_STILLPLAYING) Sleep(1);

waveInClose(hWaveIn);

return 0;

Открытие файла, запись в файл, закрытие файла:

FILE * wavfile_open( const char *filename )

{

struct wavfile_header header;

int samples_per_second = WAVFILE_SAMPLES_PER_SECOND;

int bits_per_sample = 16;

strncpy(header.riff_tag,"RIFF",4);

strncpy(header.wave_tag,"WAVE",4);

strncpy(header.fmt_tag,"fmt ",4);

strncpy(header.data_tag,"data",4);

header.riff_length = 0;

header.fmt_length = 16;

header.audio_format = 1;

header.num_channels = 1;

header.sample_rate = samples_per_second;

header.byte_rate = samples_per_second*(bits_per_sample/8);

header.block_align = bits_per_sample/8;

header.bits_per_sample = bits_per_sample;

header.data_length = 0;

FILE * file = fopen(filename,"w+");

if(!file) return 0;

fwrite(&header,sizeof(header),1,file);

fflush(file);

return file;

}

void wavfile_write( FILE *file, short data[], int length )

{

fwrite(data,sizeof(short),length,file);

}

void wavfile_close( FILE *file )

{

int file_length = ftell(file);

int data_length = file_length - sizeof(struct wavfile_header);

fseek(file,sizeof(struct wavfile_header) - sizeof(int),SEEK_SET);

fwrite(&data_length,sizeof(data_length),1,file);

int riff_length = file_length - 8;

fseek(file,4,SEEK_SET);

fwrite(&riff_length,sizeof(riff_length),1,file);

fclose(file);

}

Приложение Б

Моделирование в приложении Mathcad

Входной сигнал:

Рисунок 1 Входной сигнал

Разбиение входного сигнала на перекрывающие области:

Рисунок 2 Сегмент сигнала длительностью 23 мс.

Фильтр для сегмента:

Рисунок 3 Сегмент входного сигнала

Вычисление спектра каждого сегмента:

Рисунок 4 Спектр сегмента

Треугольные перекрывающие фильтры в мел-частотной области:

Рисунок 5 Треугольные перекрывающие фильтры

Вычисление мел-частотных кепстральных коэффициентов для каждого сегмента:

Рисунок 6 Мел-частотные кепстральные коэффициенты

Вычисление расстояния между коэффициентами двух сигналов:

Рисунок 7 Таблица расстояний

94