OSDN Git Service

[OSD][Qt][SOUND] Re-Available to build with QT_MULTIMEDIA, at least Qt6.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Sat, 1 Oct 2022 15:47:13 +0000 (00:47 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Sat, 1 Oct 2022 15:47:13 +0000 (00:47 +0900)
[OSD][Qt][SOUND] new driver/QT_MULTIMEDIA : Re-allocate namespace, add
some utilities.

source/src/qt/CMakeLists.txt
source/src/qt/osd_base.cpp
source/src/qt/osd_base.h
source/src/qt/osd_sound.cpp
source/src/qt/osd_sound_mod_consts.h [new file with mode: 0644]
source/src/qt/osd_sound_mod_qtmultimedia.cpp
source/src/qt/osd_sound_mod_qtmultimedia.h
source/src/qt/osd_sound_mod_template.cpp
source/src/qt/osd_sound_mod_template.h
source/src/qt/osd_sound_mod_utils.h [new file with mode: 0644]

index 2701839..fcc1269 100644 (file)
@@ -1,5 +1,5 @@
 message("* qt/osd")
-SET(THIS_LIB_VERSION 8.6.1)
+SET(THIS_LIB_VERSION 8.7.0)
 
 set(s_qt_osd_headers
        osd_base.h
index 77bf797..139a730 100644 (file)
@@ -92,7 +92,7 @@ OSD_BASE::OSD_BASE(std::shared_ptr<USING_FLAGS> p, std::shared_ptr<CSP_Logger> l
 
        #if 0  /* Note: Below are new sound driver. */
        m_sound_driver.reset(
-               new SOUND_OUTPUT_MODULE::M_QT_MULTIMEDIA(this,
+               new SOUND_MODULE::OUTPUT::M_QT_MULTIMEDIA(this,
                                                                                                 nullptr,
                                                                                                 48000,
                                                                                                 100,
index 7f568f7..bb700ff 100644 (file)
@@ -92,8 +92,10 @@ class CSP_logger;
 class QOpenGLContext;
 class MIDI_REDIRECTOR;
 class SIO_REDIRECTOR;
-namespace SOUND_OUTPUT_MODULE {
-       class M_BASE;
+namespace SOUND_MODULE {
+       namespace OUTPUT {
+               class M_BASE;
+       }
 }
 
 QT_BEGIN_NAMESPACE
@@ -179,7 +181,7 @@ class DLL_PREFIX OSD_BASE : public  QObject
        Q_OBJECT
 private:
        #if 1 /* Note: Below are new sound driver. */
-       std::shared_ptr<SOUND_OUTPUT_MODULE::M_BASE> m_sound_driver;
+       std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE> m_sound_driver;
        #else /* Note */
        qint64 sound_us_before_rendered;
        qint64 elapsed_us_before_rendered;
@@ -323,9 +325,11 @@ protected:
 #endif
        SDL_AudioSpec snd_spec_req, snd_spec_presented;
        void release_sound();
+#if 0  
        static void audio_capture_callback(void *udata, Uint8 *stream, int len);
        static void audio_callback(void *udata, Uint8 *stream, int len);
        void convert_sound_format(uint8_t* dst1, uint8_t* dst2, int16_t* src1, int16_t* src2, int samples1, int samples2);
+#endif
        virtual void init_sound_device_list();
 
        int sound_rate, sound_samples;
index 6a55f1a..1051484 100644 (file)
@@ -449,7 +449,7 @@ void OSD_BASE::update_sound(int* extra_frames)
        now_mute = false;
        if(sound_ok) {
                // Get sound driver 
-               std::shared_ptr<SOUND_OUTPUT_MODULE::M_BASE>sound_drv = m_sound_driver;
+               std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
                if(sound_drv.get() == nullptr) {
                        return;
                }
@@ -526,7 +526,7 @@ void OSD_BASE::initialize_sound(int rate, int samples, int* presented_rate, int*
        // If sound driver hasn't initialized, initialize.
        if(m_sound_driver.get() == nullptr) {
                m_sound_driver.reset(
-                       new SOUND_OUTPUT_MODULE::M_QT_MULTIMEDIA(this,
+                       new SOUND_MODULE::OUTPUT::M_QT_MULTIMEDIA(this,
                                                                                                         nullptr,
                                                                                                         rate,
                                                                                                         (samples * 1000) / rate,
@@ -536,7 +536,7 @@ void OSD_BASE::initialize_sound(int rate, int samples, int* presented_rate, int*
                init_sound_device_list();
                emit sig_update_sound_output_list();
        }
-       std::shared_ptr<SOUND_OUTPUT_MODULE::M_BASE>sound_drv = m_sound_driver;
+       std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
        
        debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_SOUND,
                          "OSD::%s rate=%d samples=%d m_sound_driver=%llx", __func__, rate, samples, (uintptr_t)(sound_drv.get()));
@@ -553,7 +553,7 @@ void OSD_BASE::release_sound()
        sound_initialized = false;
        sound_ok = false;
        
-       std::shared_ptr<SOUND_OUTPUT_MODULE::M_BASE>sound_drv = m_sound_driver;
+       std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
        if(sound_drv.get() != nullptr) {
                sound_drv->release_sound();
        }
@@ -572,7 +572,7 @@ void OSD_BASE::do_set_host_sound_output_device(QString device_name)
 
 const _TCHAR *OSD_BASE::get_sound_device_name(int num)
 {
-       std::shared_ptr<SOUND_OUTPUT_MODULE::M_BASE>sound_drv = m_sound_driver;
+       std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
        if(sound_drv.get() != nullptr) {
                return sound_drv->get_sound_device_name(num);
        }
@@ -581,7 +581,7 @@ const _TCHAR *OSD_BASE::get_sound_device_name(int num)
 
 void OSD_BASE::init_sound_device_list()
 {
-       std::shared_ptr<SOUND_OUTPUT_MODULE::M_BASE>sound_drv = m_sound_driver;
+       std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
        sound_device_list.clear();
        if(sound_drv.get() != nullptr) {
                std::list<std::string> _l = sound_drv->get_sound_devices_list();
@@ -597,7 +597,7 @@ void OSD_BASE::init_sound_device_list()
 void OSD_BASE::mute_sound()
 {
        if(!now_mute && sound_ok) {
-               std::shared_ptr<SOUND_OUTPUT_MODULE::M_BASE>sound_drv = m_sound_driver;
+               std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
                if(sound_drv.get() != nullptr) {
                        sound_drv->mute_sound();
                }
@@ -607,7 +607,7 @@ void OSD_BASE::mute_sound()
 void OSD_BASE::stop_sound()
 {
        if(sound_ok && sound_started) {
-               std::shared_ptr<SOUND_OUTPUT_MODULE::M_BASE>sound_drv = m_sound_driver;
+               std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
                if(sound_drv.get() != nullptr) {
                        sound_drv->stop_sound();
                }
@@ -617,7 +617,7 @@ void OSD_BASE::stop_sound()
 
 int OSD_BASE::get_sound_rate()
 {
-       std::shared_ptr<SOUND_OUTPUT_MODULE::M_BASE>sound_drv = m_sound_driver;
+       std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
        if(sound_drv.get() != nullptr) {
                return sound_drv->get_sample_rate();
        }
@@ -1223,7 +1223,7 @@ void OSD_BASE::restart_record_sound()
 #if 0 /* Temporally Disable  Caoptuing Sound 20220921 K.O */
 int OSD_BASE::get_sound_rate()
 {
-       std::shared_ptr<SOUND_OUTPUT_MODULE::M_BASE>out_driver = m_output_driver;
+       std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>out_driver = m_output_driver;
        if(out_driver.get() != nullptr) {
                return out_driver->get_sample_rate();
        }
@@ -1259,9 +1259,11 @@ bool OSD_BASE::is_capture_sound_buffer(int ch)
 }
 void *OSD_BASE::open_capture_sound_emu(int ch, int rate, int channels, int sample_type, int samples, int physical_device_num)
 {
-       if(ch < 0) return NULL;
-       if(ch >= MAX_CAPTURE_SOUNDS) return NULL;
+       if(ch < 0) return nullptr;
+       if(ch >= MAX_CAPTURE_SOUNDS) return nullptr;
        
+       void *p = nullptr;
+#if 0  
        close_capture_sound_emu(ch);
        sound_capture_desc[ch].rate = rate;
        sound_capture_desc[ch].channels = channels;
@@ -1275,7 +1277,7 @@ void *OSD_BASE::open_capture_sound_emu(int ch, int rate, int channels, int sampl
                }
        }
        
-       void *p = NULL;
+
        if(stat) {
                switch(sample_type) {
                case SAMPLE_TYPE_UINT8:
@@ -1302,6 +1304,7 @@ void *OSD_BASE::open_capture_sound_emu(int ch, int rate, int channels, int sampl
        }
        sound_capture_desc[ch].out_buffer = (uint8_t *)p;
        sound_capturing_emu[ch] = true;
+#endif
        return p;
 }
        
@@ -1310,6 +1313,7 @@ bool OSD_BASE::open_sound_capture_device(int num, int req_rate, int req_channels
        if(num < 0) return false;
        if(num >= MAX_SOUND_CAPTURE_DEVICES) return false;
        if(sound_capture_device_list.count() <= num) return false;
+#if 0  
        SDL_AudioSpec req;
        SDL_AudioSpec desired;
        req.freq = req_rate;
@@ -1389,14 +1393,17 @@ bool OSD_BASE::open_sound_capture_device(int num, int req_rate, int req_channels
                        }                               
                }
        }
+#endif
        return true;
 }
 
 bool OSD_BASE::close_sound_capture_device(int num, bool force)
 {
        // ToDo: Check capturing entries
+#if 0  
        if((capturing_sound[num]) && (sound_capture_desc[num].physical_dev > 0)) {
                SDL_CloseAudioDevice(sound_capture_desc[num].physical_dev);
        }
+#endif
        return true;
 }
diff --git a/source/src/qt/osd_sound_mod_consts.h b/source/src/qt/osd_sound_mod_consts.h
new file mode 100644 (file)
index 0000000..8bd1c74
--- /dev/null
@@ -0,0 +1,21 @@
+#pragma once
+namespace SOUND_MODULE {
+/* SOUND_MODULE */
+       enum  class __FORMAT {
+               Unsigned_Int,
+               Signed_Int,
+               Float,
+               Double,
+       };
+       enum  class __BYTEORDER {
+               Little,
+               Big,
+       };
+       typedef struct {
+               __FORMAT        format;
+               __BYTEORDER     endian;
+               size_t          word_size;
+               size_t          channels;
+       } sound_attribute;
+/* SOUND_MODULE */
+}
index 3b719aa..c525144 100644 (file)
@@ -6,9 +6,12 @@
 
 #include <QMediaDevices>
 
-namespace SOUND_OUTPUT_MODULE {
-
-M_QT_MULTIMEDIA::M_QT_MULTIMEDIA(
+namespace SOUND_MODULE {
+/* SOUND_MODULE */
+       
+       namespace OUTPUT {
+       /* SOUND_MODULE */
+       M_QT_MULTIMEDIA::M_QT_MULTIMEDIA(
                OSD_BASE *parent,
                SOUND_BUFFER_QT* deviceIO,
                int base_rate,
@@ -26,7 +29,7 @@ M_QT_MULTIMEDIA::M_QT_MULTIMEDIA(
                extra_config_values,
                extra_config_bytes )
 {
-       m_classname = "SOUND_OUTPUT_MODULE::M_QT_MULTIMEDIA";
+       m_classname = "SOUND_MODULE::OUTPUT::M_QT_MULTIMEDIA";
        
        connect(this, SIGNAL(sig_start_audio()),  this, SLOT(do_sound_start()), Qt::QueuedConnection);
        connect(this, SIGNAL(sig_stop_audio()),  this, SLOT(do_sound_stop()), Qt::QueuedConnection);
@@ -457,7 +460,6 @@ void M_QT_MULTIMEDIA::release_sound()
        m_audioOutputSink.reset();
 
        M_BASE::release_sound();
-
 }
 
 bool M_QT_MULTIMEDIA::release_driver()
@@ -623,6 +625,9 @@ void M_QT_MULTIMEDIA::stop_sound()
                }
        }
 }
+       /* SOUND_MODULE::OUTPUT */
+       }
+/* SOUND_MODULE */
 
 }
 
index 45a9b62..08cf8a5 100644 (file)
@@ -9,8 +9,6 @@
 
 #pragma once
 
-#include "./osd_sound_mod_template.h"
-
 #include <string>
 #include <list>
 #include <QAudioFormat>
 #include <QAudioDeviceInfo>
 #endif 
 
+#include "./osd_sound_mod_template.h"
+
 QT_BEGIN_NAMESPACE
 
-class SOUND_BUFFER_QT;
-namespace SOUND_OUTPUT_MODULE {
+
+namespace SOUND_MODULE {
+/* SOUND_MODULE */
+       namespace OUTPUT {
+       /* SOUND_MODULE::OUTPUT */
 class DLL_PREFIX M_QT_MULTIMEDIA
        : public M_BASE
 {
@@ -95,4 +98,9 @@ public slots:
        virtual void do_set_device_by_name(QString driver_name) override;
 
 };
+
+/* SOUND_MODULE::OUTPUT */
+       }
+/* SOUND_MODULE */
 }
+
index d643e63..460de44 100644 (file)
 #include "./osd_sound_mod_template.h"
 #include "./gui/menu_flags.h"
 
-namespace SOUND_MODULE {
-
-template <class T>     
-inline int64_t convert_from_float(T s)
-{
-       int64_t tmpval = std::llound(s * ((T)INT64_MAX));
-       return tmpval;
-}
-       
-template <class T>     
-inline int32_t convert_from_float(T s)
-{
-       int32_t tmpval = std::lound(s * ((T)INT32_MAX));
-       return tmpval;
-}
-
-template <class T>     
-inline int16_t convert_from_float(T s)
-{
-       int16_t tmpval = std::lound(s * ((T)INT16_MAX));
-       return tmpval;
-}
-template <class T>     
-inline int8_t convert_from_float(T s)
-{
-       int8_t tmpval = std::lound(s * ((T)INT8_MAX));
-       return tmpval;
-}
+#include "./osd_sound_mod_consts.h"
+#include "./osd_sound_mod_utils.h"
 
-template <class T>     
-inline uint64_t convert_from_float(T s)
-{
-       uint64_t tmpval = std::llound((s * ((T)INT64_MAX)) + ((T)INT64_MAX));
-       return tmpval;
-}
-template <class T>     
-inline uint32_t convert_from_float(T s)
-{
-       uint32_t tmpval = std::lound((s * ((T)INT32_MAX)) + ((T)INT32_MAX));
-       return tmpval;
-}
-
-template <class T>     
-inline uint16_t convert_from_float(T s)
-{
-       uint16_t tmpval = std::lound((s * ((T)INT16_MAX)) + ((T)INT16_MAX));
-       return tmpval;
-}
-       
-template <class T>     
-inline uint8_t convert_from_float(T s)
-{
-       uint8_t tmpval = std::lound((s * ((T)INT8_MAX)) + ((T)INT8_MAX));
-       return tmpval;
-}
-
-template <class T>     
-inline T convert_to_float(int64_t s)
-{
-       T tmpval = ((T)s) / ((T)INT64_MAX);
-       return tmpval;
-}
-template <class T>     
-inline T convert_to_float(int32_t s)
-{
-       T tmpval = ((T)s) / ((T)INT32_MAX);
-       return tmpval;
-}
-template <class T>     
-inline T convert_to_float(int16_t s)
-{
-       T tmpval = ((T)s) / ((T)INT16_MAX);
-       return tmpval;
-}
-template <class T>     
-inline T convert_to_float(int8_t s)
-{
-       T tmpval = ((T)s) / ((T)INT8_MAX);
-       return tmpval;
-}
-template <class T>     
-inline T convert_to_float(uint64_t s)
-{
-       T tmpval = ((T)((int64_t)(s - INT64_MAX)))  / ((T)INT64_MAX);
-       return tmpval;
-}
-template <class T>     
-inline T convert_to_float(uint32_t s)
-{
-       T tmpval = ((T)((int32_t)(s - INT32_MAX)))  / ((T)INT32_MAX);
-       return tmpval;
-}
-template <class T>     
-inline T convert_to_float(uint16_t s)
-{
-       T tmpval = ((T)((int16_t)(s - INT16_MAX)))  / ((T)INT16_MAX);
-       return tmpval;
-}
-template <class T>     
-inline T convert_to_float(uint8_t s)
-{
-       T tmpval = ((T)((int8_t)(s - INT8_MAX)))  / ((T)INT8_MAX);
-       return tmpval;
-}
-       
-}
-namespace SOUND_OUTPUT_MODULE {
-
-M_BASE::M_BASE(OSD_BASE *parent,
-                                                                                                  SOUND_BUFFER_QT* deviceIO,
-                                                                                                  int base_rate,
-                                                                                                  int base_latency_ms,
-                                                                                                  int base_channels,
-                                                                                                  void *extra_config_values,
-                                                                                                  int extra_config_bytes)
+namespace SOUND_MODULE {
+/* SOUND_MODULE */
+
+       namespace OUTPUT {
+       /* SOUND_MODULE::OUTPUT */
+
+       M_BASE::M_BASE(OSD_BASE *parent,
+                                  SOUND_BUFFER_QT* deviceIO,
+                                  int base_rate,
+                                  int base_latency_ms,
+                                  int base_channels,
+                                  void *extra_config_values,
+                                  int extra_config_bytes)
        : 
          m_config_ok(false),
          m_rate(base_rate),
@@ -134,7 +35,7 @@ M_BASE::M_BASE(OSD_BASE *parent,
          m_before_rendered(0),
          m_samples(0),
          m_mute(false),
-         m_classname("SOUND_OUTPUT_MODULE::M_BASE"),
+         m_classname("SOUND_MODULE::OUTPUT::M_BASE"),
          QObject(qobject_cast<QObject*>(parent))
 {
 
@@ -214,6 +115,12 @@ void M_BASE::request_to_release()
        emit sig_released(!(m_config_ok.load()));
 }
 
+__FORMAT M_BASE::get_sound_format()
+{
+       return __FORMAT::Signed_Int;
+}
+               
+               
 bool M_BASE::wait_driver_started(int64_t timeout_msec)
 {
        bool _r = m_prev_started.load();
@@ -722,4 +629,8 @@ int64_t M_BASE::get_bytes_left()
        }
        return 0;
 }
+
+       /* SOUND_MODULE::OUTPUT */
+       }
+       /* SOUND_MODULE */
 }
index 80d51aa..0aa4620 100644 (file)
 #include "./config.h"
 #include "./osd_types.h"
 
+
+#if !defined(__debug_log_func)
+#define __debug_log_func(...) debug_log_func(__func__, __VA_ARGS__)
+#endif
+
+
+
 QT_BEGIN_NAMESPACE
 
+
 class SOUND_BUFFER_QT;
 class OSD_BASE;
 class USING_FLAGS;
 class CSP_Logger;
 
-#define __debug_log_func(...) debug_log_func(__func__, __VA_ARGS__)
-
 namespace SOUND_MODULE {
-       enum class FORMAT {
-               Unsigned_Int,
-               Signed_Int,
-               Float,
-               Double
-       };
-       enum class BYTEORDER {
-               LITTLE_ENDIAN,
-               BIG_ENDIAN
-       };
-       inline const BYTEORDER get_system_byteorder()
-       {
-               #if __LITTLE_ENDIAN__
-               return BYTEORDER::LITTLE_ENDIAN;
-               #else
-               return BYTEORDER::BIG_ENDIAN;
-               #endif
-       }
-       typedef struct {
-               FORMAT  format;
-               ENDIAN  endian;
-               size_t  word_size;
-               size_t  channels;
-       } sound_attribute;
-       inline bool check_attribute(sound_attribute a)
-       {
-               if((a.word_size == 0) || (a.word_size > 16)) return false;
-               if((a.channels == 0) || (a.channels > 8)) return false;
-               return true;
-       }
-       inline bool compare_attribute(struct sound_attribute src, struct sound_attribute dst)
-       {
-               bool _b = true;
-               _b &= (src.format == dst.format);
-               _b &= (src.endian == dst.endian);
-               _b &= (src.word_size == dst.word_size);
-               _b &= (src.channels == dst.channels);
-               return _b;
-       }
-       template <class T>
-       inline size_t swap_endian(T *src, T* dst, size_t words)
-       {
-               if(words == 0) return 0;
-               const size_t wordsize = sizeof(T);
-               T* p = src;
-               T* q = dst;
-                       
-               __DECL_ALIGNED(16) T tmpbuf[8];
-               __DECL_ALIGNED(16) T dstbuf[8];
-               const size_t major_words = words / 8;
-               const size_t minor_words = words % 8;
-               
-               for(size_t i = 0; i < major_words; i++) {
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               tmpbuf[j] = p[j];
-                       }
-
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               uint8_t* pp = (uint8_t*)(&(tmpbuf[j]));
-                               uint8_t* qq = (uint8_t*)(&(dstbuf[j]));
-                       __DECL_VECTORIZED_LOOP
-                               for(size_t k = 0; k < sizeof(T); k++) {
-                                       qq[k] = pp[sizeof(T) - k - 1];
-                               }
-                       }
-                       
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               q[j] = dstbuf[j];
-                       }
-                       q += 8;
-                       p += 8;
-               }
-               for(size_t i = 0; i < minor_words; i++) {
-                       uint8_t* pp = (uint8_t*)(&(p[i]));
-                       uint8_t* qq = (uint8_t*)(&(q[i]));
-                       for(size_t k = 0; k < sizeof(T); k++) {
-                               qq[k] = pp[sizeof(T) - k - 1];
-                       }
-               }
-               return words;
-       }
-       template <class S, class D>
-       size_t inline convert_float_to_int(D* dst, S* src, size_t words)
-       {
-               if(dst == nullptr) return 0;
-               if(src == nullptr) return 0;
-               if(words == 0) return 0;
-               if((sizeof(D) < 1) || (sizeof(D) > 8)) return 0;
-               
-               __DECL_ALIGNED(16) S tmpsrc[8];
-               __DECL_ALIGNED(16) D tmpdst[8];
-               const size_t major_words = words / 8;
-               const size_t minor_words = words % 8;
-               
-               const int64_t max_tbl[8] = {INT8_MAX, INT16_MAX, INT16_MAX, INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX, INT64_MAX};
-               const S max_val = (S)(max_tbl[sizeof(D) - 1]);
-               __DECL_ALIGNED(16) S max_vals[8];
-               
-               __DECL_VECTORIZED_LOOP
-               for(int j = 0; j < 8; j++) {
-                       max_vals[j] = max_val;
-               }
-               
-               S* p = src;
-               D* q = dst;
-
-               for(size_t i = 0; i < major_words; i++) {
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               tmpsrc[j] = p[j];
-                       }
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               tmpdst[j] = (D)(tmpsrc[j] * max_vals[j]);
-                       }
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               q[j] = tmpdst[j];
-                       }
-                       p += 8;
-                       q += 8;
-               }
-               for(size_t j = 0; j < minor_words; j++) {
-                       q[j] = (D)(p[j] * max_val);
-               }
-               return words;
-       }
+/* SOUND_MODULE */
+       enum class __FORMAT;
+       enum class __BYTEORDER;
        
-       template <class S, class D>
-       size_t inline convert_float_to_unsigned_int(D* dst, S* src, size_t words)
-       {
-               if(dst == nullptr) return 0;
-               if(src == nullptr) return 0;
-               if(words == 0) return 0;
-               if((sizeof(D) < 1) || (sizeof(D) > 8)) return 0;
-               
-               __DECL_ALIGNED(16) S tmpsrc[8];
-               __DECL_ALIGNED(16) D tmpdst[8];
-               const size_t major_words = words / 8;
-               const size_t minor_words = words % 8;
-               
-               const int64_t max_tbl[8] = {INT8_MAX, INT16_MAX, INT16_MAX, INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX, INT64_MAX};
-               const S max_val = (S)(max_tbl[sizeof(D) - 1]);
-               __DECL_ALIGNED(16) S max_vals[8];
-               __DECL_ALIGNED(16) S diff_vals[8] = {1.0};
-               
-       __DECL_VECTORIZED_LOOP
-               for(int j = 0; j < 8; j++) {
-                       max_vals[j] = max_val;
-               }
-               
-               S* p = src;
-               D* q = dst;
-
-               for(size_t i = 0; i < major_words; i++) {
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               tmpsrc[j] = p[j];
-                       }
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               tmpsrc[j] = tmpsrc[j] + diff_vals[j];
-                       }
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               tmpdst[j] = (D)(tmpsrc[j] * max_vals[j]);
-                       }
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               q[j] = tmpdst[j];
-                       }
-                       p += 8;
-                       q += 8;
-               }
-               for(size_t j = 0; j < minor_words; j++) {
-                       q[j] = (D)((p[j] + ((S)(1.0))) * max_val);
-               }
-               return words;
-       }
-       template <class D, class S>
-       size_t inline convert_int_to_float(D* dst, S* src, size_t words)
-       {
-               if(dst == nullptr) return 0;
-               if(src == nullptr) return ;
-               if(words == 0) return 0;
-               __DECL_ALIGNED(16) S tmpsrc[8];
-               __DECL_ALIGNED(16) D tmpdst[8];
-               const size_t major_words = words / 8;
-               const size_t minor_words = words % 8;
-               const int64_t max_tbl[8] = {INT8_MAX, INT16_MAX, INT16_MAX, INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX, INT64_MAX};
-               const D max_val = (D)(max_tbl[sizeof(S) - 1]);
-               __DECL_ALIGNED(16) D max_vals[8];
-               
-       __DECL_VECTORIZED_LOOP
-               for(int j = 0; j < 8; j++) {
-                       max_vals[j] = max_val;
-               }
-               
-               S* p = src;
-               D *q = dst;
-               
-               for(size_t i = 0; i < major_words; i++) {
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               tmpsrc[j] = p[j];
-                       }
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               tmpdst[j] = ((D)tmpsrc[j]) / max_vals[j];
-                       }
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               q[j] = tmpdst[j];
-                       }
-                       p += 8;
-                       q += 8;
-               }
-               for(size_t i = 0; i < minor_words; i++) {
-                       q[j] = (D)(p[j]) / max_val;
-               }
-               return words;
-       }
-
-       template <class D, class S>
-       size_t inline convert_unsigned_int_to_float(D* dst, S* src, size_t words)
-       {
-               if(dst == nullptr) return 0;
-               if(src == nullptr) return ;
-               if(words == 0) return 0;
-               __DECL_ALIGNED(16) S tmpsrc[8];
-               __DECL_ALIGNED(16) D tmpdst[8];
-               const size_t major_words = words / 8;
-               const size_t minor_words = words % 8;
-               const int64_t max_tbl[8] = {INT8_MAX, INT16_MAX, INT16_MAX, INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX, INT64_MAX};
-               const D max_val = (D)(max_tbl[sizeof(S) - 1]);
-               __DECL_ALIGNED(16) D max_vals[8];
-               __DECL_ALIGNED(16) D diff_vals[8] = {1.0};
-               
-       __DECL_VECTORIZED_LOOP
-               for(int j = 0; j < 8; j++) {
-                       max_vals[j] = max_val;
-               }
+       namespace OUTPUT {
+       /* SOUND_MODULE::OUTPUT */
                
-               S* p = src;
-               D *q = dst;
-               
-               for(size_t i = 0; i < major_words; i++) {
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               tmpsrc[j] = p[j];
-                       }
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               tmpdst[j] = ((D)tmpsrc[j]) / max_vals[j];
-                       }
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               tmpdst[j] = tmpdst[j] - diff_vals[j];
-                       }
-               __DECL_VECTORIZED_LOOP
-                       for(size_t j = 0; j < 8; j++) {
-                               q[j] = tmpdst[j];
-                       }
-                       p += 8;
-                       q += 8;
-               }
-               for(size_t i = 0; i < minor_words; i++) {
-                       q[j] = ((D)(p[j]) / max_val) - ((D)(1.0));
-               }
-               return words;
-       }
-       
-       template <class D, class S>     
-       size_t  DLL_PREFIX convert_sound_format_int(
-               D *dst, BYTEORDER dst_endian, size_t dst_words,
-               S *src, BYTEORDER src_endian, size_t src_words
-               )
-       {
-               if(dst == nullptr) return 0;
-               if(src == nullptr) return 0;
-               if(dst_words == 0) return 0;
-               if(src_words == 0) return 0;
-               __DECL_ALIGNED(16) S tmpsrc[8];
-               __DECL_ALIGNED(16) D tmpdst[8];
-               const size_t words = std::min(src_words, dst_words);
-               const size_t major_words = words / 8;
-               const size_t minor_words = words % 8;
-               S* p = src;
-               D* q = dst;
-               if(dst_endian == src_endian) {
-                       for(size_t i = 0; i < major_words; i++) {
-                       __DECL_VECTORIZED_LOOP
-                               for(size_t j = 0; j < 8; j++) {
-                                       tmpsrc[j] = p[j];
-                               }
-                       __DECL_VECTORIZED_LOOP
-                               for(size_t j = 0; j < 8; j++) {
-                                       tmpdst[j] = (D)(tmpsrc[j]);
-                               }
-                       __DECL_VECTORIZED_LOOP
-                               for(size_t j = 0; j < 8; j++) {
-                                       q[j] = tmpdst[j];
-                               }
-                               p += 8;
-                               q += 8;
-                       }
-                       for(size_t i = 0; i < minor_words; i++) {
-                               q[i] = ((D)(p[i]));
-                       }
-               } else {
-                       for(size_t i = 0; i < major_words; i++) {
-                       __DECL_VECTORIZED_LOOP
-                               for(size_t j = 0; j < 8; j++) {
-                                       tmpsrc[j] = p[j];
-                               }
-                       __DECL_VECTORIZED_LOOP
-                               for(size_t j = 0; j < 8; j++) {
-                                       tmpdst[j] = (D)(tmpsrc[j]);
-                               }
-                               if(sizeof(D) > 1) {
-                                       swap_endian(tmpdst, q, 8);
-                               }
-                               p += 8;
-                               q += 8;
-                       }
-                       if(minor_words > 0) {
-                       __DECL_VECTORIZED_LOOP
-                               for(size_t i = 0; i < minor_words; i++) {
-                                       tmpdst[i] = ((D)(p[i]));
-                               }
-                               if(sizeof(D) > 1) {
-                                       swap_endian(tmpdst, q, minor_words);
-                               }
-                       }
-               }
-               return words;
-       }
-       
-}
-
-namespace SOUND_OUTPUT_MODULE {
-
 class DLL_PREFIX M_BASE : public QObject
 {
        Q_OBJECT
@@ -497,14 +165,7 @@ public:
        int get_latency_ms();
        int get_channels();
        int get_sample_rate();
-       virtual SOUND_MODULE::FORMAT get_sound_format()
-       {
-               return SOUND_MODULE::FORMAT::Signed_Int;
-       }
-       virtual SOUND_MODULE::FORMAT get_sound_format()
-       {
-               return SOUND_MODULE::FORMAT::Signed_Int;
-       }
+       virtual __FORMAT get_sound_format();
        
        size_t get_word_size();
        void get_buffer_parameters(int& channels, int& rate, int& latency_ms,
@@ -514,7 +175,7 @@ public:
        
        virtual M_BASE* get_real_driver()
        {
-               return dynamic_cast<SOUND_OUTPUT_MODULE::M_BASE*>(this);
+               return dynamic_cast<SOUND_MODULE::OUTPUT::M_BASE*>(this);
        }
 
        virtual std::list<std::string> get_sound_devices_list()
@@ -639,6 +300,9 @@ signals:
        // To UI: notify adding sound device list #arg1.
        void sig_add_sound_device(QString);
 };
+/* SOUND_MODULE::OUTPUT */
+}
+/* SOUND_MODULE */
 }
 QT_END_NAMESPACE
        
diff --git a/source/src/qt/osd_sound_mod_utils.h b/source/src/qt/osd_sound_mod_utils.h
new file mode 100644 (file)
index 0000000..f21acae
--- /dev/null
@@ -0,0 +1,364 @@
+#pragma once
+#include "./osd_sound_mod_consts.h"
+
+#include <limits>
+namespace SOUND_MODULE {
+/* SOUND_MODULE */
+       
+       static inline const __BYTEORDER get_system_byteorder()
+       {
+               #if __LITTLE_ENDIAN__
+               return __BYTEORDER::Little;
+               #else
+               return __BYTEORDER::Big;
+               #endif
+       }
+       inline bool check_attribute(sound_attribute a)
+       {
+               if((a.word_size == 0) || (a.word_size > 16)) return false;
+               if((a.channels == 0) || (a.channels > 8)) return false;
+               return true;
+       }
+       
+       inline bool compare_attribute(sound_attribute src, sound_attribute dst)
+       {
+               bool _b = true;
+               _b &= (src.format == dst.format);
+               _b &= (src.endian == dst.endian);
+               _b &= (src.word_size == dst.word_size);
+               _b &= (src.channels == dst.channels);
+               return _b;
+       }
+
+       
+       template <typename T>
+       size_t swap_endian(T* src, T* dst, size_t words)
+       {
+               if(words == 0) return 0;
+               const size_t wordsize = sizeof(T);
+               
+               typedef union _t_pair_t {
+                       T               data;
+                       uint8_t u8[sizeof(T)];
+               };
+               T* p = src;
+               T* q = dst;
+               
+               __DECL_ALIGNED(16) _t_pair_t tmpbuf[8];
+               __DECL_ALIGNED(16) _t_pair_t dstbuf[8];
+               const size_t major_words = words / 8;
+               const size_t minor_words = words % 8;
+               
+               for(size_t i = 0; i < major_words; i++) {
+               __DECL_VECTORIZED_LOOP
+                       for(size_t j = 0; j < 8; j++) {
+                               tmpbuf[j].data = p[j];
+                       }
+
+               __DECL_VECTORIZED_LOOP
+                       for(size_t j = 0; j < 8; j++) {
+                       __DECL_VECTORIZED_LOOP
+                               for(size_t k = 0; k < sizeof(T); k++) {
+                                       dstbuf[j].u8[k] = tmpbuf[j].u8[sizeof(T) - k - 1];
+                               }
+                       }
+                       
+               __DECL_VECTORIZED_LOOP
+                       for(size_t j = 0; j < 8; j++) {
+                               q[j] = dstbuf[j].data;
+                       }
+                       q += 8;
+                       p += 8;
+               }
+               _t_pair_t __tmp;
+               _t_pair_t __dst;
+               for(size_t i = 0; i < minor_words; i++) {
+                       __tmp.data = p[i];
+                       for(size_t k = 0; k < sizeof(T); k++) {
+                               __dst.u8[k] = __tmp.u8[sizeof(T) - k - 1]; 
+                       }
+                       q[i] = __dst.data;
+               }
+               return words;
+       }
+       template <>
+       size_t swap_endian(uint8_t* src, uint8_t* dst, size_t words)
+       {
+               if(words == 0) return 0;
+               if((uintptr_t)src == (uintptr_t)dst) return words;
+               memcpy(dst, src, words);
+               return words;
+       }       
+       template <>
+       size_t swap_endian(int8_t* src, int8_t* dst, size_t words)
+       {
+               if(words == 0) return 0;
+               if((uintptr_t)src == (uintptr_t)dst) return words;
+               memcpy(dst, src, words);
+               return words;
+       }
+       
+       /* convert format for both of integer variants */
+       template <typename S, typename D>
+       size_t convert_format(D* dst, S* src, size_t words)
+       {
+               if(dst == nullptr) return 0;
+               if(src == nullptr) return 0;
+               if(words == 0) return 0;
+
+               std::numeric_limits<S> src_limit;
+               std::numeric_limits<D> dst_limit;
+               size_t major_nwords = words / 8;
+               size_t minor_words  = words % 8;
+               
+               enum {
+                       src_false = 0,
+                       src_true  = 1,
+                       dst_false = 0,
+                       dst_true  = 2
+               };
+
+               uint8_t type_is_int =
+                       (std::numeric_limits<S>::is_exact() ? src_true : src_false) |
+                       (std::numeric_limits<D>::is_exact() ? dst_true : dst_false);
+               
+               S* p = src;
+               D* q = dst;
+               __DECL_ALIGNED(16) S srcbuf[8];
+               __DECL_ALIGNED(16) D dstbuf[8];
+               
+               switch(type_is_int) {
+               case (src_false | dst_false):
+                       // Both float or double
+                       {
+                               for(size_t i = 0; i < major_nwords; i++) {
+                               __DECL_VECTORIZED_LOOP
+                                       for(size_t j = 0; j < 8; j++) {
+                                               srcbuf[j] = p[j];
+                                       }
+                               __DECL_VECTORIZED_LOOP
+                                       for(size_t j = 0; j < 8; j++) {
+                                               dstbuf[j] = (D)(srcbuf[j]);
+                                       }
+                               __DECL_VECTORIZED_LOOP
+                                       for(size_t j = 0; j < 8; j++) {
+                                               q[j] = dstbuf[j];
+                                       }
+                                       p += 8;
+                                       q += 8;
+                               }
+                               for(size_t j = 0; j < minor_words; j++) {
+                                       q[j] = (D)(p[j]);
+                               }
+                       }
+                       break;
+               case (src_true | dst_false):
+                       // src is signed or unsigned int, dst is float or double
+                       {
+                               const D tmp_src_max = (D)(src_limit.max());
+                               __DECL_ALIGNED(16) const D src_max[8] = {tmp_src_max};
+                               __DECL_ALIGNED(16) D srcbuf_2[8];
+                               
+                               if(std::numeric_limits<S>::is_signed()) {
+                                       // Signed
+                                       for(size_t i = 0; i < major_nwords; i++) {
+                                       __DECL_VECTORIZED_LOOP
+                                               for(size_t j = 0; j < 8; j++) {
+                                                       srcbuf[j] = p[j];
+                                               }
+                                       __DECL_VECTORIZED_LOOP
+                                               for(size_t j = 0; j < 8; j++) {
+                                                       srcbuf_2[j] = (D)(srcbuf[j]);
+                                               }
+                                       __DECL_VECTORIZED_LOOP
+                                               for(size_t j = 0; j < 8; j++) {
+                                                       dstbuf[j] = srcbuf_2[j] / src_max[j];
+                                               }
+                                       __DECL_VECTORIZED_LOOP
+                                               for(size_t j = 0; j < 8; j++) {
+                                                       q[j] = dstbuf[j];
+                                               }
+                                               p += 8;
+                                               q += 8;
+                                       }
+                                       for(size_t j = 0; j < minor_words; j++) {
+                                               D _tmp = (D)(p[j]);
+                                               _tmp = _tmp / tmp_src_max;
+                                               q[j] = _tmp;
+                                       }
+                               } else {
+                                       // Unsigned
+                                       for(size_t i = 0; i < major_nwords; i++) {
+                                       __DECL_VECTORIZED_LOOP
+                                               for(size_t j = 0; j < 8; j++) {
+                                                       srcbuf[j] = p[j];
+                                               }
+                                       __DECL_VECTORIZED_LOOP
+                                               for(size_t j = 0; j < 8; j++) {
+                                                       srcbuf_2[j] = (D)(srcbuf[j]);
+                                               }
+                                       __DECL_VECTORIZED_LOOP
+                                               for(size_t j = 0; j < 8; j++) {
+                                                       dstbuf[j] = (srcbuf_2[j] / src_max[j]) - 0.5;
+                                               }
+                                       __DECL_VECTORIZED_LOOP
+                                               for(size_t j = 0; j < 8; j++) {
+                                                       q[j] = dstbuf[j];
+                                               }
+                                               p += 8;
+                                               q += 8;
+                                       }
+                                       for(size_t j = 0; j < minor_words; j++) {
+                                               D _tmp = (D)(p[j]);
+                                               _tmp = (_tmp / tmp_src_max) - 0.5;
+                                               q[j] = _tmp;
+                                       }
+                               }
+                       }
+                       break;
+               case (src_false | dst_true):
+                       //  src is float or double, dst is signed or unsigned int
+                       {
+                               const S tmp_dst_max = (S)(dst_limit.max()) + 1.0;
+                               __DECL_ALIGNED(16) const S dst_max[8] = {tmp_dst_max};
+               
+                               if(std::numeric_limits<S>::is_signed()) {
+                                       // Signed
+                                       for(size_t i = 0; i < major_nwords; i++) {
+                                       __DECL_VECTORIZED_LOOP
+                                               for(size_t j = 0; j < 8; j++) {
+                                                       srcbuf[j] = p[j];
+                                               }
+                                       __DECL_VECTORIZED_LOOP
+                                               for(size_t j = 0; j < 8; j++) {
+                                                       srcbuf[j] = srcbuf[j] * dst_max[j];
+                                               }
+                                       __DECL_VECTORIZED_LOOP
+                                               for(size_t j = 0; j < 8; j++) {
+                                                       dstbuf[j] = (D)(srcbuf[j]);
+                                               }
+                                       __DECL_VECTORIZED_LOOP
+                                               for(size_t j = 0; j < 8; j++) {
+                                                       q[j] = dstbuf[j];
+                                               }
+                                               p += 8;
+                                               q += 8;
+                                       }
+                                       for(size_t j = 0; j < minor_words; j++) {
+                                               S _tmp = p[j];
+                                               _tmp = _tmp * tmp_dst_max;
+                                               q[j] = (D)_tmp;
+                                       }
+                               } else {
+                                       // Unsigned
+                                       for(size_t i = 0; i < major_nwords; i++) {
+                                       __DECL_VECTORIZED_LOOP
+                                               for(size_t j = 0; j < 8; j++) {
+                                                       srcbuf[j] = p[j];
+                                               }
+                                       __DECL_VECTORIZED_LOOP
+                                               for(size_t j = 0; j < 8; j++) {
+                                                       srcbuf[j] = (srcbuf[j] + 0.5)  * dst_max[j];
+                                               }
+                                       __DECL_VECTORIZED_LOOP
+                                               for(size_t j = 0; j < 8; j++) {
+                                                       dstbuf[j] = (D)(srcbuf[j]);
+                                               }
+                                       __DECL_VECTORIZED_LOOP
+                                               for(size_t j = 0; j < 8; j++) {
+                                                       q[j] = dstbuf[j];
+                                               }
+                                               p += 8;
+                                               q += 8;
+                                       }
+                                       for(size_t j = 0; j < minor_words; j++) {
+                                               S _tmp = p[j];
+                                               _tmp = (_tmp + 0.5) * tmp_dst_max;
+                                               q[j] = (D)_tmp;
+                                       }
+                               }
+                       }
+                       break;
+               default:
+                       //  both src and dst are signed or unsigned int
+                       {
+                               uint8_t type_is_signed =
+                                       (std::numeric_limits<S>::is_signed() ? src_true : src_false) |
+                                       (std::numeric_limits<D>::is_signed() ? dst_true : dst_false);
+                               
+                               const ssize_t src_bit_width = sizeof(S) << 3; 
+                               const ssize_t dst_bit_width = sizeof(D) << 3;
+                               const ssize_t bit_width_diff = dst_bit_width - src_bit_width;
+                               
+                               const S tmp_src_max = src_limit.max();
+                               const D tmp_dst_max = dst_limit.max();
+                               const D tmp_bitfill = (bit_width_diff > 0) ? ((((D)1) << src_bit_width) - 1) & tmp_dst_max : 0;
+
+                               D tmp_offset;
+                               switch(type_is_signed) {
+                               case (src_true | dst_false): // signed -> unsigned
+                                       tmp_offset = (D)tmp_src_max + 1;
+                                       break;
+                               case (src_false | dst_true): // unsigned -> signed
+                                       tmp_offset = -((D)tmp_src_max + 1);
+                                       break;
+                               default:
+                                       // unsigned -> unsigned
+                                       // signed -> signed
+                                       tmp_offset = 0;
+                                       break;
+                               }
+                               if(bit_width_diff <= 0) {
+                                       tmp_offset = 0;
+                               }
+                               if((tmp_offset == 0) && (bit_width_diff == 0)) {
+                                       // Same signess && Same bitwidth
+                                       memdpy(dst, src, words * sizeof(D));
+                                       return words;
+                               }
+                               __DECL_ALIGNED(16) const D bitfill[8] = {tmp_bitfill};
+                               __DECL_ALIGNED(16) const D _offset[8] = {tmp_offset};
+                               
+                               for(size_t i = 0; i < major_nwords; i++) {
+                               __DECL_VECTORIZED_LOOP
+                                       for(size_t j = 0; j < 8; j++) {
+                                               srcbuf[j] = p[j];
+                                       }
+                               __DECL_VECTORIZED_LOOP
+                                       for(size_t j = 0; j < 8; j++) {
+                                               dstbuf[j] = (D)(srcbuf[j]);
+                                       }
+                               __DECL_VECTORIZED_LOOP
+                                       for(size_t j = 0; j < 8; j++) {
+                                               dstbuf[j] += _offset[j];
+                                       }
+                               __DECL_VECTORIZED_LOOP
+                                       for(size_t j = 0; j < 8; j++) {
+                                               dstbuf[j] <<= bit_width_diff;
+                                       }
+                               __DECL_VECTORIZED_LOOP
+                                       for(size_t j = 0; j < 8; j++) {
+                                               dstbuf[j] |= bitfill[j];
+                                       }
+                               __DECL_VECTORIZED_LOOP
+                                       for(size_t j = 0; j < 8; j++) {
+                                               q[j] = dstbuf[j];
+                                       }
+                                       p += 8;
+                                       q += 8;
+                               }
+                               for(size_t j = 0; j < minor_words; j++) {
+                                       D tmp = (D)(p[j]);
+                                       tmp += tmp_offset;
+                                       tmp <<= bit_width_diff;
+                                       tmp |= tmp_bitfill;
+                                       q[j] = tmp;
+                               }
+                       }
+                       break;
+               }
+               return words;
+       }
+       
+/* SOUND_MODULE */
+}