login

online now

We have 94 guests and no members online

search

 
Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1

TOPIC: Latency?

Latency? 6 years 2 months ago #162

Hi,
I'm planning to develop a live instrument based on the Ginsing voice library. I'm just testing out a few ideas at the moment and I'm an arduino newbie. On the other hand I'm an experienced developer so the code side shouldn't be too much trouble. At the moment I'm looking at input methods. I've written a bit of test code to speak a phrase at the push of a button. This uses a pin read by digitalRead to start and stop the speech. However, there's a long delay before hearing the audio after I push the button . What's causing this delay? The audio buffer?
Can it be reduced? Any tips for getting a snappier response?

Hope you can help, cheers.
The administrator has disabled public write access.

Re: Latency? 6 years 2 months ago #163

I would not expect there to be an appreciable delay between the function call on the Arduino to the audio output. The serial interface between the Arduino and the Babblebot runs at 9600 baud, or approximately 960 bytes per second. This suggests that the first byte sent should arrive at the chip in about 1 millisecond. Most of the commands are 4 bytes or less, but depending on how long the phrase is you may see the buffer process them in groups of 4 bytes at a time.

The time it takes to clear the buffer depends on how long it takes to speak the sequence of bytes in the buffer, but the time to the first allophone should be quick as it immediately begins processing the first allophone as soon as it arrives. It might be worthwhile to try a simple test where you send a trigger command to a DCO to see if that incurs the same latency. The trigger command is less than four bytes (header + register + data byte ) and should have a latency close to 1 ms. If you still see a large time delay it might not be related to the communication between the Arduino and the Babblebot. If this happens in a much shorter time than sending speech commands it might indicate that you are overrunning the serial buffer with previous data that has not been spoken yet.

In code, you can check for a buffer full condition by using the GS.isReady() method, which will return a false when data is being held up in the buffer. Since the allophones generally take longer than 1 ms you should not see isReady() returning false very often. It would be interesting to check the status after you read the Arduino input but before you send the data to see if this is the case, which might be why you could see a large latency, but even then it should clear the buffer in just a few milliseconds.

One other thing that might be worth testing is to run the PC link and see if you experience a large delay. This should be a good worst-case test because when you run from the PC you are sending the data down the USB serial to the Arduino, and the relaying it from the Arduino to the Ginsing board, but it should give you a sense of the general response time.

Hopefully that gives you something to experiment with. I would be interested to find out if these tests provide any more data points.
The administrator has disabled public write access.

Re: Latency? 6 years 2 months ago #178

well, I tried everything you suggested.

When I tried a trigger command the response was instant.

I didn't see any false isReady() returns after inserting debug at the point you suggested.

And the latency was slightly worse when running the pc link than when I initially discovered it in response to a button push. So that doesn't help really.

I should point out that I'm using Ginsing 1.1, Arduino 0023 and Ginsing library V1.0.

Any thoughts?

Thanks for your thorough reply by the way, very much appreciated :)

Just discovered that the latency disappeared in soundgin on later tries. Using the phoneme keyboard the voice was actually quite playable. This suggests that GinSingVoice might be slowing things down somehow...what do you think?
Last Edit: 6 years 2 months ago by sinewave. Reason: New info
The administrator has disabled public write access.

Re: Latency? 6 years 2 months ago #179

Well, this is an interesting situation to be sure.

The Ginsing library does not buffer any data and simply converts function calls into serial commands - the same commands that come from the pc link, albeit slightly delayed as the commands from the pc link are read on the default serial port and then relayed to the shield. I am beginning to suspect that perhaps some setup code on the voice might be slowing down either the phoneme playback speed or slowly blending the allophones that would make them appear to start slower.

Can you elaborate more on what you mean by latency disappeared on later tries?
Also, are you using the serial port console on the IDE for debug prints at the same time?
The administrator has disabled public write access.

Re: Latency? 6 years 2 months ago #180

The first few times I used SoundGin there was a delay between eg. pressing one of the phoneme keys (in the top right of the voice GUI) and hearing the output. The delay then was quite a bit longer than the delay I was experiencing in my code. SoundGin is pretty unstable on my pc and just disappeared without trace from my desktop a couple of times...! Haven't seen that sort of behaviour for a while. Anyway, upon restarting the app I found that I was actually able to "play" the phonemes (using the mouse) in time to music - the response was that fast ie. just what i need. I'm just using SoundGin btw no console debug.

Have to agree with you that it just doesn't seem reasonable that the conversion to serial commands in GinSingVoice is the culprit. Haven't looked in detail at the code but if there's no buffer there's no delay.

I should look at my code again, and I'll test some other voice setup options. More later.
The administrator has disabled public write access.

Re: Latency? 6 years 2 months ago #181

OK, thanks for the information.

I am currently working on a rewrite to the PC link code - the original runs Visual Basic built on Win2K, so its stability is questionable on currently operating systems, although I have not seen too many problems with it. In any case, I won't have the new speech version "ginsing speaker" until I finish the synth version "ginsing tweaker", which is currently in alpha. So until then the console software is about all we have as a realtime testbed.

It is quite bizarre that restarting the app would have any effect on the response of the system as neither the board nor the relay program should be affected by the presence or absence of the pc link. Also since you run the relay program on the Arduino in this case none of your own code should be a culprit.

I have not seen a case where the Babblebot IC gets itself into a state where it is slow to respond, but you can issue a reset command in code that will reset it, which might provide another data point. The following code will send a 3 byte message that will reset the chip to factory settings, and might be worth a try just to see if it has any effect:
  ubyte serialCmd [ 3 ] = { 0, CmdHeader, CmdHeader };

  for ( int serialIdx = 0; serialIdx < 3; serialIdx++ )
     gs.getSerial().write  ( serialCmd [serialIdx] );

I also briefly reviewed the code that sends the phoneme list down to the board as included below. It might serve to clarify what happens when you call the function to speak - as you can see it simply runs through the array and either sends the command directly or builds a command to control inflection and then sends that:

//------------------------------------------------------------------------------------
// speak - send a series of speech fragments (allophones) to the sound chip
//------------------------------------------------------------------------------------

void  GinSingVoice::speak ( GSAllophone *allophoneList )
{	
	// write allophone bytes until we hit a zero
	
	while ( (*allophoneList) != _ENDPHRASE )
	{
		ubyte dataByte  = (*allophoneList);

		
		// the byte may be an inflection 
		// if so build the inflection register byte
		
		if ( dataByte < _A )
		{
			switch ( dataByte )
			{
			case _SPEEDUP : _inflection |= SC_SpeedUpBit;    break;
			case _SPEEDDN : _inflection |= SC_SpeedDownBit;  break;
			case _VOLUP   : _inflection |= SC_VolumeUpBit;   break;
			case _VOLDN   : _inflection |= SC_VolumeDownBit; break;
			case _PITCHUP : _inflection |= SC_PitchUpBit;    break;
			case _PITCHDN : _inflection |= SC_PitchDownBit;  break;
			case _BENDUP  : _inflection |= SC_BendUpBit;     break;
			case _BENDDN  : _inflection |= SC_BendDownBit;   break;
			default       :                                  break;  
			};
		}
		
		// if its not an inflection write the allophone 
		// and set the speech control register as needed
		
		else
		{
			if ( _inflection )
			{
				gsPtr->sendCommand ( WriteOneByte , SpeechControl , _inflection ); 
				_inflection = 0;
			}
			
			gsPtr->getSerial()->write ( (*allophoneList) );

		}
		
		allophoneList++;
	}
}

None of this provides any direct potential solution, but maybe helps give you more insight into what is going on internally when a speech command is triggered. Just out of curiosity, how big is the allophone list that you are using when you call speak()?
Last Edit: 6 years 2 months ago by administrator.
The administrator has disabled public write access.
  • Page:
  • 1
Time to create page: 0.192 seconds