OSDN Git Service

[OSD][Qt][SOUND][CONFIG] Important: Now, sound output device has recorded as NAME...
[csp-qt/common_source_project-fm7.git] / source / src / qt / osd_sound.cpp
1 /*
2         Skelton for retropc emulator
3
4         Author : K.Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2015.11.30-
6
7         [Qt/SDL sound ]
8 */
9 /*
10   Note: 20220715 K.Ohta : This will be based on QtMultimedia's audio driver,
11                 But this still has a lot of delay.Will fix or discard.
12   Quote from "Audio Overview" of Qt6.3.1 's documentation;
13         https://doc.qt.io/qt-6/audiooverview.html 
14         Push and Pull
15                 The low level audio classes can operate in two modes - push and pull. 
16                 In pull mode, the audio device is started by giving it a QIODevice. 
17                 For an output device, the QAudioSink class will pull data from the 
18                 QIODevice (using QIODevice::read()) when more audio data is required. 
19                 Conversely, for pull mode with QAudioSource, when audio data is available
20                 then the data will be written directly to the QIODevice.
21                 
22                 In push mode, the audio device provides a QIODevice instance that can be
23                 written or read to as needed. 
24                 Typically, this results in simpler code but more buffering, 
25                 which may affect latency.
26 */
27
28 #include "../emu.h"
29 #include "../fileio.h"
30 #include "../fifo.h"
31 #include "../types/util_sound.h"
32 #include "../types/util_endians.h"
33
34 #include <SDL.h>
35
36 #include "qt_main.h"
37 //#include "csp_logger.h"
38 #include "gui/menu_flags.h"
39
40 #include <QString>
41 #include <QDateTime>
42 #include <QThread>
43 #include <QByteArray>
44 #include <QBuffer>
45 #include <cstdint>
46
47 #include "./sound_buffer_qt.h"
48
49 void OSD_BASE::audio_capture_callback(void *udata, Uint8 *stream, int len)
50 {
51         if(len <= 0) return;
52         if(udata == NULL) return;
53         if(stream == NULL) return;
54         int len2, len3;
55         osd_snddata_capture_t *pData = (osd_snddata_capture_t *)udata;
56
57         if(pData->read_buffer_ptr == NULL) return;
58         if((pData->writepos + len) >= pData->buffer_size) {
59                 // Need Wrap
60                 len2 = pData->buffer_size - pData->writepos;
61                 if(len2 > len) len2 = len;
62                 memset(&(pData->read_buffer_ptr[pData->writepos]), 0x00, len2);
63                 memcpy(&(pData->read_buffer_ptr[pData->writepos]), stream, len2);
64                 len3 = len - len2;
65                 if(len3 > 0) {
66                         memset(&(pData->read_buffer_ptr[0]), 0x00, len3);
67                         memcpy(&(pData->read_buffer_ptr[0]), &(stream[len2]), len3);
68                 }
69         } else {
70                 // Not need to wrap
71                 memset(&(pData->read_buffer_ptr[pData->writepos]), 0x00, len);
72                 memcpy(&(pData->read_buffer_ptr[pData->writepos]), stream, len);
73         }
74         pData->writepos += len;
75         if(pData->writepos >= pData->buffer_size) {
76                 pData->writepos -= pData->buffer_size;
77         }
78         pData->writelen += len;
79         if(pData->writelen >= pData->buffer_size) {
80                 pData->writelen = pData->buffer_size;
81         }
82 }
83
84
85 void OSD_BASE::audio_callback(void *udata, Uint8 *stream, int len)
86 {
87         if(len <= 0) return;
88         if(udata == NULL) return;
89         if(stream == NULL) return;
90         int len2, len3;
91         sdl_snddata_t *pData = (sdl_snddata_t *)udata;
92         int sndlen, sndpos, bufsize;
93         int spos = 0;
94         int format_len = 1;
95         
96         len3 = len;
97         memset(stream, 0x00, len);
98         switch(pData->sound_format) {
99         case AUDIO_S16LSB:
100         case AUDIO_S16MSB:
101         case AUDIO_U16LSB:
102         case AUDIO_U16MSB:
103                 format_len = sizeof(int16_t);
104                 break;
105         case AUDIO_S32LSB:
106         case AUDIO_S32MSB:
107                 format_len = sizeof(int32_t);
108                 break;
109         case AUDIO_F32LSB:
110         case AUDIO_F32MSB:
111                 format_len = sizeof(float);
112                 break;
113         }
114         
115         
116         if(pData->p_config->general_sound_level < INT16_MIN) pData->p_config->general_sound_level = INT16_MIN;
117         if(pData->p_config->general_sound_level > INT16_MAX)  pData->p_config->general_sound_level = INT16_MAX;
118         *pData->snd_total_volume = (uint8_t)(((uint32_t)(pData->p_config->general_sound_level + (-INT16_MIN))) >> 9);
119                 
120         do {
121                 sndlen = *(pData->sound_data_len);
122                 bufsize = *(pData->sound_buffer_size);
123                 sndpos = *(pData->sound_write_pos);
124                 if(*pData->sound_exit) {
125                         return;
126                 }
127                 
128                 sndpos = sndpos * format_len;
129                 sndlen = sndlen * format_len; // ToDo: Multiple format
130                 bufsize = bufsize * format_len; // ToDo: Multiple format
131                 
132                 if(sndlen >= len) sndlen = len;
133                 if((sndpos + sndlen) >= bufsize) { // Need to wrap
134                         int len2 = bufsize - sndpos;
135                         uint8_t* p = (uint8_t *)(*pData->sound_buf_ptr);
136                         uint8_t* s = &stream[spos];
137                         p = &p[sndpos];
138 #if defined(USE_SDL2)
139                         SDL_MixAudioFormat(s, p, pData->sound_format, len2, *(pData->snd_total_volume));
140 #else
141                         SDL_MixAudio(s, p, len2, *(pData->snd_total_volume));
142 #endif
143                         spos += len2;
144                         len2 = sndlen - len2;
145                         s = &stream[spos];
146                         *(pData->sound_write_pos) = 0;
147                         if(len2 > 0) {
148                                 p = (uint8_t *)(*pData->sound_buf_ptr);
149                                 p = &p[0];
150 #if defined(USE_SDL2)
151                                 SDL_MixAudioFormat(s, p, pData->sound_format, len2, *(pData->snd_total_volume));
152 #else
153                                 SDL_MixAudio(s, p, len2, *(pData->snd_total_volume));
154 #endif
155                                 *(pData->sound_write_pos) = (len2 / format_len);
156                                 if(*(pData->sound_buffer_size) <= *(pData->sound_write_pos)) {
157                                         *(pData->sound_write_pos) = 0;
158                                 }
159                                 sndpos = len2;
160                                 spos += len2;
161                                 len2 = 0;
162                         }
163                         len -= sndlen;
164                 } else { // No Need to wrap
165                         int len2 = sndlen;
166                         uint8_t* p = (uint8_t *)(*pData->sound_buf_ptr);
167                         uint8_t* s = &stream[spos];
168                         p = &p[sndpos];
169 #if defined(USE_SDL2)
170                         SDL_MixAudioFormat(s, p, pData->sound_format, len2, *(pData->snd_total_volume));
171 #else
172                         SDL_MixAudio(s, p, len2, *(pData->snd_total_volume));
173 #endif
174                         *(pData->sound_write_pos) += (len2 / format_len); 
175                         if(*(pData->sound_buffer_size) <= *(pData->sound_write_pos)) {
176                                 *(pData->sound_write_pos) = 0;
177                         }
178                         spos += len2;
179                         len -= sndlen;
180                 }
181                 *(pData->sound_data_len)  -= (sndlen / format_len);
182                 if(*(pData->sound_data_len) <= 0) return;
183                 if(spos >= len3) return;
184                 // WIP: Do place wait (1ms)?
185         } while(len > 0);
186 }
187
188 const _TCHAR *OSD_BASE::get_vm_device_name()
189 {
190         if(using_flags != NULL) {
191                 QString s = using_flags->get_device_name();
192                 static QByteArray __n = s.toUtf8();
193                 return (const _TCHAR*)(__n.constData());
194         }
195         return (const _TCHAR*)"";
196 }
197
198
199 int OSD_BASE::get_sound_device_num()
200 {
201         return sound_device_list.count();
202 }
203 #if 0
204 const _TCHAR *OSD_BASE::get_sound_device_name(int num)
205 {
206         if(num < 0) return NULL;
207         if(num >= sound_device_list.count()) return NULL;
208         QString sdev = sound_device_list.at(num);
209         sdev.truncate(1023);
210         static QByteArray _n;
211         _n.clear();
212         _n = sdev.toUtf8().constData();
213
214         return (const _TCHAR*)(_n.constData());
215 }
216
217 void OSD_BASE::get_sound_device_list()
218 {
219         sound_device_list.clear();
220 #if defined(USE_SDL2)
221         const _TCHAR* drvname = SDL_GetCurrentAudioDriver();
222         if(drvname == nullptr) return;
223         debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND, "Using Sound Driver: %s\n", drvname);
224         for(int i = 0; i < SDL_GetNumAudioDevices(0); i++) {
225                 QString tmps = QString::fromUtf8(SDL_GetAudioDeviceName(i, 0));
226                 debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND,
227                                   "Audio Device #%d: %s", i, tmps.toLocal8Bit().constData());
228                 sound_device_list.append(tmps);
229         }
230 #endif
231 }
232
233 void OSD_BASE::initialize_sound(int rate, int samples, int* presented_rate, int* presented_samples)
234 {
235         std::string devname;
236         int i;
237
238         bool pre_initialized = sound_initialized;
239         if(sound_initialized) {
240                 release_sound();
241         }
242
243         sound_capture_device_list.clear();
244 #if 0
245         for(int ch = 0 ; ch < MAX_CAPTURE_SOUND; ch++) {
246                 // ToDo: Allocation.
247                 // ToDo: Close physical device.
248                 if(!pre_initialized) {
249                         sound_capturing_emu[ch] = false;
250                         
251                         sound_capture_desc[ch].physical_dev = 0;
252                         sound_capture_desc[ch].read_format = AUDIO_S16SYS;
253                         sound_capture_desc[ch].read_rate = 0;
254                         sound_capture_desc[ch].read_channels = 0;
255                         sound_capture_desc[ch].read_samples = 0;
256                         sound_capture_desc[ch].read_silence = 0;
257                         sound_capture_desc[ch].read_size = 0;
258                         sound_capture_desc[ch].read_userdata = NULL;
259                         sound_capture_desc[ch].sample_type = 0; // ToDo : ENUM
260                         sound_capture_desc[ch].rate = 0;
261                         sound_capture_desc[ch].channels = 0;
262                         sound_capture_desc[ch].samples = 0;
263                         sound_capture_desc[ch].write_size = 0;
264                         sound_capture_desc[ch].write_pos = 0;
265                         sound_capture_desc[ch].read_data_len = 0;
266                         sound_capture_desc[ch].read_buffer_len = 0;
267                         sound_capture_desc[ch].read_buffer_ptr = NULL;
268                         sound_capture_desc[ch].out_buffer = NULL;
269                 }
270         }
271         for(int num = 0 ; num < MAX_SOUND_CAPTURE_DEVICES; num++) {
272                 sound_capture_dev_desc[num].format = AUDIO_S16SYS;
273                 sound_capture_dev_desc[num].sample_rate = 0;
274                 sound_capture_dev_desc[num].channels = 0;
275                 sound_capture_dev_desc[num].buffer_samples = 0;
276                 sound_capture_dev_desc[num].silence = 0;
277                 sound_capture_dev_desc[num].size = 0;
278                 sound_capture_dev_desc[num].callback = audio_capture_callback;
279                 sound_capture_dev_desc[num].userdata.format = AUDIO_S16SYS;
280                 sound_capture_dev_desc[num].userdata.buffer_size = 0;
281                 sound_capture_dev_desc[num].userdata.readlen = 0;
282                 sound_capture_dev_desc[num].userdata.writelen = 0;
283                 sound_capture_dev_desc[num].userdata.readpos = 0;
284                 sound_capture_dev_desc[num].userdata.read_buffer_ptr = NULL;
285                 capturing_sound[num] = false;
286         }
287 #endif
288         
289         sound_rate = rate;
290         sound_samples = samples;
291         rec_sound_buffer_ptr = 0;
292         sound_ok = sound_started = now_mute = now_record_sound = false;
293         sound_write_pos = 0;
294         sound_data_len = 0;
295         sound_buffer_size = 0;
296         sound_data_pos = 0;
297         sound_exit = false;
298         sound_debug = false;
299         //sound_debug = true;
300         sound_buf_ptr = NULL;
301         sound_initialized = false;
302         // initialize direct sound
303
304         snd_total_volume = 127;
305    
306         snddata.sound_buf_ptr = (uint8_t**)(&sound_buf_ptr);
307         snddata.sound_buffer_size = &sound_buffer_size;
308         snddata.sound_write_pos = &sound_write_pos;
309         snddata.sound_data_len = &sound_data_len;
310         snddata.snd_total_volume = &snd_total_volume;
311         snddata.sound_exit = &sound_exit;
312         snddata.sound_debug = &sound_debug;
313         snddata.p_config = p_config;
314         
315         snd_spec_req.format = AUDIO_S16SYS;
316         snd_spec_req.channels = 2;
317         snd_spec_req.freq = sound_rate;
318         //snd_spec_req.samples = ((sound_rate * 100) / 1000);
319         snd_spec_req.samples = samples;
320         snd_spec_req.callback = &(this->audio_callback);
321         snd_spec_req.userdata = (void *)&snddata;
322 #if defined(USE_SDL2)
323         audio_dev_id = 0;
324         if(!(sound_device_list.isEmpty())) {
325                 QString sdev;
326                 if(p_config->sound_device_num >= sound_device_list.count()) {
327                         p_config->sound_device_num = sound_device_list.count() - 1;
328                 }
329                 if(p_config->sound_device_num <= 0) {
330                         p_config->sound_device_num = 0;
331                 }
332                 sdev = sound_device_list.at(p_config->sound_device_num);
333                 audio_dev_id = SDL_OpenAudioDevice(sdev.toUtf8().constData(), 0,
334                                                                                    &snd_spec_req, &snd_spec_presented,
335                                                                                    0);
336                 debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND, "Try to open DEVICE #%d: %s -> %s: DEVID=%d\n",
337                                   p_config->sound_device_num, sdev.toUtf8().constData(), (audio_dev_id <= 0) ? "FAIL" : "SUCCESS", audio_dev_id);
338         } else {
339                 audio_dev_id = SDL_OpenAudioDevice("", 0,
340                                                                                    &snd_spec_req, &snd_spec_presented,
341                                                                                    0);
342                 debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND, "Try to open DEVICE #%d:  %s: DEVID=%d\n",
343                                   p_config->sound_device_num, (audio_dev_id <= 0) ? "FAIL" : "SUCCESS", audio_dev_id);
344
345         }
346 #else
347         audio_dev_id = 1;
348         SDL_OpenAudio(&snd_spec_req, &snd_spec_presented);
349 #endif
350
351 #if defined(USE_SDL2)
352         if(audio_dev_id <= 0) {
353                 debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND,"Failed to initialize sound\n");
354                 if(presented_rate != NULL) {
355                         *presented_rate = sound_rate;
356                 }
357                 if(presented_samples != NULL) {
358                         *presented_samples = sound_samples;
359                 }
360                 sound_initialized = false;
361                 sound_ok = sound_first_half = false;
362                 return;
363         }
364 #endif
365         snddata.sound_format = snd_spec_presented.format;
366         if((snd_spec_presented.freq != sound_rate) ||
367            (snd_spec_presented.samples != sound_samples)) { // DEINI
368                 sound_rate = snd_spec_presented.freq;
369                 sound_samples = snd_spec_presented.samples;
370         }
371         debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND,"Sample rate=%d samples=%d\n", sound_rate, sound_samples);
372         if(presented_rate != NULL) {
373                 *presented_rate = sound_rate;
374         }
375         if(presented_samples != NULL) {
376                 *presented_samples = sound_samples;
377         }
378         // secondary buffer
379         int format_len = 1;
380         switch(snddata.sound_format) {
381         case AUDIO_S16LSB:
382         case AUDIO_S16MSB:
383         case AUDIO_U16LSB:
384         case AUDIO_U16MSB:
385                 format_len = sizeof(int16_t);
386                 break;
387         case AUDIO_S32LSB:
388         case AUDIO_S32MSB:
389                 format_len = sizeof(int32_t);
390                 break;
391         case AUDIO_F32LSB:
392         case AUDIO_F32MSB:
393                 format_len = sizeof(float);
394                 break;
395         }
396         sound_buffer_size = sound_samples * snd_spec_presented.channels * 2;
397         sound_buf_ptr = (uint8_t *)malloc(sound_buffer_size * format_len); 
398         if(sound_buf_ptr == NULL) {
399 #if defined(USE_SDL2)              
400                 SDL_CloseAudioDevice(audio_dev_id);
401 #else      
402                 SDL_CloseAudio();
403 #endif     
404                 return;
405         }
406
407         debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND,
408                                                   "Sound OK: BufSize = %d", sound_buffer_size);
409         memset(sound_buf_ptr, 0x00, sound_buffer_size * format_len);
410         sound_initialized = true;
411         sound_ok = sound_first_half = true;
412 }
413
414 void OSD_BASE::release_sound()
415 {
416         // release SDL sound
417         sound_exit = true;
418         sound_initialized = false;
419 #if 0
420         for(int num = 0; num < MAX_SOUND_CAPTURE_DEVICES; num++) {
421                 if(capturing_sound[num]) {
422                         close_sound_capture_device(num, true);
423                 }
424         }
425         // ToDo: Reopen
426         for(int ch = 0; ch < MAX_CAPTURE_SOUNDS; ch++) {
427                 if(sound_capturing_emu[ch]) {
428                         close_capture_sound_emu(ch);
429                 }
430         }
431 #endif
432 #if defined(USE_SDL2)   
433         //SDL_PauseAudioDevice(audio_dev_id, 1);
434         SDL_CloseAudioDevice(audio_dev_id);
435 #else   
436         SDL_CloseAudio();
437 #endif   
438         stop_record_sound();
439         if(sound_buf_ptr != NULL) free(sound_buf_ptr);
440         sound_buf_ptr = NULL;
441         // stop recording
442 }
443 #else
444 // QT_Multimedia
445 #include <QtMultimedia>
446 void OSD_BASE::initialize_sound(int rate, int samples, int* presented_rate, int* presented_samples)
447 {
448         // ToDo: Sound Input
449         QAudioFormat desired;
450         if(m_audioOutputSink != nullptr) {
451                 m_audioOutputSink->stop();
452                 delete m_audioOutputSink;
453                 m_audioOutputSink = nullptr;
454         }
455         desired.setChannelCount(2);
456         desired.setSampleRate(rate);
457         desired.setSampleFormat(QAudioFormat::Int16);
458         desired.setChannelConfig(QAudioFormat::ChannelConfigStereo);
459
460         bool output_available = false;
461         if(m_audioOutputDevice.isFormatSupported(desired)) {
462                     desired = m_audioOutputDevice.preferredFormat();
463         }
464         m_audioOutputFormat = desired;
465         m_audioOutputSink = new QAudioSink(m_audioOutputDevice, m_audioOutputFormat, this);
466         //m_audioOutputSink = new QAudioSink(m_audioOutputFormat, this);
467
468         if(m_audioOutput != nullptr) {
469                 if(m_audioOutput->isOpen()) {
470                         m_audioOutput->close();
471                 }
472                 delete m_audioOutput;
473                 m_audioOutput = nullptr;
474         }
475         rate = m_audioOutputFormat.sampleRate();
476         if(rate <= 0) rate = 8000;
477         int wordsize = sizeof(int16_t);
478         switch(m_audioOutputFormat.sampleFormat()) {
479         case QAudioFormat::UInt8:
480                 wordsize = sizeof(uint8_t);
481                 break;
482         case QAudioFormat::Int16:
483                 wordsize = sizeof(int16_t);
484                 break;
485         case QAudioFormat::Int32:
486                 wordsize = sizeof(int32_t);
487                 break;
488         case QAudioFormat::Float:
489                 wordsize = sizeof(float);
490                 break;
491         }
492         int outbuffer_length = samples * 2;
493         #if 1
494         m_audioOutput = new SOUND_BUFFER_QT(samples * 2 * sizeof(int16_t) * 2);
495         if(m_audioOutput != nullptr) {
496                 m_audioOutput->open(QIODeviceBase::ReadWrite);
497         }
498         #endif
499         sound_samples = samples;
500         sound_rate = rate;
501 //      sound_samples = samples;
502 //      sound_rate = rate;
503         debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND,"Sample rate=%d samples=%d\n", sound_rate, sound_samples);
504         
505         rec_sound_buffer_ptr = 0;
506         sound_ok = sound_started = now_mute = now_record_sound = false;
507         sound_write_pos = 0;
508         sound_data_len = 0;
509         sound_buffer_size = 0;
510         sound_data_pos = 0;
511         sound_exit = false;
512         sound_debug = false;
513         //sound_debug = true;
514         sound_buf_ptr = NULL;
515
516         if(presented_rate != nullptr) {
517                 *presented_rate = sound_rate;
518         }
519         if(presented_samples != nullptr) {
520                 *presented_samples = sound_samples;
521         }
522
523         
524 //      if(m_audioOutput != nullptr) {
525                 if(m_audioOutputSink != nullptr) {
526                         sound_ok = true;
527                         sound_initialized = true;
528                         if(p_config != nullptr) {
529                                 double _ll = (double)(p_config->general_sound_level + INT16_MAX) / 65535.0;
530                                 m_audioOutputSink->setVolume(_ll);
531                         }
532                         connect(m_audioOutputSink, SIGNAL(stateChanged(QAudio::State)), this, SLOT(handleStateChanged(QAudio::State)));
533                         //m_audioOutputSink->setBufferSize(1024);
534                         //m_audioOutputSink->setBufferSize(sound_samples * 2 * sizeof(int16_t) * 2);
535                         m_audioOutput->reset();
536                         //m_audioOutputSink->start(m_audioOutput);
537                         //m_audioOutputSink->suspend();
538                 } else {
539                         sound_ok = false;
540                         sound_initialized = false;
541                         m_audioOutput = nullptr;
542                 }
543 //      }
544         debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND,
545                                                   "Sound OK: BufSize = %d", outbuffer_length);
546
547 }
548
549 void OSD_BASE::release_sound()
550 {
551         // ToDo: Sound Input
552         // release Qt Multimedia sound
553         sound_exit = true;
554         sound_initialized = false;
555         if(m_audioOutputSink != nullptr) {
556                 m_audioOutputSink->stop();
557                 int timeout = 1000;
558                 while((m_audioOutputSink->state() != QAudio::StoppedState) && (timeout >= 0)) {
559                         QThread::usleep(1000); // Wait 1mS
560                         timeout--;
561                 }
562                 delete m_audioOutputSink;
563                 m_audioOutputSink = nullptr;
564         }
565 #if 1
566         if(m_audioOutput != nullptr) {
567                 if(m_audioOutput->isOpen()) {
568                         m_audioOutput->close();
569                 }
570                 delete m_audioOutput;
571                 m_audioOutput = nullptr;
572         }
573 #endif
574         sound_ok = false;
575         sound_initialized = false;
576 }
577
578 void OSD_BASE::do_update_master_volume(int level)
579 {
580         QMutexLocker l(vm_mutex);
581         double _ll = (double)(level + INT16_MAX) / 65535.0;
582         debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND,
583                           "Set Master Volume to %f .", _ll);
584         if(m_audioOutputSink != nullptr) {
585                 m_audioOutputSink->setVolume(_ll);
586         }
587 }
588
589 void OSD_BASE::do_set_host_sound_output_device(QString device_name)
590 {
591         if(device_name.isEmpty()) return;
592         QString _older = m_audioOutputDevice.description();
593         if(device_name == QString::fromUtf8("Default")) {
594                 m_audioOutputDevice = QMediaDevices::defaultAudioOutput();
595         } else {
596                 QList<QAudioDevice> devlist = QMediaDevices::audioOutputs(); 
597                 for(auto p = devlist.begin(); p != devlist.end() ; ++p) {
598                         if((*p).description() == device_name) {
599                                 m_audioOutputDevice = *p;
600                                 break;
601                         }
602                 }
603         }
604         QString _newer = m_audioOutputDevice.description();
605         if(_older.compare(_newer) != 0) {
606                 QMutexLocker l(vm_mutex);
607                 if((p_config != nullptr) && (using_flags != nullptr)) {
608                         int freq_val = using_flags->get_sound_sample_rate(p_config->sound_frequency);
609                         double latency_val = using_flags->get_sound_latency(p_config->sound_latency);
610                         sound_rate = freq_val;
611                         sound_samples = (int)((double)sound_rate * latency_val + 0.5);
612                 }
613                 int dummy_rate;
614                 int dummy_samples;
615                 if(sound_initialized) {
616                         initialize_sound(sound_rate, sound_samples, &dummy_rate, &dummy_samples);
617                 }
618                 if((dummy_rate != sound_rate) || (dummy_samples != sound_samples)) {
619                         sound_rate = dummy_rate;
620                         sound_samples = dummy_samples;
621                 }
622         }
623 }
624
625 const _TCHAR *OSD_BASE::get_sound_device_name(int num)
626 {
627         if((num < 0) || (num >= sound_device_list.count())) return (const _TCHAR *)nullptr;
628
629         QString sdev = sound_device_list.at(num);
630         sdev.truncate(1023);
631         static QByteArray _n;
632         _n.clear();
633         _n = sdev.toUtf8().constData();
634
635         return (const _TCHAR*)(_n.constData());
636 }
637
638 void OSD_BASE::get_sound_device_list()
639 {
640         sound_device_list.clear();
641         QList<QAudioDevice> tmplist = QMediaDevices::audioOutputs();
642         int i = 0;
643         for(auto p = tmplist.begin(); p != tmplist.end(); ++p) {
644                 QString tmps = (*p).description().toUtf8();
645                 sound_device_list.append(tmps);
646                 debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND,
647                                   "Audio Device #%d: %s", i, tmps.toLocal8Bit().constData());
648                 i++;
649         }
650 }
651                 
652 #endif
653 void OSD_BASE::convert_sound_format(uint8_t* dst1, uint8_t* dst2, int16_t* src1, int16_t* src2, int samples1, int samples2)
654 {
655         if(dst1 == NULL) return;
656         if(snddata.sound_format == AUDIO_S16SYS) { // Not Convert
657                 if((src1 != NULL) && (samples1 > 0)) {
658                         my_memcpy(dst1, src1, samples1 * sizeof(int16_t));
659                 }
660                 if((src2 != NULL) && (samples2 > 0) && (dst2 != NULL)) {
661                         my_memcpy(dst2, src2, samples2 * sizeof(int16_t));
662                 }
663                 return;
664         }
665
666         union {
667 #if defined(__LITTLE_ENDIAN__)
668                 uint8_t l, h, h1, h2;
669 #else           
670                 uint8_t h2, h1, h, l;
671 #endif
672                 float f;
673                 uint32_t d;
674         } float_data;
675         
676         switch(snddata.sound_format) {
677                 // S16SYS
678         case AUDIO_S8:
679                 if(src1 != NULL) {
680                         int16_t *q = (int16_t*)src1;
681                         int8_t* p = (int8_t*)dst1;
682                         int dat;
683                         for(int i = 0; i < samples1; i++) {
684                                 dat = q[i];
685                                 dat >>= 8;
686                                 p[i] = dat;
687                         }
688                 }
689                 if((src2 != NULL) && (dst2 != NULL)) {
690                         int16_t *q = (int16_t*)src2;
691                         int8_t* p = (int8_t*)dst2;
692                         int dat;
693                         for(int i = 0; i < samples2; i++) {
694                                 dat = q[i];
695                                 dat >>= 8;
696                                 p[i] = dat;
697                         }
698                 }
699                 break;
700         case AUDIO_U8:
701                 if(src1 != NULL) {
702                         int16_t *q = (int16_t*)src1;
703                         uint8_t* p = (uint8_t*)dst1;
704                         int dat;
705                         for(int i = 0; i < samples1; i++) {
706                                 dat = q[i];
707                                 dat += 32768;
708                                 dat >>= 8;
709                                 p[i] = dat;
710                         }
711                 }
712                 if((src2 != NULL) && (dst2 != NULL)) {
713                         int16_t *q = (int16_t*)src2;
714                         uint8_t* p = (uint8_t*)dst2;
715                         int dat;
716                         for(int i = 0; i < samples2; i++) {
717                                 dat = q[i];
718                                 dat += 32768;
719                                 dat >>= 8;
720                                 p[i] = dat;
721                         }
722                 }
723                 break;
724         case AUDIO_S16LSB:
725                 if(src1 != NULL) {
726                         int16_t *q = (int16_t*)src1;
727                         int16_t* p = (int16_t*)dst1;
728                         pair16_t dat;
729                         for(int i = 0; i < samples1; i++) {
730                                 dat.sw = q[i];
731 #if defined(__LITTLE_ENDIAN__)
732                                 p[i] = dat.sw;
733 #else
734                                 p[i] = dat.get_2bytes_le_to();
735 #endif
736                         }
737                 }
738                 if((src2 != NULL) && (dst2 != NULL)) {
739                         int16_t* q = (int16_t*)src2;
740                         int16_t* p = (int16_t*)dst2;
741                         pair16_t dat;
742                         for(int i = 0; i < samples2; i++) {
743                                 dat.sw = q[i];
744 #if defined(__LITTLE_ENDIAN__)
745                                 p[i] = dat.sw;
746 #else
747                                 p[i] = dat.get_2bytes_le_to();
748 #endif
749                         }
750                 }
751                 break;
752         case AUDIO_U16LSB:
753                 if(src1 != NULL) {
754                         int16_t* q = (int16_t*)src1;
755                         uint16_t* p = (uint16_t*)dst1;
756                         pair16_t dat;
757                         int32_t d2;
758                         for(int i = 0; i < samples1; i++) {
759                                 d2 = q[i];
760                                 d2 = d2 + 32768;
761 #if defined(__LITTLE_ENDIAN__)
762                                 p[i] = d2 & 0xffff;
763 #else
764                                 dat.w = d2 & 0xffff;
765                                 p[i] = dat.get_2bytes_le_to();
766 #endif
767                         }
768                 }
769                 if((src2 != NULL) && (dst2 != NULL)) {
770                         int16_t* q = (int16_t*)src2;
771                         uint16_t* p = (uint16_t*)dst2;
772                         pair16_t dat;
773                         int d2;
774                         for(int i = 0; i < samples2; i++) {
775                                 d2 = q[i];
776                                 d2 = d2 + 32768;
777 #if defined(__LITTLE_ENDIAN__)
778                                 p[i] = d2 & 0xffff;
779 #else
780                                 dat.w = d2 & 0xffff;
781                                 p[i] = dat.get_2bytes_le_to();
782 #endif
783                         }
784                 }
785                 break;
786         case AUDIO_S16MSB:
787                 if(src1 != NULL) {
788                         int16_t *q = (int16_t*)src1;
789                         int16_t* p = (int16_t*)dst1;
790                         pair16_t dat;
791                         for(int i = 0; i < samples1; i++) {
792                                 dat.sw = q[i];
793 #if defined(__LITTLE_ENDIAN__)
794                                 p[i] = dat.get_2bytes_be_to();
795 #else
796                                 p[i] = dat.w;
797 #endif
798                         }
799                 }
800                 if((src2 != NULL) && (dst2 != NULL)) {
801                         int16_t* q = (int16_t*)src2;
802                         int16_t* p = (int16_t*)dst2;
803                         pair16_t dat;
804                         for(int i = 0; i < samples2; i++) {
805                                 dat.sw = q[i];
806 #if defined(__LITTLE_ENDIAN__)
807                                 p[i] = dat.get_2bytes_be_to();
808 #else
809                                 p[i] = dat.w;
810 #endif
811                         }
812                 }
813                 break;
814         case AUDIO_U16MSB:
815                 if(src1 != NULL) {
816                         int16_t* q = (int16_t*)src1;
817                         uint16_t* p = (uint16_t*)dst1;
818                         pair16_t dat;
819                         int d2;
820                         for(int i = 0; i < samples1; i++) {
821                                 d2 = q[i];
822                                 d2 = d2 + 32768;
823 #if defined(__LITTLE_ENDIAN__)
824                                 dat.w = d2 & 0xffff;
825                                 p[i] = dat.get_2bytes_be_to();
826 #else
827                                 p[i] = d2 & 0xffff;
828 #endif
829                         }
830                 }
831                 if((src2 != NULL) && (dst2 != NULL)) {
832                         int16_t* q = (int16_t*)src2;
833                         uint16_t* p = (uint16_t*)dst2;
834                         pair16_t dat;
835                         int d2;
836                         for(int i = 0; i < samples2; i++) {
837                                 d2 = q[i];
838                                 d2 = d2 + 32768;
839 #if defined(__LITTLE_ENDIAN__)
840                                 dat.w = d2 & 0xffff;
841                                 p[i] = dat.get_2bytes_be_to();
842 #else
843                                 p[i] = d2 & 0xffff;
844 #endif
845                         }
846                 }
847                 break;
848         case AUDIO_S32LSB:
849                 if(src1 != NULL) {
850                         uint32_t data;
851                         uint32_t* p = (uint32_t*)dst1;
852                         int32_t* q = (int32_t*)src1;
853                         for(int i = 0; i < samples1; i++) {
854                                 data = q[i];
855                                 data <<= 16;
856                                 p[i] = EndianToLittle_DWORD(data);
857                         }
858                 }
859                 if((src2 != NULL) && (dst2 != NULL)) {
860                         uint32_t data;
861                         uint32_t* p = (uint32_t*)dst2;
862                         int32_t* q = (int32_t*)src2;
863                         for(int i = 0; i < samples2; i++) {
864                                 data = q[i];
865                                 data <<= 16;
866                                 p[i] = EndianToLittle_DWORD(data);
867                         }
868                 }
869                 break;
870         case AUDIO_S32MSB:
871                 if(src1 != NULL) {
872                         uint32_t data;
873                         uint32_t* p = (uint32_t*)dst1;
874                         int32_t* q = (int32_t*)src1;
875                         for(int i = 0; i < samples1; i++) {
876                                 data = q[i];
877                                 data <<= 16;
878                                 p[i] = EndianToBig_DWORD(data);
879                         }
880                 }
881                 if((src2 != NULL) && (dst2 != NULL)) {
882                         uint32_t* p = (uint32_t*)dst2;
883                         int32_t* q = (int32_t*)src2;
884                         uint32_t data;
885                         for(int i = 0; i < samples2; i++) {
886                                 data = q[i];
887                                 data <<= 16;
888                                 p[i] = EndianToBig_DWORD(data);
889                         }
890                 }
891                 break;
892         case AUDIO_F32LSB:
893                 if(src1 != NULL) {
894                         uint32_t* p = (uint32_t*)dst1;
895                         int32_t* q = (int32_t*)src1;
896                         for(int i = 0; i < samples1; i++) {
897                                 float_data.f = q[i];
898                                 float_data.f /= 65536;
899                                 p[i] = EndianToLittle_DWORD(float_data.d);
900                         }
901                 }
902                 if((src2 != NULL) && (dst2 != NULL)) {
903                         uint32_t* p = (uint32_t*)dst2;
904                         int32_t* q = (int32_t*)src2;
905                         for(int i = 0; i < samples2; i++) {
906                                 float_data.f = q[i];
907                                 float_data.f /= 65536;
908                                 p[i] = EndianToLittle_DWORD(float_data.d);
909                         }
910                 }
911                 break;
912         case AUDIO_F32MSB:
913                 if(src1 != NULL) {
914                         uint32_t* p = (uint32_t*)dst1;
915                         int32_t* q = (int32_t*)src1;
916                         for(int i = 0; i < samples1; i++) {
917                                 float_data.f = q[i];
918                                 float_data.f /= 65536;
919                                 p[i] = EndianToBig_DWORD(float_data.d);
920                         }
921                 }
922                 if((src2 != NULL) && (dst2 != NULL)) {
923                         uint32_t* p = (uint32_t*)dst2;
924                         int32_t* q = (int32_t*)src2;
925                         for(int i = 0; i < samples2; i++) {
926                                 float_data.f = q[i];
927                                 float_data.f /= 65536;
928                                 p[i] = EndianToBig_DWORD(float_data.d);
929                         }
930                 }
931                 break;
932         }
933 }
934 #if 0
935 void OSD_BASE::update_sound(int* extra_frames)
936 {
937         *extra_frames = 0;
938         
939         now_mute = false;
940         if(sound_ok) {
941                 uint32_t play_c, size1, size2;
942                 //uint32_t offset;
943                 uint8_t *ptr1, *ptr2;
944                 
945                 // start play
946                 // check current position
947                 play_c = sound_write_pos;
948                 if(sound_debug) debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_SOUND,
949                                                                                           "Called time=%d sound_write_pos=%d\n", osd_timer.elapsed(), play_c);
950                 if(!sound_first_half) {
951                         if((int)play_c < (sound_buffer_size / 2)) {
952                                 return;
953                         }
954                         //offset = 0;
955                 } else {
956                         if((int)play_c >= (sound_buffer_size / 2)) {
957                                 return;
958                         }
959                         //offset = sound_buffer_size / 2;
960                 }
961                 //SDL_UnlockAudio();
962                 // sound buffer must be updated
963                 Sint16* sound_buffer = (Sint16 *)this->create_sound(extra_frames);
964                 if(now_record_sound || now_record_video) {
965                         if(sound_samples > rec_sound_buffer_ptr) {
966                                 int samples = sound_samples - rec_sound_buffer_ptr;
967                                 int length = samples * sizeof(int16_t) * 2; // stereo
968                                 rec_sound_bytes += length;
969                                 if(now_record_video) {
970                                         //AGAR_DebugLog(AGAR_LOG_DEBUG, "Push Sound %d bytes\n", length);
971                                         emit sig_enqueue_audio((int16_t *)(&(sound_buffer[rec_sound_buffer_ptr * 2])), length);
972                                 }
973                                 // record sound
974                                 if(now_record_sound) {
975                                         rec_sound_fio->Fwrite(sound_buffer + rec_sound_buffer_ptr * 2, length, 1);
976                                 }
977                                 //if(now_record_video) {
978                                 //      // sync video recording
979                                 //      static double frames = 0;
980                                 //      static int prev_samples = -1;
981                                 //      static double prev_fps = -1;
982                                 //      double fps = this->vm_frame_rate();
983                                 //      frames = fps * (double)samples / (double)sound_rate;
984                                 //}
985                                 //printf("Wrote %d samples ptr=%d\n", samples, rec_sound_buffer_ptr);
986                                 rec_sound_buffer_ptr += samples;
987                                 if(rec_sound_buffer_ptr >= sound_samples) rec_sound_buffer_ptr = 0;
988                         }
989                 }
990                 if(sound_buffer) {
991                         int ssize;
992                         int pos;
993                         int pos2;
994                                 int format_len = 1;
995                         if(sound_initialized) {
996                                         switch(snddata.sound_format) {
997                                         case AUDIO_S16LSB:
998                                         case AUDIO_S16MSB:
999                                         case AUDIO_U16LSB:
1000                                         case AUDIO_U16MSB:
1001                                                 format_len = sizeof(int16_t);
1002                                                 break;
1003                                         case AUDIO_S32LSB:
1004                                         case AUDIO_S32MSB:
1005                                                 format_len = sizeof(int32_t);
1006                                                 break;
1007                                         case AUDIO_F32LSB:
1008                                         case AUDIO_F32MSB:
1009                                                 format_len = sizeof(float);
1010                                                 break;
1011                                         }
1012                                         ssize = sound_samples * snd_spec_presented.channels;
1013                                 pos = sound_data_pos;
1014                                 pos2 = pos + ssize;
1015                                 ptr1 = (uint8_t*)(&sound_buf_ptr[pos * format_len]);
1016                                 if(pos2 >= sound_buffer_size) {
1017                                                 size1 = sound_buffer_size  - pos;
1018                                                 size2 = pos2 - sound_buffer_size;
1019                                                 ptr2 = &sound_buf_ptr[0];
1020                                         } else {
1021                                                 size1 = ssize;
1022                                                 size2 = 0;
1023                                                 ptr2 = NULL;
1024                                         }
1025 #if defined(USE_SDL2)   
1026                                         SDL_LockAudioDevice(audio_dev_id);
1027 #else
1028                                         SDL_LockAudio();
1029 #endif
1030 #if 0
1031                                         if(ptr1) {
1032                                                 my_memcpy(ptr1, sound_buffer, size1 * format_len);
1033                                         }
1034                                         if((ptr2) && (size2 > 0)) {
1035                                                 my_memcpy(ptr2, &sound_buffer[size1], size2 * format_len);
1036                                         }
1037 #else
1038                                         convert_sound_format(ptr1, ptr2, sound_buffer, &sound_buffer[size1], size1, size2);
1039 #endif
1040
1041                                         sound_data_len = sound_data_len + ssize;
1042                                         if(sound_data_len >= sound_buffer_size) sound_data_len = sound_buffer_size;
1043                                         sound_data_pos = sound_data_pos + ssize;
1044                                         if(sound_data_pos >= sound_buffer_size) sound_data_pos = sound_data_pos - sound_buffer_size;
1045                                         if(!sound_started) sound_started = true;
1046 #if defined(USE_SDL2)   
1047                                         SDL_UnlockAudioDevice(audio_dev_id);
1048 #else
1049                                         SDL_UnlockAudio();
1050 #endif
1051                                         //SDL_UnlockAudio();
1052                                         SDL_PauseAudioDevice(audio_dev_id, 0);
1053                         }
1054                 }
1055            
1056 //              SDL_PauseAudioDevice(audio_dev_id, 0);
1057                 sound_first_half = !sound_first_half;
1058         }
1059 }
1060
1061 void OSD_BASE::mute_sound()
1062 {
1063         if(!now_mute && sound_ok) {
1064                 // check current position
1065                 uint32_t size1, size2;
1066             
1067                 uint8_t *ptr1, *ptr2;
1068                 // WIP
1069                 int ssize;
1070                 int pos;
1071                 int pos2;
1072 #if defined(USE_SDL2)   
1073                 SDL_LockAudioDevice(audio_dev_id);
1074 #else
1075                 SDL_LockAudio();
1076 #endif
1077                 int format_len = 1;
1078                 switch(snddata.sound_format) {
1079                 case AUDIO_S16LSB:
1080                 case AUDIO_S16MSB:
1081                 case AUDIO_U16LSB:
1082                 case AUDIO_U16MSB:
1083                         format_len = sizeof(int16_t);
1084                         break;
1085                 case AUDIO_S32LSB:
1086                 case AUDIO_S32MSB:
1087                         format_len = sizeof(int32_t);
1088                         break;
1089                 case AUDIO_F32LSB:
1090                 case AUDIO_F32MSB:
1091                         format_len = sizeof(float);
1092                         break;
1093                 }
1094                 ssize = sound_buffer_size / 2;
1095                 pos = sound_data_pos;
1096                 pos2 = pos + ssize;
1097                 ptr1 = &sound_buf_ptr[pos * format_len];
1098                 if(pos2 >= sound_buffer_size) {
1099                         size1 = sound_buffer_size - pos;
1100                         size2 = pos2 - sound_buffer_size;
1101                         ptr2 = &sound_buf_ptr[0];
1102                 } else {
1103                         size1 = ssize;
1104                         size2 = 0;
1105                         ptr2 = NULL;
1106                 }
1107                 
1108                 if(ptr1) {
1109                         memset(ptr1, 0x00, size1 * format_len);
1110                 }
1111                 if((ptr2) && (size2 > 0)){
1112                         memset(ptr2, 0x00, size2 * format_len);
1113                 }
1114                 sound_data_pos = (sound_data_pos + ssize) % sound_buffer_size;
1115 #if defined(USE_SDL2)   
1116                 SDL_UnlockAudioDevice(audio_dev_id);
1117 #else
1118                 SDL_UnlockAudio();
1119 #endif
1120         }
1121         now_mute = true;
1122 }
1123
1124 void OSD_BASE::stop_sound()
1125 {
1126         if(sound_ok && sound_started) {
1127                 //sound_exit = true;
1128 #if defined(USE_SDL2)   
1129                 SDL_PauseAudioDevice(audio_dev_id, 1);
1130 #else   
1131                 SDL_PauseAudio(1);
1132 #endif   
1133                 sound_started = false;
1134                 //sound_exit = false;
1135         }
1136 }
1137 void OSD_BASE::handleStateChanged(QAudio::State newState)
1138 {
1139 }
1140 #else
1141
1142 void OSD_BASE::handleStateChanged(QAudio::State newState)
1143 {
1144         switch(newState) {
1145         case QAudio::ActiveState:
1146                 debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND, _T("AUDIO:ACTIVE"));
1147                 break;
1148         case QAudio::IdleState:
1149                 debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND, _T("AUDIO:IDLE"));
1150                 //if(m_audioOutputSink != nullptr) {
1151                 //      m_audioOutputSink->stop();
1152                 //}
1153                 break;
1154         case QAudio::StoppedState:
1155 #if 0
1156                 if(m_audioOutput != nullptr) {
1157                         if(!(m_audioOutput->isOpen())) {
1158                                 m_audioOutput->close();
1159                         }
1160                         delete m_audioOutput;
1161                 }
1162                 if(m_audioOutputBuffer != nullptr) {
1163                         m_audioOutput = new QBuffer(m_audioOutInternalBuffer, this);
1164                         m_audioOutput->open(QIODeviceBase::ReadWrite);
1165                         m_audioOutput->reset();
1166                         m_audioOutput->close();
1167                 }
1168 #endif
1169                 //m_audioOutput = nullptr;
1170                 debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND, _T("AUDIO:STOP"));
1171                 break;
1172         case QAudio::SuspendedState:
1173                 debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND, _T("AUDIO:SUSPEND"));
1174                 break;
1175         }
1176 }
1177 void OSD_BASE::update_sound(int* extra_frames)
1178 {
1179         *extra_frames = 0;
1180         
1181         now_mute = false;
1182         if(sound_ok) {
1183                 //debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND, "Sink->bytesFree() = %d", m_audioOutputSink->bytesFree());
1184                 if(!sound_started) {
1185                         sound_started = true;
1186                         if(m_audioOutput != nullptr) {
1187                                 if(m_audioOutputSink->state() == QAudio::StoppedState) {
1188                                         m_audioOutput->reset();
1189                                         m_audioOutputSink->start(m_audioOutput);
1190                                 } else if(m_audioOutputSink->state() == QAudio::SuspendedState) {
1191                                         m_audioOutput->reset();
1192                                         m_audioOutputSink->resume();
1193                                 }
1194                         }
1195                         return;
1196                 }
1197                 
1198                 int now_mixed_ptr = 0;
1199                 if(vm != nullptr) {
1200                         now_mixed_ptr = vm->get_sound_buffer_ptr();
1201                 }
1202                 if(now_mixed_ptr < sound_samples) {
1203                         return;
1204                 }
1205                 // Input
1206                 int16_t* sound_buffer = (int16_t*)create_sound(extra_frames);
1207                 if(now_record_sound || now_record_video) {
1208                         if(sound_samples > rec_sound_buffer_ptr) {
1209                                 int samples = sound_samples - rec_sound_buffer_ptr;
1210                                 int length = samples * sizeof(int16_t) * 2; // stereo
1211                                 rec_sound_bytes += length;
1212                                 if(now_record_video) {
1213                                         //AGAR_DebugLog(AGAR_LOG_DEBUG, "Push Sound %d bytes\n", length);
1214                                         emit sig_enqueue_audio((int16_t *)(&(sound_buffer[rec_sound_buffer_ptr * 2])), length);
1215                                 }
1216                                 // record sound
1217                                 if(now_record_sound) {
1218                                         rec_sound_fio->Fwrite(sound_buffer + rec_sound_buffer_ptr * 2, length, 1);
1219                                 }
1220                                 //if(now_record_video) {
1221                                 //      // sync video recording
1222                                 //      static double frames = 0;
1223                                 //      static int prev_samples = -1;
1224                                 //      static double prev_fps = -1;
1225                                 //      double fps = this->vm_frame_rate();
1226                                 //      frames = fps * (double)samples / (double)sound_rate;
1227                                 //}
1228                                 //printf("Wrote %d samples ptr=%d\n", samples, rec_sound_buffer_ptr);
1229                                 rec_sound_buffer_ptr += samples;
1230                                 if(rec_sound_buffer_ptr >= sound_samples) rec_sound_buffer_ptr = 0;
1231                         }
1232                 }
1233                 //if(sound_initialized) return;
1234                 if(sound_buffer != nullptr) {
1235                         if(m_audioOutput != nullptr) {
1236                                 int wordsize = sizeof(int32_t);
1237                                 switch(m_audioOutputFormat.sampleFormat()) {
1238                                 case QAudioFormat::UInt8:
1239                                         wordsize = sizeof(uint8_t);
1240                                         break;
1241                                 case QAudioFormat::Int16:
1242                                         wordsize = sizeof(int16_t);
1243                                         break;
1244                                 case QAudioFormat::Int32:
1245                                         wordsize = sizeof(int32_t);
1246                                         break;
1247                                 case QAudioFormat::Float:
1248                                         wordsize = sizeof(float);
1249                                         break;
1250                                 }
1251                                 // ToDo: Not Int16.
1252                                 //qint64 sound_len = sound_samples * sound_rate * 2 * wordsize;
1253                                 qint64 sound_len = sound_samples * 2;
1254                                 qint64 written = 0;
1255                                 int _count = sound_samples * 2;
1256                                 if(m_audioOutputSink->state() != QAudio::ActiveState) {
1257                                         m_audioOutput->reset();
1258                                         if(m_audioOutputSink->state() == QAudio::SuspendedState) {
1259                                                 m_audioOutputSink->resume();
1260                                         }
1261                                 } 
1262                                 if(m_audioOutputSink->state() != QAudio::StoppedState) {
1263                                         double _ll = (double)(p_config->general_sound_level + INT16_MAX) / 65535.0;
1264                                         m_audioOutputSink->setVolume(_ll);
1265                                         qint64 _result = m_audioOutput->write((const char *)sound_buffer, _count * sizeof(int16_t));
1266                                 }
1267                                 //debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND, "write_to_buffer: desired=%d wrote=%d", _count * sizeof(int16_t), _result);
1268                                 //                      m_audioOutputSink->start(m_audioOutput);
1269
1270                                 //sound_data_len += _count;
1271                         }
1272                 }
1273         }
1274 }
1275
1276 void OSD_BASE::mute_sound()
1277 {
1278         if(!(now_mute) && (sound_ok)) {
1279                 if(m_audioOutputSink != nullptr) {
1280                         switch(m_audioOutputSink->state()) {
1281                         case QAudio::ActiveState:
1282                         case QAudio::IdleState:
1283                                 m_audioOutputSink->suspend();
1284                                 break;
1285                         default:
1286                                 break;
1287                         }
1288                         if(m_audioOutput != nullptr) {
1289                                 m_audioOutput->reset();
1290                         }
1291                         
1292                 }
1293         }
1294         now_mute = true;
1295 }
1296 void OSD_BASE::stop_sound()
1297 {
1298         if((sound_ok) && (sound_started)) {
1299                 if(m_audioOutputSink != nullptr) {
1300                         switch(m_audioOutputSink->state()) {
1301                         case QAudio::ActiveState:
1302                         case QAudio::IdleState:
1303                         case QAudio::SuspendedState:
1304                                 m_audioOutputSink->stop();
1305                                 break;
1306                         default:
1307                                 break;
1308                         }
1309                         if(m_audioOutput != nullptr) {
1310                                 m_audioOutput->reset();
1311                         }
1312                 }
1313         }
1314 }
1315
1316 #endif
1317 void OSD_BASE::start_record_sound()
1318 {
1319    
1320         if(!now_record_sound) {
1321                 //LockVM();
1322                 QDateTime nowTime = QDateTime::currentDateTime();
1323                 QString tmps = QString::fromUtf8("Sound_Save_emu");
1324                 tmps = tmps + get_vm_config_name();
1325                 tmps = tmps + QString::fromUtf8("_");
1326                 tmps = tmps + nowTime.toString(QString::fromUtf8("yyyy-MM-dd_hh-mm-ss.zzz"));
1327                 tmps = tmps + QString::fromUtf8(".wav");
1328                 strncpy((char *)sound_file_name, tmps.toLocal8Bit().constData(), sizeof(sound_file_name) - 1);
1329                 // create wave file
1330                 rec_sound_fio = new FILEIO();
1331                 if(rec_sound_fio->Fopen(bios_path(sound_file_name), FILEIO_WRITE_BINARY)) {
1332                         // write dummy wave header
1333                         write_dummy_wav_header((void *)rec_sound_fio);
1334                         
1335                         rec_sound_bytes = 0;
1336                         rec_sound_buffer_ptr = 0;
1337                         now_record_sound = true;
1338                 } else {
1339                         // failed to open the wave file
1340                         delete rec_sound_fio;
1341                 }
1342                 //UnlockVM();
1343         }
1344 }
1345
1346 void OSD_BASE::stop_record_sound()
1347 {
1348                 if(now_record_sound) {
1349                         //LockVM();
1350                 if(rec_sound_bytes == 0) {
1351                         rec_sound_fio->Fclose();
1352                         rec_sound_fio->RemoveFile(sound_file_name);
1353                 } else {
1354                         // update wave header
1355                         wav_header_t wav_header;
1356                         wav_chunk_t wav_chunk;
1357         #if 0           
1358                         if(!set_wav_header(&wav_header, &wav_chunk, 2, snd_spec_presented.freq, 16,
1359                                                          (size_t)(rec_sound_bytes + sizeof(wav_header) + sizeof(wav_chunk)))) {
1360         #else
1361                         if(!set_wav_header(&wav_header, &wav_chunk, 2, (uint32_t)(m_audioOutputFormat.sampleRate()), 16,
1362                                                          (size_t)(rec_sound_bytes + sizeof(wav_header) + sizeof(wav_chunk)))) {
1363         #endif
1364                                 delete rec_sound_fio;
1365                                 now_record_sound = false;
1366                                 return;
1367                         }
1368                         rec_sound_fio->Fseek(0, FILEIO_SEEK_SET);
1369                         rec_sound_fio->Fwrite(&wav_header, sizeof(wav_header_t), 1);
1370                         rec_sound_fio->Fwrite(&wav_chunk, sizeof(wav_chunk), 1);
1371                         rec_sound_fio->Fclose();
1372                 }
1373                 delete rec_sound_fio;
1374                 now_record_sound = false;
1375                 //UnlockVM();
1376         }
1377 }
1378
1379 void OSD_BASE::restart_record_sound()
1380 {
1381         bool tmp = now_record_sound;
1382         stop_record_sound();
1383         if(tmp) {
1384                 start_record_sound();
1385         }
1386 }
1387
1388 #if 0
1389 int OSD_BASE::get_sound_rate()
1390 {
1391         return snd_spec_presented.freq;
1392 }
1393 #else
1394 int OSD_BASE::get_sound_rate()
1395 {
1396         return (int)(m_audioOutputFormat.sampleRate());
1397 }
1398 #endif
1399
1400 void OSD_BASE::close_capture_sound_emu(int ch)
1401 {
1402         if(ch < 0) return;
1403         if(ch >= MAX_CAPTURE_SOUNDS) return;
1404         if(sound_capture_desc[ch].out_buffer != NULL) {
1405                 free(sound_capture_desc[ch].out_buffer);
1406         }
1407         sound_capture_desc[ch].out_buffer = NULL;
1408         sound_capturing_emu[ch] = false;
1409 }
1410
1411 void *OSD_BASE::get_capture_sound_buffer(int ch)
1412 {
1413         if(ch < 0) return NULL;
1414         if(ch >= MAX_CAPTURE_SOUNDS) return NULL;
1415         return sound_capture_desc[ch].out_buffer;
1416 }
1417
1418 bool OSD_BASE::is_capture_sound_buffer(int ch)
1419 {
1420         if(ch < 0) return false;
1421         if(ch >= MAX_CAPTURE_SOUNDS) return false;
1422         if(sound_capture_desc[ch].out_buffer == NULL) return false;
1423         return sound_capturing_emu[ch];
1424 }
1425 void *OSD_BASE::open_capture_sound_emu(int ch, int rate, int channels, int sample_type, int samples, int physical_device_num)
1426 {
1427         if(ch < 0) return NULL;
1428         if(ch >= MAX_CAPTURE_SOUNDS) return NULL;
1429         
1430         close_capture_sound_emu(ch);
1431         sound_capture_desc[ch].rate = rate;
1432         sound_capture_desc[ch].channels = channels;
1433         sound_capture_desc[ch].samples = samples;
1434         sound_capture_desc[ch].sample_type = sample_type;
1435         sound_capture_desc[ch].physical_dev = physical_device_num;
1436         bool stat = false;
1437         if((physical_device_num >= 0) && (physical_device_num < sound_capture_device_list.count()) && (physical_device_num < MAX_SOUND_CAPTURE_DEVICES)) {
1438                 if(!(capturing_sound[physical_device_num])) {
1439                         stat = open_sound_capture_device(physical_device_num, (rate < 44100) ? 44100 : rate, (channels > 2) ? channels : 2);
1440                 }
1441         }
1442         
1443         void *p = NULL;
1444         if(stat) {
1445                 switch(sample_type) {
1446                 case SAMPLE_TYPE_UINT8:
1447                 case SAMPLE_TYPE_SINT8:
1448                         p = malloc(sizeof(uint8_t) * channels * (samples + 100));
1449                         break;
1450                 case SAMPLE_TYPE_UINT16_BE:
1451                 case SAMPLE_TYPE_SINT16_BE:
1452                 case SAMPLE_TYPE_UINT16_LE:
1453                 case SAMPLE_TYPE_SINT16_LE:
1454                         p = malloc(sizeof(uint16_t) * channels * (samples + 100));
1455                         break;
1456                 case SAMPLE_TYPE_UINT32_BE:
1457                 case SAMPLE_TYPE_SINT32_BE:
1458                 case SAMPLE_TYPE_UINT32_LE:
1459                 case SAMPLE_TYPE_SINT32_LE:
1460                 p = malloc(sizeof(uint32_t) * channels * (samples + 100));
1461                 break;
1462                 case SAMPLE_TYPE_FLOAT_BE:
1463                 case SAMPLE_TYPE_FLOAT_LE:
1464                         p = malloc(sizeof(float) * channels * (samples + 100));
1465                         break;
1466                 }
1467         }
1468         sound_capture_desc[ch].out_buffer = (uint8_t *)p;
1469         sound_capturing_emu[ch] = true;
1470         return p;
1471 }
1472         
1473 bool OSD_BASE::open_sound_capture_device(int num, int req_rate, int req_channels)
1474 {
1475         if(num < 0) return false;
1476         if(num >= MAX_SOUND_CAPTURE_DEVICES) return false;
1477         if(sound_capture_device_list.count() <= num) return false;
1478         SDL_AudioSpec req;
1479         SDL_AudioSpec desired;
1480         req.freq = req_rate;
1481         req.channels = req_channels;
1482         req.silence = 0;
1483         req.format = AUDIO_S16SYS;
1484         req.samples = (sizeof(sound_capture_buffer[num]) / sizeof(int16_t)) / req_channels;
1485         req.callback = &(this->audio_capture_callback);
1486         req.userdata = (void *)(&(sound_capture_dev_desc[num].userdata));
1487         
1488         if(!(capturing_sound[num])) {
1489                 sound_capture_desc[num].physical_dev = SDL_OpenAudioDevice((const char *)sound_capture_device_list.value(num).toUtf8().constData(), 1, &req, &desired, SDL_AUDIO_ALLOW_FORMAT_CHANGE);
1490                 if(sound_capture_desc[num].physical_dev <= 0) {
1491                         debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND,"Failed to initialize sound capture device \"%s\"\n", (const char *)sound_capture_device_list.value(num).toUtf8().constData());
1492                         sound_capture_desc[num].physical_dev = -1;
1493                         return false;
1494                 }
1495                 // Device OK
1496                 capturing_sound[num] = true;
1497                 sound_capture_dev_desc[num].format = desired.format;
1498                 sound_capture_dev_desc[num].sample_rate = desired.freq;
1499                 sound_capture_dev_desc[num].channels = desired.channels;
1500                 sound_capture_dev_desc[num].buffer_samples = desired.samples;
1501                 sound_capture_dev_desc[num].size = desired.size;
1502                 sound_capture_dev_desc[num].callback = desired.callback;
1503                 sound_capture_dev_desc[num].silence = desired.silence;
1504                 int buflen = desired.samples * desired.channels;
1505                 switch(desired.format) {
1506                 case AUDIO_S8:
1507                 case AUDIO_U8:
1508                         buflen = buflen * sizeof(int8_t);
1509                         break;
1510                 case AUDIO_S16LSB:
1511                 case AUDIO_S16MSB:
1512                 case AUDIO_U16LSB:
1513                 case AUDIO_U16MSB:
1514                         buflen = buflen * sizeof(int16_t);
1515                         break;
1516                 case AUDIO_S32LSB:
1517                 case AUDIO_S32MSB:
1518                         buflen = buflen * sizeof(int32_t);
1519                         break;
1520                 case AUDIO_F32LSB:
1521                 case AUDIO_F32MSB:
1522                         buflen = buflen * sizeof(float);
1523                         break;
1524                 default:
1525                         break;
1526                 }
1527                 
1528                 sound_capture_dev_desc[num].userdata.buffer_size = buflen;
1529                 sound_capture_dev_desc[num].userdata.format = desired.format;
1530                 sound_capture_dev_desc[num].userdata.readlen = 0;
1531                 sound_capture_dev_desc[num].userdata.writelen = 0;
1532                 sound_capture_dev_desc[num].userdata.readpos = 0;
1533                 sound_capture_dev_desc[num].userdata.writepos = 0;
1534                 sound_capture_dev_desc[num].userdata.read_buffer_ptr = &(sound_capture_buffer[num][0]);
1535                 memset(&(sound_capture_buffer[num][0]), 0x00, buflen);
1536                 
1537                 for(int ch = 0; ch < MAX_SOUND_CAPTURE_DEVICES; ch++) {
1538                         if(sound_capture_desc[ch].physical_dev == num) {
1539                                 sound_capture_desc[ch].read_format = desired.format;
1540                                 sound_capture_desc[ch].read_rate = desired.freq;
1541                                 sound_capture_desc[ch].read_silence = desired.silence;
1542                                 sound_capture_desc[ch].read_size = desired.size;
1543                                 sound_capture_desc[ch].read_channels = desired.channels;
1544                                 sound_capture_desc[ch].read_samples = desired.samples;
1545                                 sound_capture_desc[ch].read_callback = desired.callback;
1546                                 sound_capture_desc[ch].read_userdata = desired.userdata;
1547                                 
1548                                 sound_capture_desc[ch].read_pos = 0;
1549                                 sound_capture_desc[ch].read_data_len = 0;
1550                                 sound_capture_desc[ch].read_buffer_len = buflen;
1551                                 sound_capture_desc[ch].read_buffer_ptr = (uint8_t *)(&(sound_capture_buffer[num][0]));
1552
1553                                 
1554                         }                               
1555                 }
1556         }
1557         return true;
1558 }
1559
1560 bool OSD_BASE::close_sound_capture_device(int num, bool force)
1561 {
1562         // ToDo: Check capturing entries
1563         if((capturing_sound[num]) && (sound_capture_desc[num].physical_dev > 0)) {
1564                 SDL_CloseAudioDevice(sound_capture_desc[num].physical_dev);
1565         }
1566         return true;
1567 }