fairon
asked on
unsigned char's
hey,
I havent used unsigned char's a lot but need to get something finished fast so dont have the time to get aquanted... I have an app that is a text to speach simulator and I need to concatenate sounds to create a word. The sound data is stored with unsigned char's(BYTE*) and I'm unsure as to how I can build the word. I've tryed using CStrings to do the job instead, but the data hasen't come out well and the sound player gets errors. Heres where I'm adding the sounds. (sorry if it doesnt format well.)
CString word; //word data
int phonemeNum = 0; //Num of phoneme to add to word
int from = 0; //pointer to start of current phoneme
int wordLength = 0; //word char length
CString input;
.
.
.
while(from < input.GetLength())
{
//speech synthesis
phonemeNum = get_phoneme(input, from);
//debug
cout << phonemeNum << " ";
int idx = phonemeNum;
//Add phonemes together to create word (Overlap phonemes)
//if space phoneme, play word... clear word...
if (phonemeNum != 52){
//*** If not space *** (add phoneme to word)
int len = phoneme[idx].get_len(); //get length
wordLength = wordLength + len; //add length to word length
unsigned char* data = new unsigned char[len]; //create char
memcpy(data, (unsigned char*)(phoneme[idx].get_da ta()), len); //put data into char
CString temp = data; //convert datato CString
word = word + temp; //add data to end of word
}else{ //*** If space *** (play word)
unsigned char* wordData = new unsigned char[wordLength]; //create char the size of the word
LPCTSTR tempWordData = word; //change word to const char
memcpy(wordData, (const char*)(tempWordData), wordLength); //place word in unsigned char
//cout << LPCTSTR(word);
//cout << wordLength;
/*****- Play Word -*****/
wave.AddRef();
wave.SetFormat( phoneme[0].get_rate(), // sample rate
phoneme[0].get_bytepersec( ), // data rate
phoneme[0].get_bytesample( ), // bytes/sam,
phoneme[0].get_bitssample( )); // bits/sam
wave.Load(wordData, wordLength, phoneme[0].get_bitssample( ));
wave.Play();
wave.Release();
wordLength = 0;
word = "";
}
}
This code is a bit sloppy... but I don't know how else I can concatenate the sounds(phonemes)...?
I havent used unsigned char's a lot but need to get something finished fast so dont have the time to get aquanted... I have an app that is a text to speach simulator and I need to concatenate sounds to create a word. The sound data is stored with unsigned char's(BYTE*) and I'm unsure as to how I can build the word. I've tryed using CStrings to do the job instead, but the data hasen't come out well and the sound player gets errors. Heres where I'm adding the sounds. (sorry if it doesnt format well.)
CString word; //word data
int phonemeNum = 0; //Num of phoneme to add to word
int from = 0; //pointer to start of current phoneme
int wordLength = 0; //word char length
CString input;
.
.
.
while(from < input.GetLength())
{
//speech synthesis
phonemeNum = get_phoneme(input, from);
//debug
cout << phonemeNum << " ";
int idx = phonemeNum;
//Add phonemes together to create word (Overlap phonemes)
//if space phoneme, play word... clear word...
if (phonemeNum != 52){
//*** If not space *** (add phoneme to word)
int len = phoneme[idx].get_len(); //get length
wordLength = wordLength + len; //add length to word length
unsigned char* data = new unsigned char[len]; //create char
memcpy(data, (unsigned char*)(phoneme[idx].get_da
CString temp = data; //convert datato CString
word = word + temp; //add data to end of word
}else{ //*** If space *** (play word)
unsigned char* wordData = new unsigned char[wordLength]; //create char the size of the word
LPCTSTR tempWordData = word; //change word to const char
memcpy(wordData, (const char*)(tempWordData), wordLength); //place word in unsigned char
//cout << LPCTSTR(word);
//cout << wordLength;
/*****- Play Word -*****/
wave.AddRef();
wave.SetFormat( phoneme[0].get_rate(), // sample rate
phoneme[0].get_bytepersec(
phoneme[0].get_bytesample(
phoneme[0].get_bitssample(
wave.Load(wordData, wordLength, phoneme[0].get_bitssample(
wave.Play();
wave.Release();
wordLength = 0;
word = "";
}
}
This code is a bit sloppy... but I don't know how else I can concatenate the sounds(phonemes)...?
I dont see why you are using unsigned chars, and why you are creating them on the heap at that. Why not do it with normal char[] and then use strcat to concatenate ?
ASKER
The problem is that I was given the code to do with how the sounds are stored etc and I'm trying to work with whats there... Currently the sound is stored as: BYTE* data;
and phoneme[idx].get_data() returns this data.
The CWave player takes an unsigned char* to play a sound.
I need to concatenate the data from 2(or more) "phoneme[idx].get_data()"' s to create a new unsigned char* to send to wave.load.
I created something simpler without CStrings below but it still didnt work:
unsigned char* word[100000];
if (phonemeNum != 52){
int length = phoneme[idx].get_len();
wordLength = wordLength + length;
memcpy(word, (unsigned char*)(phoneme[idx].get_da ta()), length);
}else{
wave.AddRef();
wave.SetFormat( phoneme[0].get_rate(), // sample rate
phoneme[0].get_bytepersec( ), // data rate
phoneme[0].get_bytesample( ), // bytes/sam,
phoneme[0].get_bitssample( )); // bits/sam
unsigned char* data = new unsigned char[wordLength];
memcpy(data, (unsigned char*)(word), wordLength);
wave.Load(data, wordLength, phoneme[0].get_bitssample( ));
wave.Play();
wave.Release();
}
and phoneme[idx].get_data() returns this data.
The CWave player takes an unsigned char* to play a sound.
I need to concatenate the data from 2(or more) "phoneme[idx].get_data()"'
I created something simpler without CStrings below but it still didnt work:
unsigned char* word[100000];
if (phonemeNum != 52){
int length = phoneme[idx].get_len();
wordLength = wordLength + length;
memcpy(word, (unsigned char*)(phoneme[idx].get_da
}else{
wave.AddRef();
wave.SetFormat( phoneme[0].get_rate(), // sample rate
phoneme[0].get_bytepersec(
phoneme[0].get_bytesample(
phoneme[0].get_bitssample(
unsigned char* data = new unsigned char[wordLength];
memcpy(data, (unsigned char*)(word), wordLength);
wave.Load(data, wordLength, phoneme[0].get_bitssample(
wave.Play();
wave.Release();
}
Right, you can construct a CString from your unsigned char[] like this:
CString str(phoneme[idx].get_data( ));
and then concatenate two CStrings in the normal + manner. This gives the correct result.
CString str(phoneme[idx].get_data(
and then concatenate two CStrings in the normal + manner. This gives the correct result.
ASKER
Thats basically what I was doing before... but I dont think thats the problem.
How is the best way to turn the CString back into an unsigned char[]..?
How is the best way to turn the CString back into an unsigned char[]..?
..Just looking into that now...
There is some information here
http://www.gamedev.net/community/forums/topic.asp?topic_id=213156
although it might not be too much use.
http://www.gamedev.net/community/forums/topic.asp?topic_id=213156
although it might not be too much use.
..although it now looks like you can concatenate two unsigned char [] arrays together with strcat if you convert them to char* first.
This appears to give the correct result. Try it.
This appears to give the correct result. Try it.
As mrwad99 already told you
CString temp(phoneme[idx].get_data ());
word += temp;
is equivalent to
unsigned char* data = new unsigned char[len]; //create char
memcpy(data, (unsigned char*)(phoneme[idx].get_da ta()), len); //put data into char
CString temp = data; //convert datato CString
word = word + temp; //add data to end of word
Depending on the type of get_data() member you may need a cast to char* .
CString temp((char*)phoneme[idx].g et_data()) ;
However, if the data contains binary data with binary zeros, both methods will fail as the CString constructor uses a strlen() function that stops copying at the first occurrence of a binary zero character. If this is a problem you may overcome this by that
CString temp((char*)phoneme[idx].g et_data(), len); // the buffer must not be null-terminated and may contain binary null characters.
word += temp;
But, if you cannot use that CString buffer as an argument when a null-terminating string is required, e. g. with cout << temp; Here output stops at the first occurence of a zero character.
Regards, Alex
CString temp(phoneme[idx].get_data
word += temp;
is equivalent to
unsigned char* data = new unsigned char[len]; //create char
memcpy(data, (unsigned char*)(phoneme[idx].get_da
CString temp = data; //convert datato CString
word = word + temp; //add data to end of word
Depending on the type of get_data() member you may need a cast to char* .
CString temp((char*)phoneme[idx].g
However, if the data contains binary data with binary zeros, both methods will fail as the CString constructor uses a strlen() function that stops copying at the first occurrence of a binary zero character. If this is a problem you may overcome this by that
CString temp((char*)phoneme[idx].g
word += temp;
But, if you cannot use that CString buffer as an argument when a null-terminating string is required, e. g. with cout << temp; Here output stops at the first occurence of a zero character.
Regards, Alex
That the sounds are returned on a BYTE* doesn't mean that they're all printable characters. So parsing it to CString it's not a good idea. The sound is on a BYTE* Buffer and it could contain 0x00 characters, I guess it should be treated as a block of memory and not as a string of chars.
ASKER
" I guess it should be treated as a block of memory and not as a string of chars."
how can i do this?
and why wouldnt this work?
unsigned char* word[100000];
int length = phoneme[idx].get_len();
wordLength = wordLength + length;
memcpy(word, (unsigned char*)(phoneme[idx].get_da ta()), length);
how can i do this?
and why wouldnt this work?
unsigned char* word[100000];
int length = phoneme[idx].get_len();
wordLength = wordLength + length;
memcpy(word, (unsigned char*)(phoneme[idx].get_da
Well that would work, but it would not achieve what you want which is unsigned char concatenation. All memcpy does is copy one memory block to another, overwriting anything that is there.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.