Пример #1
0
static int encode_audio(struct mgcp_process_rtp_state *state,
			uint8_t *dst, size_t buf_size, size_t max_samples)
{
	int nbytes = 0;
	size_t nsamples = 0;
	/* Encode samples into dst */
	while (nsamples + state->dst_samples_per_frame <= max_samples) {
		if (nbytes + state->dst_frame_size > buf_size) {
			if (nbytes > 0)
				break;

			/* Not even one frame fits into the buffer */
			LOGP(DMGCP, LOGL_INFO,
			     "Encoding (RTP) buffer too small: %d > %d.\n",
			     nbytes + state->dst_frame_size, buf_size);
			return -ENOSPC;
		}
		switch (state->dst_fmt) {
		case AF_GSM:
			gsm_encode(state->dst.gsm_handle,
				   state->samples + state->sample_offs, dst);
			break;
#ifdef HAVE_BCG729
		case AF_G729:
			bcg729Encoder(state->dst.g729_enc,
				      state->samples + state->sample_offs, dst);
			break;
#endif
		case AF_PCMU:
			ulaw_encode(state->samples + state->sample_offs, dst,
				    state->src_samples_per_frame);
			break;
		case AF_PCMA:
			alaw_encode(state->samples + state->sample_offs, dst,
				    state->src_samples_per_frame);
			break;
		case AF_S16:
			memmove(dst, state->samples + state->sample_offs,
				state->dst_frame_size);
			break;
		case AF_L16:
			l16_encode(state->samples + state->sample_offs, dst,
				   state->src_samples_per_frame);
			break;
		default:
			break;
		}
		dst        += state->dst_frame_size;
		nbytes     += state->dst_frame_size;
		state->sample_offs += state->dst_samples_per_frame;
		nsamples   += state->dst_samples_per_frame;
	}
	state->sample_cnt -= nsamples;
	return nbytes;
}
void wav2c(FILE *in, FILE *out, FILE *outh)
{
	uint32_t header[5];
	int16_t format, channels, bits;
	uint32_t rate;
	uint32_t i, length, padlength=0, arraylen;
	int32_t audio=0;

	// read the WAV file's header
	for (i=0; i<5; i++) {
		header[i] = read_uint32(in);
	}
	if (header[0] != 0x46464952 || header[2] != 0x45564157
	  || header[3] != 0x20746D66 || header[4] != 0x00000010) {
		 die("error in format of file %s", filename);
	}

	// read the audio format parameters
	format = read_int16(in);
	channels = read_int16(in);
	rate = read_uint32(in);
	read_uint32(in); // ignore byterate
	read_int16(in);  // ignore blockalign
	bits = read_int16(in);
	//printf("format: %d, channels: %d, rate: %d, bits %d\n", format, channels, rate, bits);
	if (format != 1)
		die("file %s is compressed, only uncompressed supported", filename);
	if (rate != 44100 && rate != 22050 && rate != 11025 /*&& rate != 8000*/ )
		die("sample rate %d in %s is unsupported\n"
		  "Only 44100, 22050, 11025 work", rate, filename);
	if (channels != 1 && channels != 2)
		die("file %s has %d channels, but only 1 & 2 are supported", filename, channels);
	if (bits != 16)
		die("file %s has %d bit format, but only 16 is supported", filename, bits);

	// read the data header, skip non-audio data
	while (1) {
		header[0] = read_uint32(in);
		length = read_uint32(in);
		if (header[0] == 0x61746164) break; // beginning of actual audio data
		// skip over non-audio data
		for (i=0; i < length; i++) {
			read_uint8(in);
		}
	}

	// the length must be a multiple of the data size
	if (channels == 2) {
		if (length % 4) die("file %s data length is not a multiple of 4", filename);
		length = length / 4;
	}
	if (channels == 1) {
		if (length % 1) die("file %s data length is not a multiple of 2", filename);
		length = length / 2;
	}
	if (length > 0xFFFFFF) die("file %s data length is too long", filename);
	bcount = 0;

	// AudioPlayMemory requires padding to 2.9 ms boundary (128 samples @ 44100)
	if (rate == 44100) {
		padlength = padding(length, 128);
		format = 1;
	} else if (rate == 22050) {
		padlength = padding(length, 64);
		format = 2;
	} else if (rate == 11025) {
		padlength = padding(length, 32);
		format = 3;
	}
	if (pcm_mode) {
		arraylen = ((length + padlength) * 2 + 3) / 4 + 1;
		format |= 0x80;
	} else {
		arraylen = (length + padlength + 3) / 4 + 1;
	}
	total_length += arraylen;

	// output a minimal header, just the length, #bits and sample rate
	fprintf(outh, "extern const unsigned int AudioSample%s[%d];\n", samplename, arraylen);
	fprintf(out, "// Converted from %s, using %d Hz, %s encoding\n", filename, rate,
	  (pcm_mode ? "16 bit PCM" : "u-law"));
	fprintf(out, "const unsigned int AudioSample%s[%d] = {\n", samplename, arraylen);
	fprintf(out, "0x%08X,", length | (format << 24));
	wcount = 1;

	// finally, read the audio data
	while (length > 0) {
		if (channels == 1) {
			audio = read_int16(in);
		} else {
			audio = read_int16(in);
			audio += read_int16(in);
			audio /= 2;
		}
		if (pcm_mode) {
			print_byte(out, audio);
			print_byte(out, audio >> 8);
		} else {
			print_byte(out, ulaw_encode(audio));
		}
		length--;
	}