Is there the CommandLineToArgvA function in windows c/c++ (VS 2022)? - c++

There is the CommandLineToArgvW() function, which is CommandLineToArgv + W, where this W means wide char (wchar_t in C/C++). But the CommandLineToArgvA() function that should exist, such as GetCommandLineW() and GetCommandLineA(), does not exist, apparently.
char:
int argv;
char **argv = CommandLineToArgvA(GetCommandLineA(), &argc);
wide char:
int argv;
wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
Well, I searched every corner of the Internet for the term CommandLineToArgvA() and the most I found was this function in Linux Wine... I want to know, does this function exist, and if yes, is it normal that it is "hidden"? Otherwise, does it really not exist?
edit: The question was whether there was the CommandLineToArgvA function in the Windows API, however, it does not exist (comment by Remy Lebeau). The answer I checked as correct is the one that best explains how to use the existing CommandLineToArgvW function and turn the wchar_t into char, which will provide the same result that would be provided with the CommandLineToArgvA function if it existed.

I don’t think you should try parsing your own command-line string. Windows does it one way. Trying to write duplicate code to do the same thing is the Wrong Thing™ to do.
Just get the command-line, then use the Window facilities to convert it to UTF-8.
#include <stdlib.h>
#include <windows.h>
#include <shellapi.h>
#pragma comment(lib, "Shell32")
void get_command_line_args( int * argc, char *** argv )
{
// Get the command line arguments as wchar_t strings
wchar_t ** wargv = CommandLineToArgvW( GetCommandLineW(), argc );
if (!wargv) { *argc = 0; *argv = NULL; return; }
// Count the number of bytes necessary to store the UTF-8 versions of those strings
int n = 0;
for (int i = 0; i < *argc; i++)
n += WideCharToMultiByte( CP_UTF8, 0, wargv[i], -1, NULL, 0, NULL, NULL ) + 1;
// Allocate the argv[] array + all the UTF-8 strings
*argv = malloc( (*argc + 1) * sizeof(char *) + n );
if (!*argv) { *argc = 0; return; }
// Convert all wargv[] --> argv[]
char * arg = (char *)&((*argv)[*argc + 1]);
for (int i = 0; i < *argc; i++)
{
(*argv)[i] = arg;
arg += WideCharToMultiByte( CP_UTF8, 0, wargv[i], -1, arg, n, NULL, NULL ) + 1;
}
(*argv)[*argc] = NULL;
}
Obtains an argv just like the one main() gets, with a final NULL element
and writeable and all.
Interface is easy enough. Don’t forget to free() the result when you are done with it. Example usage:
#include <stdio.h>
#include <stdlib.h>
void f(void)
{
int argc;
char ** argv;
get_command_line_args( &argc, &argv );
for (int n = 0; n < argc; n++)
printf( " %d : %s\n", n, argv[n] );
free( argv );
}
int main(void)
{
f();
}
Enjoy!

Related

I am trying to pass some strings trough espeak and it reads them but I get "segmentation fault"

This is my code. I want to get 5 strings from the user and espeak reads each of them when user interred it. But I get segmentation fault(core dumped) message.
#include <string.h>
#include <malloc.h>
#include <espeak/speak_lib.h>
int test()
{
espeak_POSITION_TYPE position_type;
espeak_AUDIO_OUTPUT output;
char *path=NULL;
int Buflength = 500, Options=0;
void* user_data;
t_espeak_callback *SynthCallback;
espeak_PARAMETER Parm;
char Voice[] = {"English"};
int i=0;
char text[1000];
unsigned int Size,position=0, end_position=0, flags=espeakCHARS_AUTO, *unique_identifier;
output = AUDIO_OUTPUT_PLAYBACK;
espeak_Initialize(output, Buflength, path, Options );
espeak_SetVoiceByName(Voice);
const char *langNativeString = "en_US";
espeak_VOICE voice={0};
voice.languages = langNativeString;
voice.name = "US";
voice.variant = 2;
voice.gender = 1;
Size = strlen(text)+1;
for (i=0; i<5; i++)
{
scanf("%s ", &text);
printf("%s", text);
espeak_Synth( text, Size, position, position_type, end_position, flags,
unique_identifier, user_data );
espeak_Synchronize( );
fflush(stdout);
}
return 0;
}
int main(int argc, char* argv[] )
{
test();
return 0;
}
I tried some modification but none of them worked. I want the program works like this:
User input: hi
espeak says: hi
user input: one
espeak says: one
(for 5
inputs)
But when I try to interring more than 4 characters as input,it gives segmentation fault error!
The two main issues are:
you use strlen on an uninitialized array of chars;
the unique_identifier argument of espeak_Synth must be NULL or point to an unsigned int (see the source code) while now it is an unsigned pointer to random memory.
Move strlen after scanf, use NULL instead of unique_identifier and your code will suddenly work (kind of).
There are many other issues though: useless variables, uninitialized variables, no input sanitization and more. IMO a better approach would be to throw away the test function and rewrite it from scratch properly.
Addendum
This is how I'd rewrite the above code. It is still suboptimal (no input sanitization, no error checking) but IMO it is much cleaner.
#include <stdio.h>
#include <string.h>
#include <espeak/speak_lib.h>
static void say(const char *text)
{
static int initialized = 0;
if (! initialized) {
espeak_Initialize(AUDIO_OUTPUT_PLAYBACK, 0, NULL, 0);
espeak_SetVoiceByName("en");
initialized = 1;
}
espeak_Synth(text, strlen(text)+1,
0, POS_CHARACTER, 0,
espeakCHARS_UTF8, NULL, NULL);
espeak_Synchronize();
}
int main()
{
char text[1000];
int i;
for (i = 0; i < 5; ++i) {
scanf("%s", text);
say(text);
}
return 0;
}

How to make execvp() handle multiple arguments?

I have a problem with execvp() in C++. Here is my code:
char * argv[]={};
command_counter = 0;
char line[255];
fgets(line,255,stdin);
argv[0] = strtok(line, TOKEN);//seperate the command with TOKEN
while (arg = strtok(NULL, TOKEN)) {
++command_counter;
cout << command_counter << endl;
argv[command_counter] = arg;
cout << argv[command_counter] << endl;
}
argv[++command_counter] = (char *) NULL;
execvp(argv[0],argv);
But the problem is, multiple arguments are not working when I use execvp() like this.
Like ls -a -l, it is only executing the ls -a as a result.
What's wrong with this program?
With the help of you guys the problem was solved by changing the statement of char * argv[128]
The first thing that's wrong with it is that you're creating a zero-sized array to store the arguments:
char * argv[]={};
then populating it.
That's a big undefined behaviour red flag right there.
A quick and dirty fix would be ensuring you have some space there:
char * argv[1000];
but, to be honest, that has its own problems if you ever get to the point where you may have more than a thousand arguments.
Bottom line is, you should ensure there's enough space in the array for storing your arguments.
One way of doing this is with dynamic memory allocation, which expands the array of arguments as needed, so as to ensure there's always enough space:
using namespace std;
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#define TOKEN " "
static char **addArg (char **argv, size_t *pSz, size_t *pUsed, char *str) {
// Make sure enough space for another one.
if (*pUsed == *pSz) {
*pSz = *pSz + 25;
argv = (char **) realloc (argv, *pSz * sizeof (char*));
if (argv == 0) {
cerr << "Out of memory\n";
exit (1);
}
}
// Add it and return (possibly new) array.
argv[(*pUsed)++] = (str == 0) ? 0 : strdup (str);
return argv;
}
int main (void) {
Initial size, used and array.
size_t sz = 0, used = 0;
char **argv = 0;
// Temporary pointer and command.
char *str, line[] = "ls -a -l";
// Add the command itself.
argv = addArg (argv, &sz, &used, strtok (line, TOKEN));
// Add each argument in turn, then the terminator.
while ((str = strtok (0, TOKEN)) != 0)
argv = addArg (argv, &sz, &used, str);
argv = addArg (argv, &sz, &used, 0);
// Then execute it.
execvp (argv[0], argv);
// Shouldn't reach here.
return 0;
}

One Way hash function in C

is there any method to compute a one way hash in C programming, which returns the array of bytes for the resulting hash value..
Thanks..
You could use a Lib for that. For example libgcrypt.
Take a look here. That is almost the same question that you askt here.
For the libgcrypt11-dev package (gcrypt.h)
#include <gcrypt.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv){
/* Test for arg string */
if ( argc < 2 ){
fprintf( stderr, "Usage: %s <string>\n", argv[0] );
exit( 1 );
}
/* Length of message to encrypt */
int msg_len = strlen( argv[1] );
/* Length of resulting sha1 hash - gcry_md_get_algo_dlen
* returns digest lenght for an algo */
int hash_len = gcry_md_get_algo_dlen( GCRY_MD_SHA1 );
/* output sha1 hash - this will be binary data */
unsigned char hash[ hash_len ];
/* output sha1 hash - converted to hex representation
* 2 hex digits for every byte + 1 for trailing \0 */
char *out = (char *) malloc( sizeof(char) * ((hash_len*2)+1) );
char *p = out;
/* calculate the SHA1 digest. This is a bit of a shortcut function
* most gcrypt operations require the creation of a handle, etc. */
gcry_md_hash_buffer( GCRY_MD_SHA1, hash, argv[1], msg_len );
/* Convert each byte to its 2 digit ascii
* hex representation and place in out */
int i;
for ( i = 0; i < hash_len; i++, p += 2 ) {
snprintf ( p, 3, "%02x", hash[i] );
}
printf( "%s\n", out );
free( out );
}

How to pass pointer and pointer to a function?

I implement a function that acts like getline( .. ). So my initial approach is:
#include <cstdio>
#include <cstdlib>
#include <cstring>
void getstr( char*& str, unsigned len ) {
char c;
size_t i = 0;
while( true ) {
c = getchar(); // get a character from keyboard
if( '\n' == c || EOF == c ) { // if encountering 'enter' or 'eof'
*( str + i ) = '\0'; // put the null terminate
break; // end while
}
*( str + i ) = c;
if( i == len - 1 ) { // buffer full
len = len + len; // double the len
str = ( char* )realloc( str, len ); // reallocate memory
}
++i;
}
}
int main() {
const unsigned DEFAULT_SIZE = 4;
char* str = ( char* )malloc( DEFAULT_SIZE * sizeof( char ) );
getstr( str, DEFAULT_SIZE );
printf( str );
free( str );
return 0;
}
Then, I think I should switch to pure C instead of using half C/C++. So I change char*& to char**:
Pointer to Pointer version ( crahsed )
#include <cstdio>
#include <cstdlib>
#include <cstring>
void getstr( char** str, unsigned len ) {
char c;
size_t i = 0;
while( true ) {
c = getchar(); // get a character from keyboard
if( '\n' == c || EOF == c ) { // if encountering 'enter' or 'eof'
*( *str + i ) = '\0'; // put the null terminate
break; // done input end while
}
*( *str + i ) = c;
if( i == len - 1 ) { // buffer full
len = len + len; // double the len
*str = ( char* )realloc( str, len ); // reallocate memory
}
++i;
}
}
int main() {
const unsigned DEFAULT_SIZE = 4;
char* str = ( char* )malloc( DEFAULT_SIZE * sizeof( char ) );
getstr( &str, DEFAULT_SIZE );
printf( str );
free( str );
return 0;
}
But this version crashed, ( access violation ). I tried run the debugger, but I could not find where it crashed. I'm running Visual Studio 2010 so could you guys show me how to fix it?
Another weird thing I've encountered is that, if I leave the "&" out, it only works with Visual Studio, but not g++. That is
void getstr( char* str, unsigned len )
From my understanding, whenever we use pointer to allocate or deallocate a block of memory, we actually modify where that pointer are pointing to. So I think we have to use either ** or *& to modify the pointer. However, because it run correctly in Visual Studio, is it just luck or it should be ok either way?
Then, I think I should switch to pure C instead of using half C/C++.
I suggest the other direction. Go full-blown C++.
Your pointer crash is probably in the realloc
*str = ( char* )realloc( str, len )
Should be
*str = ( char* )realloc( *str, len )
As Steve points out, your code leaks the original if realloc fails, so maybe change it to something like:
char* tmp = (char*) realloc(*str, len)
if (tmp) {
*str = tmp
} else {
// realloc failed.. sigh
}
Well, running it in a debugger highlights this line
*str = ( char* )realloc( str, len ); // reallocate memory
where there is a mismatch between str - the pointer to the variable - and *str - the pointer to the memory.
I'd be tempted to rewrite it so it returns the string, or zero on error, rather than having a void return and an in/out parameter ( like fgets does, which seems to be the function you're sort-of copying the behaviour of ). Or wrap such a function. That style doesn't let you get confused as you're only ever dealing with a pointer to char, rather than a pointer to pointer to char.
char* getstr_impl ( char* str, unsigned len ) {...}
void getstr( char** str, unsigned len ) {
*str = getstr_impl ( *str, len );
}

Espeak SAPI/dll usage on Windows?

Question: I am trying to use the espeak text-to-speech engine.
So for I got it working wounderfully on linux (code below).
Now I wanted to port this basic program to windows, too, but it's nearly impossible...
Part of the problem is that the windows dll only allows for AUDIO_OUTPUT_SYNCHRONOUS, which means it requires a callback, but I can't figure out how to play the audio from the callback... First it crashed, then I realized, I need a callback function, now I get the data in the callback function, but I don't know how to play it... as it is neither a wav file nor plays automatically as on Linux.
The sourceforge site is rather useless, because it basically says use the SAPI version, but then there is no example on how to use the sapi espeak dll...
Anyway, here's my code, can anybody help?
#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);
}
}
*/
The above code is for Linux.
The below code is about as far as I got on Vista x64 (32 bit emu):
#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;
}
Have you tried passing the buffer you obtain in your callback to sndplaysnd()??
Declare Function sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszSoundName As String, ByVal uFlags As Long) As Long
Its standard winAPI is as follows:
sndPlaySound(buffer[0], SND_ASYNC | SND_MEMORY)
Alternately, if you have a wav-file that has the audio to play:
sndPlaySound(filename, SND_ASYNC)
playsound has a ASYNC mode that wouldn't block your program's execution while the audio is being played.
NOTE: I have used it in VB and the above snippets are for use in VB. If you are coding in VC++, you might have to modify them accordingly. But the basic intention remains the same; to pass the buffer to sndPlaySound with the ASYNC flag set.
Good LUCK!!
Several changes in source code are needed to make the windows library have the same functionality as the one on Linux. I listed the changes here. The ready to use binary is also available.
All the patches and the description were also sent to espeak maintainer (publicly, through the mailing list and patches tracker), so maybe in future it will be available directly.