Exemplo n.º 1
0
void
module_close(int status)
{
	DBG("Espeak: close().");

	DBG("Espeak: Terminating threads");
	espeak_stop_requested = TRUE;
	espeak_close_requested =TRUE;

	pthread_mutex_lock(&playback_queue_mutex);
	pthread_cond_broadcast(&playback_queue_condition);
	pthread_mutex_unlock(&playback_queue_mutex);

	sem_post(espeak_play_semaphore);
	sem_post(espeak_stop_or_pause_semaphore);
	/* Give threads a chance to quit on their own terms. */
	g_usleep(25000);

	/* Make sure threads have really exited */
	pthread_cancel(espeak_play_thread);
	pthread_cancel(espeak_stop_or_pause_thread);

	DBG("Joining  play thread.");
	pthread_join(espeak_play_thread, NULL);
	DBG("Joinging stop thread.");
	pthread_join(espeak_stop_or_pause_thread, NULL);

	DBG("Espeak: terminating synthesis.");
	espeak_Terminate();

	DBG("Espeak: Closing audio output");
	if (module_audio_id) {
		spd_audio_close(module_audio_id);
	}

	DBG("Freeing resources.");
	espeak_clear_playback_queue();
	espeak_free_voice_list();

	pthread_mutex_destroy(&espeak_state_mutex);
	pthread_mutex_destroy(&espeak_play_suspended_mutex);
	pthread_mutex_destroy(&espeak_stop_or_pause_suspended_mutex);
	pthread_mutex_destroy(&playback_queue_mutex);
	pthread_cond_destroy(&playback_queue_condition);
	sem_destroy(espeak_play_semaphore);
	sem_destroy(espeak_stop_or_pause_semaphore);

	exit(status);
}
Exemplo n.º 2
0
/* Stop or Pause thread. */
static void *_espeak_stop_or_pause(void *nothing)
{
	int ret;

	log_msg(OTTS_LOG_INFO, "Espeak: Stop or pause thread starting.......");

	/* Block all signals to this thread. */
	set_speaking_thread_parameters();

	while (!espeak_close_requested) {
		/* If semaphore not set, set suspended lock and suspend until it is signaled. */
		if (0 != sem_trywait(espeak_stop_or_pause_semaphore)) {
			pthread_mutex_lock
			    (&espeak_stop_or_pause_suspended_mutex);
			sem_wait(espeak_stop_or_pause_semaphore);
			pthread_mutex_unlock
			    (&espeak_stop_or_pause_suspended_mutex);
		}
		log_msg(OTTS_LOG_INFO, "Espeak: Stop or pause semaphore on.");
		if (espeak_close_requested)
			break;
		if (!espeak_stop_requested) {
			/* This sometimes happens after wake-up from suspend-to-disk.  */
			log_msg(OTTS_LOG_WARN,
				"Espeak: Warning: spurious wake-up  of stop thread.");
			continue;
		}

		pthread_mutex_lock(&playback_queue_mutex);
		pthread_cond_broadcast(&playback_queue_condition);
		pthread_mutex_unlock(&playback_queue_mutex);

		if (module_audio_id) {
			log_msg(OTTS_LOG_WARN, "Espeak: Stopping audio.");
			ret = opentts_audio_stop(module_audio_id);
			DBG_WARN(ret == 0,
				 "spd_audio_stop returned non-zero value.");
			while (is_thread_busy(&espeak_play_suspended_mutex)) {
				ret = opentts_audio_stop(module_audio_id);
				DBG_WARN(ret == 0,
					 "spd_audio_stop returned non-zero value.");
				g_usleep(5000);
			}
		} else {
			while (is_thread_busy(&espeak_play_suspended_mutex)) {
				g_usleep(5000);
			}
		}

		log_msg(OTTS_LOG_INFO,
			"Espeak: Waiting for synthesis to stop.");
		ret = espeak_Cancel();
		DBG_WARN(ret == EE_OK, "Espeak: error in espeak_Cancel().");

		log_msg(OTTS_LOG_DEBUG, "Espeak: Clearing playback queue.");
		espeak_clear_playback_queue();

		int save_pause_state = espeak_pause_state;
		pthread_mutex_lock(&espeak_state_mutex);
		espeak_state_reset();
		pthread_mutex_unlock(&espeak_state_mutex);

		if (save_pause_state == ESPEAK_PAUSE_MARK_REPORTED) {
			module_report_event_pause();
		} else {
			module_report_event_stop();
		}

		log_msg(OTTS_LOG_INFO,
			"Espeak: Stop or pause thread ended.......\n");
	}
	pthread_exit(NULL);
}