Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

unsigned char's

Posted on 2004-04-17
12
Medium Priority
?
2,545 Views
Last Modified: 2008-02-01
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_data()), 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)...?
0
Comment
Question by:fairon
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
  • 2
  • +1
12 Comments
 
LVL 19

Expert Comment

by:mrwad99
ID: 10848682
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 ?
0
 

Author Comment

by:fairon
ID: 10848744
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_data()), 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();

                        }
0
 
LVL 19

Expert Comment

by:mrwad99
ID: 10848775
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.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:fairon
ID: 10848803
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[]..?
0
 
LVL 19

Expert Comment

by:mrwad99
ID: 10848806
..Just looking into that now...
0
 
LVL 19

Expert Comment

by:mrwad99
ID: 10848828
There is some information here

http://www.gamedev.net/community/forums/topic.asp?topic_id=213156

although it might not be too much use.
0
 
LVL 19

Expert Comment

by:mrwad99
ID: 10848837
..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.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 10848920
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_data()), 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].get_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].get_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

 
0
 
LVL 9

Expert Comment

by:Cayce
ID: 10849981
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.
0
 

Author Comment

by:fairon
ID: 10852548
" 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_data()), length);
0
 
LVL 19

Expert Comment

by:mrwad99
ID: 10852678
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.
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 500 total points
ID: 10853002
do this:

unsigned char* word[100000];
wordLength = 0;
.....

int length = phoneme[idx].get_len();
memcpy(&word[wordLength], (unsigned char*)(phoneme[idx].get_data()), length);
wordLength = wordLength + length;

That concatenates.

Regards, Alex
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

722 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question