static struct timidity_data *make_timidity_data(const char *file) { struct timidity_data *data; data = (struct timidity_data *)xmalloc (sizeof(struct timidity_data)); data->midisong = NULL; decoder_error_init (&data->error); MidIStream *midistream = mid_istream_open_file(file); if(midistream==NULL) { decoder_error(&data->error, ERROR_FATAL, 0, "Can't open midifile: %s", file); return data; } data->midisong = mid_song_load(midistream, &midioptions); mid_istream_close(midistream); if(data->midisong==NULL) { decoder_error(&data->error, ERROR_FATAL, 0, "Can't load midifile: %s", file); return data; } return data; }
static struct mp3_data *mp3_open_internal (const char *file, const int buffered) { struct mp3_data *data; data = (struct mp3_data *)xmalloc (sizeof(struct mp3_data)); data->ok = 0; decoder_error_init (&data->error); /* Reset information about the file */ data->freq = 0; data->channels = 0; data->skip_frames = 0; data->bitrate = -1; data->avg_bitrate = -1; /* Open the file */ data->io_stream = io_open (file, buffered); if (io_ok(data->io_stream)) { data->ok = 1; data->size = io_file_size (data->io_stream); mad_stream_init (&data->stream); mad_frame_init (&data->frame); mad_synth_init (&data->synth); if (options_get_int("Mp3IgnoreCRCErrors")) mad_stream_options (&data->stream, MAD_OPTION_IGNORECRC); data->duration = count_time_internal (data); mad_frame_mute (&data->frame); data->stream.next_frame = NULL; data->stream.sync = 0; data->stream.error = MAD_ERROR_NONE; if (io_seek(data->io_stream, SEEK_SET, 0) == (off_t)-1) { decoder_error (&data->error, ERROR_FATAL, 0, "seek failed"); io_close (data->io_stream); mad_stream_finish (&data->stream); mad_frame_finish (&data->frame); mad_synth_finish (&data->synth); data->ok = 0; } data->stream.error = MAD_ERROR_BUFLEN; } else { decoder_error (&data->error, ERROR_FATAL, 0, "Can't open: %s", io_strerror(data->io_stream)); io_close (data->io_stream); } return data; }
static void *process_header (struct spx_data *data) { void *st; const SpeexMode *mode; int modeID; SpeexCallback callback; int enhance = ENHANCE_AUDIO; data->header = speex_packet_to_header ((char*)data->op.packet, data->op.bytes); if (!data->header) { decoder_error (&data->error, ERROR_FATAL, 0, "Can't open speex file: can't read header"); return NULL; } if (data->header->mode >= SPEEX_NB_MODES) { decoder_error (&data->error, ERROR_FATAL, 0, "Can't open speex file: Mode number %"PRId32 " does not exist in this version", data->header->mode); return NULL; } modeID = data->header->mode; mode = speex_mode_list[modeID]; if (mode->bitstream_version < data->header->mode_bitstream_version) { decoder_error (&data->error, ERROR_FATAL, 0, "Can't open speex file: The file was encoded " "with a newer version of Speex."); return NULL; } if (mode->bitstream_version > data->header->mode_bitstream_version) { decoder_error (&data->error, ERROR_FATAL, 0, "Can't open speex file: The file was encoded " "with an older version of Speex."); return NULL; } st = speex_decoder_init (mode); speex_decoder_ctl(st, SPEEX_SET_ENH, &enhance); speex_decoder_ctl(st, SPEEX_GET_FRAME_SIZE, &data->frame_size); callback.callback_id = SPEEX_INBAND_STEREO; callback.func = speex_std_stereo_request_handler; callback.data = &data->stereo; speex_decoder_ctl(st, SPEEX_SET_HANDLER, &callback); speex_decoder_ctl(st, SPEEX_SET_SAMPLING_RATE, &data->header->rate); return st; }
static void unpack_raw(struct tmate_unpacker *uk, const char **buf, size_t *len) { if (uk->argc == 0) decoder_error(); if (uk->argv[0].type != MSGPACK_OBJECT_RAW) decoder_error(); *len = uk->argv[0].via.raw.size; *buf = uk->argv[0].via.raw.ptr; uk->argv++; uk->argc--; }
static void *sndfile_open (const char *file) { struct sndfile_data *data; data = (struct sndfile_data *)xmalloc (sizeof(struct sndfile_data)); decoder_error_init (&data->error); memset (&data->snd_info, 0, sizeof(data->snd_info)); if (!(data->sndfile = sf_open(file, SFM_READ, &data->snd_info))) { /* FIXME: sf_strerror is not thread save with NULL argument */ decoder_error (&data->error, ERROR_FATAL, 0, "Can't open file: %s", sf_strerror(NULL)); return data; } debug ("Opened file %s", file); debug ("Channels: %d", data->snd_info.channels); debug ("Format: %08X", data->snd_info.format); debug ("Sample rate: %d", data->snd_info.samplerate); return data; }
/* Fill in the mad buffer, return number of bytes read, 0 on eof or error */ static size_t fill_buff (struct mp3_data *data) { size_t remaining; ssize_t read_size; unsigned char *read_start; if (data->stream.next_frame != NULL) { remaining = data->stream.bufend - data->stream.next_frame; memmove (data->in_buff, data->stream.next_frame, remaining); read_start = data->in_buff + remaining; read_size = INPUT_BUFFER - remaining; } else { read_start = data->in_buff; read_size = INPUT_BUFFER; remaining = 0; } read_size = io_read (data->io_stream, read_start, read_size); if (read_size < 0) { decoder_error (&data->error, ERROR_FATAL, 0, "read error: %s", io_strerror(data->io_stream)); return 0; } else if (read_size == 0) return 0; mad_stream_buffer(&data->stream, data->in_buff, read_size + remaining); data->stream.error = 0; return read_size; }
static void init_unpacker(struct tmate_unpacker *uk, msgpack_object obj) { if (obj.type != MSGPACK_OBJECT_ARRAY) decoder_error(); uk->argv = obj.via.array.ptr; uk->argc = obj.via.array.size; }
static int64_t unpack_int(struct tmate_unpacker *uk) { int64_t val; if (uk->argc == 0) decoder_error(); if (uk->argv[0].type != MSGPACK_OBJECT_POSITIVE_INTEGER && uk->argv[0].type != MSGPACK_OBJECT_NEGATIVE_INTEGER) decoder_error(); val = uk->argv[0].via.i64; uk->argv++; uk->argc--; return val; }
static void *sndfile_open (const char *file) { int fd; struct sndfile_data *data; data = (struct sndfile_data *)xmalloc (sizeof(struct sndfile_data)); decoder_error_init (&data->error); memset (&data->snd_info, 0, sizeof(data->snd_info)); data->timing_broken = false; fd = open (file, O_RDONLY); if (fd == -1) { char *err = xstrerror (errno); decoder_error (&data->error, ERROR_FATAL, 0, "Can't open file: %s", err); free (err); return data; } /* sf_open_fd() close()s 'fd' on error and in sf_close(). */ data->sndfile = sf_open_fd (fd, SFM_READ, &data->snd_info, SF_TRUE); if (!data->sndfile) { /* FIXME: sf_strerror is not thread safe with NULL argument */ decoder_error (&data->error, ERROR_FATAL, 0, "Can't open file: %s", sf_strerror(NULL)); return data; } /* If the timing is broken, sndfile only decodes up to the broken value. */ data->timing_broken = is_timing_broken (fd, data); if (data->timing_broken) { decoder_error (&data->error, ERROR_FATAL, 0, "File too large for audio format!"); return data; } debug ("Opened file %s", file); debug ("Channels: %d", data->snd_info.channels); debug ("Format: %08X", data->snd_info.format); debug ("Sample rate: %d", data->snd_info.samplerate); return data; }
static cibool asap_load(ASAP_Decoder *d, const char *filename) { struct io_stream *s; ssize_t module_len; unsigned char *module; cibool ok; const ASAPInfo *info; int song; int duration; d->asap = NULL; decoder_error_init(&d->error); s = io_open(filename, 0); if (s == NULL) { decoder_error(&d->error, ERROR_FATAL, 0, "Can't open %s", filename); return FALSE; } module_len = io_file_size(s); module = (unsigned char *) xmalloc(module_len); module_len = io_read(s, module, module_len); io_close(s); d->asap = ASAP_New(); if (d->asap == NULL) { decoder_error(&d->error, ERROR_FATAL, 0, "Out of memory"); return FALSE; } ok = ASAP_Load(d->asap, filename, module, module_len); free(module); if (!ok) { decoder_error(&d->error, ERROR_FATAL, 0, "Unsupported file format"); return FALSE; } info = ASAP_GetInfo(d->asap); song = ASAPInfo_GetDefaultSong(info); duration = ASAPInfo_GetDuration(info, song); if (duration < 0) duration = DEFAULT_SONG_LENGTH * 1000; d->duration = duration; return TRUE; }
static int wav_seek (void *prv_data, int sec) { struct wavpack_data *data = (struct wavpack_data *)prv_data; assert (sec >= 0); if ( WavpackSeekSample (data->wpc, sec * data->sample_rate) ) return sec; decoder_error (&data->error, ERROR_FATAL, 0, "Fatal seeking error!"); return -1; }
static void handle_message(struct tmate_decoder *decoder, msgpack_object obj) { struct tmate_unpacker _uk; struct tmate_unpacker *uk = &_uk; init_unpacker(uk, obj); switch (unpack_int(uk)) { case TMATE_NOTIFY: tmate_notify(uk); break; case TMATE_CLIENT_PANE_KEY: tmate_client_pane_key(uk); break; case TMATE_CLIENT_RESIZE: tmate_client_resize(uk); break; case TMATE_CLIENT_EXEC_CMD: tmate_client_exec_cmd(uk); break; case TMATE_CLIENT_ENV: tmate_client_env(uk); break; case TMATE_CLIENT_READY: tmate_client_ready(decoder, uk); break; default: decoder_error(); } }
static void *spx_open (const char *file) { struct io_stream *stream; struct spx_data *data; stream = io_open (file, 1); if (io_ok(stream)) data = spx_open_internal (stream); else { data = (struct spx_data *)xmalloc (sizeof(struct spx_data)); decoder_error_init (&data->error); decoder_error (&data->error, ERROR_STREAM, 0, "Can't open file: %s", io_strerror(data->stream)); data->ok = 0; } return data; }
static void *wav_open (const char *file) { struct wavpack_data *data; data = (struct wavpack_data *)xmalloc (sizeof(struct wavpack_data)); data->ok = 0; decoder_error_init (&data->error); int o_flags = OPEN_2CH_MAX | OPEN_WVC; char wv_error[100]; if ((data->wpc = WavpackOpenFileInput(file, wv_error, o_flags, 0)) == NULL) { decoder_error (&data->error, ERROR_FATAL, 0, "%s", wv_error); logit ("wv_open error: %s", wv_error); } else wav_data_init (data); return data; }
static int ffmpeg_decode (void *prv_data, char *buf, int buf_len, struct sound_params *sound_params) { struct ffmpeg_data *data = (struct ffmpeg_data *)prv_data; int ret; int data_size; AVPacket pkt, pkt_tmp; uint8_t *pkt_data; int pkt_size = 0; int filled = 0; /* The sample buffer should be 16 byte aligned (because SSE), a segmentation * fault may occur otherwise. * * See: avcodec.h in ffmpeg */ char avbuf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2] __attribute__((aligned(16))); decoder_error_clear (&data->error); sound_params->channels = data->enc->channels; sound_params->rate = data->enc->sample_rate; sound_params->fmt = SFMT_S16 | SFMT_NE; if (data->remain_buf) { int to_copy = MIN (buf_len, data->remain_buf_len); debug ("Copying %d bytes from the remain buf", to_copy); memcpy (buf, data->remain_buf, to_copy); if (to_copy < data->remain_buf_len) { memmove (data->remain_buf, data->remain_buf + to_copy, data->remain_buf_len - to_copy); data->remain_buf_len -= to_copy; } else { debug ("Remain buf is now empty"); free (data->remain_buf); data->remain_buf = NULL; data->remain_buf_len = 0; } return to_copy; } do { ret = av_read_frame (data->ic, &pkt); if (ret < 0) return 0; memcpy(&pkt_tmp, &pkt, sizeof(pkt)); pkt_data = pkt.data; pkt_size = pkt.size; debug ("Got %dB packet", pkt_size); while (pkt_size) { int len; #if LIBAVCODEC_VERSION_INT >= ((52<<16)+(26<<8)+0) data_size = sizeof (avbuf); len = avcodec_decode_audio3 (data->enc, (int16_t *)avbuf, &data_size, &pkt); #elif LIBAVCODEC_VERSION_INT >= ((51<<16)+(50<<8)+0) data_size = sizeof (avbuf); len = avcodec_decode_audio2 (data->enc, (int16_t *)avbuf, &data_size, pkt_data, pkt_size); #else len = avcodec_decode_audio (data->enc, (int16_t *)avbuf, &data_size, pkt_data, pkt_size); #endif debug ("Decoded %dB", data_size); if (len < 0) { /* skip frame */ decoder_error (&data->error, ERROR_STREAM, 0, "Error in the stream!"); break; } pkt_data += len; pkt_size -= len; if (buf_len) { int to_copy = MIN (data_size, buf_len); memcpy (buf, avbuf, to_copy); buf += to_copy; filled += to_copy; buf_len -= to_copy; debug ("Copying %dB (%dB filled)", to_copy, filled); if (to_copy < data_size) put_in_remain_buf (data, avbuf + to_copy, data_size - to_copy); } else if (data_size) add_to_remain_buf (data, avbuf, data_size); } } while (!filled); /* 2.0 - 16bit/sample*/ data->bitrate = pkt.size * 8 / ((filled + data->remain_buf_len) / 2.0 / sound_params->channels / sound_params->rate) / 1000; av_free_packet (&pkt_tmp); return filled; }
static void *ffmpeg_open (const char *file) { struct ffmpeg_data *data; int err; unsigned int i; int audio_index = -1; data = (struct ffmpeg_data *)xmalloc (sizeof(struct ffmpeg_data)); data->ok = 0; decoder_error_init (&data->error); memset (&data->ap, 0, sizeof(data->ap)); err = av_open_input_file (&data->ic, file, NULL, 0, &data->ap); if (err < 0) { decoder_error (&data->error, ERROR_FATAL, 0, "Can't open file"); return data; } err = av_find_stream_info (data->ic); if (err < 0) { decoder_error (&data->error, ERROR_FATAL, 0, "Could not find codec parameters (err %d)", err); av_close_input_file (data->ic); return data; } av_read_play (data->ic); for (i = 0; i < data->ic->nb_streams; i++) { data->enc = data->ic->streams[i]->codec; if (data->enc->codec_type == CODEC_TYPE_AUDIO) { audio_index = i; break; } } if (audio_index == -1) { decoder_error (&data->error, ERROR_FATAL, 0, "No audio stream in file"); av_close_input_file (data->ic); return data; } /* hack for AC3 */ if (data->enc->channels > 2) data->enc->channels = 2; data->codec = avcodec_find_decoder (data->enc->codec_id); if (!data->codec || avcodec_open(data->enc, data->codec) < 0) { decoder_error (&data->error, ERROR_FATAL, 0, "No codec for this file."); av_close_input_file (data->ic); return data; } data->remain_buf = NULL; data->remain_buf_len = 0; data->ok = 1; data->avg_bitrate = (int) (data->ic->file_size / (data->ic->duration / 1000000) * 8); data->bitrate = data->ic->bit_rate / 1000; return data; }
/* Read the speex header. Return 0 on error. */ static int read_speex_header (struct spx_data *data) { int packet_count = 0; int stream_init = 0; char *buf; ssize_t nb_read; int header_packets = 2; while (packet_count < header_packets) { /* Get the ogg buffer for writing */ buf = ogg_sync_buffer (&data->oy, 200); /* Read bitstream from input file */ nb_read = io_read (data->stream, buf, 200); if (nb_read < 0) { decoder_error (&data->error, ERROR_FATAL, 0, "Can't open speex file: IO error: %s", io_strerror(data->stream)); return 0; } if (nb_read == 0) { decoder_error (&data->error, ERROR_FATAL, 0, "Can't open speex header"); return 0; } ogg_sync_wrote (&data->oy, nb_read); /* Loop for all complete pages we got (most likely only one) */ while (ogg_sync_pageout(&data->oy, &data->og) == 1) { if (stream_init == 0) { ogg_stream_init(&data->os, ogg_page_serialno(&data->og)); stream_init = 1; } /* Add page to the bitstream */ ogg_stream_pagein (&data->os, &data->og); /* Extract all available packets FIXME: EOS! */ while (ogg_stream_packetout(&data->os, &data->op) == 1) { /* If first packet, process as Speex header */ if (packet_count == 0) { data->st = process_header (data); if (!data->st) { ogg_stream_clear (&data->os); return 0; } data->rate = data->header->rate; data->nchannels = data->header->nb_channels; data->frames_per_packet = data->header->frames_per_packet; /*data->vbr = data->header->vbr; */ if (!data->frames_per_packet) data->frames_per_packet=1; data->output = xmalloc (data->frame_size * data->nchannels * data->frames_per_packet * sizeof(int16_t)); data->output_start = 0; data->output_left = 0; header_packets += data->header->extra_headers; } else if (packet_count == 1) { data->comment_packet_len = data->op.bytes; data->comment_packet = xmalloc ( sizeof(char) * data->comment_packet_len); memcpy (data->comment_packet, data->op.packet, data->comment_packet_len); } packet_count++; } } } return 1; }
static void *aac_open_internal (struct io_stream *stream, const char *fname) { struct aac_data *data; NeAACDecConfigurationPtr neaac_cfg; unsigned char channels; unsigned long sample_rate; int n; /* init private struct */ data = xcalloc (1, sizeof *data); data->decoder = NeAACDecOpen(); /* set decoder config */ neaac_cfg = NeAACDecGetCurrentConfiguration(data->decoder); neaac_cfg->outputFormat = FAAD_FMT_16BIT; /* force 16 bit audio */ neaac_cfg->downMatrix = 1; /* 5.1 -> stereo */ neaac_cfg->dontUpSampleImplicitSBR = 0; /* upsample, please! */ NeAACDecSetConfiguration(data->decoder, neaac_cfg); if (stream) data->stream = stream; else { data->stream = io_open (fname, 1); if (!io_ok(data->stream)) { decoder_error (&data->error, ERROR_FATAL, 0, "Can't open AAC file: %s", io_strerror(data->stream)); return data; } } /* find a frame */ if (buffer_fill_frame(data) <= 0) { decoder_error (&data->error, ERROR_FATAL, 0, "Not a valid (or unsupported) AAC file"); return data; } /* in case of a bug, make sure there is at least some data * in the buffer for NeAACDecInit() to work with. */ if (buffer_fill_min(data, 256) <= 0) { decoder_error (&data->error, ERROR_FATAL, 0, "AAC file/stream too short"); return data; } /* init decoder, returns the length of the header (if any) */ channels = (unsigned char)data->channels; sample_rate = data->sample_rate; n = NeAACDecInit (data->decoder, buffer_data(data), buffer_length(data), &sample_rate, &channels); data->channels = channels; data->sample_rate = (int)sample_rate; if (n < 0) { decoder_error (&data->error, ERROR_FATAL, 0, "libfaad can't open this stream"); return data; } logit ("sample rate %dHz, channels %d", data->sample_rate, data->channels); if (!data->sample_rate || !data->channels) { decoder_error (&data->error, ERROR_FATAL, 0, "Invalid AAC sound parameters"); return data; } /* skip the header */ logit ("skipping header (%d bytes)", n); buffer_consume (data, n); /*NeAACDecInitDRM(data->decoder, data->sample_rate, data->channels);*/ data->ok = 1; return data; }