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--; }