diff --git a/src/internal_modules/roc_audio/sample_spec.cpp b/src/internal_modules/roc_audio/sample_spec.cpp index fe9629092..357d644d0 100644 --- a/src/internal_modules/roc_audio/sample_spec.cpp +++ b/src/internal_modules/roc_audio/sample_spec.cpp @@ -13,6 +13,7 @@ #include "roc_core/macro_helpers.h" #include "roc_core/panic.h" #include "roc_packet/units.h" +#include "sample_spec.h" namespace roc { namespace audio { @@ -136,6 +137,12 @@ bool SampleSpec::is_valid() const { && sample_rate_ != 0 && channel_set_.is_valid(); } +bool SampleSpec::is_empty() const { + return sample_fmt_ == SampleFormat_Invalid + && pcm_fmt_ == PcmFormat_Invalid + && sample_rate_ == 0 && channel_set_.num_channels() == 0; +} + bool SampleSpec::is_raw() const { return sample_fmt_ == SampleFormat_Pcm && pcm_fmt_ == Sample_RawFormat; } diff --git a/src/internal_modules/roc_audio/sample_spec.h b/src/internal_modules/roc_audio/sample_spec.h index dc5f3cc9b..8ef737302 100644 --- a/src/internal_modules/roc_audio/sample_spec.h +++ b/src/internal_modules/roc_audio/sample_spec.h @@ -66,6 +66,8 @@ class SampleSpec { //! Check if sample spec has non-zero rate and valid channel set. bool is_valid() const; + bool is_empty() const; + //! Check if samples are in raw format. //! @returns //! true if sample_format() is SampleFormat_Pcm and pcm_format() diff --git a/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_source.cpp b/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_source.cpp index 941136110..c6bb06837 100644 --- a/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_source.cpp +++ b/src/internal_modules/roc_sndio/target_sndfile/roc_sndio/sndfile_source.cpp @@ -25,6 +25,11 @@ SndfileSource::SndfileSource(core::IArena& arena, const Config& config) return; } + if (!config.sample_spec.is_empty()) { + roc_log(LogError, "sndfile source: setting io encoding not supported"); + return; + } + frame_length_ = config.frame_length; sample_spec_ = config.sample_spec; @@ -231,13 +236,6 @@ bool SndfileSource::open_(const char* path) { return false; } - if (sample_rate_ != 0 && sample_rate_ != (size_t)file_info_.samplerate) { - roc_log(LogInfo, - "sndfile source: can't set rate: samplerate in argument is different " - "from file samplerate"); - return false; - } - sample_spec_.set_sample_rate((unsigned long)file_info_.samplerate); roc_log(LogInfo, diff --git a/src/internal_modules/roc_sndio/target_sox/roc_sndio/sox_source.cpp b/src/internal_modules/roc_sndio/target_sox/roc_sndio/sox_source.cpp index ef1c0e93e..9bb5f7711 100644 --- a/src/internal_modules/roc_sndio/target_sox/roc_sndio/sox_source.cpp +++ b/src/internal_modules/roc_sndio/target_sox/roc_sndio/sox_source.cpp @@ -32,14 +32,9 @@ SoxSource::SoxSource(core::IArena& arena, const Config& config) } frame_length_ = config.frame_length; + + sample_spec_ = config.sample_spec; - if (config.sample_spec.num_channels() == 0) { - sample_spec_ = - audio::SampleSpec(44100, audio::Sample_RawFormat, audio::ChanLayout_Surround, - audio::ChanOrder_Smpte, 0x3); - } else { - sample_spec_ = config.sample_spec; - } if (frame_length_ == 0) { roc_log(LogError, "sox source: frame length is zero"); @@ -115,13 +110,13 @@ void SoxSource::pause() { } if (!input_) { - roc_panic("sox source: pause: non-open input file or device"); + roc_panic("sox source: pause: non-open device"); } roc_log(LogDebug, "sox source: pausing: driver=%s input=%s", driver_name_.c_str(), input_name_.c_str()); - if (!is_file_) { + if(!is_file_){ close_(); } @@ -158,12 +153,17 @@ bool SoxSource::restart() { if (is_file_ && !eof_) { if (!seek_(0)) { + roc_panic("Reached"); roc_log(LogError, "sox source: seek failed when restarting: driver=%s input=%s", driver_name_.c_str(), input_name_.c_str()); return false; } } else { + if(is_file_){ + sample_spec_.clear(); + } + if (input_) { close_(); } @@ -360,23 +360,24 @@ bool SoxSource::open_() { return false; } - if (input_->signal.channels != sample_spec_.num_channels()) { - roc_log(LogError, - "sox source: can't open: unsupported # of channels: " - "expected=%lu actual=%lu", - (unsigned long)sample_spec_.num_channels(), - (unsigned long)input_->signal.channels); - return false; - } - is_file_ = !(input_->handler.flags & SOX_FILE_DEVICE); - if (is_file_ && sample_spec_.sample_rate() != input_->signal.rate - && sample_spec_.sample_rate() != 0) { - roc_log(LogInfo, - "sndfile source: can't set rate: samplerate in argument is different " - "from file samplerate"); - return false; + if (is_file_) { + if(!sample_spec_.is_empty()){ + roc_log(LogError, "sox source: setting io encoding for files not supported"); + return false; + } + sample_spec_ = sample_spec(); + } + else{ + if (input_->signal.channels != sample_spec_.num_channels()) { + roc_log(LogError, + "sox source: can't open: unsupported # of channels: " + "expected=%lu actual=%lu", + (unsigned long)sample_spec_.num_channels(), + (unsigned long)input_->signal.channels); + return false; + } } sample_spec_.set_sample_rate((unsigned long)input_->signal.rate); diff --git a/src/internal_modules/roc_sndio/wav_source.cpp b/src/internal_modules/roc_sndio/wav_source.cpp index 4dd260c61..458d3564a 100644 --- a/src/internal_modules/roc_sndio/wav_source.cpp +++ b/src/internal_modules/roc_sndio/wav_source.cpp @@ -14,14 +14,15 @@ namespace roc { namespace sndio { WavSource::WavSource(core::IArena& arena, const Config& config) - : eof_(false) + : file_opened_(false) + , eof_(false) , valid_(false) { if (config.latency != 0) { roc_log(LogError, "wav source: setting io latency not supported"); return; } - if (config.sample_spec.is_valid()) { + if (!config.sample_spec.is_empty()) { roc_log(LogError, "wav source: setting io encoding not supported"); return; } diff --git a/src/tests/roc_sndio/test_backend_sink.cpp b/src/tests/roc_sndio/test_backend_sink.cpp index eef878b20..a0bafc589 100644 --- a/src/tests/roc_sndio/test_backend_sink.cpp +++ b/src/tests/roc_sndio/test_backend_sink.cpp @@ -38,12 +38,12 @@ TEST_GROUP(backend_sink) { * sink_config.sample_spec.num_channels()); } - bool supports_aiff(IBackend & backend) { + bool supports_wav(IBackend & backend) { bool supports = false; core::Array driver_list(arena); backend.discover_drivers(driver_list); for (size_t n = 0; n < driver_list.size(); n++) { - if (strcmp(driver_list[n].name, "aiff") == 0) { + if (strcmp(driver_list[n].name, "wav") == 0) { supports = true; break; } @@ -57,10 +57,10 @@ TEST(backend_sink, noop) { for (size_t n_backend = 0; n_backend < BackendMap::instance().num_backends(); n_backend++) { IBackend& backend = BackendMap::instance().nth_backend(n_backend); - if (!supports_aiff(backend)) { + if (!supports_wav(backend)) { continue; } - core::TempFile file("test.aiff"); + core::TempFile file("test.wav"); IDevice* backend_device = backend.open_device( DeviceType_Sink, DriverType_File, NULL, file.path(), sink_config, arena); CHECK(backend_device != NULL); @@ -73,7 +73,7 @@ TEST(backend_sink, error) { for (size_t n_backend = 0; n_backend < BackendMap::instance().num_backends(); n_backend++) { IBackend& backend = BackendMap::instance().nth_backend(n_backend); - if (!supports_aiff(backend)) { + if (!supports_wav(backend)) { continue; } IDevice* backend_device = backend.open_device( @@ -85,9 +85,9 @@ TEST(backend_sink, error) { TEST(backend_sink, has_clock) { for (size_t n_backend = 0; n_backend < BackendMap::instance().num_backends(); n_backend++) { - core::TempFile file("test.aiff"); + core::TempFile file("test.wav"); IBackend& backend = BackendMap::instance().nth_backend(n_backend); - if (!supports_aiff(backend)) { + if (!supports_wav(backend)) { continue; } IDevice* backend_device = backend.open_device( @@ -103,9 +103,9 @@ TEST(backend_sink, sample_rate_auto) { sink_config.sample_spec.set_sample_rate(0); for (size_t n_backend = 0; n_backend < BackendMap::instance().num_backends(); n_backend++) { - core::TempFile file("test.aiff"); + core::TempFile file("test.wav"); IBackend& backend = BackendMap::instance().nth_backend(n_backend); - if (!supports_aiff(backend)) { + if (!supports_wav(backend)) { continue; } IDevice* backend_device = backend.open_device( @@ -122,9 +122,9 @@ TEST(backend_sink, sample_rate_force) { sink_config.sample_spec.set_sample_rate(SampleRate); for (size_t n_backend = 0; n_backend < BackendMap::instance().num_backends(); n_backend++) { - core::TempFile file("test.aiff"); + core::TempFile file("test.wav"); IBackend& backend = BackendMap::instance().nth_backend(n_backend); - if (!supports_aiff(backend)) { + if (!supports_wav(backend)) { continue; } IDevice* backend_device = backend.open_device( diff --git a/src/tests/roc_sndio/test_backend_source.cpp b/src/tests/roc_sndio/test_backend_source.cpp index 81b6f7da4..75e64f6c2 100644 --- a/src/tests/roc_sndio/test_backend_source.cpp +++ b/src/tests/roc_sndio/test_backend_source.cpp @@ -42,12 +42,12 @@ const core::nanoseconds_t FrameDuration = FrameSize * core::Second core::HeapArena arena; core::BufferFactory buffer_factory(arena, MaxBufSize); -bool supports_aiff(IBackend& backend) { +bool supports_wav(IBackend& backend) { bool supports = false; core::Array driver_list(arena); backend.discover_drivers(driver_list); for (size_t n = 0; n < driver_list.size(); n++) { - if (strcmp(driver_list[n].name, "aiff") == 0) { + if (strcmp(driver_list[n].name, "wav") == 0) { supports = true; break; } @@ -76,13 +76,12 @@ TEST_GROUP(backend_source) { TEST(backend_source, noop) { for (size_t n_backend = 0; n_backend < BackendMap::instance().num_backends(); n_backend++) { - core::TempFile file("test.aiff"); + core::TempFile file("test.wav"); IBackend& backend = BackendMap::instance().nth_backend(n_backend); - if (!supports_aiff(backend)) { + if (!supports_wav(backend)) { continue; } - { test::MockSource mock_source; IDevice* backend_device = backend.open_device( @@ -108,7 +107,7 @@ TEST(backend_source, error) { for (size_t n_backend = 0; n_backend < BackendMap::instance().num_backends(); n_backend++) { IBackend& backend = BackendMap::instance().nth_backend(n_backend); - if (!supports_aiff(backend)) { + if (!supports_wav(backend)) { continue; } IDevice* backend_device = backend.open_device( @@ -120,10 +119,10 @@ TEST(backend_source, error) { TEST(backend_source, has_clock) { for (size_t n_backend = 0; n_backend < BackendMap::instance().num_backends(); n_backend++) { - core::TempFile file("test.aiff"); + core::TempFile file("test.wav"); IBackend& backend = BackendMap::instance().nth_backend(n_backend); - if (!supports_aiff(backend)) { + if (!supports_wav(backend)) { continue; } @@ -155,10 +154,10 @@ TEST(backend_source, has_clock) { TEST(backend_source, sample_rate_auto) { for (size_t n_backend = 0; n_backend < BackendMap::instance().num_backends(); n_backend++) { - core::TempFile file("test.aiff"); + core::TempFile file("test.wav"); IBackend& backend = BackendMap::instance().nth_backend(n_backend); - if (!supports_aiff(backend)) { + if (!supports_wav(backend)) { continue; } @@ -193,10 +192,10 @@ TEST(backend_source, sample_rate_auto) { TEST(backend_source, sample_rate_mismatch) { for (size_t n_backend = 0; n_backend < BackendMap::instance().num_backends(); n_backend++) { - core::TempFile file("test.aiff"); + core::TempFile file("test.wav"); IBackend& backend = BackendMap::instance().nth_backend(n_backend); - if (!supports_aiff(backend)) { + if (!supports_wav(backend)) { continue; } @@ -220,24 +219,18 @@ TEST(backend_source, sample_rate_mismatch) { IDevice* backend_device = backend.open_device( DeviceType_Source, DriverType_File, "wav", file.path(), source_config, arena); - - if (strcmp(backend.name(), "wav") == 0) { - CHECK(backend_device != NULL); - core::ScopedPtr backend_source(backend_device->to_source(), arena); - CHECK(backend_source != NULL); - } else { - CHECK(backend_device == NULL); - } + + CHECK(backend_device == NULL); } } TEST(backend_source, pause_resume) { for (size_t n_backend = 0; n_backend < BackendMap::instance().num_backends(); n_backend++) { - core::TempFile file("test.aiff"); + core::TempFile file("test.wav"); IBackend& backend = BackendMap::instance().nth_backend(n_backend); - if (!supports_aiff(backend)) { + if (!supports_wav(backend)) { continue; } @@ -266,7 +259,8 @@ TEST(backend_source, pause_resume) { audio::sample_t frame_data1[FrameSize * NumChans] = {}; audio::Frame frame1(frame_data1, FrameSize * NumChans); - CHECK(backend_source->state() == DeviceState_Active); + // TODO(gh-706): check state + CHECK(backend_source->read(frame1)); audio::sample_t frame_data2[FrameSize * NumChans] = {}; @@ -274,21 +268,21 @@ TEST(backend_source, pause_resume) { backend_source->pause(); if (strcmp(backend.name(), "SoX") == 0) { - CHECK(backend_source->state() == DeviceState_Paused); + // TODO(gh-706): check state CHECK(!backend_source->read(frame2)); CHECK(backend_source->resume()); - CHECK(backend_source->state() == DeviceState_Active); + // TODO(gh-706): check state CHECK(backend_source->read(frame2)); } else { - CHECK(backend_source->state() == DeviceState_Active); + // TODO(gh-706): check state CHECK(backend_source->read(frame2)); CHECK(backend_source->resume()); - CHECK(backend_source->state() == DeviceState_Active); + // TODO(gh-706): check state CHECK(!backend_source->read(frame2)); } @@ -302,10 +296,10 @@ TEST(backend_source, pause_resume) { TEST(backend_source, pause_restart) { for (size_t n_backend = 0; n_backend < BackendMap::instance().num_backends(); n_backend++) { - core::TempFile file("test.aiff"); + core::TempFile file("test.wav"); IBackend& backend = BackendMap::instance().nth_backend(n_backend); - if (!supports_aiff(backend)) { + if (!supports_wav(backend)) { continue; } @@ -334,7 +328,8 @@ TEST(backend_source, pause_restart) { audio::sample_t frame_data1[FrameSize * NumChans] = {}; audio::Frame frame1(frame_data1, FrameSize * NumChans); - CHECK(backend_source->state() == DeviceState_Active); + // TODO(gh-706): check state + CHECK(backend_source->read(frame1)); backend_source->pause(); @@ -343,25 +338,27 @@ TEST(backend_source, pause_restart) { audio::Frame frame2(frame_data2, FrameSize * NumChans); if (strcmp(backend.name(), "SoX") == 0) { - CHECK(backend_source->state() == DeviceState_Paused); + // TODO(gh-706): check state CHECK(!backend_source->read(frame2)); CHECK(backend_source->restart()); - CHECK(backend_source->state() == DeviceState_Active); + // TODO(gh-706): check state CHECK(backend_source->read(frame2)); } else { - CHECK(backend_source->state() == DeviceState_Active); + // TODO(gh-706): check state CHECK(backend_source->read(frame2)); CHECK(backend_source->restart()); - CHECK(backend_source->state() == DeviceState_Active); + // TODO(gh-706): check state CHECK(backend_source->read(frame2)); } + + if (memcmp(frame_data1, frame_data2, sizeof(frame_data1)) != 0) { FAIL("frames should be equal"); } @@ -371,10 +368,10 @@ TEST(backend_source, pause_restart) { TEST(backend_source, eof_restart) { for (size_t n_backend = 0; n_backend < BackendMap::instance().num_backends(); n_backend++) { - core::TempFile file("test.aiff"); + core::TempFile file("test.wav"); IBackend& backend = BackendMap::instance().nth_backend(n_backend); - if (!supports_aiff(backend)) { + if (!supports_wav(backend)) { continue; } diff --git a/src/tests/roc_sndio/test_pump.cpp b/src/tests/roc_sndio/test_pump.cpp index 42230584e..47a44d3b2 100644 --- a/src/tests/roc_sndio/test_pump.cpp +++ b/src/tests/roc_sndio/test_pump.cpp @@ -47,12 +47,12 @@ const core::nanoseconds_t BufDuration = BufSize * core::Second core::HeapArena arena; core::BufferFactory buffer_factory(arena, BufSize); -bool supports_aiff(IBackend& backend) { +bool supports_wav(IBackend& backend) { bool supports = false; core::Array driver_list(arena); backend.discover_drivers(driver_list); for (size_t n = 0; n < driver_list.size(); n++) { - if (strcmp(driver_list[n].name, "aiff") == 0) { + if (strcmp(driver_list[n].name, "wav") == 0) { supports = true; break; } @@ -89,7 +89,7 @@ TEST(pump, write_read) { IBackend& backend = BackendMap::instance().nth_backend(n_backend); - if (!supports_aiff(backend)) { + if (!supports_wav(backend)) { continue; } @@ -135,7 +135,7 @@ TEST(pump, write_overwrite_read) { core::TempFile file("test.wav"); IBackend& backend = BackendMap::instance().nth_backend(n_backend); - if (!supports_aiff(backend)) { + if (!supports_wav(backend)) { continue; }