X-Git-Url: https://code.delx.au/pulseaudio/blobdiff_plain/ff38eaf67773e0039befb95c0f9ad91e7a06fc3f..f7afaa264497e98a6f93c483ec10f22d40e17417:/src/pulsecore/sound-file-stream.c?ds=sidebyside diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index 3453637f..33f7337f 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -40,7 +39,8 @@ #include #include #include -#include +#include +#include #include "sound-file-stream.h" @@ -63,9 +63,8 @@ enum { FILE_STREAM_MESSAGE_UNLINK }; -PA_DECLARE_CLASS(file_stream); +PA_DEFINE_PRIVATE_CLASS(file_stream, pa_msgobject); #define FILE_STREAM(o) (file_stream_cast(o)) -static PA_DEFINE_CHECK_TYPE(file_stream, pa_msgobject); /* Called from main context */ static void file_stream_unlink(file_stream *u) { @@ -133,7 +132,7 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s * we are heard right-away. */ if (PA_SINK_INPUT_IS_LINKED(state) && i->thread_info.state == PA_SINK_INPUT_INIT) - pa_sink_input_request_rewind(i, 0, FALSE, TRUE, TRUE); + pa_sink_input_request_rewind(i, 0, false, true, true); } /* Called from IO thread context */ @@ -200,7 +199,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk } return -1; - } +} static void sink_input_process_rewind_cb(pa_sink_input *i, size_t nbytes) { file_stream *u; @@ -234,10 +233,12 @@ int pa_play_file( const pa_cvolume *volume) { file_stream *u = NULL; - SF_INFO sfinfo; pa_sample_spec ss; + pa_channel_map cm; pa_sink_input_new_data data; int fd; + SF_INFO sfi; + pa_memchunk silence; pa_assert(sink); pa_assert(fname); @@ -251,13 +252,7 @@ int pa_play_file( u->readf_function = NULL; u->memblockq = NULL; - memset(&sfinfo, 0, sizeof(sfinfo)); - - if ((fd = open(fname, O_RDONLY -#ifdef O_NOCTTY - |O_NOCTTY -#endif - )) < 0) { + if ((fd = pa_open_cloexec(fname, O_RDONLY, 0)) < 0) { pa_log("Failed to open file %s: %s", fname, pa_cstrerror(errno)); goto fail; } @@ -281,52 +276,38 @@ int pa_play_file( pa_log_debug("POSIX_FADV_WILLNEED succeeded."); #endif - if (!(u->sndfile = sf_open_fd(fd, SFM_READ, &sfinfo, 1))) { + pa_zero(sfi); + if (!(u->sndfile = sf_open_fd(fd, SFM_READ, &sfi, 1))) { pa_log("Failed to open file %s", fname); - pa_close(fd); goto fail; } - switch (sfinfo.format & 0xFF) { - case SF_FORMAT_PCM_16: - case SF_FORMAT_PCM_U8: - case SF_FORMAT_PCM_S8: - ss.format = PA_SAMPLE_S16NE; - u->readf_function = (sf_count_t (*)(SNDFILE *sndfile, void *ptr, sf_count_t frames)) sf_readf_short; - break; - - case SF_FORMAT_ULAW: - ss.format = PA_SAMPLE_ULAW; - break; - - case SF_FORMAT_ALAW: - ss.format = PA_SAMPLE_ALAW; - break; + fd = -1; - case SF_FORMAT_FLOAT: - default: - ss.format = PA_SAMPLE_FLOAT32NE; - u->readf_function = (sf_count_t (*)(SNDFILE *sndfile, void *ptr, sf_count_t frames)) sf_readf_float; - break; + if (pa_sndfile_read_sample_spec(u->sndfile, &ss) < 0) { + pa_log("Failed to determine file sample format."); + goto fail; } - ss.rate = (uint32_t) sfinfo.samplerate; - ss.channels = (uint8_t) sfinfo.channels; - - if (!pa_sample_spec_valid(&ss)) { - pa_log("Unsupported sample format in file %s", fname); - goto fail; + if (pa_sndfile_read_channel_map(u->sndfile, &cm) < 0) { + if (ss.channels > 2) + pa_log_info("Failed to determine file channel map, synthesizing one."); + pa_channel_map_init_extend(&cm, ss.channels, PA_CHANNEL_MAP_DEFAULT); } + u->readf_function = pa_sndfile_readf_function(&ss); + pa_sink_input_new_data_init(&data); - data.sink = sink; + pa_sink_input_new_data_set_sink(&data, sink, false); data.driver = __FILE__; pa_sink_input_new_data_set_sample_spec(&data, &ss); + pa_sink_input_new_data_set_channel_map(&data, &cm); pa_sink_input_new_data_set_volume(&data, volume); pa_proplist_sets(data.proplist, PA_PROP_MEDIA_NAME, pa_path_get_filename(fname)); pa_proplist_sets(data.proplist, PA_PROP_MEDIA_FILENAME, fname); + pa_sndfile_init_proplist(u->sndfile, data.proplist); - pa_sink_input_new(&u->sink_input, sink->core, &data, 0); + pa_sink_input_new(&u->sink_input, sink->core, &data); pa_sink_input_new_data_done(&data); if (!u->sink_input) @@ -339,7 +320,9 @@ int pa_play_file( u->sink_input->state_change = sink_input_state_change_cb; u->sink_input->userdata = u; - u->memblockq = pa_memblockq_new(0, MEMBLOCKQ_MAXLENGTH, 0, pa_frame_size(&ss), 1, 1, 0, NULL); + pa_sink_input_get_silence(u->sink_input, &silence); + u->memblockq = pa_memblockq_new("sound-file-stream memblockq", 0, MEMBLOCKQ_MAXLENGTH, 0, &ss, 1, 1, 0, &silence); + pa_memblock_unref(silence.memblock); pa_sink_input_put(u->sink_input); @@ -349,8 +332,10 @@ int pa_play_file( return 0; fail: - if (u) - file_stream_unref(u); + file_stream_unref(u); + + if (fd >= 0) + pa_close(fd); return -1; }