예제 #1
0
void
decode_wav_using_siren7 (char *input_file, char *output_file)
{
	FILE * input;
	FILE * output;
	RIFF riff_header;
	WAVE_CHUNK current_chunk;
	fmtChunkEx fmt_info;
	unsigned char *out_data = NULL;
	unsigned char *out_ptr = NULL;
	unsigned char InBuffer[40];
	unsigned int fileOffset;
	unsigned int chunkOffset;

	SirenDecoder decoder = Siren7_NewDecoder(16000);
	
	input = fopen(input_file, "rb");
	output = fopen(output_file, "wb");

	fileOffset = 0;
	fread(&riff_header, sizeof(RIFF), 1, input);
	fileOffset += sizeof(RIFF);

	riff_header.ChunkId = GUINT32_FROM_LE(riff_header.ChunkId);
	riff_header.ChunkSize = GUINT32_FROM_LE(riff_header.ChunkSize);
	riff_header.TypeID = GUINT32_FROM_LE(riff_header.TypeID);

	if (riff_header.ChunkId == RIFF_ID && riff_header.TypeID == WAVE_ID) {
		while (fileOffset < riff_header.ChunkSize) {
			fread(&current_chunk, sizeof(WAVE_CHUNK), 1, input);
			fileOffset += sizeof(WAVE_CHUNK);
			current_chunk.ChunkId = GUINT32_FROM_LE(current_chunk.ChunkId);
			current_chunk.ChunkSize = GUINT32_FROM_LE(current_chunk.ChunkSize);

			chunkOffset = 0;
			if (current_chunk.ChunkId == FMT__ID) {
				fread(&fmt_info, sizeof(fmtChunk), 1, input);
				/* Should convert from LE the fmt_info structure, but it's not necessary... */
				if (current_chunk.ChunkSize > sizeof(fmtChunk)) {
					fread(&(fmt_info.ExtraSize), sizeof(short), 1, input);
					fmt_info.ExtraSize= GUINT32_FROM_LE(fmt_info.ExtraSize);
					fmt_info.ExtraContent = (unsigned char *) malloc (fmt_info.ExtraSize);
					fread(fmt_info.ExtraContent, fmt_info.ExtraSize, 1, input);
				} else {
					fmt_info.ExtraSize = 0;
					fmt_info.ExtraContent = NULL;
				}
			} else if (current_chunk.ChunkId  == DATA_ID) {
				out_data = (unsigned char *) malloc(current_chunk.ChunkSize * 16);
				out_ptr = out_data;
				while (chunkOffset + 40 <= current_chunk.ChunkSize) {
					fread(InBuffer, 1, 40, input);
					Siren7_DecodeFrame(decoder, InBuffer, out_ptr);
					out_ptr += 640;
					chunkOffset += 40;
				}
				fread(InBuffer, 1, current_chunk.ChunkSize - chunkOffset, input);
			} else {
				fseek(input, current_chunk.ChunkSize, SEEK_CUR);
			}
			fileOffset += current_chunk.ChunkSize;
		}
	}
	
	/* The WAV heder should be converted TO LE, but should be done inside the library and it's not important for now ... */
	fwrite(&(decoder->WavHeader), sizeof(decoder->WavHeader), 1, output);
	fwrite(out_data, 1, GUINT32_FROM_LE(decoder->WavHeader.DataSize), output);
	fclose(output);

	Siren7_CloseDecoder(decoder);

	free(out_data);
	if (fmt_info.ExtraContent != NULL)
		free(fmt_info.ExtraContent);
}
예제 #2
0
static GstFlowReturn
gst_siren_dec_handle_frame (GstAudioDecoder * bdec, GstBuffer * buf)
{
  GstSirenDec *dec;
  GstFlowReturn ret = GST_FLOW_OK;
  GstBuffer *out_buf;
  guint8 *in_data, *out_data;
  guint i, size, num_frames;
  gint out_size, in_size;
  gint decode_ret;
  GstMapInfo inmap, outmap;

  dec = GST_SIREN_DEC (bdec);

  size = gst_buffer_get_size (buf);

  GST_LOG_OBJECT (dec, "Received buffer of size %u", size);

  g_return_val_if_fail (size % 40 == 0, GST_FLOW_ERROR);
  g_return_val_if_fail (size > 0, GST_FLOW_ERROR);

  /* process 40 input bytes into 640 output bytes */
  num_frames = size / 40;

  /* this is the input/output size */
  in_size = num_frames * 40;
  out_size = num_frames * 640;

  GST_LOG_OBJECT (dec, "we have %u frames, %u in, %u out", num_frames, in_size,
      out_size);

  out_buf = gst_audio_decoder_allocate_output_buffer (bdec, out_size);
  if (out_buf == NULL)
    goto alloc_failed;

  /* get the input data for all the frames */
  gst_buffer_map (buf, &inmap, GST_MAP_READ);
  gst_buffer_map (out_buf, &outmap, GST_MAP_WRITE);

  in_data = inmap.data;
  out_data = outmap.data;

  for (i = 0; i < num_frames; i++) {
    GST_LOG_OBJECT (dec, "Decoding frame %u/%u", i, num_frames);

    /* decode 40 input bytes to 640 output bytes */
    decode_ret = Siren7_DecodeFrame (dec->decoder, in_data, out_data);
    if (decode_ret != 0)
      goto decode_error;

    /* move to next frame */
    out_data += 640;
    in_data += 40;
  }

  gst_buffer_unmap (buf, &inmap);
  gst_buffer_unmap (out_buf, &outmap);

  GST_LOG_OBJECT (dec, "Finished decoding");

  /* might really be multiple frames,
   * but was treated as one for all purposes here */
  ret = gst_audio_decoder_finish_frame (bdec, out_buf, 1);

done:
  return ret;

  /* ERRORS */
alloc_failed:
  {
    GST_DEBUG_OBJECT (dec, "failed to pad_alloc buffer: %d (%s)", ret,
        gst_flow_get_name (ret));
    goto done;
  }
decode_error:
  {
    GST_AUDIO_DECODER_ERROR (bdec, 1, STREAM, DECODE, (NULL),
        ("Error decoding frame: %d", decode_ret), ret);
    if (ret == GST_FLOW_OK)
      gst_audio_decoder_finish_frame (bdec, NULL, 1);
    gst_buffer_unref (out_buf);
    goto done;
  }
}