mirror of
https://github.com/linux-speakup/espeakup.git
synced 2026-08-24 00:24:17 +02:00
use user_data to detect old events
When espeak_Cancel is called, change the value of user_data that is passed to the events, and, in the callback, use this to test to see if cancel was received. If the value of user_data has changed, discarde events that have the old value. This patch is from Chris Brannon.
This commit is contained in:
parent
a9398bdeb4
commit
4889572ad1
4 changed files with 39 additions and 8 deletions
34
alsa.c
34
alsa.c
|
|
@ -53,20 +53,41 @@ int minimum(int x, int y)
|
|||
|
||||
static int alsa_callback(short *audio, int numsamples, espeak_EVENT * events)
|
||||
{
|
||||
static int discarding_packets = 0;
|
||||
static int user_data_old = 0;
|
||||
int samples_written = 0;
|
||||
int avail;
|
||||
int to_write;
|
||||
snd_pcm_state_t state;
|
||||
int user_data_new;
|
||||
|
||||
pthread_mutex_lock(&audio_mutex);
|
||||
user_data_new = *(int *) events->user_data;
|
||||
if (stop_requested) {
|
||||
snd_pcm_drop(handle);
|
||||
stop_requested = 0;
|
||||
pthread_mutex_unlock(&audio_mutex);
|
||||
return 1;
|
||||
discarding_packets = 1;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&audio_mutex);
|
||||
|
||||
/*
|
||||
* If discarding_packets is true, then do the following.
|
||||
* Compare user_data_old and user_data_new. If they are equal,
|
||||
* then espeak is still sending stale data through the callback.
|
||||
* Keep on discarding it, and return 1.
|
||||
* If they are different, a new stream has started. We can stop
|
||||
* discarding. Just process the new data.
|
||||
*/
|
||||
|
||||
if (discarding_packets) {
|
||||
if (user_data_new == user_data_old)
|
||||
return 1; /* Discard stale data. */
|
||||
else
|
||||
discarding_packets = 0;
|
||||
}
|
||||
|
||||
user_data_old = user_data_new;
|
||||
snd_pcm_status(handle, status);
|
||||
state = snd_pcm_status_get_state(status);
|
||||
if (state != SND_PCM_STATE_RUNNING)
|
||||
|
|
@ -76,7 +97,7 @@ static int alsa_callback(short *audio, int numsamples, espeak_EVENT * events)
|
|||
avail = snd_pcm_avail_update(handle);
|
||||
if (avail == 0)
|
||||
continue;
|
||||
if(avail < 0) {
|
||||
if (avail < 0) {
|
||||
/* Apparently this also can fail on buffer underrun. */
|
||||
snd_pcm_prepare(handle);
|
||||
continue;
|
||||
|
|
@ -166,9 +187,12 @@ void stop_audio(void)
|
|||
pthread_mutex_unlock(&audio_mutex);
|
||||
}
|
||||
|
||||
void allow_audio(void)
|
||||
void lock_audio_mutex(void)
|
||||
{
|
||||
pthread_mutex_lock(&audio_mutex);
|
||||
stop_requested = 0;
|
||||
}
|
||||
|
||||
void unlock_audio_mutex(void)
|
||||
{
|
||||
pthread_mutex_unlock(&audio_mutex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,12 @@ void stop_audio(void)
|
|||
return;
|
||||
}
|
||||
|
||||
void allow_audio(void)
|
||||
void lock_audio_mutex(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void unlock_audio_mutex(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,8 @@ extern void *softsynth_thread(void *arg);
|
|||
extern void select_audio_mode(void);
|
||||
extern int init_audio(unsigned int rate);
|
||||
extern void stop_audio(void);
|
||||
extern void allow_audio(void);
|
||||
extern void lock_audio_mutex(void);
|
||||
extern void unlock_audio_mutex(void);
|
||||
extern volatile int should_run;
|
||||
extern volatile int runner_must_stop;
|
||||
extern int self_pipe_fds[2];
|
||||
|
|
|
|||
3
synth.c
3
synth.c
|
|
@ -130,7 +130,9 @@ static espeak_ERROR stop_speech(void)
|
|||
|
||||
stop_audio();
|
||||
rc = espeak_Cancel();
|
||||
lock_audio_mutex();
|
||||
user_data = (user_data + 1) % 100;
|
||||
unlock_audio_mutex();
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -138,7 +140,6 @@ static espeak_ERROR speak_text(struct synth_t * s)
|
|||
{
|
||||
espeak_ERROR rc;
|
||||
|
||||
allow_audio();
|
||||
rc = espeak_Synth(s->buf, s->len + 1, 0, POS_CHARACTER, 0, 0, NULL,
|
||||
&user_data);
|
||||
return rc;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue