diff options
Diffstat (limited to 'drumgizmo/output')
-rw-r--r-- | drumgizmo/output/oss.cc | 55 | ||||
-rw-r--r-- | drumgizmo/output/oss.h | 4 |
2 files changed, 57 insertions, 2 deletions
diff --git a/drumgizmo/output/oss.cc b/drumgizmo/output/oss.cc index 4e02e97..ee13a84 100644 --- a/drumgizmo/output/oss.cc +++ b/drumgizmo/output/oss.cc @@ -38,6 +38,8 @@ OSSOutputEngine::OSSOutputEngine() , srate{44100} , format{AFMT_S32_NE} , data{} + , max_fragments{4} + , fragment_size{8} { data.clear(); data.resize(1024 * num_channels); @@ -45,7 +47,7 @@ OSSOutputEngine::OSSOutputEngine() bool OSSOutputEngine::init(const Channels& channels) { - int tmp, mode = O_WRONLY; + int tmp, mode = O_WRONLY, fragments; num_channels = channels.size(); if((fd = open(dev.data(), mode, 0)) == -1) @@ -54,6 +56,14 @@ bool OSSOutputEngine::init(const Channels& channels) return false; } + fragments = max_fragments << 16 | fragment_size; + tmp = fragments; + if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1 || tmp != fragments) + { + perror("SNDCTL_DSP_SETFRAGMENT"); + exit(-1); + } + tmp = format; if(ioctl(fd, SNDCTL_DSP_SETFMT, &tmp) == -1 || tmp != format) { @@ -99,6 +109,44 @@ void OSSOutputEngine::setParm(const std::string& parm, const std::string& value) std::cerr << value << std::endl; } } + else if(parm == "max_fragments") + { + try + { + max_fragments = std::stoi(value); + } + catch(...) + { + std::cerr << "[OSSOutputEngine] Invalid max_fragments "; + std::cerr << value << std::endl; + } + if(max_fragments < 2) + { + std::cerr << "[OSSoutputEngine] max_fragments must be at least 2\n"; + std::cerr << "Setting max_fragments to 2" << std::endl; + max_fragments = 2; + } + } + else if(parm == "fragment_size") + { + try + { + fragment_size = std::stoi(value); + } + catch(...) + { + std::cerr << "[OSSOutputEngine] Invalid fragment_size "; + std::cerr << value << std::endl; + } + if(fragment_size < 4) + { + std::cerr << "[OSSoutputEngine] fragment_size must be at least 4\n"; + std::cerr << "Setting fragment_size to 4 ("; + fragment_size = 4; + auto fragment_byte_size = 1 << fragment_size; + std::cerr << fragment_byte_size << "Bytes)" << std::endl; + } + } else { std::cerr << "[OSSOutputEngine] Unsupported parameter '"; @@ -106,6 +154,11 @@ void OSSOutputEngine::setParm(const std::string& parm, const std::string& value) } } +void OSSOutputEngine::pre(size_t nsamples) +{ + data.resize(nsamples * num_channels); +} + void OSSOutputEngine::run(int ch, sample_t* samples, size_t nsamples) { // Convert to int format and diff --git a/drumgizmo/output/oss.h b/drumgizmo/output/oss.h index d44cd1c..889021f 100644 --- a/drumgizmo/output/oss.h +++ b/drumgizmo/output/oss.h @@ -39,7 +39,7 @@ public: void setParm(const std::string& parm, const std::string& value) override; bool start() override { return true; }; void stop() override {}; - void pre(size_t nsamples) override { data.resize(nsamples * num_channels); }; + void pre(size_t nsamples) override; void run(int ch, sample_t* samples, size_t nsamples) override; void post(size_t nsamples) override; bool isFreewheeling() const override { return false; }; @@ -52,5 +52,7 @@ private: std::size_t num_channels; unsigned int srate; unsigned int format; + unsigned int max_fragments; + unsigned int fragment_size; std::vector<std::int32_t> data; }; |