示例#1
0
static int
spk_construct (volatile SpeechSynthesizer *spk, char **parameters) {
  swift_result_t result;

  spk->setVolume = spk_setVolume;
  spk->setRate = spk_setRate;

  if (setEnvironmentVariable("SWIFT_HOME", SWIFT_ROOT)) {
    swift_params *engineParameters;

    if ((engineParameters = swift_params_new(NULL))) {
      if ((swiftEngine = swift_engine_open(engineParameters))) {
        if ((swiftPort = swift_port_open(swiftEngine, NULL))) {
          {
            const char *name = parameters[PARM_NAME];
            if (name && *name) {
              swift_voice *voice;
              if (*name == '/') {
                logMessage(LOG_DEBUG, "setting swift voice directory: %s", name);
                voice = swift_port_set_voice_from_dir(swiftPort, name);
              } else {
                logMessage(LOG_DEBUG, "setting swift voice name: %s", name);
                voice = swift_port_set_voice_by_name(swiftPort, name);
              }

              if (!voice) {
                 logMessage(LOG_WARNING, "Swift voice set error: %s", name);
              }
            }
          }

          setStringParameter("tts/content-type", "text/plain");

          logMessage(LOG_INFO, "Swift Engine: %s for %s, version %s, %s",
                     swift_engine_name, swift_platform, swift_version, swift_date);
          return 1;
        } else {
          logMessage(LOG_ERR, "Swift port open error.");
        }

        if ((result = swift_engine_close(swiftEngine)) != SWIFT_SUCCESS) {
          speechError(result, "engine close");
        }
        swiftEngine = NULL;
      } else {
        logMessage(LOG_ERR, "Swift engine open error.");
      }
    } else {
      logMessage(LOG_ERR, "Swift engine parameters allocation error.");
    }
  }

  return 0;
}
示例#2
0
static void cepstral_text_param_tts(switch_speech_handle_t *sh, char *param, const char *val)
{
	cepstral_t *cepstral;

	cepstral = sh->private_info;
	assert(cepstral != NULL);

	if (!strcasecmp(param, "voice")) {
		const char *voice_name = val;
		if (!strcasecmp(voice_name, "next")) {
			if ((cepstral->voice = swift_port_find_next_voice(cepstral->port))) {
				if (SWIFT_FAILED(swift_port_set_voice(cepstral->port, cepstral->voice))) {
					cepstral->done = cepstral->done_gen = 1;
					return;
				}
				voice_name = swift_voice_get_attribute(cepstral->voice, "name");
			} else {
				voice_name = NULL;
			}
		} else {
			if (voice_name && SWIFT_FAILED(swift_port_set_voice_by_name(cepstral->port, voice_name))) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid voice %s!\n", voice_name);
				voice_name = NULL;
			}
		}

		if (!voice_name) {
			/* Find the first voice on the system */
			if ((cepstral->voice = swift_port_find_first_voice(cepstral->port, NULL, NULL)) == NULL) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find any voices!\n");
				cepstral->done = cepstral->done_gen = 1;
				return;
			}

			/* Set the voice found by find_first_voice() as the port's current voice */
			if (SWIFT_FAILED(swift_port_set_voice(cepstral->port, cepstral->voice))) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set voice.\n");
				cepstral->done = cepstral->done_gen = 1;
				return;
			}

			voice_name = swift_voice_get_attribute(cepstral->voice, "name");
		}

		if (voice_name) {
			switch_copy_string(sh->voice, voice_name, sizeof(sh->voice));
		}

		return;
	}

	swift_port_set_param_string(cepstral->port, param, val, NULL);
}
示例#3
0
static int app_exec(struct ast_channel *chan, void *data)
{
	int res = 0, argc = 0, max_digits = 0, timeout = 0, alreadyran = 0, old_writeformat = 0;
	int ms, len, availatend;
	char *argv[3], *parse = NULL, *text = NULL, *rc = NULL;
	char tmp_exten[2], results[20];
	struct ast_module_user *u;
	struct ast_frame *f;
	struct timeval next;
	struct stuff *ps;

	struct myframe {
		struct ast_frame f;
		unsigned char offset[AST_FRIENDLY_OFFSET];
		unsigned char frdata[framesize];
	} myf;

	swift_engine *engine;
	swift_port *port = NULL;
	swift_voice *voice;
	swift_params *params;
	swift_result_t sresult;
	swift_background_t tts_stream;
	unsigned int event_mask;

	memset(results, 0 ,20);
	memset(tmp_exten, 0, 2);
	memset(argv, 0, 3);

	parse = ast_strdupa(data);
	u = ast_module_user_add(chan);
	argc = ast_app_separate_args(parse, ',', argv, 3);
	text = argv[0];

	if (!ast_strlen_zero(argv[1])) {
		timeout = strtol(argv[1], NULL, 0);
	}
	if (!ast_strlen_zero(argv[2])) {
		max_digits = strtol(argv[2], NULL, 0);
	}
	if (ast_strlen_zero(text)) {
		ast_log(LOG_WARNING, "%s requires text to speak!\n", app);
		return -1;
	}
	if (!ast_strlen_zero(text)) {
		ast_log(LOG_DEBUG, "Text to Speak : %s\n", text);
	}
	if (timeout > 0) {
		ast_log(LOG_DEBUG, "Timeout : %d\n", timeout);
	}
	if (max_digits > 0) {
		ast_log(LOG_DEBUG, "Max Digits : %d\n", max_digits);
	}

	ps = malloc(sizeof(struct stuff));
	swift_init_stuff(ps);

	/* Setup synthesis */

	if ((engine = swift_engine_open(NULL)) == NULL) {
		ast_log(LOG_ERROR, "Failed to open Swift Engine.\n");
		goto exception;
	}

	params = swift_params_new(NULL);
	swift_params_set_string(params, "audio/encoding", "ulaw");
	swift_params_set_string(params, "audio/sampling-rate", "8000");
	swift_params_set_string(params, "audio/output-format", "raw");
	swift_params_set_string(params, "tts/text-encoding", "utf-8");

	/* Additional swift parameters
	 *
	 * swift_params_set_float(params, "speech/pitch/shift", 1.0);
	 * swift_params_set_int(params, "speech/rate", 150);
	 * swift_params_set_int(params, "audio/volume", 110);
	 * swift_params_set_int(params, "audio/deadair", 0);
	 */

	if ((port = swift_port_open(engine, params)) == NULL) {
		ast_log(LOG_ERROR, "Failed to open Swift Port.\n");
		goto exception;
	}
	if ((voice = swift_port_set_voice_by_name(port, cfg_voice)) == NULL) {
		ast_log(LOG_ERROR, "Failed to set voice.\n");
		goto exception;
	}

	event_mask = SWIFT_EVENT_AUDIO | SWIFT_EVENT_END;
	swift_port_set_callback(port, &swift_cb, event_mask, ps);

	if (SWIFT_FAILED(swift_port_speak_text(port, text, 0, NULL, &tts_stream, NULL))) {
		ast_log(LOG_ERROR, "Failed to speak.\n");
		goto exception;
	}
	if (chan->_state != AST_STATE_UP) {
		ast_answer(chan);
	}

	ast_stopstream(chan);
	old_writeformat = chan->writeformat;

	if (ast_set_write_format(chan, AST_FORMAT_ULAW) < 0) {
		ast_log(LOG_WARNING, "Unable to set write format.\n");
		goto exception;
	}

	res = 0;

	/* Wait 100ms first for synthesis to start crankin'; if that's not
	 * enough the
	 */

	next = ast_tvadd(ast_tvnow(), ast_tv(0, 100000));

	while (swift_generator_running(ps)) {
		ms = ast_tvdiff_ms(next, ast_tvnow());

		if (ms <= 0) {
			if (swift_bytes_available(ps) > 0) {
				ASTOBJ_WRLOCK(ps);
				len = fmin(framesize, ps->qc);
				availatend = cfg_buffer_size - (ps->pq_r - ps->q);

				if (len > availatend) {
					/* read #1: to end of q buf */
					memcpy(myf.frdata, ps->pq_r, availatend);
					ps->qc -= availatend;

					/* read #2: reset to start of q buf and get rest */
					ps->pq_r = ps->q;
					memcpy(myf.frdata + availatend, ps->pq_r, len - availatend);
					ps->qc -= len - availatend;
					ps->pq_r += len - availatend;
				} else {
					ast_log(LOG_DEBUG, "Easy read; %d bytes and %d at end, %d free\n", len, availatend, cfg_buffer_size - ps->qc);
					memcpy(myf.frdata, ps->pq_r, len);
					ps->qc -= len;
					ps->pq_r += len;
				}

				myf.f.frametype = AST_FRAME_VOICE;
				myf.f.subclass = AST_FORMAT_ULAW;
				myf.f.datalen = len;
				myf.f.samples = len;
				myf.f.data.ptr = myf.frdata;
				myf.f.mallocd = 0;
				myf.f.offset = AST_FRIENDLY_OFFSET;
				myf.f.src = __PRETTY_FUNCTION__;
				myf.f.delivery.tv_sec = 0;
				myf.f.delivery.tv_usec = 0;

				if (ast_write(chan, &myf.f) < 0) {
					ast_log(LOG_DEBUG, "ast_write failed\n");
				}

				ast_log(LOG_DEBUG, "wrote a frame of %d\n", len);

				if (ps->qc < 0) {
					ast_log(LOG_DEBUG, "queue claims to contain negative bytes. Huh? qc < 0\n");
				}

				ASTOBJ_UNLOCK(ps);
				next = ast_tvadd(next, ast_samp2tv(myf.f.samples, samplerate));
			} else {
				next = ast_tvadd(next, ast_samp2tv(framesize / 2, samplerate));
				ast_log(LOG_DEBUG, "Whoops, writer starved for audio\n");
			}
		} else {
			ms = ast_waitfor(chan, ms);

			if (ms < 0) {
				ast_log(LOG_DEBUG, "Hangup detected\n");
				res = -1;
				ASTOBJ_WRLOCK(ps);
				ps->immediate_exit = 1;
				ASTOBJ_UNLOCK(ps);
			} else if (ms) {
				f = ast_read(chan);

				if (!f) {
					ast_log(LOG_DEBUG, "Null frame == hangup() detected\n");
					res = -1;
					ASTOBJ_WRLOCK(ps);
					ps->immediate_exit = 1;
					ASTOBJ_UNLOCK(ps);
				} else if (f->frametype == AST_FRAME_DTMF && timeout > 0 && max_digits > 0) {
					char originDTMF = f->subclass;
					alreadyran = 1;
					res = 0;
					ASTOBJ_WRLOCK(ps);
					ps->immediate_exit = 1;
					ASTOBJ_UNLOCK(ps);

					if (max_digits > 1) {
						rc = listen_for_dtmf(chan, timeout, max_digits - 1);
					}
					if (rc) {
						sprintf(results, "%c%s", originDTMF, rc);
					} else {
						sprintf(results, "%c", originDTMF);
					}

					ast_log(LOG_NOTICE, "DTMF = %s\n", results);
					pbx_builtin_setvar_helper(chan, "SWIFT_DTMF", results);
				}
				ast_frfree(f);
			}
		}

		ASTOBJ_RDLOCK(ps);

		if (ps->immediate_exit && !ps->generating_done) {
			if (SWIFT_FAILED(sresult = swift_port_stop(port, tts_stream, SWIFT_EVENT_NOW))) {
				ast_log(LOG_NOTICE, "Early top of swift port failed\n");
			}
		}

		ASTOBJ_UNLOCK(ps);
	}
	if (alreadyran == 0 && timeout > 0 && max_digits > 0) {
		rc = listen_for_dtmf(chan, timeout, max_digits);

		if (rc != NULL) {
			sprintf(results, "%s", rc);
			ast_log(LOG_NOTICE, "DTMF = %s\n", results);
			pbx_builtin_setvar_helper(chan, "SWIFT_DTMF", results);
		}
	}
	if (max_digits >= 1 && results != NULL) {
		if (cfg_goto_exten) {
			ast_log(LOG_NOTICE, "GoTo(%s|%s|%d) : ", chan->context, results, 1);

			if (ast_exists_extension (chan, chan->context, results, 1, chan->cid.cid_num)) {
				ast_log(LOG_NOTICE, "OK\n");
				ast_copy_string(chan->exten, results, sizeof(chan->exten) - 1);
				chan->priority = 0;
			} else {
				ast_log(LOG_NOTICE, "FAILED\n");
			}
		}
	}

	exception:

	if (port != NULL) {
		swift_port_close(port);
	}
	if (engine != NULL) {
		swift_engine_close(engine);
	}
	if (ps && ps->q) {
		ast_free(ps->q);
		ps->q = NULL;
	}
	if (ps) {
		ast_free(ps);
		ps = NULL;
	}
	if (!res && old_writeformat) {
		ast_set_write_format(chan, old_writeformat);
	}

	ast_module_user_remove(u);
	return res;
}
示例#4
0
static switch_status_t cepstral_speech_open(switch_speech_handle_t *sh, const char *voice_name, int rate, switch_speech_flag_t *flags)
{
	cepstral_t *cepstral = switch_core_alloc(sh->memory_pool, sizeof(*cepstral));
	char srate[25];

	if (!cepstral) {
		return SWITCH_STATUS_MEMERR;
	}

	if (switch_buffer_create_dynamic(&cepstral->audio_buffer, MY_BLOCK_SIZE, MY_BUF_LEN, 0) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write Buffer Failed!\n");
		return SWITCH_STATUS_MEMERR;
	}


	switch_mutex_init(&cepstral->audio_lock, SWITCH_MUTEX_NESTED, sh->memory_pool);


	cepstral->params = swift_params_new(NULL);
	swift_params_set_string(cepstral->params, "audio/encoding", "pcm16");
	switch_snprintf(srate, sizeof(srate), "%d", rate);
	swift_params_set_string(cepstral->params, "audio/sampling-rate", srate);


	/* Open a Swift Port through which to make TTS calls */
	if (!(cepstral->port = swift_port_open(engine, cepstral->params))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open Swift Port.\n");
		goto all_done;
	}


	if (voice_name && SWIFT_FAILED(swift_port_set_voice_by_name(cepstral->port, voice_name))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid voice %s!\n", voice_name);
		voice_name = NULL;
	}

	if (zstr(voice_name)) {
		/* Find the first voice on the system */
		if ((cepstral->voice = swift_port_find_first_voice(cepstral->port, NULL, NULL)) == NULL) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find any voices!\n");
			goto all_done;
		}

		/* Set the voice found by find_first_voice() as the port's current voice */
		if (SWIFT_FAILED(swift_port_set_voice(cepstral->port, cepstral->voice))) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set voice.\n");
			goto all_done;
		}

		voice_name = (char *) swift_voice_get_attribute(cepstral->voice, "name");
	}

	if (voice_name) {
		switch_copy_string(sh->voice, voice_name, sizeof(sh->voice));
	}

	swift_port_set_callback(cepstral->port, &write_audio, SWIFT_EVENT_AUDIO, cepstral);

	sh->private_info = cepstral;
	return SWITCH_STATUS_SUCCESS;

  all_done:
	return SWITCH_STATUS_FALSE;
}