/* Sends a chunk of audio to the audio player and waits for completion or error. */ static gboolean espeak_send_to_audio(TPlaybackQueueEntry *playback_queue_entry) { int ret = 0; AudioTrack track; track.num_samples = playback_queue_entry->data.audio.num_samples; track.num_channels = 1; track.sample_rate = espeak_sample_rate; track.bits = 16; track.samples = playback_queue_entry->data.audio.audio_chunk; DBG("Espeak: Sending %i samples to audio.", track.num_samples); /* Volume is controlled by the synthesizer. Always play at normal on audio device. */ spd_audio_set_volume(module_audio_id, 85); ret = spd_audio_play(module_audio_id, track, SPD_AUDIO_LE); if (ret < 0) { DBG("ERROR: Can't play track for unknown reason."); return FALSE; } DBG("Espeak: Sent to audio."); return TRUE; }
/* Plays the specified audio file. */ static gboolean espeak_play_file(char *filename) { gboolean result = TRUE; #if HAVE_SNDFILE int subformat; sf_count_t items; sf_count_t readcount; SNDFILE* sf; SF_INFO sfinfo; DBG("Espeak: Playing |%s|", filename); memset (&sfinfo, 0, sizeof (sfinfo)); sf = sf_open(filename, SFM_READ, &sfinfo); subformat = sfinfo.format & SF_FORMAT_SUBMASK ; items = sfinfo.channels * sfinfo.frames; DBG("Espeak: frames = %ld, channels = %d", sfinfo.frames, sfinfo.channels); DBG("Espeak: samplerate = %i, items = %Ld", sfinfo.samplerate, (long long) items); DBG("Espeak: major format = 0x%08X, subformat = 0x%08X, endian = 0x%08X", sfinfo.format & SF_FORMAT_TYPEMASK, subformat, sfinfo.format & SF_FORMAT_ENDMASK); if (sfinfo.channels < 1 || sfinfo.channels > 2) { DBG("Espeak: ERROR: channels = %d.\n", sfinfo.channels); result = FALSE; goto cleanup1; } if (sfinfo.frames > 0x7FFFFFFF) { DBG("Espeak: ERROR: Unknown number of frames."); result = FALSE; goto cleanup1; } if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE) { /* Set scaling for float to integer conversion. */ sf_command (sf, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE); } AudioTrack track; track.num_samples = sfinfo.frames; track.num_channels = sfinfo.channels; track.sample_rate = sfinfo.samplerate; track.bits = 16; track.samples = malloc(items * sizeof(short)); if (NULL == track.samples) { DBG("Espeak: ERROR: Cannot allocate audio buffer."); result = FALSE; goto cleanup1; } readcount = sf_read_short(sf, (short *) track.samples, items); DBG("Espeak: read %Ld items from audio file.", (long long) readcount); if (readcount > 0) { track.num_samples = readcount / sfinfo.channels; DBG("Espeak: Sending %i samples to audio.", track.num_samples); /* Volume is controlled by the synthesizer. Always play at normal on audio device. */ spd_audio_set_volume(module_audio_id, EspeakSoundIconVolume); int ret = spd_audio_play(module_audio_id, track, SPD_AUDIO_LE); if (ret < 0) { DBG("ERROR: Can't play track for unknown reason."); result = FALSE; goto cleanup2; } DBG("Espeak: Sent to audio."); } cleanup2: xfree(track.samples); cleanup1: sf_close(sf); #endif return result; }
char *do_message(SPDMessageType msgtype) { int ret; char *cur_line; GString *msg; size_t n; int nlines = 0; msg = g_string_new(""); printf("202 OK RECEIVING MESSAGE\n"); fflush(stdout); while (1) { cur_line = NULL; n = 0; ret = spd_getline(&cur_line, &n, stdin); nlines++; if (ret == -1) return g_strdup("401 ERROR INTERNAL"); if (!strcmp(cur_line, "..\n")) { g_free(cur_line); cur_line = g_strdup(".\n"); } else if (!strcmp(cur_line, ".\n")) { /* Strip the trailing \n */ msg->str[strlen(msg->str) - 1] = 0; g_free(cur_line); break; } g_string_append(msg, cur_line); g_free(cur_line); } if ((msgtype != SPD_MSGTYPE_TEXT) && (nlines > 2)) { return g_strdup("305 DATA MORE THAN ONE LINE"); } if ((msgtype == SPD_MSGTYPE_CHAR) && (!strcmp(msg->str, "space"))) { g_string_free(msg, 1); msg = g_string_new(" "); } /* no sure we need this check here at all */ if (msg->str == NULL || msg->str[0] == 0) { DBG("requested data NULL or empty\n"); g_string_free(msg, TRUE); return g_strdup("301 ERROR CANT SPEAK"); } /* check voice and synthesis_voice settings for consistency */ if (msg_settings.voice.name == NULL && msg_settings_old.voice.name != NULL && msg_settings.voice_type == msg_settings_old.voice_type) { /* force to set voice again, since synthesis_voice changed to NULL */ msg_settings_old.voice_type = -1; } /* Volume is controlled by the synthesizer. Always play at normal on audio device. */ if (spd_audio_set_volume(module_audio_id, 85) < 0) { DBG("Can't set volume. audio not initialized?"); } ret = module_speak(msg->str, strlen(msg->str), msgtype); g_string_free(msg, 1); if (ret <= 0) return g_strdup("301 ERROR CANT SPEAK"); return g_strdup("200 OK SPEAKING"); }