2010-04-18 11 views
6

प्रश्न: मैं espeak टेक्स्ट-टू-स्पीच इंजन का उपयोग करने की कोशिश कर रहा हूं। तो मैं इसे लिनक्स (नीचे कोड) पर घायल तरीके से काम कर रहा हूं। अब मैं बंदरगाह के लिए इस बुनियादी कार्यक्रम खिड़कियों के लिए भी चाहता था, लेकिन यह लगभग असंभव है ...एस्पेक एसएपीआई/डीएलएल उपयोग?

समस्या का एक हिस्सा Windows DLL कि केवल AUDIO_OUTPUT_SYNCHRONOUS, जिसका अर्थ है कि यह एक कॉलबैक की आवश्यकता के लिए अनुमति देता है, लेकिन मैं यह कर सकते हैं ' यह नहीं पता कि कॉलबैक से ऑडियो कैसे खेलें ... सबसे पहले यह क्रैश हो गया, फिर मुझे एहसास हुआ, मुझे कॉलबैक फ़ंक्शन चाहिए, अब मुझे कॉलबैक फ़ंक्शन में डेटा मिलता है, लेकिन मुझे नहीं पता कि इसे कैसे खेलें .. क्योंकि यह न तो एक WAV फ़ाइल है और न ही लिनक्स पर स्वचालित रूप से चलाता है।

sourceforge साइट बल्कि बेकार है, क्योंकि यह मूल रूप से SAPI के संस्करण का उपयोग करें कहते हैं, लेकिन फिर वहाँ कैसे sapi eSpeak dll का उपयोग करने पर कोई उदाहरण है ...

वैसे भी, यहाँ मेरी कोड है, किसी को भी मदद कर सकते हैं ?

#ifdef __cplusplus 
#include <cstdio> 
#include <cstdlib> 
#include <cstring> 
#else 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#endif 

#include <assert.h> 
#include <ctype.h> 

//#include "speak_lib.h" 
#include "espeak/speak_lib.h" 

// libespeak-dev: /usr/include/espeak/speak_lib.h 
// apt-get install libespeak-dev 
// apt-get install libportaudio-dev 

// g++ -o mine mine.cpp -lespeak 
// g++ -o mine mine.cpp -I/usr/include/espeak/ -lespeak 
// gcc -o mine mine.cpp -I/usr/include/espeak/ -lespeak 


char voicename[40]; 
int samplerate; 
int quiet = 0; 
static char genders[4] = {' ','M','F',' '}; 

//const char *data_path = "/usr/share/"; // /usr/share/espeak-data/ 
const char *data_path = NULL; // use default path for espeak-data 


int strrcmp(const char *s, const char *sub) 
{ 
int slen = strlen(s); 
int sublen = strlen(sub); 
return memcmp(s + slen - sublen, sub, sublen); 
} 


char * strrcpy(char *dest, const char *source) 
{ 
// Pre assertions 
assert(dest != NULL); 
assert(source != NULL); 
assert(dest != source); 

// tk: parentheses 
while((*dest++ = *source++)) 
    ; 
return(--dest); 
} 

const char* GetLanguageVoiceName(const char* pszShortSign) 
{ 
#define LANGUAGE_LENGTH 30 
static char szReturnValue[LANGUAGE_LENGTH] ; 
memset(szReturnValue, 0, LANGUAGE_LENGTH); 

for (int i = 0; pszShortSign[i] != '\0'; ++i) 
    szReturnValue[i] = (char) tolower(pszShortSign[i]); 

const espeak_VOICE **voices; 
espeak_VOICE voice_select; 
voices = espeak_ListVoices(NULL); 

const espeak_VOICE *v; 
for(int ix=0; (v = voices[ix]) != NULL; ix++) 
{ 
    if(!strrcmp(v->languages, szReturnValue)) 
    { 
     strcpy(szReturnValue, v->name); 
     return szReturnValue; 
    } 
} // End for 

strcpy(szReturnValue, "default"); 
return szReturnValue; 
} // End function getvoicename 


void ListVoices() 
{ 
const espeak_VOICE **voices; 
espeak_VOICE voice_select; 
voices = espeak_ListVoices(NULL); 

const espeak_VOICE *v; 
for(int ix=0; (v = voices[ix]) != NULL; ix++) 
{ 
    printf("Shortsign: %s\n", v->languages); 
    printf("age: %d\n", v->age); 
    printf("gender: %c\n", genders[v->gender]); 
    printf("name: %s\n", v->name); 
    printf("\n\n"); 
} // End for 
} // End function getvoicename 


int main() 
{ 
printf("Hello World!\n"); 
const char* szVersionInfo = espeak_Info(NULL); 

printf("Espeak version: %s\n", szVersionInfo); 
samplerate = espeak_Initialize(AUDIO_OUTPUT_PLAYBACK,0,data_path,0); 

strcpy(voicename, "default"); 
// espeak --voices 
strcpy(voicename, "german"); 
strcpy(voicename, GetLanguageVoiceName("DE")); 

if(espeak_SetVoiceByName(voicename) != EE_OK) 
{ 
    printf("Espeak setvoice error...\n"); 
} 

static char word[200] = "Hello World" ; 
strcpy(word, "TV-fäns aufgepasst, es ist 20 Uhr 15. Zeit für Rambo 3"); 
strcpy(word, "Unnamed Player wurde zum Opfer von GSG9"); 
int speed = 220; 
int volume = 500; // volume in range 0-100 0=silence 
int pitch = 50; // base pitch, range 0-100. 50=normal 

// espeak.cpp 625 
espeak_SetParameter(espeakRATE, speed, 0); 
espeak_SetParameter(espeakVOLUME,volume,0); 
espeak_SetParameter(espeakPITCH,pitch,0); 
// espeakRANGE: pitch range, range 0-100. 0-monotone, 50=normal 
// espeakPUNCTUATION: which punctuation characters to announce: 
    // value in espeak_PUNCT_TYPE (none, all, some), 
espeak_VOICE *voice_spec = espeak_GetCurrentVoice(); 
voice_spec->gender=2; // 0=none 1=male, 2=female, 
//voice_spec->age = age; 

espeak_SetVoiceByProperties(voice_spec); 


espeak_Synth((char*) word, strlen(word)+1, 0, POS_CHARACTER, 0, espeakCHARS_AUTO, NULL, NULL); 
espeak_Synchronize(); 

strcpy(voicename, GetLanguageVoiceName("EN")); 
espeak_SetVoiceByName(voicename); 
strcpy(word, "Geany was fragged by GSG9 Googlebot"); 
strcpy(word, "Googlebot"); 

espeak_Synth((char*) word, strlen(word)+1, 0, POS_CHARACTER, 0, espeakCHARS_AUTO, NULL, NULL); 
espeak_Synchronize(); 


espeak_Terminate(); 
printf("Espeak terminated\n"); 
return EXIT_SUCCESS; 
} 

/* 
if(espeak_SetVoiceByName(voicename) != EE_OK) 
{ 
    memset(&voice_select,0,sizeof(voice_select)); 
    voice_select.languages = voicename; 
    if(espeak_SetVoiceByProperties(&voice_select) != EE_OK) 
    { 
     fprintf(stderr,"%svoice '%s'\n",err_load,voicename); 
     exit(2); 
    } 
} 
*/ 

उपरोक्त कोड लिनक्स के लिए है। नीचे कोड के बारे में के रूप में दूर है के रूप में मैं Vista x64 (32 बिट एमु) पर मिल गया:

#ifdef __cplusplus 
#include <cstdio> 
#include <cstdlib> 
#include <cstring> 
#else 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#endif 

#include <assert.h> 
#include <ctype.h> 

#include "speak_lib.h" 
//#include "espeak/speak_lib.h" 

// libespeak-dev: /usr/include/espeak/speak_lib.h 
// apt-get install libespeak-dev 
// apt-get install libportaudio-dev 

// g++ -o mine mine.cpp -lespeak 
// g++ -o mine mine.cpp -I/usr/include/espeak/ -lespeak 
// gcc -o mine mine.cpp -I/usr/include/espeak/ -lespeak 


char voicename[40]; 
int iSampleRate; 
int quiet = 0; 
static char genders[4] = {' ','M','F',' '}; 

//const char *data_path = "/usr/share/"; // /usr/share/espeak-data/ 
//const char *data_path = NULL; // use default path for espeak-data 
const char *data_path = "C:\\Users\\Username\\Desktop\\espeak-1.43-source\\espeak-1.43-source\\"; 


int strrcmp(const char *s, const char *sub) 
{ 
int slen = strlen(s); 
int sublen = strlen(sub); 
return memcmp(s + slen - sublen, sub, sublen); 
} 


char * strrcpy(char *dest, const char *source) 
{ 
// Pre assertions 
assert(dest != NULL); 
assert(source != NULL); 
assert(dest != source); 

// tk: parentheses 
while((*dest++ = *source++)) 
    ; 
return(--dest); 
} 

const char* GetLanguageVoiceName(const char* pszShortSign) 
{ 
#define LANGUAGE_LENGTH 30 
static char szReturnValue[LANGUAGE_LENGTH] ; 
memset(szReturnValue, 0, LANGUAGE_LENGTH); 

for (int i = 0; pszShortSign[i] != '\0'; ++i) 
    szReturnValue[i] = (char) tolower(pszShortSign[i]); 

const espeak_VOICE **voices; 
espeak_VOICE voice_select; 
voices = espeak_ListVoices(NULL); 

const espeak_VOICE *v; 
for(int ix=0; (v = voices[ix]) != NULL; ix++) 
{ 
    if(!strrcmp(v->languages, szReturnValue)) 
    { 
     strcpy(szReturnValue, v->name); 
     return szReturnValue; 
    } 
} // End for 

strcpy(szReturnValue, "default"); 
return szReturnValue; 
} // End function getvoicename 


void ListVoices() 
{ 
const espeak_VOICE **voices; 
espeak_VOICE voice_select; 
voices = espeak_ListVoices(NULL); 

const espeak_VOICE *v; 
for(int ix=0; (v = voices[ix]) != NULL; ix++) 
{ 
    printf("Shortsign: %s\n", v->languages); 
    printf("age: %d\n", v->age); 
    printf("gender: %c\n", genders[v->gender]); 
    printf("name: %s\n", v->name); 
    printf("\n\n"); 
} // End for 
} // End function getvoicename 


/* Callback from espeak. Directly speaks using AudioTrack. */ 
#define LOGI(x) printf("%s\n", x) 
static int AndroidEspeakDirectSpeechCallback(short *wav, int numsamples, espeak_EVENT *events) 
{ 
    char buf[100]; 
    sprintf(buf, "AndroidEspeakDirectSpeechCallback: %d samples", numsamples); 
    LOGI(buf); 

    if (wav == NULL) 
{ 
     LOGI("Null: speech has completed"); 
    } 

    if (numsamples > 0) 
{ 
     //audout->write(wav, sizeof(short) * numsamples); 
     sprintf(buf, "AudioTrack wrote: %d bytes", sizeof(short) * numsamples); 
     LOGI(buf); 
    } 

    return 0; // continue synthesis (1 is to abort) 
} 


static int AndroidEspeakSynthToFileCallback(short *wav, int numsamples,espeak_EVENT *events) 
{ 
    char buf[100]; 
    sprintf(buf, "AndroidEspeakSynthToFileCallback: %d samples", numsamples); 
    LOGI(buf); 

    if (wav == NULL) 
{ 
     LOGI("Null: speech has completed"); 
    } 

    // The user data should contain the file pointer of the file to write to 
    //void* user_data = events->user_data; 
FILE* user_data = fopen ("myfile1.wav" , "ab"); 

    FILE* fp = static_cast<FILE *>(user_data); 

    // Write all of the samples 
    fwrite(wav, sizeof(short), numsamples, fp); 
    return 0; // continue synthesis (1 is to abort) 
} 



int main() 
{ 
printf("Hello World!\n"); 
const char* szVersionInfo = espeak_Info(NULL); 

printf("Espeak version: %s\n", szVersionInfo); 

iSampleRate = espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS, 4096, data_path, 0); 
if (iSampleRate <= 0) 
{ 
    printf("Unable to initialize espeak"); 
    return EXIT_FAILURE; 
} 

//samplerate = espeak_Initialize(AUDIO_OUTPUT_PLAYBACK,0,data_path,0); 

//ListVoices(); 

strcpy(voicename, "default"); 
// espeak --voices 
//strcpy(voicename, "german"); 
//strcpy(voicename, GetLanguageVoiceName("DE")); 

if(espeak_SetVoiceByName(voicename) != EE_OK) 
{ 
    printf("Espeak setvoice error...\n"); 
} 

static char word[200] = "Hello World" ; 
strcpy(word, "TV-fäns aufgepasst, es ist 20 Uhr 15. Zeit für Rambo 3"); 
strcpy(word, "Unnamed Player wurde zum Opfer von GSG9"); 
int speed = 220; 
int volume = 500; // volume in range 0-100 0=silence 
int pitch = 50; // base pitch, range 0-100. 50=normal 


// espeak.cpp 625 
espeak_SetParameter(espeakRATE, speed, 0); 
espeak_SetParameter(espeakVOLUME,volume,0); 
espeak_SetParameter(espeakPITCH,pitch,0); 
// espeakRANGE: pitch range, range 0-100. 0-monotone, 50=normal 
// espeakPUNCTUATION: which punctuation characters to announce: 
    // value in espeak_PUNCT_TYPE (none, all, some), 
//espeak_VOICE *voice_spec = espeak_GetCurrentVoice(); 
//voice_spec->gender=2; // 0=none 1=male, 2=female, 
//voice_spec->age = age; 

//espeak_SetVoiceByProperties(voice_spec); 

//espeak_SetSynthCallback(AndroidEspeakDirectSpeechCallback); 
espeak_SetSynthCallback(AndroidEspeakSynthToFileCallback); 

unsigned int unique_identifier; 
espeak_ERROR err = espeak_Synth((char*) word, strlen(word)+1, 0, POS_CHARACTER, 0, espeakCHARS_AUTO, &unique_identifier, NULL); 

err = espeak_Synchronize(); 



/* 
strcpy(voicename, GetLanguageVoiceName("EN")); 
espeak_SetVoiceByName(voicename); 
strcpy(word, "Geany was fragged by GSG9 Googlebot"); 
strcpy(word, "Googlebot"); 

espeak_Synth((char*) word, strlen(word)+1, 0, POS_CHARACTER, 0, espeakCHARS_AUTO, NULL, NULL); 
espeak_Synchronize(); 
*/ 

// espeak_Cancel(); 
espeak_Terminate(); 
printf("Espeak terminated\n"); 
system("pause"); 
return EXIT_SUCCESS; 
} 
+1

+1 लाइब्रेरी के रूप में espeak का उपयोग करने के तरीके के कुछ उदाहरण कोड पोस्ट करने के लिए +1। मुझे उदाहरण खोजने में मुश्किल हुई है। धन्यवाद। – Noremac

उत्तर

1

आप sndplaysnd() करने के लिए अपने कॉलबैक में बफर आप प्राप्त गुजर करने की कोशिश की है ??

sndPlaySound(filename, SND_ASYNC) 

playsound एक ASYNC है:

sndPlaySound(buffer[0], SND_ASYNC | SND_MEMORY) 

वैकल्पिक रूप से यदि आप एक wav फ़ाइल ऑडियो खेलने के लिए है कि है,:

Declare Function sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszSoundName As String, ByVal uFlags As Long) As Long 

इसके मानक WINAPI इस प्रकार है मोड जो ऑडियो प्रोग्राम चलाए जाने पर आपके प्रोग्राम के निष्पादन को अवरुद्ध नहीं करेगा।

नोट: मैंने इसे वीबी में उपयोग किया है और उपरोक्त स्निपेट वीबी में उपयोग के लिए हैं। यदि आप वीसी ++ में कोडिंग कर रहे हैं, तो आपको उन्हें तदनुसार संशोधित करना पड़ सकता है। लेकिन मूल मंशा वही रहता है; ASYNC ध्वज सेट के साथ बफर को sndPlaySound में पास करने के लिए।

अच्छा लकीर !!

+0

sndPlaySound (WAV, SND_ASYNC | SND_MEMORY); धन्यवाद, इसे सी ++ में winmm.lib से लिंक करने की आवश्यकता है, लेकिन मैंने कोशिश की और यह काम नहीं करता है (कोई क्रैश नहीं, लेकिन कोई आवाज नहीं, मैंने एसएनडी _ की भी कोशिश की) ... sndPlaySound (wav [0], SND_ASYNC | SND_MEMORY); क्रैश –

+0

चूंकि यू इसका उपयोग कर रहे हैं, FILE * user_data = fopen ("myfile1.wav", "ab"); आउटपुट myfile1.wav में है।SndPlaySound (फ़ाइल नाम, SND_ASYNC) का उपयोग कर खेलना कोशिश की ?? अपने मीडिया-भुगतानकर्ता में myfile1.wav को चलाने का प्रयास करें और जांचें कि इसमें कोई भाषण डेटा है या नहीं। मैं उत्सुक हूँ ... – TheCodeArtist

+0

यह एक वैव फ़ाइल नहीं है, यह केवल डेटा है ... यह mediaplayer –

3

विंडोज लाइब्रेरी को लिनक्स पर एक जैसी कार्यक्षमता बनाने के लिए स्रोत कोड में कई बदलावों की आवश्यकता है। मैंने here में परिवर्तन सूचीबद्ध किए हैं। बाइनरी का उपयोग करने के लिए तैयार भी उपलब्ध है।

सभी पैच और विवरण एस्पीक रखरखाव (सार्वजनिक रूप से, मेलिंग सूची और पैच ट्रैकर के माध्यम से) को भी भेजे गए थे, इसलिए भविष्य में यह सीधे उपलब्ध होगा।