OSDN Git Service

[OSD][SOUND][QT_MULTIMEDIA] Make be more correctness updating timestamp.
[csp-qt/common_source_project-fm7.git] / source / src / qt / sound-drivers / qt_multimedia / osd_sound_mod_qtmultimedia.cpp
1 #include "../../../config.h"
2 #include "../../gui/menu_flags.h"
3 #include "../../osd_base.h"
4
5 #include "../sound_buffer_qt.h"
6
7 #include "./osd_sound_mod_qtmultimedia.h"
8
9 #include <algorithm>
10
11 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
12 #include <QMediaDevices>
13 #endif
14
15 namespace SOUND_MODULE {
16 /* SOUND_MODULE */
17         
18         namespace OUTPUT {
19         /* SOUND_MODULE */
20         M_QT_MULTIMEDIA::M_QT_MULTIMEDIA(
21                 OSD_BASE *parent,
22                 SOUND_BUFFER_QT* deviceIO,
23                 int base_rate,
24                 int base_latency_ms,
25                 int base_channels,
26                 void *extra_config_values,
27                 int extra_config_bytes )
28                 :
29         M_BASE(
30                 parent,
31                 deviceIO,
32                 base_rate,
33                 base_latency_ms,
34                 base_channels,
35                 extra_config_values,
36                 extra_config_bytes )
37 {
38         m_classname = "SOUND_MODULE::OUTPUT::M_QT_MULTIMEDIA";
39         
40         connect(this, SIGNAL(sig_start_audio()),  this, SLOT(do_sound_start()), Qt::QueuedConnection);
41         connect(this, SIGNAL(sig_stop_audio()),  this, SLOT(do_sound_stop()), Qt::QueuedConnection);
42         connect(this, SIGNAL(sig_pause_audio()),  this, SLOT(do_sound_suspend()), Qt::QueuedConnection);
43         connect(this, SIGNAL(sig_resume_audio()),  this, SLOT(do_sound_resume()), Qt::QueuedConnection);
44         connect(this, SIGNAL(sig_discard_audio()),  this, SLOT(do_discard_sound()), Qt::QueuedConnection);
45         connect(this, SIGNAL(sig_set_volume(double)),  this, SLOT(do_sound_volume(double)), Qt::QueuedConnection);
46
47         connect(parent, SIGNAL(sig_set_sound_volume(int)),  this, SLOT(set_volume(int)), Qt::QueuedConnection);
48         connect(parent, SIGNAL(sig_set_sound_volume(double)),  this, SLOT(set_volume(double)), Qt::QueuedConnection);
49         connect(parent, SIGNAL(sig_set_sound_device(QString)),  this, SLOT(do_set_device_by_name(QString)), Qt::QueuedConnection);
50         
51         initialize_sound_devices_list();
52 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
53         m_audioOutputDevice = QMediaDevices::defaultAudioOutput();
54 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
55         m_audioOutputDevice = QAudioDeviceInfo::defaultOutputDevice();
56 #endif          
57         m_device_is_default = true;
58         m_device_name = "Default";
59         
60         QString _drv = QString::fromStdString(m_device_name);
61         config_t* _ccp = get_config_ptr();
62         if(_ccp != nullptr) {
63                 if(strlen(_ccp->sound_device_name) > 0) {
64                         _drv = QString::fromUtf8(_ccp->sound_device_name);
65                 }
66         }
67         auto _match = std::find(devices_name_list.begin(), devices_name_list.end(), _drv.toLocal8Bit().toStdString());
68         if(_match != devices_name_list.end()) {
69                 m_device_name = (*_match);
70         }
71         m_config_ok = initialize_driver();
72 }
73
74 M_QT_MULTIMEDIA::~M_QT_MULTIMEDIA()
75 {
76 }
77
78 void M_QT_MULTIMEDIA::driver_state_changed(QAudio::State newState)
79 {
80         switch(newState) {
81         case QAudio::ActiveState:
82                 __debug_log_func(_T("AUDIO:ACTIVE"));
83                 break;
84         case QAudio::IdleState:
85                 __debug_log_func(_T("AUDIO:IDLE"));
86                 //if(m_audioOutputSink != nullptr) {
87                 //      m_audioOutputSink->stop();
88                 //}
89                 break;
90         case QAudio::StoppedState:
91                 __debug_log_func(_T("AUDIO:STOP"));
92                 break;
93         case QAudio::SuspendedState:
94                 __debug_log_func(_T("AUDIO:SUSPEND"));
95                 break;
96         #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
97         case QAudio::InterruptedState:
98                 __debug_log_func(_T("AUDIO:INTERRUPTED"));
99                 break;
100         #endif
101         
102         }
103 }
104
105
106 void M_QT_MULTIMEDIA::update_driver_fileio()
107 {
108         m_driver_fileio = m_fileio;
109 }
110
111
112
113 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
114 void M_QT_MULTIMEDIA::set_audio_format(QAudioDevice dest_device, QAudioFormat& desired, int& channels, int& rate)
115 {
116         int _channels = channels;
117         if(dest_device.minimumChannelCount() > _channels) {
118                 _channels = dest_device.minimumChannelCount();
119         } else if(dest_device.maximumChannelCount() < _channels) {
120                 _channels = dest_device.maximumChannelCount();
121         }
122         if(dest_device.minimumSampleRate() > rate) {
123                 rate = dest_device.minimumSampleRate();
124         } else if(dest_device.maximumSampleRate() < rate) {
125                 rate = dest_device.maximumSampleRate();
126         }
127         if((rate <= 0)) {
128                 return;
129         }
130         if(_channels > 0) {
131                 channels = _channels; // Workaround 20221008 K.O
132         }
133         desired.setSampleRate(rate);
134
135         QList<QAudioFormat::SampleFormat> _al = dest_device.supportedSampleFormats();
136         if(_al.contains(QAudioFormat::Int16)) {
137                 desired.setSampleFormat(QAudioFormat::Int16);
138         } else if(_al.contains(QAudioFormat::Int32)) {
139                 desired.setSampleFormat(QAudioFormat::Int32);
140         } else {
141                 desired.setSampleFormat(QAudioFormat::Unknown);
142         }
143
144         switch(channels) {
145         case 1:
146                 channels = 1;
147                 desired.setChannelConfig(QAudioFormat::ChannelConfigMono);
148                 break;
149         case 2:
150                 desired.setChannelConfig(QAudioFormat::ChannelConfigStereo);
151                 break;
152         case 3:
153                 desired.setChannelConfig(QAudioFormat::ChannelConfig2Dot1);
154                 break;
155         case 5:
156                 desired.setChannelConfig(QAudioFormat::ChannelConfigSurround5Dot0);
157                 break;
158         case 6:
159                 desired.setChannelConfig(QAudioFormat::ChannelConfigSurround5Dot1);
160                 break;
161         case 7:
162                 desired.setChannelConfig(QAudioFormat::ChannelConfigSurround7Dot0);
163                 break;
164         case 8:
165                 desired.setChannelConfig(QAudioFormat::ChannelConfigSurround7Dot1);
166                 break;
167         default:
168                 channels = 2;
169                 desired.setChannelConfig(QAudioFormat::ChannelConfigStereo);
170                 break;
171         }
172         desired.setChannelCount(channels);      
173 }
174 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
175 void M_QT_MULTIMEDIA::set_audio_format(QAudioDeviceInfo dest_device, QAudioFormat& desired, int& channels, int& rate)
176 {
177         int _channels = channels;
178         QList<int> channelsList = dest_device.supportedChannelCounts();
179         QList<int> ratesList    = dest_device.supportedSampleRates();
180
181         int _min_channels = INT_MAX;
182         int _max_channels = 0;
183         for(auto i = channelsList.begin() ; i != channelsList.end(); ++i) {
184                 if((*i) < _min_channels) _min_channels = (*i);
185                 if((*i) > _max_channels) _max_channels = (*i);
186         }
187         if(_min_channels > _channels) {
188                 _channels = _min_channels;
189         } else if(_max_channels < _channels) {
190                 _channels = _max_channels;
191         }
192         
193         int _min_rate = INT_MAX;
194         int _max_rate = 0;
195         for(auto i = ratesList.begin() ; i != ratesList.end(); ++i) {
196                 if((*i) < _min_rate) _min_rate = (*i);
197                 if((*i) > _max_rate) _max_rate = (*i);
198         }
199         if(_min_rate > rate) {
200                 rate = _min_rate;
201         } else if(_max_rate < rate) {
202                 rate = _max_rate;
203         }
204         if((rate <= 0)) {
205                 return;
206         }
207         if(_channels > 0) {
208                 channels = _channels; // Workaround 20221008 K.O
209         }
210         
211         desired.setSampleRate(rate);
212         desired.setSampleSize(16);
213         desired.setSampleType(QAudioFormat::SignedInt);
214         #if Q_BYTE_ORDER == Q_BIG_ENDIAN        
215         desired.setByteOrder(QAudioFormat::BigEndian);
216         #else
217         desired.setByteOrder(QAudioFormat::LittleEndian);
218         #endif
219
220         desired.setChannelCount(channels);      
221 }
222 #endif          
223
224 bool M_QT_MULTIMEDIA::initialize_driver()
225 {
226         bool result = false;
227
228 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
229         QAudioDevice tmp_output_device;
230 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
231         QAudioDeviceInfo tmp_output_device;
232 #endif
233         tmp_output_device = get_device_by_name(QString::fromStdString(m_device_name));
234         QAudioFormat tmp_output_format = tmp_output_device.preferredFormat();
235         
236         int _channels = m_channels;
237         int _rate = m_rate;
238         set_audio_format(tmp_output_device, tmp_output_format, _channels, _rate);
239         if((_channels > 0) && (_rate > 0)) {
240                 m_channels = _channels;
241                 m_rate = _rate;
242         } else {
243                 tmp_output_format = tmp_output_device.preferredFormat();
244                 _channels = tmp_output_format.channelCount();
245                 _rate     = tmp_output_format.sampleRate();
246                 if((_rate <= 0) || (_channels <= 0)) {
247                         return false; // None devices.
248                 }
249         }
250         m_audioOutputDevice = tmp_output_device;
251         m_audioOutputFormat = tmp_output_format;
252         
253 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
254         m_audioOutputSink.reset(new QAudioSink(m_audioOutputDevice, m_audioOutputFormat, this));
255 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
256         m_audioOutputSink.reset(new QAudioOutput(m_audioOutputDevice, m_audioOutputFormat, this));
257 #endif  
258         result = ((m_audioOutputSink.get() != nullptr) /* || (m_audioInputSource.get() != nullptr) */);
259         if(result) {
260                 connect(m_audioOutputSink.get(), SIGNAL(stateChanged(QAudio::State)), this, SLOT(driver_state_changed(QAudio::State)));
261                 m_channels = m_audioOutputSink->format().channelCount();
262                 m_rate = m_audioOutputSink->format().sampleRate();
263                 m_config_ok = true;
264         }
265         m_samples = ((qint64)m_latency_ms * (qint64)(m_rate)) / 1000;
266         if(m_samples <= 0) {
267                 m_samples = 4800;
268         }
269         update_driver_fileio();
270
271         __debug_log_func(_T("status=%s"), (m_config_ok) ? _T("OK") : _T("NG"));
272         return result;
273 }
274
275 void M_QT_MULTIMEDIA::initialize_sound_devices_list()
276 {
277         devices_name_list.clear();
278 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
279         m_audioOutputsList = QMediaDevices::audioOutputs();
280         for(auto i = m_audioOutputsList.begin(); i != m_audioOutputsList.end(); ++i) {
281                 devices_name_list.push_back((*i).description().toStdString());
282         }
283 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
284         m_audioOutputsList = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
285         for(auto i = m_audioOutputsList.begin(); i != m_audioOutputsList.end(); ++i) {
286                 devices_name_list.push_back((*i).deviceName().toStdString());
287         }
288 #endif  
289 }
290
291 std::list<std::string> M_QT_MULTIMEDIA::get_sound_devices_list()
292 {
293         return devices_name_list;
294 }
295
296 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
297 QAudioDevice M_QT_MULTIMEDIA::get_device_by_name(QString driver_name)
298 #else
299 QAudioDeviceInfo M_QT_MULTIMEDIA::get_device_by_name(QString driver_name)
300 #endif
301 {
302 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
303         QAudioDevice dest_device = m_audioOutputDevice;
304 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
305         QAudioDeviceInfo dest_device = m_audioOutputDevice;
306 #endif
307         
308         if((driver_name == QString::fromUtf8("Default")) || (driver_name.isEmpty())) {
309                 m_device_is_default = true;
310 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
311                 dest_device = QMediaDevices::defaultAudioOutput();
312 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
313                 dest_device = QAudioDeviceInfo::defaultOutputDevice();
314 #endif          
315         } else {
316                 for(auto i = m_audioOutputsList.begin(); i != m_audioOutputsList.end(); ++i) {
317 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
318                         if((*i).description().compare(driver_name) == 0) {
319                                 dest_device = *i;
320                                 m_device_is_default = false;
321                                 break;
322                         }
323 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
324                         if((*i).deviceName().compare(driver_name) == 0) {
325                                 dest_device = *i;
326                                 m_device_is_default = false;
327                                 break;
328                         }
329 #endif
330                 }
331         }
332         QString dest_device_name;
333 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
334         dest_device_name = dest_device.description();
335 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
336         dest_device_name = dest_device.deviceName();
337 #endif
338         
339         __debug_log_func(_T("desired_driver=%s using=%s"), driver_name.toLocal8Bit().constData(), dest_device_name.toLocal8Bit().constData());
340
341         return dest_device;
342 }
343         
344 void M_QT_MULTIMEDIA::do_set_device_by_name(QString driver_name)
345 {
346 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
347         QAudioDevice dest_device = get_device_by_name(driver_name);
348 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
349         QAudioDeviceInfo dest_device = get_device_by_name(driver_name);
350 #endif
351         setup_device(dest_device, m_rate, m_channels, m_latency_ms, true);
352 }
353
354 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
355 void M_QT_MULTIMEDIA::setup_device(QAudioDevice dest_device, int& rate,int& channels,int& latency_ms, bool force_reinit)
356 #else
357 void M_QT_MULTIMEDIA::setup_device(QAudioDeviceInfo dest_device, int& rate,int& channels,int& latency_ms, bool force_reinit)
358 #endif
359 {
360         if(dest_device.isNull()) return; // None initialize if NULL.
361         
362         __debug_log_func(_T("Expected: rate=%d channels=%d latency=%dmSec reinit=%d"), rate, channels, latency_ms, force_reinit);
363         
364         if(!(force_reinit)) {
365                 // If already initialized and not changed, skip.
366                 if((m_audioOutputDevice == dest_device)
367                    && (rate == m_rate)
368                    && (channels == m_channels)
369                    && (latency_ms == m_latency_ms)
370                    && (m_audioOutputSink.get() != nullptr)
371                    && (m_fileio.get() != nullptr)) {
372                         if(m_fileio->isOpen()) {
373                                 return;
374                         }
375                         update_driver_fileio();
376                         __debug_log_func(_T("Nothing changed.Exit."));
377
378                         //real_reconfig_sound(rate, channels, latency_ms);
379                         emit sig_start_audio();
380                         return;
381                 }
382         }
383         if((m_audioOutputDevice.isNull()) || (m_audioOutputDevice != dest_device)) {
384                 force_reinit = true;
385         }
386         bool force_req_reinit = false;
387         if(!(force_reinit)) {
388                 if(m_latency_ms != latency_ms) {
389                         force_req_reinit = true;
390                 }
391                 if(m_audioOutputSink.get() != nullptr) {
392                         if((m_audioOutputSink->format().channelCount() != channels) ||
393                            (m_audioOutputSink->format().sampleRate() != rate)) {
394                                 force_req_reinit = true;
395                         }
396                 } else {
397                         force_reinit = true;
398                 }
399         }
400
401         
402         if((force_reinit) || (force_req_reinit)) {
403                 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
404                 QString __name = dest_device.description();
405                 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
406                 QString __name = dest_device.deviceName();
407                 #endif
408                 
409                 QAudioFormat desired = dest_device.preferredFormat();
410                 int _channels = channels;
411                 int _rate = rate;
412                 set_audio_format(dest_device, desired, channels, rate);
413                 if((channels <= 0) || (rate <= 0)) {
414                         __debug_log_func(_T("Desired device \"%s\" don't be effective.Make fallback. rate=%d channels=%d"), __name.toLocal8Bit().constData(), rate, channels);
415                         channels = _channels;
416                         rate = _rate;
417                         return;
418                 }
419                 
420                 if(m_audioOutputSink.get() != nullptr) {
421                         if(m_audioOutputSink->state() != QAudio::StoppedState) {
422                                 m_audioOutputSink->stop();
423                                 wait_driver_stopped(1000);
424                         }
425                         m_audioOutputSink->disconnect();
426                         m_audioOutputSink.reset();
427                 }
428                 
429                 m_audioOutputDevice = dest_device;
430                 m_audioOutputFormat = desired;
431                 
432 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
433                 m_audioOutputSink.reset(new QAudioSink(dest_device, desired, this));
434 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
435                 m_audioOutputSink.reset(new QAudioOutput(dest_device, desired, this));
436 #endif
437                 if(m_audioOutputSink.get() != nullptr) {
438                         connect(m_audioOutputSink.get(), SIGNAL(stateChanged(QAudio::State)), this, SLOT(driver_state_changed(QAudio::State)));
439                         channels = m_audioOutputSink->format().channelCount();
440                         rate = m_audioOutputSink->format().sampleRate();
441                         QString _tmpname = QString::fromUtf8("Defalut");
442                         if(!(m_device_is_default)) {
443                                 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
444                                 _tmpname = m_audioOutputDevice.description();
445                                 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
446                                 _tmpname = m_audioOutputDevice.deviceName();
447                                 #endif
448                         }
449                         m_device_name = _tmpname.toLocal8Bit().toStdString();
450                         config_t* _ccp = get_config_ptr();
451                         if(_ccp != nullptr) {
452                                 memset(_ccp->sound_device_name, 0x00, sizeof(_ccp->sound_device_name));
453                                 my_tcscpy_s(_ccp->sound_device_name, (sizeof(_ccp->sound_device_name) / sizeof(_TCHAR)) - 1, _tmpname.toUtf8().constData());
454                         }
455
456                         recalc_samples(rate, latency_ms, true, true);
457
458                         m_config_ok = (m_fileio.get() != nullptr);
459                                 
460                         if(m_config_ok.load()) {
461                                 real_reconfig_sound(rate, channels, latency_ms);
462                         }
463                 } else {
464                         m_device_name.clear();
465                         m_config_ok = false;
466                         
467                         int64_t _samples =
468                                 ((int64_t)rate * latency_ms) / 1000;
469                         if(_samples < 100) _samples = 100;
470                         if(m_fileio.get() != nullptr) {
471                                 if(m_fileio->isOpen()) {
472                                         m_fileio->close();
473                                 }
474                                 m_fileio.reset();
475                                 update_driver_fileio();
476                         }
477                         m_samples = _samples;
478                         m_latency_ms = latency_ms;
479                         m_rate = rate;
480                         m_channels = channels;
481                 }
482         }
483         __debug_log_func(_T("Result: rate=%d channels=%d latency=%dmSec reinit=%d"), m_rate, m_channels, m_latency_ms, force_reinit);
484         if(m_audioOutputSink.get() != nullptr) {
485                 update_driver_fileio();
486                 emit sig_start_audio();
487                 //update_render_point_usec();
488         }
489 }
490
491 const std::string M_QT_MULTIMEDIA::set_device_sound(const _TCHAR* driver_name, int& rate,int& channels,int& latency_ms)
492 {
493         if(driver_name == nullptr) {
494                 return (const std::string)(std::string(""));
495         }
496         if(strlen(driver_name) <= 0) {
497                 return (const std::string)(std::string(""));
498         }
499         
500         QString _name = QString::fromUtf8(driver_name);
501         
502 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
503         QAudioDevice dest_device = get_device_by_name(_name);
504 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
505         QAudioDeviceInfo dest_device = get_device_by_name(_name);
506 #endif
507         setup_device(dest_device, rate, channels, latency_ms, false);
508         
509 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
510         return m_audioOutputDevice.description().toStdString();
511 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
512         return m_audioOutputDevice.deviceName().toStdString();
513 #else
514         return (const std::string)(std::string(""));
515 #endif  
516 }
517
518 bool M_QT_MULTIMEDIA::real_reconfig_sound(int& rate,int& channels,int& latency_ms)
519 {
520         if((rate <= 0) || (channels < 1) || (latency_ms < 10)) {
521                 return false;
522         }
523
524         int64_t _samples = (rate * latency_ms) / 1000;
525         if((rate != m_rate) || (_samples != m_samples) || (m_latency_ms != latency_ms)) {
526                 m_device_name = set_device_sound((const _TCHAR *)(m_device_name.c_str()), rate, channels, latency_ms);
527                 __debug_log_func(_T("Returned Driver=\"%s\" rate=%dHz channles=%d latency=%dmSec"), m_device_name.c_str(), rate, channels, latency_ms);
528                 //emit sig_set_sound_device(m_device_name);
529         }
530         if((rate <= 0) || (latency_ms <= 0)) {
531                 rate = 48000;
532                 latency_ms = 100;
533                 channels = 2;
534                 m_config_ok = false;
535         }
536         if(recalc_samples(rate, latency_ms, true, false)) {
537                 m_prev_started = m_mute = false;
538         }
539         
540         return m_config_ok.load();
541 }
542
543
544 void M_QT_MULTIMEDIA::release_sound()
545 {
546 //      std::lock_guard<std::recursive_timed_mutex> locker(m_locker);
547         
548         m_audioOutputSink->disconnect();
549
550         if(m_audioOutputSink.get() != nullptr) {
551                 m_audioOutputSink->stop();
552         }
553         m_audioOutputSink.reset();
554
555         M_BASE::release_sound();
556 }
557
558 bool M_QT_MULTIMEDIA::release_driver()
559 {
560         emit sig_stop_audio();
561         if(!(wait_driver_stopped(1000))) return false;
562         return release_driver_fileio();
563 }
564         
565 void M_QT_MULTIMEDIA::do_sound_start()
566 {
567 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
568         std::shared_ptr<QAudioSink> p = m_audioOutputSink;
569 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
570         std::shared_ptr<QAudioOutput> p = m_audioOutputSink;
571 #endif
572         if(m_driver_fileio.get() != nullptr) {
573                 m_driver_fileio->reset();
574         }
575         if(p.get() != nullptr) {
576                 p->start(m_driver_fileio.get());
577                 __debug_log_func("GO. fileio=%0llx", m_driver_fileio.get());
578         }
579         update_render_point_usec();
580         m_prev_started = true;
581 }
582
583 void M_QT_MULTIMEDIA::do_sound_stop()
584 {
585 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
586         std::shared_ptr<QAudioSink> p = m_audioOutputSink;
587 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
588         std::shared_ptr<QAudioOutput> p = m_audioOutputSink;
589 #endif
590         if(p.get() != nullptr) {
591                 p->stop();
592         }
593         do_discard_sound();
594         update_render_point_usec();
595         m_prev_started = false;
596 }
597
598 void M_QT_MULTIMEDIA::do_sound_resume()
599 {
600 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
601         std::shared_ptr<QAudioSink> p = m_audioOutputSink;
602 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
603         std::shared_ptr<QAudioOutput> p = m_audioOutputSink;
604 #endif
605         if(p.get() != nullptr) {
606                 p->resume();
607                 update_render_point_usec();
608         }
609 }
610
611 void M_QT_MULTIMEDIA::do_sound_suspend()
612 {
613 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
614         std::shared_ptr<QAudioSink> p = m_audioOutputSink;
615 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
616         std::shared_ptr<QAudioOutput> p = m_audioOutputSink;
617 #endif
618         if(p.get() != nullptr) {
619                 p->suspend();
620         }
621 }
622
623 void M_QT_MULTIMEDIA::do_sound_volume(double level)
624 {
625 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
626         std::shared_ptr<QAudioSink> p = m_audioOutputSink;
627 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
628         std::shared_ptr<QAudioOutput> p = m_audioOutputSink;
629 #endif
630         if(p.get() != nullptr) {
631                 p->setVolume(level);
632         }
633 }
634
635 int64_t M_QT_MULTIMEDIA::driver_elapsed_usec()
636 {
637 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
638         std::shared_ptr<QAudioSink> p = m_audioOutputSink;
639 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
640         std::shared_ptr<QAudioOutput> p = m_audioOutputSink;
641 #endif
642         if(p.get() != nullptr) {
643                 return (int64_t)(p->elapsedUSecs());
644         }
645         return 0;
646 }
647
648 int64_t M_QT_MULTIMEDIA::driver_processed_usec()
649 {
650 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
651         std::shared_ptr<QAudioSink> p = m_audioOutputSink;
652 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
653         std::shared_ptr<QAudioOutput> p = m_audioOutputSink;
654 #endif
655         if(p.get() != nullptr) {
656                 return (int64_t)(p->processedUSecs());
657         }
658         return 0;
659 }
660
661 bool M_QT_MULTIMEDIA::is_driver_started()
662 {
663         bool _b = M_BASE::is_driver_started();
664         std::shared_ptr<SOUND_BUFFER_QT> q = m_driver_fileio;
665         if(q.get() == nullptr) {
666                 return false;
667         }
668         if(!(q->isOpen())) {
669                 return false;
670         }
671         
672 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
673         std::shared_ptr<QAudioSink> p = m_audioOutputSink;
674 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
675         std::shared_ptr<QAudioOutput> p = m_audioOutputSink;
676 #endif
677         if(p.get() == nullptr) {
678                 return false;
679         }
680         if(p->state() == QAudio::StoppedState) {
681                 return false;
682         }
683         return _b;
684 }
685
686 void M_QT_MULTIMEDIA::mute_sound()
687 {
688         if(!(m_mute.load()) && (m_config_ok.load())) {
689                 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
690                 std::shared_ptr<QAudioSink> p = m_audioOutputSink;
691                 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
692                 std::shared_ptr<QAudioOutput> p = m_audioOutputSink;
693                 #endif
694                 
695                 if(p.get() != nullptr) {
696                         switch(p->state()) {
697                         case QAudio::ActiveState:
698                         case QAudio::IdleState:
699                                 emit sig_pause_audio();
700                                 emit sig_discard_audio();
701                                 break;
702                         default:
703                                 break;
704                         }
705                 }
706         }
707         m_mute = true;
708 }
709
710 void M_QT_MULTIMEDIA::do_discard_sound()
711 {
712         std::shared_ptr<SOUND_BUFFER_QT> q = m_driver_fileio;
713         if(q.get() != nullptr) {
714                 q->reset();
715         }
716 }
717
718 void M_QT_MULTIMEDIA::stop_sound()
719 {
720         if((m_config_ok.load()) && (m_prev_started)) {
721                 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
722                 std::shared_ptr<QAudioSink> p = m_audioOutputSink;
723                 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
724                 std::shared_ptr<QAudioOutput> p = m_audioOutputSink;
725                 #endif
726                 if(p.get() != nullptr) {
727                         switch(p->state()) {
728                         case QAudio::ActiveState:
729                         case QAudio::IdleState:
730                         case QAudio::SuspendedState:
731                                 emit sig_stop_audio();
732                                 break;
733                         default:
734                                 break;
735                         }
736                 }
737         }
738 }
739
740         /* SOUND_MODULE::OUTPUT */
741         }
742 /* SOUND_MODULE */
743
744 }
745