Синтезаторы речи - русский синтезатор речи RHVoice
Участников: 2
Страница 1 из 1
Синтезаторы речи - русский синтезатор речи RHVoice
не так давно, в свет вышел очередной бесплатный синтезатор русской речи RHVoice. этот синтезатор выпускается под GNU General Public License, тоесть с открытыми исходниками.
он обладает не плохой разборчивостью, средней интонацией. пока имеет два голоса, мужской и женский.
разработала его, неповерите!, девушка - Ольга яковлева. синтезатор разрабатывает, вроде под linux'ом, и портирует еще под windows.
в первую очередь, целью стояло, разработать синтезатор с разборчивой речью, чтобы незрячие могли использовать его в программах экранного доступа.
как раз, первая версия под windows , была сделана под программу экранного доступа nvda.
сейчас же, синтезатор разрабатывается и под программу nvda, и под speech api 5- (sapi5).
естественно, он используется и в программах экранного доступа под linux.
подробно, на чем основан, ссылки на ресурсы, прочитаете в подкаталоге RHVoice-doc.
мне понравился этот синт, и я решил адаптировать заголовочные файлы под FreeBasic.
качаем синтезатор + заголовочный файл + пример программы:
http://svalka-spb.narod.ru/soft/RHVoice.rar
Я НЕСТАЛ ПЕРЕГРУЖАТЬ ПРИМЕР ПРОГРАММЫ КУЧЕЙ ФУНКЦИЙ, ВСЕ ДОЛЖНО БЫТЬ ПОНЯТНО.
ДОКУМЕНТАЦИИ К СИНТЕЗАТОРУ ПОКА НЕТ, НО ЕСЛИ ЧТО-ТО НЕ ПОЙМЕТЕ, БУДЕМ РАЗБИРАТЬСЯ.
ДАННЫЙ ПРИМЕР ПРОГРАММЫ РАБОТАЕТ ТОЛЬКО ПОД WINDOWS.
пользователям LINUX, ЕСЛИ НАЙДЕТЕ, ИЛИ САМИ СМОЖЕТЕ СОБРАТЬ БИБЛИОТЕКУ RHVoice ИЗ ИСХОДНИКОВ, ПРИДЕТСЯ СДЕЛАТЬ некоторые изменения.
файл RHVoice.bi
тестовая программа - файл RHVoice.bas
он обладает не плохой разборчивостью, средней интонацией. пока имеет два голоса, мужской и женский.
разработала его, неповерите!, девушка - Ольга яковлева. синтезатор разрабатывает, вроде под linux'ом, и портирует еще под windows.
в первую очередь, целью стояло, разработать синтезатор с разборчивой речью, чтобы незрячие могли использовать его в программах экранного доступа.
как раз, первая версия под windows , была сделана под программу экранного доступа nvda.
сейчас же, синтезатор разрабатывается и под программу nvda, и под speech api 5- (sapi5).
естественно, он используется и в программах экранного доступа под linux.
подробно, на чем основан, ссылки на ресурсы, прочитаете в подкаталоге RHVoice-doc.
мне понравился этот синт, и я решил адаптировать заголовочные файлы под FreeBasic.
качаем синтезатор + заголовочный файл + пример программы:
http://svalka-spb.narod.ru/soft/RHVoice.rar
Я НЕСТАЛ ПЕРЕГРУЖАТЬ ПРИМЕР ПРОГРАММЫ КУЧЕЙ ФУНКЦИЙ, ВСЕ ДОЛЖНО БЫТЬ ПОНЯТНО.
ДОКУМЕНТАЦИИ К СИНТЕЗАТОРУ ПОКА НЕТ, НО ЕСЛИ ЧТО-ТО НЕ ПОЙМЕТЕ, БУДЕМ РАЗБИРАТЬСЯ.
ДАННЫЙ ПРИМЕР ПРОГРАММЫ РАБОТАЕТ ТОЛЬКО ПОД WINDOWS.
пользователям LINUX, ЕСЛИ НАЙДЕТЕ, ИЛИ САМИ СМОЖЕТЕ СОБРАТЬ БИБЛИОТЕКУ RHVoice ИЗ ИСХОДНИКОВ, ПРИДЕТСЯ СДЕЛАТЬ некоторые изменения.
файл RHVoice.bi
- Код:
'/* Copyright (C) 2010, 2011 Olga Yakovleva <yakovleva.o.v@gmail.com> */
'/* 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 3 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, see <http://www.gnu.org/licenses/>. */
' *** adapted headers for FreeBasic by electrik
#ifndef RHVOICE_bi
#define RHVOICE_bi
extern "c" lib "rhvoice"
type RHVoice_message_s as any
type as RHVoice_message_s ptr RHVoice_message
enum RHVoice_init_option
RHVoice_preload_voices=1
end enum
enum RHVoice_message_type
RHVoice_message_text
RHVoice_message_ssml
RHVoice_message_characters
end enum
enum RHVoice_event_type
RHVoice_event_word_start
RHVoice_event_word_end
RHVoice_event_sentence_start
RHVoice_event_sentence_end
RHVoice_event_mark
RHVoice_event_play
end enum
union id_
as const zstring ptr name '/* For marks and audio elements */
as integer number '/* For words and sentences */
end union
type RHVoice_event
as RHVoice_message message
as RHVoice_event_type type
as integer text_position '/* in unicode characters */
as integer text_length '/* in unicode characters */
as integer audio_position
union
id as id_
end union
end type
type RHVoice_callback as function (byval samples as const short ptr,byval num_samples as integer,byval events as const RHVoice_event ptr,byval num_events as integer,byval message as RHVoice_message) as integer
enum RHVoice_position_type
RHVoice_position_word
RHVoice_position_sentence
RHVoice_position_mark
end enum
union id2
as integer number
as const zstring ptr name
end union
type RHVoice_position
as RHVoice_position_type ptype
union
id as id2
end union
end type
enum RHVoice_punctuation_mode
RHVoice_punctuation_none
RHVoice_punctuation_all
RHVoice_punctuation_some
end enum
enum RHVoice_voice_gender
RHVoice_voice_gender_unknown
RHVoice_voice_gender_male
RHVoice_voice_gender_female
end enum
'/* This mode applies to reading by characters. */
enum RHVoice_capitals_mode
RHVoice_capitals_off
RHVoice_capitals_pitch
RHVoice_capitals_sound
end enum
'/* Under Windows we assume that the paths are in UTF-8 */
'/* This function returns sample rate on success and 0 on error */
declare function RHVoice_initialize(byval data_path as const zstring ptr,byval callback as RHVoice_callback ptr,byval cfg_path as const zstring ptr,byval options as uinteger) as integer
declare sub RHVoice_terminate()
'/* The following three functions accept only valid unicode strings */
declare function RHVoice_new_message_utf8(byval text as const any ptr,byval length as integer,byval mtype as RHVoice_message_type) as RHVoice_message
declare function RHVoice_new_message_utf16(byval text as const any ptr,byval length as integer,byval mtype as RHVoice_message_type) as RHVoice_message
declare function RHVoice_new_message_utf32(byval text as const any ptr,byval length as integer,byval mtype as RHVoice_message_type) as RHVoice_message
declare sub RHVoice_delete_message(byval message as RHVoice_message)
declare function RHVoice_speak(byval message as RHVoice_message) as integer
declare function RHVoice_get_xml_base(byval message as RHVoice_message) as const zstring ptr
declare function RHVoice_set_position(byval message as RHVoice_message,byval position as const RHVoice_position ptr) as integer
declare function RHVoice_get_word_count(byval message as RHVoice_message) as integer
declare function RHVoice_get_sentence_count(byval message as RHVoice_message) as integer
declare sub RHVoice_set_rate(byval rate as single)
declare function RHVoice_get_rate() as single
declare sub RHVoice_set_pitch(byval pitch as single)
declare function RHVoice_get_pitch() as single
declare sub RHVoice_set_volume(byval volume as single)
declare function RHVoice_get_volume() as single
declare function RHVoice_get_min_rate() as single
declare function RHVoice_get_default_rate() as single
declare function RHVoice_get_max_rate() as single
declare function RHVoice_get_min_pitch() as single
declare function RHVoice_get_default_pitch() as single
declare function RHVoice_get_max_pitch() as single
declare function RHVoice_get_default_volume() as single
declare function RHVoice_get_max_volume() as single
declare sub RHVoice_set_variant(byval variant as integer)
declare function RHVoice_get_variant() as integer
declare function RHVoice_get_variant_count() as integer
declare function RHVoice_get_variant_name(byval variant as integer) as const zstring ptr
declare function RHVoice_find_variant(byval name as const zstring ptr) as integer
declare function RHVoice_get_voice_count() as integer
declare function RHVoice_get_voice_name(byval id as integer) as const zstring ptr
declare function RHVoice_get_voice_gender(byval id as integer) as RHVoice_voice_gender
declare function RHVoice_find_voice(byval name as const zstring ptr) as integer
declare sub RHVoice_set_voice(byval id as integer)
declare function RHVoice_get_voice() as integer
declare sub RHVoice_set_punctuation_mode(byval mode as RHVoice_punctuation_mode)
declare function RHVoice_get_punctuation_mode() as RHVoice_punctuation_mode
declare sub RHVoice_set_punctuation_list(byval list as const zstring ptr)
declare sub RHVoice_set_capitals_mode(mode as RHVoice_capitals_mode)
declare function RHVoice_get_capitals_mode() as RHVoice_capitals_mode
declare sub RHVoice_set_user_data(byval message as RHVoice_message,byval data as any ptr)
declare function RHVoice_get_user_data(byval message as RHVoice_message) as any ptr
declare sub RHVoice_set_message_rate(byval message as RHVoice_message,byval rate as single)
declare sub RHVoice_set_message_pitch(byval message as RHVoice_message,byval pitch as single)
declare sub RHVoice_set_message_volume(byval message as RHVoice_message,byval volume as single)
declare function RHVoice_get_version() as const zstring ptr
end extern
#endif
тестовая программа - файл RHVoice.bas
- Код:
#include "windows.bi"
#include "win/mmsystem.bi"
#include "crt.bi"
#include "RHVoice.bi"
declare function callback cdecl (byval samples as const short ptr,byval num_samples as integer,byval events as const RHVoice_event ptr,byval num_events as integer,byval message as RHVoice_message) as integer
declare sub ShowErrorMessage()
#define nhdr 3
dim shared wFormat as WaveFormatEx ' структура формата звуковых данных
dim shared wHdr(nhdr) as wavehdr ' структура заголовка буфера
dim shared buf(nhdr) as zstring * 9600 ' буфер для звуковых данных
dim shared numbuf as integer = 0
dim shared lenBuf as integer ' длина буфера
dim shared hOut as HANDLE ' хэндл звукового устройства
dim shared hEvent as HANDLE ' хэндл объекта события
dim msg as RHVoice_message = 0 ' сообщения RHVoice
dim prog_path as const string = ExePath() ' получим путь к директории из которой запущена программа
dim Data_path as const string = prog_path & "/RHVoice-data" ' путь к данным синтезатора - там хранятся голоса
dim cfg_path as const string = prog_path & "/RHVoice-config" 'путь к настройкам и словарям синтезатора
dim sample_rate as uInteger ' частота дискретизации
' инициализируем RHVoice. функция возвращает частоту дискретизации. в случае ошибки нуль.
sample_rate=RHVoice_initialize _
(Data_path, _ ' путь к данным синтезатора
cast(RHvoice_callback ptr, @callback), _ ' указатель на функцию обратного вызова
cfg_path, _ ' путь к настройкам синтезатора
RHVoice_preload_voices) ' опция инициализации - предзагрузка голосов
if sample_rate = 0 then
print "can't initialize RHVoice"
end 1
end if
' заполним структуру формата звуковых данных
wFormat.wFormatTag=1 ' данные в формате pcm
wFormat.nChannels= 1 'число каналов 1
wFormat.nSamplesPerSec = sample_rate ' частота дискретизации
wFormat.nAvgBytesPerSec = sample_rate*2 ' частота выдачи байт
wFormat.nBlockAlign= 2 ' выравнивание
wFormat.wBitsPerSample = 16 ' 16 бит на семпл
' создадим объект события
hEvent = CreateEvent(NULL,false,false,NULL)
if waveOutOpen(@hOut, -1,@wFormat,cptr(DWORD,hEvent),0,CALLBACK_EVENT) then ' если при открытии устройства произошла ошибка
ShowErrorMessage() ' покажем сообщение об ошибке
CloseHandle(hEvent) ' закроем хэндл объекта события
end 1
end if
dim voice as integer = RHVoice_find_voice("Aleksandr") ' найдем голос по имени Aleksandr
if voice > 0 then ' если номер голоса больше нуль, значит голос найден
RHVoice_set_voice(voice) ' установим голос по номеру
else
print "no voice"
closeHandle(hOut)
CloseHandle(hEvent) ' закроем хэндл объекта события
end 1
end if
dim testString as string * 512 = "привет. меня зовут александр. я русский синтезатор речи RHVoice. сотворила меня ольга яковлева, за что ей огромное спасибо! "
dim wideString as wstring * 1024 ' юникодовая строка
MultiByteToWideChar(CP_ACP,0,strPtr(testString),len(testString),wideString,len(testString)*2) ' перекодируем анси в юникод
msg=RHVoice_new_message_utf16 _ ' подготовим текст, который будем говорить
(cast(any ptr,@wideString), _ ' строка с текстом
len(wideString), _ ' длина строки в юникоде
RHVoice_message_text) ' тип сообщения
if msg= 0 then ' если ошибка
RHVoice_terminate() ' завершаем работу RHVOICE '
closeHandle(hOut)
CloseHandle(hEvent) ' закроем хэндл объекта события
end 1
end if
RHVoice_speak(msg) ' скажем наш текст
RHVoice_delete_message(msg) ' удаляем сообщение
' выберем другой голос
voice = RHVoice_find_voice("Elena") ' найдем голос по имени Elena
if voice > 0 then ' если номер голоса больше нуль, значит голос найден
RHVoice_set_voice(voice) ' установим голос по номеру
else
print "no voice"
closeHandle(hOut)
CloseHandle(hEvent) ' закроем хэндл объекта события
end 1
end if
testString = "а меня завут елена. я женский голос синтезатора RHVoice. меня тоже создала ольга."
MultiByteToWideChar(CP_ACP,0,strPtr(testString),len(testString),wideString,len(testString)*2)
msg=RHVoice_new_message_utf16 _ ' подготовим текст, который будем говорить
(cast(any ptr,@wideString), _ ' строка с текстом
len(wideString), _ ' длина строки
RHVoice_message_text) ' тип сообщения
if msg= 0 then ' если ошибка
RHVoice_terminate() ' завершаем работу RHVOICE '
closeHandle(hOut)
CloseHandle(hEvent) ' закроем хэндл объекта события
end 1
end if
RHVoice_speak(msg) ' скажем наш текст
RHVoice_delete_message(msg) ' удаляем сообщение
' вернемся опять к александру
voice = RHVoice_find_voice("Aleksandr") ' найдем голос по имени Aleksandr
if voice > 0 then ' если номер голоса больше нуль, значит голос найден
RHVoice_set_voice(voice) ' установим голос по номеру
else
print "no voice"
closeHandle(hOut)
CloseHandle(hEvent) ' закроем хэндл объекта события
end 1
end if
RHVoice_set_rate(0.5) ' установим скорость помедленнее
testString = "Я такой пьяный, что язык не ворочается. надо еще за бутылкой сходить."
MultiByteToWideChar(CP_ACP,0,strPtr(testString),len(testString),wideString,len(testString)*2)
msg=RHVoice_new_message_utf16 _ ' подготовим текст, который будем говорить
(cast(any ptr,@wideString), _ ' строка с текстом
len(wideString), _ ' длина строки
RHVoice_message_text) ' тип сообщения
if msg= 0 then ' если ошибка
RHVoice_terminate() ' завершаем работу RHVOICE '
closeHandle(hOut)
CloseHandle(hEvent) ' закроем хэндл объекта события
end 1
end if
RHVoice_speak(msg) ' скажем наш текст
RHVoice_delete_message(msg) ' удаляем сообщение
RHVoice_set_pitch(0.0) ' установим питч по нулям
testString = "ё маё! я уже совсем допился, голос сел нафиг. что же дальше со мной будет! страшно как-то, но за третьей всё равно пойду."
MultiByteToWideChar(CP_ACP,0,strPtr(testString),len(testString),wideString,len(testString)*2)
msg=RHVoice_new_message_utf16 _ ' подготовим текст, который будем говорить
(cast(any ptr,@wideString), _ ' строка с текстом
len(wideString), _ ' длина строки
RHVoice_message_text) ' тип сообщения
if msg= 0 then ' если ошибка
RHVoice_terminate() ' завершаем работу RHVOICE '
closeHandle(hOut)
CloseHandle(hEvent) ' закроем хэндл объекта события
end 1
end if
RHVoice_speak(msg) ' скажем наш текст
RHVoice_delete_message(msg) ' удаляем сообщение
RHVoice_terminate() ' завершим работу RHVoice
WaveOutClose(hOut) ' закроем устройство воспроизведения
CloseHandle(hEvent) ' закроем хэндл объекта события
end
' функция обратного вызова
' в ней мы будем выводить звуковые данные на звуковую карту
function callback cdecl _
(byval samples as const short ptr, _ ' указатель на буфер со звуковыми данными
byval num_samples as integer, _ ' число семплов(отсчетов) - в нашем случае один семпл 16 бит - 2 байта(short)
byval events as const RHVoice_event ptr, _ ' указатель на события
byval num_events as integer, _ ' число событий
byval message as RHVoice_message) as integer ' сообщение
lenBuf = num_samples*sizeof(short)
memcpy(@buf(numbuf),cast(any ptr,samples),lenbuf)
' заполним структуру заголовка буфера воспроизведения
wHdr(numbuf).lpData = @buf(numbuf)
wHdr(numbuf).dwBufferLength = lenbuf
' подготовим заголовок буфера
waveOutPrepareHeader(hOut,@wHdr(numbuf),32)
' проиграем буфер
WaveOutWrite(hOut,@wHdr(numbuf),32)
WaitForSingleObject(hEvent, infinite) ' ждем пока драйвер не вернет буфер
WaveOutUnprepareHeader(hOut,@wHdr(numbuf),32)
numbuf +=1
if numbuf > 3 then numbuf = 0
return 1
end function
sub ShowErrorMessage()
dim as dword errid = GetLastError()
dim as zstring * 1024 formatString
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,0,errid,0,@formatString,1023,0)
messageBox(0,formatString,"RTC",MB_ICONERROR or MB_TASKMODAL)
end sub
electrik- Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 43
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург
Re: Синтезаторы речи - русский синтезатор речи RHVoice
Дааа.. Я в шоке! Умница Ольга! Реалистичность голоса на хорошем уровне. Женский голос (по крайней мере та фраза, которая в примере) вообще кажется реальным. Спасибо ей. И конечно спасибо тебе electrik за адаптацию проекта. Теперь при желании можно кое-какие подсказки в своих прогах озвучивать, да и вообще с таким голосом читалку не стыдно сделать.
Единственно у меня в пути до проекта с движком были русские символы. С таким подходом инициализация не выполняется. Так что размещать движок надо строго в английской директории.
P.S. Если не против, размещу адаптированный проект на своем сайте для скачивания.
Единственно у меня в пути до проекта с движком были русские символы. С таким подходом инициализация не выполняется. Так что размещать движок надо строго в английской директории.
P.S. Если не против, размещу адаптированный проект на своем сайте для скачивания.
trew- Сообщения : 331
Дата регистрации : 2010-10-14
Re: Синтезаторы речи - русский синтезатор речи RHVoice
привет. конечно можно, даже нужно. ведь ваш сайт уже много народу посещает,
поповоду русских букв, я еще не разобрался. в комментариях к функции инициализации,написано, что кодировка путей должна быть в utf-8.
'/* Under Windows we assume that the paths are in UTF-8 */
пока я не знаю, как в utf-8 кодируются русские буквы.
а так можно, сделать перекодировку строки и вперед.
синтезатор может читать из кодировок utf-8?, utf-16 и utf-32.
вообще, надо обертки сделать, просто типа:
speak("hello world")
поповоду русских букв, я еще не разобрался. в комментариях к функции инициализации,написано, что кодировка путей должна быть в utf-8.
'/* Under Windows we assume that the paths are in UTF-8 */
пока я не знаю, как в utf-8 кодируются русские буквы.
а так можно, сделать перекодировку строки и вперед.
синтезатор может читать из кодировок utf-8?, utf-16 и utf-32.
вообще, надо обертки сделать, просто типа:
speak("hello world")
electrik- Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 43
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург
Re: Синтезаторы речи - русский синтезатор речи RHVoice
вообще, надо обертки сделать, просто типа:
speak("hello world")
Ты уже решил это делать или неопределенно? Если решил, тогда я подожду выкладывать, потом сразу готовое с обертками выложу.
trew- Сообщения : 331
Дата регистрации : 2010-10-14
Re: Синтезаторы речи - русский синтезатор речи RHVoice
пока нет. я думаю, тут уж каждый сам под себя сделает. кто-то любит процедурное программирование, а кто-то объектноорентированное.
electrik- Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 43
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург
Страница 1 из 1
Права доступа к этому форуму:
Вы не можете отвечать на сообщения
|
|