FileReader::Status FileReader::writeToStream(pa_stream *p, size_t nbytes) { int frameSize = pa_frame_size(&m_s); int len = qMin(nbytes, (nbytes/frameSize) * nbytes); void *buff = pa_xmalloc(len); if (!buff) { qWarning() << "Failed to allocate buffer"; return StatusError; } sf_count_t read = sf_read_raw(m_file, buff, len); if (pa_stream_write(p, buff, read, pa_xfree, 0, PA_SEEK_RELATIVE) < 0) { qWarning() << "Failed to write to pulse audio stream"; pa_xfree(buff); return StatusError; } m_pos += read; if (m_pos == size()) { // Over. return StatusEof; } if (read != len) { return StatusError; } return StatusOk; }
/* This is called whenever new data may be written to the stream */ static void stream_write_callback(pa_stream *s, size_t length, void *userdata) { pa_assert(s); pa_assert(length > 0); if (raw) { pa_assert(!sndfile); if (stdio_event) mainloop_api->io_enable(stdio_event, PA_IO_EVENT_INPUT); if (!buffer) return; do_stream_write(length); } else { sf_count_t bytes; void *data; pa_assert(sndfile); for (;;) { size_t data_length = length; if (pa_stream_begin_write(s, &data, &data_length) < 0) { pa_log(_("pa_stream_begin_write() failed: %s"), pa_strerror(pa_context_errno(context))); quit(1); return; } if (readf_function) { size_t k = pa_frame_size(&sample_spec); if ((bytes = readf_function(sndfile, data, (sf_count_t) (data_length/k))) > 0) bytes *= (sf_count_t) k; } else bytes = sf_read_raw(sndfile, data, (sf_count_t) data_length); if (bytes > 0) pa_stream_write(s, data, (size_t) bytes, NULL, 0, PA_SEEK_RELATIVE); else pa_stream_cancel_write(s); /* EOF? */ if (bytes < (sf_count_t) data_length) { start_drain(); break; } /* Request fulfilled */ if ((size_t) bytes >= length) break; length -= bytes; } } }
static int quh_sndfile_in_write (st_quh_nfo_t * file) { (void) file; quh.buffer_len = sf_read_raw (sndfile, quh.buffer, QUH_MAXBUFSIZE); return 0; }
void test_read_raw_or_die (SNDFILE *file, int pass, void *test, sf_count_t items, int line_num) { sf_count_t count ; if ((count = sf_read_raw (file, test, items)) != items) { printf ("\n\nLine %d", line_num) ; if (pass > 0) printf (" (pass %d)", pass) ; printf (" : sf_read_raw failed with short read (%ld => %ld).\n", SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ; fflush (stdout) ; puts (sf_strerror (file)) ; exit (1) ; } ; return ; } /* test_read_raw_or_die */
int main (int argc, char *argv[]) { static char strbuffer [BUFFER_LEN] ; unsigned int linecount ; char *progname, *infilename ; SNDFILE *infile ; SF_INFO sfinfo ; int k, start, readcount ; progname = strrchr (argv [0], '/') ; progname = progname ? progname + 1 : argv [0] ; if (argc != 2) { print_usage (progname) ; return 1 ; } ; infilename = argv [1] ; if (! (infile = sf_open (infilename, SFM_READ, &sfinfo))) { printf ("Error : Not able to open input file %s.\n", infilename) ; sf_perror (NULL) ; sf_command (NULL, SFC_GET_LOG_INFO, strbuffer, BUFFER_LEN) ; printf (strbuffer) ; return 1 ; } ; start = 0 ; linecount = 24 ; while ((readcount = sf_read_raw (infile, strbuffer, linecount))) { printf ("%08X: ", start) ; for (k = 0 ; k < readcount ; k++) printf ("%02X ", strbuffer [k] & 0xFF) ; for (k = readcount ; k < 16 ; k++) printf (" ") ; printf ("\n") ; start += readcount ; } ; sf_close (infile) ; return 0 ; } /* main */
static int sndfile_read (DB_fileinfo_t *_info, char *bytes, int size) { sndfile_info_t *info = (sndfile_info_t*)_info; int samplesize = _info->fmt.channels * _info->fmt.bps / 8; if (size / samplesize + info->currentsample > info->endsample) { size = (info->endsample - info->currentsample + 1) * samplesize; trace ("sndfile: size truncated to %d bytes, cursample=%d, endsample=%d\n", size, info->currentsample, info->endsample); if (size <= 0) { return 0; } } int n = 0; if (info->read_as_short) { n = sf_readf_short(info->ctx, (short *)bytes, size/samplesize); } else { n = sf_read_raw (info->ctx, (short *)bytes, size); if (info->sf_format == SF_FORMAT_PCM_U8) { for (int i = 0; i < n; i++) { int sample = ((uint8_t *)bytes)[i]; ((int8_t *)bytes)[i] = sample-0x80; } } n /= samplesize; } info->currentsample += n; size = n * samplesize; _info->readpos = (float)(info->currentsample-info->startsample)/_info->fmt.samplerate; if (info->bitrate > 0) { deadbeef->streamer_set_bitrate (info->bitrate); } return size; }
unsigned AudioFileSndfile::read(void* buffer, Sound::Type type, unsigned frames) { if (!_handle || !(_mode == ModeRead || _mode == ModeReadWrite)) { RUNTIME_ERROR("Attempt to read file not opened for reading."); } sf_count_t count; switch (type) { case Sound::Type::Float32: count = sf_readf_float(_handle.get(), static_cast<Sound::Float32*>(buffer), frames); break; case Sound::Type::Float64: count = sf_readf_double(_handle.get(), static_cast<Sound::Float64*>(buffer), frames); break; case Sound::Type::Int8: count = sf_read_raw(_handle.get(), buffer, frames * _info.channels); break; case Sound::Type::Int16: count = sf_readf_short(_handle.get(), static_cast<Sound::Int16*>(buffer), frames); break; case Sound::Type::Int32: count = sf_readf_int(_handle.get(), static_cast<Sound::Int32*>(buffer), frames); break; default: RUNTIME_ERROR("Unsupported sample type"); } int errorNumber = sf_error(_handle.get()); if (errorNumber) { SNDFILE_ERROR(errorNumber, "Error while reading file"); } return unsigned(count); }
static switch_status_t sndfile_file_read(switch_file_handle_t *handle, void *data, size_t *len) { size_t inlen = *len; sndfile_context *context = handle->private_info; if (switch_test_flag(handle, SWITCH_FILE_DATA_RAW)) { *len = (size_t) sf_read_raw(context->handle, data, inlen); } else if (switch_test_flag(handle, SWITCH_FILE_DATA_INT)) { *len = (size_t) sf_readf_int(context->handle, (int *) data, inlen); } else if (switch_test_flag(handle, SWITCH_FILE_DATA_SHORT)) { *len = (size_t) sf_readf_short(context->handle, (short *) data, inlen); } else if (switch_test_flag(handle, SWITCH_FILE_DATA_FLOAT)) { *len = (size_t) sf_readf_float(context->handle, (float *) data, inlen); } else if (switch_test_flag(handle, SWITCH_FILE_DATA_DOUBLE)) { *len = (size_t) sf_readf_double(context->handle, (double *) data, inlen); } else { *len = (size_t) sf_readf_int(context->handle, (int *) data, inlen); } handle->pos += *len; handle->sample_count += *len; return *len ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; }
int pa_sound_file_load( pa_mempool *pool, const char *fname, pa_sample_spec *ss, pa_channel_map *map, pa_memchunk *chunk, pa_proplist *p) { SNDFILE *sf = NULL; SF_INFO sfi; int ret = -1; size_t l; sf_count_t (*readf_function)(SNDFILE *sndfile, void *ptr, sf_count_t frames) = NULL; void *ptr = NULL; int fd; pa_assert(fname); pa_assert(ss); pa_assert(chunk); pa_memchunk_reset(chunk); if ((fd = pa_open_cloexec(fname, O_RDONLY, 0)) < 0) { pa_log("Failed to open file %s: %s", fname, pa_cstrerror(errno)); goto finish; } #ifdef HAVE_POSIX_FADVISE if (posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL) < 0) { pa_log_warn("POSIX_FADV_SEQUENTIAL failed: %s", pa_cstrerror(errno)); goto finish; } else pa_log_debug("POSIX_FADV_SEQUENTIAL succeeded."); #endif pa_zero(sfi); if (!(sf = sf_open_fd(fd, SFM_READ, &sfi, 1))) { pa_log("Failed to open file %s", fname); goto finish; } fd = -1; if (pa_sndfile_read_sample_spec(sf, ss) < 0) { pa_log("Failed to determine file sample format."); goto finish; } if ((map && pa_sndfile_read_channel_map(sf, map) < 0)) { if (ss->channels > 2) pa_log("Failed to determine file channel map, synthesizing one."); pa_channel_map_init_extend(map, ss->channels, PA_CHANNEL_MAP_DEFAULT); } if (p) pa_sndfile_init_proplist(sf, p); if ((l = pa_frame_size(ss) * (size_t) sfi.frames) > PA_SCACHE_ENTRY_SIZE_MAX) { pa_log("File too large"); goto finish; } chunk->memblock = pa_memblock_new(pool, l); chunk->index = 0; chunk->length = l; readf_function = pa_sndfile_readf_function(ss); ptr = pa_memblock_acquire(chunk->memblock); if ((readf_function && readf_function(sf, ptr, sfi.frames) != sfi.frames) || (!readf_function && sf_read_raw(sf, ptr, (sf_count_t) l) != (sf_count_t) l)) { pa_log("Premature file end"); goto finish; } ret = 0; finish: if (sf) sf_close(sf); if (ptr) pa_memblock_release(chunk->memblock); if (ret != 0 && chunk->memblock) pa_memblock_unref(chunk->memblock); if (fd >= 0) pa_close(fd); return ret; }
/* Called from IO thread context */ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) { file_stream *u; pa_sink_input_assert_ref(i); pa_assert(chunk); u = FILE_STREAM(i->userdata); file_stream_assert_ref(u); if (!u->memblockq) return -1; for (;;) { pa_memchunk tchunk; size_t fs; void *p; sf_count_t n; if (pa_memblockq_peek(u->memblockq, chunk) >= 0) { chunk->length = PA_MIN(chunk->length, length); pa_memblockq_drop(u->memblockq, chunk->length); return 0; } if (!u->sndfile) break; tchunk.memblock = pa_memblock_new(i->sink->core->mempool, length); tchunk.index = 0; p = pa_memblock_acquire(tchunk.memblock); if (u->readf_function) { fs = pa_frame_size(&i->sample_spec); n = u->readf_function(u->sndfile, p, (sf_count_t) (length/fs)); } else { fs = 1; n = sf_read_raw(u->sndfile, p, (sf_count_t) length); } pa_memblock_release(tchunk.memblock); if (n <= 0) { pa_memblock_unref(tchunk.memblock); sf_close(u->sndfile); u->sndfile = NULL; break; } tchunk.length = (size_t) n * fs; pa_memblockq_push(u->memblockq, &tchunk); pa_memblock_unref(tchunk.memblock); } if (pa_sink_input_safe_to_remove(i)) { pa_memblockq_free(u->memblockq); u->memblockq = NULL; pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(u), FILE_STREAM_MESSAGE_UNLINK, NULL, 0, NULL, NULL); } return -1; }