Package: espeakup / 1:0.80-16

audio-pause Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
commit 5339da3144f394eb6e6dd3df116b854d78476565
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Sat Jun 30 15:41:20 2018 +0200

    Support audio pauses
    
    When the Linux console is e.g. switched to a graphical VT, the kernel
    emits \x01P to notify that it is not able to read the screen any more,
    and the software synthesis can thus release the audio card, for other
    screen readers to take over.
    
    This implements it by adding a paused_espeak variable that tracks
    whether we have suspended espeak.  When more text comes, we can simply
    reinitialize espeak.
    
    This fixes #10.

diff --git a/espeakup.h b/espeakup.h
index 8fc0ee2..e8e89a7 100644
--- a/espeakup.h
+++ b/espeakup.h
@@ -45,6 +45,7 @@ enum command_t {
 	CMD_SET_VOLUME,
 	CMD_SPEAK_TEXT,
 	CMD_FLUSH,
+	CMD_PAUSE,
 	CMD_UNKNOWN,
 };
 
@@ -86,6 +87,7 @@ extern void close_softsynth(void);
 extern void *softsynth_thread(void *arg);
 extern volatile int should_run;
 extern volatile int stop_requested;
+extern int paused_espeak;
 extern int self_pipe_fds[2];
 #define PIPE_READ_FD (self_pipe_fds[0])
 #define PIPE_WRITE_FD (self_pipe_fds[1])
diff --git a/softsynth.c b/softsynth.c
index efa2351..ca9c5c3 100644
--- a/softsynth.c
+++ b/softsynth.c
@@ -133,6 +133,9 @@ static int process_command(struct synth_t *s, char *buf, int start)
 		case 'v':
 			cmd = CMD_SET_VOLUME;
 			break;
+		case 'P':
+			cmd = CMD_PAUSE;
+			break;
 		default:
 			cmd = CMD_UNKNOWN;
 			break;
diff --git a/espeak.c b/espeak.c
index f1f8064..5fd9342 100644
--- a/espeak.c
+++ b/espeak.c
@@ -40,6 +40,7 @@ const int rateOffset = 80;
 const int volumeMultiplier = 22;
 
 volatile int stop_requested = 0;
+int paused_espeak = 1;
 
 static int acsint_callback(short *wav, int numsamples, espeak_EVENT * events)
 {
@@ -211,6 +212,32 @@ static void synth_queue_clear()
 	}
 }
 
+static void reinitialize_espeak(struct synth_t *s)
+{
+	int rate;
+
+	/* Re-initialize espeak */
+	rate = espeak_Initialize(AUDIO_OUTPUT_PLAYBACK, 50, NULL, 0);
+	if (rate < 0) {
+		fprintf(stderr, "Unable to initialize espeak.\n");
+		return;
+	}
+
+	/* We need a callback in acsint mode, but not in speakup mode. */
+	if (espeakup_mode == ESPEAKUP_MODE_ACSINT)
+		espeak_SetSynthCallback(acsint_callback);
+
+	/* Set parameters again */
+	espeak_SetVoiceByName(s->voice);
+	espeak_SetParameter(espeakRANGE, s->frequency * frequencyMultiplier, 0);
+	espeak_SetParameter(espeakPITCH, s->pitch * pitchMultiplier, 0);
+	espeak_SetParameter(espeakRATE, s->rate * rateMultiplier + rateOffset, 0);
+	espeak_SetParameter(espeakVOLUME, (s->volume + 1) * volumeMultiplier, 0);
+	espeak_SetParameter(espeakCAPITALS, 0, 0);
+	paused_espeak = 0;
+	return;
+}
+
 static void queue_process_entry(struct synth_t *s)
 {
 	espeak_ERROR error;
@@ -222,6 +249,11 @@ static void queue_process_entry(struct synth_t *s)
 		current = (struct espeak_entry_t *) queue_remove(synth_queue);
 	}
 	pthread_mutex_unlock(&queue_guard);
+
+	if (current->cmd != CMD_PAUSE && paused_espeak) {
+		reinitialize_espeak(s);
+	}
+
 	switch (current->cmd) {
 	case CMD_SET_FREQUENCY:
 		error = set_frequency(s, current->value, current->adjust);
@@ -246,6 +278,13 @@ static void queue_process_entry(struct synth_t *s)
 		s->len = current->len;
 		error = speak_text(s);
 		break;
+	case CMD_PAUSE:
+		if (!paused_espeak) {
+			espeak_Cancel();
+			espeak_Terminate();
+			paused_espeak = 1;
+		}
+		break;
 	default:
 		break;
 	}
@@ -282,6 +321,7 @@ int initialize_espeak(struct synth_t *s)
 	set_rate(s, defaultRate, ADJ_SET);
 	set_volume(s, defaultVolume, ADJ_SET);
 	espeak_SetParameter(espeakCAPITALS, 0, 0);
+	paused_espeak = 0;
 	return 0;
 }
 
diff --git a/espeakup.c b/espeakup.c
index 1981430..eda3e9c 100644
--- a/espeakup.c
+++ b/espeakup.c
@@ -231,7 +231,8 @@ int main(int argc, char **argv)
 	pthread_join(softsynth_thread_id, NULL);
 	pthread_join(espeak_thread_id, NULL);
 
-	espeak_Terminate();
+	if (!paused_espeak)
+		espeak_Terminate();
 	close_softsynth();
 
 out: