static bool dsdiff_read(struct decoder *decoder, struct input_stream *is, void *data, size_t length) { size_t nbytes = decoder_read(decoder, is, data, length); return nbytes == length; }
static mpc_int32_t mpc_read_cb(cb_first_arg, void *ptr, mpc_int32_t size) { struct mpc_decoder_data *data = (struct mpc_decoder_data *) cb_data; return decoder_read(data->decoder, data->is, ptr, size); }
/** * Decode one "DSD" chunk. */ static bool dsdiff_decode_chunk(struct decoder *decoder, struct input_stream *is, unsigned channels, uint64_t chunk_size, bool fileisdff, bool bitreverse) { uint8_t buffer[8192]; /* Scratch buffer for DSF samples to convert to the needed normal Left/Right regime of samples */ uint8_t dsf_scratch_buffer[8192]; const size_t sample_size = sizeof(buffer[0]); const size_t frame_size = channels * sample_size; const unsigned buffer_frames = sizeof(buffer) / frame_size; const unsigned buffer_samples = buffer_frames * frame_size; const size_t buffer_size = buffer_samples * sample_size; while (chunk_size > 0) { /* see how much aligned data from the remaining chunk fits into the local buffer */ unsigned now_frames = buffer_frames; size_t now_size = buffer_size; if (chunk_size < (uint64_t)now_size) { now_frames = (unsigned)chunk_size / frame_size; now_size = now_frames * frame_size; } size_t nbytes = decoder_read(decoder, is, buffer, now_size); if (nbytes != now_size) return false; chunk_size -= nbytes; if (lsbitfirst || bitreverse) bit_reverse_buffer(buffer, buffer + nbytes); if (!fileisdff) dsf_to_pcm_order(buffer, dsf_scratch_buffer, nbytes); enum decoder_command cmd = decoder_data(decoder, is, buffer, nbytes, 0); switch (cmd) { case DECODE_COMMAND_NONE: break; case DECODE_COMMAND_START: case DECODE_COMMAND_STOP: return false; case DECODE_COMMAND_SEEK: /* not implemented yet */ decoder_seek_error(decoder); break; } } return dsdiff_skip(decoder, is, chunk_size); }
static int32_t wavpack_input_read_bytes(void *id, void *data, int32_t bcount) { uint8_t *buf = (uint8_t *)data; int32_t i = 0; if (wpin(id)->last_byte != EOF) { *buf++ = wpin(id)->last_byte; wpin(id)->last_byte = EOF; --bcount; ++i; } /* wavpack fails if we return a partial read, so we just wait until the buffer is full */ while (bcount > 0) { size_t nbytes = decoder_read( wpin(id)->decoder, wpin(id)->is, buf, bcount ); if (nbytes == 0) { /* EOF, error or a decoder command */ break; } i += nbytes; bcount -= nbytes; buf += nbytes; } return i; }
static bool mp3_fill_buffer(struct mp3_data *data) { size_t remaining, length; unsigned char *dest; if (data->stream.next_frame != NULL) { remaining = data->stream.bufend - data->stream.next_frame; memmove(data->input_buffer, data->stream.next_frame, remaining); dest = (data->input_buffer) + remaining; length = READ_BUFFER_SIZE - remaining; } else { remaining = 0; length = READ_BUFFER_SIZE; dest = data->input_buffer; } /* we've exhausted the read buffer, so give up!, these potential * mp3 frames are way too big, and thus unlikely to be mp3 frames */ if (length == 0) return false; length = decoder_read(data->decoder, data->input_stream, dest, length); if (length == 0) return false; mad_stream_buffer(&data->stream, data->input_buffer, length + remaining); (data->stream).error = 0; return true; }
bool decoder_buffer_fill(struct decoder_buffer *buffer) { size_t nbytes; if (buffer->consumed > 0) decoder_buffer_shift(buffer); if (buffer->length >= buffer->size) /* buffer is full */ return false; nbytes = decoder_read(buffer->decoder, buffer->is, buffer->data + buffer->length, buffer->size - buffer->length); if (nbytes == 0) /* end of file, I/O error or decoder command received */ return false; buffer->length += nbytes; assert(buffer->length <= buffer->size); return true; }
/** * Skip some bytes from the #input_stream. */ static bool dsdiff_skip(struct decoder *decoder, struct input_stream *is, goffset delta) { assert(delta >= 0); if (delta == 0) return true; if (is->seekable) return input_stream_seek(is, delta, SEEK_CUR, NULL); char buffer[8192]; while (delta > 0) { size_t length = sizeof(buffer); if ((goffset)length > delta) length = delta; size_t nbytes = decoder_read(decoder, is, buffer, length); if (nbytes == 0) return false; delta -= nbytes; } return true; }
static void pcm_stream_decode(struct decoder *decoder, struct input_stream *is) { static const struct audio_format audio_format = { .sample_rate = 44100, .format = SAMPLE_FORMAT_S16, .channels = 2, }; GError *error = NULL; enum decoder_command cmd; double time_to_size = audio_format_time_to_size(&audio_format); float total_time = -1; if (is->size >= 0) total_time = is->size / time_to_size; decoder_initialized(decoder, &audio_format, is->seekable, total_time); do { char buffer[4096]; size_t nbytes = decoder_read(decoder, is, buffer, sizeof(buffer)); if (nbytes == 0 && input_stream_eof(is)) break; cmd = nbytes > 0 ? decoder_data(decoder, is, buffer, nbytes, 0) : decoder_get_command(decoder); if (cmd == DECODE_COMMAND_SEEK) { goffset offset = (goffset)(time_to_size * decoder_seek_where(decoder)); if (input_stream_seek(is, offset, SEEK_SET, &error)) { decoder_command_finished(decoder); } else { g_warning("seeking failed: %s", error->message); g_error_free(error); decoder_seek_error(decoder); } cmd = DECODE_COMMAND_NONE; } } while (cmd == DECODE_COMMAND_NONE); } static const char *const pcm_mime_types[] = { /* for streams obtained by the cdio_paranoia input plugin */ "audio/x-mpd-cdda-pcm", NULL }; const struct decoder_plugin pcm_decoder_plugin = { .name = "pcm", .stream_decode = pcm_stream_decode, .mime_types = pcm_mime_types, };
static size_t ogg_read_cb(void *ptr, size_t size, size_t nmemb, void *data) { struct vorbis_input_stream *vis = data; size_t ret = decoder_read(vis->decoder, vis->input_stream, ptr, size * nmemb); errno = 0; return ret / size; }
/** * @brief Calculate Current Speed and distance */ void calculateCurSpeed(void) { uint16_t encoderCurrent = 0; encoderCurrent = decoder_read(DECODER); gl_encoderTotal = gl_encoderTotal + encoderCurrent; gl_curSpeed = (encoderCurrent * 110) / (4 * 2) ; // 200 decoder_clear(); /*清零当前计数器*/ gl_distanceTotal = (uint16_t)(gl_encoderTotal / DISTANCE_PRESCALE); // cm }
static bool dsdiff_read_payload(struct decoder *decoder, struct input_stream *is, const struct dsdiff_chunk_header *header, void *data, size_t length) { uint64_t size = dsdiff_chunk_size(header); if (size != (uint64_t)length) return false; size_t nbytes = decoder_read(decoder, is, data, length); return nbytes == length; }
static GByteArray *mod_loadfile(struct decoder *decoder, struct input_stream *is) { unsigned char *data; GByteArray *bdatas; size_t ret; if (is->size == 0) { g_warning("file is empty"); return NULL; } if (is->size > MODPLUG_FILE_LIMIT) { g_warning("file too large"); return NULL; } //known/unknown size, preallocate array, lets read in chunks if (is->size > 0) { bdatas = g_byte_array_sized_new(is->size); } else { bdatas = g_byte_array_sized_new(MODPLUG_PREALLOC_BLOCK); } data = g_malloc(MODPLUG_READ_BLOCK); while (true) { ret = decoder_read(decoder, is, data, MODPLUG_READ_BLOCK); if (ret == 0) { if (input_stream_lock_eof(is)) /* end of file */ break; /* I/O error - skip this song */ g_free(data); g_byte_array_free(bdatas, true); return NULL; } if (bdatas->len + ret > MODPLUG_FILE_LIMIT) { g_warning("stream too large\n"); g_free(data); g_byte_array_free(bdatas, TRUE); return NULL; } g_byte_array_append(bdatas, data, ret); } g_free(data); return bdatas; }
static bool wavpack_open_wvc(struct decoder *decoder, struct input_stream *is_wvc, struct wavpack_input *wpi) { char *utf8url; char *wvc_url = NULL; bool ret; char first_byte; size_t nbytes; /* * As we use dc->utf8url, this function will be bad for * single files. utf8url is not absolute file path :/ */ utf8url = decoder_get_uri(decoder); if (utf8url == NULL) { return false; } wvc_url = g_strconcat(utf8url, "c", NULL); g_free(utf8url); ret = input_stream_open(is_wvc, wvc_url); g_free(wvc_url); if (!ret) { return false; } /* * And we try to buffer in order to get know * about a possible 404 error. */ nbytes = decoder_read( decoder, is_wvc, &first_byte, sizeof(first_byte) ); if (nbytes == 0) { input_stream_close(is_wvc); return false; } /* push it back */ wavpack_input_init(wpi, decoder, is_wvc); wpi->last_byte = first_byte; return true; }
static struct input_stream * wavpack_open_wvc(struct decoder *decoder, const char *uri, struct wavpack_input *wpi) { struct input_stream *is_wvc; char *wvc_url = NULL; char first_byte; size_t nbytes; /* * As we use dc->utf8url, this function will be bad for * single files. utf8url is not absolute file path :/ */ if (uri == NULL) return false; wvc_url = g_strconcat(uri, "c", NULL); is_wvc = input_stream_open(wvc_url, NULL); g_free(wvc_url); if (is_wvc == NULL) return NULL; /* * And we try to buffer in order to get know * about a possible 404 error. */ nbytes = decoder_read( decoder, is_wvc, &first_byte, sizeof(first_byte) ); if (nbytes == 0) { input_stream_close(is_wvc); return NULL; } /* push it back */ wavpack_input_init(wpi, decoder, is_wvc); wpi->last_byte = first_byte; return is_wvc; }
static FLAC__StreamDecoderReadStatus flac_read_cb(G_GNUC_UNUSED const FLAC__StreamDecoder *fd, FLAC__byte buf[], flac_read_status_size_t *bytes, void *fdata) { struct flac_data *data = fdata; size_t r; r = decoder_read(data->decoder, data->input_stream, (void *)buf, *bytes); *bytes = r; if (r == 0) { if (decoder_get_command(data->decoder) != DECODE_COMMAND_NONE || input_stream_lock_eof(data->input_stream)) return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; else return FLAC__STREAM_DECODER_READ_STATUS_ABORT; } return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; }
/* * read (decode) next raw block. (use 'setposition' to seek between blocks. */ int callc fennec_plugin_read(unsigned long id, unsigned long dsize, unsigned long* dread, void* rdata) { if(id >= pstreams_count)return 0; if(!pstreams[id].initialized)return 0; while(plugin_busy)sys_pass(); plugin_busy = 1; if(plugin_error) { plugin_busy = 0; return 0; } *dread = decoder_read(id, rdata, dsize); plugin_busy = 0; if(!(*dread)) return fennec_input_nodata; else return 1; }
/** * Skip the #input_stream to the specified offset. */ static bool dsdiff_skip_to(struct decoder *decoder, struct input_stream *is, goffset offset) { if (is->seekable) return input_stream_seek(is, offset, SEEK_SET, NULL); if (is->offset > offset) return false; char buffer[8192]; while (is->offset < offset) { size_t length = sizeof(buffer); if (offset - is->offset < (goffset)length) length = offset - is->offset; size_t nbytes = decoder_read(decoder, is, buffer, length); if (nbytes == 0) return false; } assert(is->offset == offset); return true; }
static void mp3_parse_id3(struct mp3_data *data, size_t tagsize, struct tag **mpd_tag, struct replay_gain_info **replay_gain_info_r) { struct id3_tag *id3_tag = NULL; id3_length_t count; id3_byte_t const *id3_data; id3_byte_t *allocated = NULL; count = data->stream.bufend - data->stream.this_frame; if (tagsize <= count) { id3_data = data->stream.this_frame; mad_stream_skip(&(data->stream), tagsize); } else { allocated = g_malloc(tagsize); memcpy(allocated, data->stream.this_frame, count); mad_stream_skip(&(data->stream), count); while (count < tagsize) { size_t len; len = decoder_read(data->decoder, data->input_stream, allocated + count, tagsize - count); if (len == 0) break; else count += len; } if (count != tagsize) { g_debug("error parsing ID3 tag"); g_free(allocated); return; } id3_data = allocated; } id3_tag = id3_tag_parse(id3_data, tagsize); if (id3_tag == NULL) { g_free(allocated); return; } if (mpd_tag) { struct tag *tmp_tag = tag_id3_import(id3_tag); if (tmp_tag != NULL) { if (*mpd_tag != NULL) tag_free(*mpd_tag); *mpd_tag = tmp_tag; } } if (replay_gain_info_r) { struct replay_gain_info *tmp_rgi = parse_id3_replay_gain_info(id3_tag); if (tmp_rgi != NULL) { if (*replay_gain_info_r) replay_gain_info_free(*replay_gain_info_r); *replay_gain_info_r = tmp_rgi; } } id3_tag_delete(id3_tag); g_free(allocated); }
static void mp3_parse_id3(struct mp3_data *data, size_t tagsize, struct tag **mpd_tag) { #ifdef HAVE_ID3TAG struct id3_tag *id3_tag = NULL; id3_length_t count; id3_byte_t const *id3_data; id3_byte_t *allocated = NULL; count = data->stream.bufend - data->stream.this_frame; if (tagsize <= count) { id3_data = data->stream.this_frame; mad_stream_skip(&(data->stream), tagsize); } else { allocated = g_malloc(tagsize); memcpy(allocated, data->stream.this_frame, count); mad_stream_skip(&(data->stream), count); while (count < tagsize) { size_t len; len = decoder_read(data->decoder, data->input_stream, allocated + count, tagsize - count); if (len == 0) break; else count += len; } if (count != tagsize) { g_debug("error parsing ID3 tag"); g_free(allocated); return; } id3_data = allocated; } id3_tag = id3_tag_parse(id3_data, tagsize); if (id3_tag == NULL) { g_free(allocated); return; } if (mpd_tag) { struct tag *tmp_tag = tag_id3_import(id3_tag); if (tmp_tag != NULL) { if (*mpd_tag != NULL) tag_free(*mpd_tag); *mpd_tag = tmp_tag; } } if (data->decoder != NULL) { struct replay_gain_info rgi; char *mixramp_start; char *mixramp_end; float replay_gain_db = 0; if (parse_id3_replay_gain_info(&rgi, id3_tag)) { replay_gain_db = decoder_replay_gain(data->decoder, &rgi); data->found_replay_gain = true; } if (parse_id3_mixramp(&mixramp_start, &mixramp_end, id3_tag)) { g_debug("setting mixramp_tags"); decoder_mixramp(data->decoder, replay_gain_db, mixramp_start, mixramp_end); } } id3_tag_delete(id3_tag); g_free(allocated); #else /* !HAVE_ID3TAG */ (void)mpd_tag; /* This code is enabled when libid3tag is disabled. Instead of parsing the ID3 frame, it just skips it. */ size_t count = data->stream.bufend - data->stream.this_frame; if (tagsize <= count) { mad_stream_skip(&data->stream, tagsize); } else { mad_stream_skip(&data->stream, count); while (count < tagsize) { size_t len = tagsize - count; char ignored[1024]; if (len > sizeof(ignored)) len = sizeof(ignored); len = decoder_read(data->decoder, data->input_stream, ignored, len); if (len == 0) break; else count += len; } } #endif }
int file_read(struct file_handle *h, unsigned char *buffer, size_t size) { return decoder_read(h->dec, buffer, size); }