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(¤t_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); }
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; } }