Example #1
0
/*! \brief encode the temporary buffer and generate a frame */
static struct ast_frame *lintoilbc_frameout(struct ast_trans_pvt *pvt)
{
	struct ilbc_coder_pvt *tmp = pvt->pvt;
	int datalen = 0;
	int samples = 0;

	/* We can't work on anything less than a frame in size */
	if (pvt->samples < ILBC_SAMPLES)
		return NULL;
	while (pvt->samples >= ILBC_SAMPLES) {
		float tmpf[ILBC_SAMPLES];
		int i;

		/* Encode a frame of data */
		for (i = 0 ; i < ILBC_SAMPLES ; i++)
			tmpf[i] = tmp->buf[samples + i];
		iLBC_encode( pvt->outbuf.uc + datalen, tmpf, &tmp->enc);

		datalen += ILBC_FRAME_LEN;
		samples += ILBC_SAMPLES;
		pvt->samples -= ILBC_SAMPLES;
	}

	/* Move the data at the end of the buffer to the front */
	if (pvt->samples)
		memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);

	return ast_trans_frameout(pvt, datalen, samples);
}
Example #2
0
/*! \brief encode and produce a frame */
static struct ast_frame *lintocodec2_frameout(struct ast_trans_pvt *pvt)
{
	struct codec2_translator_pvt *tmp = pvt->pvt;
	struct ast_frame *result = NULL;
	struct ast_frame *last = NULL;
	int samples = 0; /* output samples */

	while (pvt->samples >= CODEC2_SAMPLES) {
		struct ast_frame *current;

		/* Encode a frame of data */
		codec2_encode(tmp->state, pvt->outbuf.uc, tmp->buf + samples);

		samples += CODEC2_SAMPLES;
		pvt->samples -= CODEC2_SAMPLES;

		current = ast_trans_frameout(pvt, CODEC2_FRAME_LEN, CODEC2_SAMPLES);

		if (!current) {
			continue;
		} else if (last) {
			AST_LIST_NEXT(last, frame_list) = current;
		} else {
			result = current;
		}
		last = current;
	}

	/* Move the data at the end of the buffer to the front */
	if (samples) {
		memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
	}

	return result;
}
/*! \brief encode and produce a frame */
static struct ast_frame *lintogsm_frameout(struct ast_trans_pvt *pvt)
{
	struct gsm_translator_pvt *tmp = pvt->pvt;
	int datalen = 0;
	int samples = 0;

	/* We can't work on anything less than a frame in size */
	if (pvt->samples < GSM_SAMPLES)
		return NULL;
	while (pvt->samples >= GSM_SAMPLES) {
		/* Encode a frame of data */
		gsm_encode(tmp->gsm, tmp->buf, (gsm_byte *)pvt->outbuf + datalen);
		datalen += GSM_FRAME_LEN;
		samples += GSM_SAMPLES;
		pvt->samples -= GSM_SAMPLES;
		/* Move the data at the end of the buffer to the front */
		if (pvt->samples)
			memmove(tmp->buf, tmp->buf + GSM_SAMPLES, pvt->samples * 2);
	}
	return ast_trans_frameout(pvt, datalen, samples);
}
Example #4
0
static struct ast_frame *lintoopus_frameout(struct ast_trans_pvt *pvt)
{
	struct opus_coder_pvt *opvt = pvt->pvt;
	int datalen = 0;	/* output bytes */
	int samples = 0;	/* output samples */

	/* We can't work on anything less than a frame in size */
	if (pvt->samples < opvt->framesize) {
		return NULL;
	}

	/* Encode 160 samples (or more if it's not narrowband) */
	ast_debug(3, "[Encoder #%d (%d)] %d samples, %d bytes\n",
		opvt->id,
		opvt->sampling_rate,
		opvt->framesize,
		opvt->framesize * 2);

	if ((datalen = opus_encode(opvt->opus, opvt->buf, opvt->framesize, pvt->outbuf.uc, BUFFER_SAMPLES)) < 0) {
		ast_log(LOG_ERROR, "Error encoding the Opus frame: %s\n", opus_strerror(datalen));
		return NULL;
	}

	samples += opvt->framesize;
	pvt->samples -= opvt->framesize;

	/* Move the data at the end of the buffer to the front */
	if (pvt->samples) {
		memmove(opvt->buf, opvt->buf + samples, pvt->samples * 2);
	}

	ast_debug(3, "[Encoder #%d (%d)]   >> Got %d samples, %d bytes\n",
		opvt->id,
		opvt->sampling_rate,
		opvt->multiplier * samples,
		datalen);

	return ast_trans_frameout(pvt, datalen, opvt->multiplier * samples);
}
Example #5
0
/*! \brief convert work buffer and produce output frame */
static struct ast_frame *lintospeex_frameout(struct ast_trans_pvt *pvt)
{
	struct speex_coder_pvt *tmp = pvt->pvt;
	int is_speech=1;
	int datalen = 0;	/* output bytes */
	int samples = 0;	/* output samples */

	/* We can't work on anything less than a frame in size */
	if (pvt->samples < tmp->framesize)
		return NULL;
	speex_bits_reset(&tmp->bits);
	while (pvt->samples >= tmp->framesize) {
#ifdef _SPEEX_TYPES_H
		/* Preprocess audio */
		if (preproc)
			is_speech = speex_preprocess(tmp->pp, tmp->buf + samples, NULL);
		/* Encode a frame of data */
		if (is_speech) {
			/* If DTX enabled speex_encode returns 0 during silence */
			is_speech = speex_encode_int(tmp->speex, tmp->buf + samples, &tmp->bits) || !dtx;
		} else {
			/* 5 zeros interpreted by Speex as silence (submode 0) */
			speex_bits_pack(&tmp->bits, 0, 5);
		}
#else
		{
			float fbuf[1024];
			int x;
			/* Convert to floating point */
			for (x = 0; x < tmp->framesize; x++)
				fbuf[x] = tmp->buf[samples + x];
			/* Encode a frame of data */
			is_speech = speex_encode(tmp->speex, fbuf, &tmp->bits) || !dtx;
		}
#endif
		samples += tmp->framesize;
		pvt->samples -= tmp->framesize;
	}

	/* Move the data at the end of the buffer to the front */
	if (pvt->samples)
		memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);

	/* Use AST_FRAME_CNG to signify the start of any silence period */
	if (is_speech) {
		tmp->silent_state = 0;
	} else {
		if (tmp->silent_state) {
			return NULL;
		} else {
			tmp->silent_state = 1;
			speex_bits_reset(&tmp->bits);
			memset(&pvt->f, 0, sizeof(pvt->f));
			pvt->f.frametype = AST_FRAME_CNG;
			pvt->f.samples = samples;
			/* XXX what now ? format etc... */
		}
	}

	/* Terminate bit stream */
	speex_bits_pack(&tmp->bits, 15, 5);
	datalen = speex_bits_write(&tmp->bits, pvt->outbuf.c, pvt->t->buf_size);
	return ast_trans_frameout(pvt, datalen, samples);
}
/*! \brief convert work buffer and produce output frame */
static struct ast_frame *lintospeex_frameout(struct ast_trans_pvt *pvt)
{
	struct speex_coder_pvt *tmp = pvt->pvt;
	int is_speech=1;
	int datalen = 0;	/* output bytes */
	int samples = 0;	/* output samples */

	/* We can't work on anything less than a frame in size */
	if (pvt->samples < tmp->framesize)
		return NULL;
	speex_bits_reset(&tmp->bits);
	while (pvt->samples >= tmp->framesize) {
#ifdef _SPEEX_TYPES_H
		/* Preprocess audio */
		if (preproc)
			is_speech = speex_preprocess(tmp->pp, tmp->buf + samples, NULL);
		/* Encode a frame of data */
		if (is_speech) {
			/* If DTX enabled speex_encode returns 0 during silence */
			is_speech = speex_encode_int(tmp->speex, tmp->buf + samples, &tmp->bits) || !dtx;
		} else {
			/* 5 zeros interpreted by Speex as silence (submode 0) */
			speex_bits_pack(&tmp->bits, 0, 5);
		}
#else
		{
			float fbuf[1024];
			int x;
			/* Convert to floating point */
			for (x = 0; x < tmp->framesize; x++)
				fbuf[x] = tmp->buf[samples + x];
			/* Encode a frame of data */
			is_speech = speex_encode(tmp->speex, fbuf, &tmp->bits) || !dtx;
		}
#endif
		samples += tmp->framesize;
		pvt->samples -= tmp->framesize;
	}

	/* Move the data at the end of the buffer to the front */
	if (pvt->samples)
		memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);

	/* Use AST_FRAME_CNG to signify the start of any silence period */
	if (is_speech) {
		tmp->silent_state = 0;
	} else {
		if (tmp->silent_state) {
			return NULL;
		} else {
			struct ast_frame frm = {
				.frametype = AST_FRAME_CNG,
				.src = pvt->t->name,
			};

			/*
			 * XXX I don't think the AST_FRAME_CNG code has ever
			 * really worked for speex.  There doesn't seem to be
			 * any consumers of the frame type.  Everyone that
			 * references the type seems to pass the frame on.
			 */
			tmp->silent_state = 1;

			/* XXX what now ? format etc... */
			return ast_frisolate(&frm);
		}
	}

	/* Terminate bit stream */
	speex_bits_pack(&tmp->bits, 15, 5);
	datalen = speex_bits_write(&tmp->bits, pvt->outbuf.c, pvt->t->buf_size);
	return ast_trans_frameout(pvt, datalen, samples);
}

static void speextolin_destroy(struct ast_trans_pvt *arg)
{
	struct speex_coder_pvt *pvt = arg->pvt;

	speex_decoder_destroy(pvt->speex);
	speex_bits_destroy(&pvt->bits);
}

static void lintospeex_destroy(struct ast_trans_pvt *arg)
{
	struct speex_coder_pvt *pvt = arg->pvt;
#ifdef _SPEEX_TYPES_H
	if (preproc)
		speex_preprocess_state_destroy(pvt->pp);
#endif
	speex_encoder_destroy(pvt->speex);
	speex_bits_destroy(&pvt->bits);
}

static struct ast_translator speextolin = {
	.name = "speextolin",
	.src_codec = {
		.name = "speex",
		.type = AST_MEDIA_TYPE_AUDIO,
		.sample_rate = 8000,
	},
	.dst_codec = {
		.name = "slin",
		.type = AST_MEDIA_TYPE_AUDIO,
		.sample_rate = 8000,
	},
	.format = "slin",