- •Назначение и условия применения 53
- •Введение
- •1 Постановка задачи
- •2 Аналитическая часть
- •2.1Факторы, влияющие на уникальность речи
- •2.2 Система распознавания личности
- •2.3 Образец и его предобработка
- •2.3.1 Обрабатываемый образец
- •2.3.2 Предварительная обработка
- •2.4 Извлечение признаков
- •2.4.2. Кепстральные коэффициенты, основанные на линейного предсказания
- •2.5 Обработка извлеченных признаков
- •2.6 Способы классификации моделей
- •2.6.1 Вычисление расстояний
- •2.6.2. Метод опорных векторов
- •2.6.3 Модель гауссовых смесей
- •2.6.4 Метод ближайшего соседа
- •2.7 Аналогичные программы
- •VoiceKey
- •VoiceNet
- •2.8 Недостатки большинства системы идентификации по голосу
- •2.9 Действующие национальные стандарты
- •3 Конструкторская часть
- •3.1. Функциональная схема аппаратных средств
- •3.2 Функциональная схема программного средства
- •3.3 Информационная схема программного средства
- •3.4 Алгоритм программного средства
- •7. Вычисление расстояний.
- •3.5. Язык программирования и среда разработки
- •4 Документация программного средства
- •4.1 Техническое задание
- •4.1.1 Основания для разработки
- •4.1.2 Назначение разработки
- •4.1.3 Требования к программному средству
- •4.1.4 Требования к программной документации
- •4.2 Руководство системного программиста
- •4.2.1 Общие сведения о программном средстве
- •4.2.2 Структура программного средства
- •4.3 Руководство администратора
- •4.3.1 Назначение и условия применения
- •4.4 Руководство оператора
- •4.4.1 Назначение и условия применения
- •4.4.2 Выполнение программного средства
- •5. Экспериментальная часть
- •6 Организационно - экономическая часть
- •6.1 Описание эффектов от внедрения разработки
- •6.2 Планирование процесса разработки программного средства
- •Техническое задание – 15%;
- •6.3 Смета затрат на разработку
- •6.3.1 Материальные затраты
- •6.3.2 Расходы на оплату труда
- •6.3.3 Отчисления на социальные страхования от заработной платы
- •6.3.4 Амортизационные отчисления
- •6.3.5. Прочие прямые расходы
- •6.3.6 Накладные расходы
- •7 Безопасность жизнедеятельности
- •7.1 Введение
- •7.2 Анализ опасных и вредных факторов
- •7.3 Мероприятия по нормализации и защите от вредных и опасных воздействий.
- •7.4 Возможные чрезвычайные ситуации
- •7.5 Оценка напряженности трудового процесса
- •7.6. Выводы
- •Список используемой литературы
- •Приложения
Приложения
Приложение А
Исходный код
Переменные для хранения звуковых волн и контейнеров:
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 Таблица расстояний
