OSDN Git Service

[OSD][SOUND][Qt][WIP] Implementing sound driver skelton.This still be work-in-progress.
[csp-qt/common_source_project-fm7.git] / source / src / qt / osd_sound_mod_template.h
index fb31e06..b70e1f7 100644 (file)
 
 #include <QObject>
 #include <mutex>
+#include <memory>
 
 #include "../common.h"
-#include "../fifo_templates.h"
+#include "./sound_buffer_qt.h"
 
 QT_BEGIN_NAMESPACE
 
 class OSD_BASE;
 class USING_FLAGS;
 class CSP_Logger;
-class DLL_PREFIX SOUND_MODULE_BASE : public QObject
+
+class DLL_PREFIX SOUND_OUTPUT_MODULE_BASE : public QObject
 {
        Q_OBJECT
 protected:
-       OSD_BASE    *m_OSD;
-       USING_FLAGS *m_using_flags;
-       CSP_Logger  *m_logger;
-       void        *m_extconfig;
-       FIFO_BASE::LOCKED_RINGBUFFER<int16_t> *m_queue;
-       std::recursive_mutex m_locker;
-       std::recursive_mutex m_locker_outqueue;
-public:
-       SOUND_MODULE_BASE(OSD_BASE *parent, USING_FLAGS *pflags, CSP_Logger *logger, int buffer_size = 4096, void *configvalues = nullptr)
-               : m_OSD(parent), m_using_flags(pflags), m_logger(logger),
-               m_extconfig(configvalues), 
-               QObject(qobject_cast<QObject*>parent)
-       {
-               m_queue = new FIFO_BASE::LOCKED_RINGBUFFER<int16_t>(buffer_size);
-       }
-       ~SOUND_MODULE_BASE()
+       OSD*                                                            m_OSD;
+       std::shared_ptr<SOUND_BUFFER_QT>        m_fileio;
+       std::shared_ptr<USING_FLAGS>            m_using_flags;
+       
+       std::atomic<bool>                                       m_config_ok;
+
+       int64_t                                                         m_chunk_bytes;
+       int64_t                                                         m_buffer_bytes;
+       
+       int                                                                     m_rate;
+       int                                                                     m_latency_ms;
+       int                                                                     m_channels;
+       size_t                                                          m_wordsize;
+       std::atomic<void*>                                      m_extconfig_ptr;
+       std::atomic<int>                                        m_extconfig_bytes;
+       std::atomic<int>                                        m_loglevel;
+       std::atomic<int>                                        m_logdomain;
+
+       virtual void update_driver_fileio()
        {
-               std::lock_guard<std::recursive_mutex> locker(m_locker);
-               std::lock_guard<std::recursive_mutex> locker(m_locker_outqueue);
-               if(m_queue != nullptr) {
-                       delete m_queue;
-               }
+               release_driver_fileio();
+               // Update driver side of fileio by m_fileio;
+               //connect(m_fileio.get(), SIGNAL(bytesWritten(qint64)), real_driver, SLOT, QObject::DirectConnection);
+               //connect(m_fileio.get(), SIGNAL(aboutToClose()), real_driver, SLOT, QObject::DirectConnection);
+               // Optional:
+               // connect(m_fileio.get(), SIGNAL(readyRead()), real_driver, SLOT, QObject::DirectConnection);
        }
-       virtual int get_sound_rate(bool is_input = false, int dev_channel = 0)
+
+       virtual void release_driver_fileio()
        {
-               return 44100;
+               // Maybe disconnect some signals via m_fileio.
        }
        
-       virtual int64_t enqueueOutputSink(int16_t* p, int64_t size)
+       template <class... Args>
+               bool debug_log(Args... args)
        {
-               std::lock_guard<std::recursive_mutex> locker(m_locker_outqueue);
-               if(m_queue != nullptr) {
-                       bool flag;
-                       int64_t wsize = m_queue->write(p, size, flag);
-                       if((wsize > size) || (wsize <= 0) || !(flag)) {
-                               return 0;
-                       }
-                       return wsize;
-               }
-               return 0;
+               _TCHAR buf[1024];
+               memset(buf, 0x00, sizeof(buf));
+               my_sprintf_s(buf, sizeof(buf) - 1, args);
+
+               return do_send_log(m_loglevel.load(), m_logdomain.load(),
+                                                  QString::fromUtf8(buf, sizeof(buf)));
        }
        
-       virtual int64_t dequeueOutputSink(int16_t* p, int64_t size)
-       {
-               std::lock_guard<std::recursive_mutex> locker(m_locker_outqueue);
-               if(m_queue != nullptr) {
-                       bool flag;
-                       int64_t rsize = m_queue->read(p, size, flag);
-                       if((rsize > size) || (rsize <= 0) || !(flag)) {
-                               return 0;
-                       }
-                       return rsize;
-               }
-               return 0;
+public:
+       SOUND_OUTPUT_MODULE_BASE(OSD_BASE *parent,
+                                                        SOUND_BUFFER_QT* deviceIO = nullptr,
+                                                        int base_rate = 48000,
+                                                        int base_latency_ms = 100,
+                                                        int base_channels = 2,
+                                                        void *extra_config_values = nullptr);
+       ~SOUND_OUTPUT_MODULE_BASE();
+
+       std::recursive_timed_mutex                              m_locker;
+
+       virtual void initialize_driver()
+       {
+               // AT LEAST:
+               // connect(this, SIGNAL(sig_start_audio()), ..., QObject::QueuedConnection);
+               // connect(this, SIGNAL(sig_pause_audio()), ..., QObject::QueuedConnection);
+               // connect(this, SIGNAL(sig_resume_audio()), ..., QObject::QueuedConnection);
+               // connect(this, SIGNAL(sig_close_audio()), ..., QObject::QueuedConnection);
+               // connect(this, SIGNAL(sig_discard_audio()), ..., QObject::QueuedConnection);
+               // connect(this, SIGNAL(sig_released(bool)), ..., QObject::QueuedConnection);
+               // connect(this, SIGNAL(sig_req_open_sound(int, int, QString)), ..., QObject::QueuedConnection);
+
+               // For Logging
+               // connect(real_driver, SIGNAL(sig_log(QString)), this, SLOT(do_send_log(QString)), QObject::QueuedConnection);
+               // connect(real_driver, SIGNAL(sig_log(int, int, QString)), this, SLOT(do_send_log(int, int, QString)), QObject::QueuedConnection);
        }
-       virtual int64_t enqueueInputSource(int device_ch, int16_t* p, int64_t size)
+       virtual void release_driver()
        {
-               return 0;
        }
-       virtual int64_t dequeueInputSource(int device_ch, int16_t* p, int64_t size)
+       
+       int64_t update_sound(void* datasrc, int samples);
+       
+       std::shared_ptr<QIODevice> set_io_device(QIODevice *p);
+       std::shared_ptr<QIODevice> set_io_device(std::shared_ptr<QIODevice> ps);
+       std::shared_ptr<QIODevice> get_io_device()
        {
-               return 0;
+               return m_fileio;
        }
+       bool is_io_device_exists();
        
-       virtual int64_t outputSinkQueueSize()
+       virtual uint64_t wrote_data_to()
        {
-               std::lock_guard<std::recursive_mutex> locker(m_locker_outqueue);
-               if(m_queue != nullptr) {
-                       return m_queue->size();
-               }
                return 0;
        }
-       virtual int64_t outputSinkDataCount()
+       virtual int64_t driver_elapsed_usec()
        {
-               std::lock_guard<std::recursive_mutex> locker(m_locker_outqueue);
-               if(m_queue != nullptr) {
-                       return m_queue->count();
-               }
                return 0;
        }
-       virtual bool outputSinkQueueAvailable()
-       {
-               std::lock_guard<std::recursive_mutex> locker(m_locker_outqueue);
-               if(m_queue != nullptr) {
-                       return m_queue->available();
-               }
-               return false;
-       }
-       virtual bool outputSinkQueueReadReady()
-       {
-               std::lock_guard<std::recursive_mutex> locker(m_locker_outqueue);
-               if(m_queue != nullptr) {
-                       return m_queue->read_ready();
-               }
-               return false;
-       }
-       virtual bool outputSinkQueueWriteReady()
-       {
-               std::lock_guard<std::recursive_mutex> locker(m_locker_outqueue);
-               if(m_queue != nullptr) {
-                       return m_queue->write_ready();
-               }
-               return false;
-       }
-
-
-       virtual int64_t inputSourceQueueSize(int input_ch = 0)
+       virtual int64_t driver_processed_usec()
        {
                return 0;
        }
-       virtual int64_t inputSourceDataCount(int input_ch = 0)
+       bool config_ok()
        {
-               return 0;
+               return m_config_ok.load();
        }
-       virtual bool inputSourceQueueAvailable(int input_ch = 0)
-       {
-               return false;
-       }
-       virtual bool inputSourceQueueReadReady(int input_ch = 0)
+       
+       int64_t get_buffer_bytes();
+       int64_t get_chunk_bytes();
+       int get_latency_ms();
+       int get_channels();
+       int get_sample_rate();
+       size_t get_word_size();
+       void get_buffer_parameters(int& channels, int& rate, int& latency_ms,
+                                                          size_t& word_size, int& chunk_bytes, int& buffer_bytes);
+       virtual int64_t get_bytes_available();
+       virtual int64_t get_bytes_left();
+       
+       virtual SOUND_OUTPUT_MODULE_BASE* get_real_driver()
        {
-               return false;
+               return dynamic_cast<SOUND_OUTPUT_MODULE_BASE>this;
        }
-       virtual bool inputSourceQueueWriteReady(int input_ch = 0)
+
+       virtual std::list<std::string> get_sound_devices_list()
        {
-               return false;
+               static std::list<std::string> dummy_list;
+               return dummy_list;
        }
        
-       virtual bool initalizeSoundOutputDevice(int channels, int sample_rate, int& samples_per_chunk, int& chunks, std::string device_name)
+       virtual const _TCHAR* get_sound_device_name(int num)
        {
-               return true;
+               return (const _TCHAR*)nullptr;
        }
-
-       virtual bool initalizeSoundOutputDevice(int channels, int sample_rate, int& samples_per_chunk, int& chunks, int device_num)
+       virtual const _TCHAR* get_current_device_name()
        {
-               return true;
+               return (const _TCHAR*)(_T("Empty"));
        }
-       virtual bool detachSoundOutputDevice()
-       {
-               return true;
-       }
-       virtual bool isSoundOutputDeviceReady()
+       
+       virtual void set_logger(const std::shared_ptr<CSP_Logger> logger);
+       virtual void set_system_flags(const std::shared_ptr<USING_FLAGS> p);
+       void* get_extra_config_ptr()
        {
-               return false;
+               return m_extconfig_ptr.load();
        }
-
-       virtual bool initalizeSoundInputDevice(int channels, int sample_rate, int& samples_per_chunk, int& chunks, std::string device_name)
+       int get_extra_config_bytes()
        {
-               return true;
+               return m_extconfig_bytes.load();
        }
+       virtual bool set_extra_config(void* p, int bytes);
+       virtual bool modify_extra_config(void* p, int& bytes);
+public slot:
+       virtual void update_config() {}
+       virtual void update_extra_config() {}
+       
+       bool start();
+       bool pause();
+       bool resume();
+       bool stop();
+       bool discard();
 
-       virtual bool initalizeSoundInputDevice(int input_channel, int channels, int sample_rate, int& samples_per_chunk, int& chunks, int device_num)
+       virtual void reset_to_defalut() {} 
+       virtual void set_volume(double level) {}
+       virtual bool is_running_sound()
        {
                return true;
        }
-       virtual void detachSoundInputDevice(int input_channel = 0)
+       bool update_rate(int rate)
        {
-               return true;
+               return reconfig_sound(rate, m_channels);
        }
-       virtual bool isSoundInputDeviceReady(int input_channel = 0)
+       bool update_channels(int channels)
        {
-               return false;
+               return reconfig_sound(m_rate, channels);
        }
+       bool update_latency(int latency_ms, bool fortce = false);
+       bool reconfig_sound(int rate, int channels);
+       void request_to_release();
        
-       virtual void soundOutHandler(int64_t& req_size, void* userdata = nullptr)
+       virtual bool do_send_log(int level, int domain, QString _str);
+       virtual bool do_send_log(int level, int domain, const _TCHAR* _str, int maxlen);
+       virtual bool do_send_log(const _TCHAR* str, int maxlen)
        {
+               do_send_log(m_loglevel.load(), m_logdomain.load(), _str, maxlen);
        }
-       virtual void soundInHandler(int64_t &req_size, void* userdata = nullptr)
+       virtual bool do_send_log(const QString _str)
        {
+               do_send_log(m_loglevel.load(), m_logdomain.load(), _str);
        }
-       // Kick sound out handler
-       virtual bool soundOutReq()
-       {
-               return true;
-       }
-       // Kick sound in handler
-       virtual bool soundInReq(int input_ch)
-       {
-               return true;
-       }
-public slot:
-       virtual void initialize_sound(int rate, int samples, int* presented_rate, int* presented_samples)
+       
+       virtual void do_set_device_by_name(QString name) {};
+       virtual void do_set_device_by_name(const _TCHAR *name)
        {
-               std::lock_guard<std::recursive_mutex> locker(m_locker_outqueue);
-               // more lock via m_locker etc, if needs.
-               if(presented_rate != nullptr) {
-                       *presenyted_rate = rate;
-               }
-               if(presented_samples != nullptr) {
-                       *presenyted_samples = samples;
+               if(name != nullptr) {
+                       do_set_device_by_name(QString::fromUtf8(name));
                }
        }
-       virtual void update_sound(int* extra_frames) {}
-       virtual void mute_sound() {}
-       virtual void stop_sound() {}
-
-       // *PURE* SLOTS
-       virtual void do_start_recording_sound() {}
-       virtual void do_stop_recording_sound() {}
-       virtual void do_restart_recording_sound() {}
-       virtual void do_request_capture_sound(int ch) {}
-       virtual void do_resize_output_buffer(int count, int channels) {}
-       virtual void do_resize_capture_buffer(int ch, int count, int channels) {}
-       virtual void do_receive_external_sound(int count, int channels, int16_t* data) {}
-
-       virtual void set_logger(CSP_Logger* logger)
-       {
-               std::lock_guard<std::recursive_mutex> locker(m_locker);
-               m_logger = logger;
-       }
-       virtual void set_osd(OSD_BASE* p)
+       virtual void do_set_device_by_name(const _TCHAR *name, int maxlen)
        {
-               std::lock_guard<std::recursive_mutex> locker(m_locker);
-               m_OSD = p;
+               if((name != nullptr) && (maxlen > 0)) {
+                       do_set_device_by_name(QString::fromUtf8(name, maxlen));
+               }
        }
+       virtual void do_set_device_by_number(int) {};
+       
+       // This set device by device-name having QAction (as QObject).
+       virtual void do_set_device_by_name(void);
+       virtual void do_set_device_by_number(void);
 
-       virtual void set_system_flags(USING_FLAGS* p)
-       {
-               std::lock_guard<std::recursive_mutex> locker(m_locker);
-               m_using_flags = p;
-       }
-       virtual void update_extra_config(void* p)
-       {
-               std::lock_guard<std::recursive_mutex> locker(m_locker);
-               m_extconfig = p;
-               // more lock via m_locker_outqueue etc, if needs.
-       }
+       // From real driver: notify to update sound devices list.
+       virtual void do_update_device_list() {}
        
+       virtual void set_osd(OSD_BASE* p);
+
 signals:
-       void sig_send_log(QString);
-       void sig_send_log_with_class(int, int, QString);
-       void sig_req_input(int64_t);
-       void sig_complete_output(int64_t);
-       void sig_send_captured_sound_data(int, int64_t, int, int16_t[]);
-       void sig_send_output_sound_data(int64_t, int, int16_t[]);
+       // loglevel, logdomain, message
+       void sig_send_log(int, int, QString);
+       // rate, channels, path
+       void sig_req_open_sound(int, int, QString);
+       //
+       void sig_start_audio();
+       void sig_pause_audio();
+       void sig_resume_audio();
+       void sig_close_audio();
+       void sig_discard_audio();
+       // 
+       // notify completed to release sound driver.
+       void sig_released(bool);
+       // To UI: notify reset sound device list.
+       void sig_reset_sound_device_list();
+       // To UI: notify update sound device list #arg1 to #arg2.
+       void sig_set_sound_device(int, QString);
+       // To UI: notify adding sound device list #arg1.
+       void sig_add_sound_device(QString);
 };
 
 QT_END_NAMESPACE