OSDN Git Service

[SOUND][Qt] (Maybe) Fix jitters at new driver.
[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 "gui/menu_flags.h"
38
39 #include <QDateTime>
40 #include <QByteArray>
41
42 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
43 #include <QApplication>
44 #endif
45
46 #include <cstdint>
47
48 #include "./sound-drivers/sound_buffer_qt.h"
49 #include "./sound-drivers/osd_sound_mod_template.h"
50
51 #include "../gui/emu_thread_tmpl.h"
52
53 int OSD_BASE::get_sound_device_num()
54 {
55         return sound_device_list.count();
56 }
57 /* SDL DRIVER: Temporally disabled */
58 #if 0
59 void OSD_BASE::audio_capture_callback(void *udata, Uint8 *stream, int len)
60 {
61         if(len <= 0) return;
62         if(udata == NULL) return;
63         if(stream == NULL) return;
64         int len2, len3;
65         osd_snddata_capture_t *pData = (osd_snddata_capture_t *)udata;
66
67         if(pData->read_buffer_ptr == NULL) return;
68         if((pData->writepos + len) >= pData->buffer_size) {
69                 // Need Wrap
70                 len2 = pData->buffer_size - pData->writepos;
71                 if(len2 > len) len2 = len;
72                 memset(&(pData->read_buffer_ptr[pData->writepos]), 0x00, len2);
73                 memcpy(&(pData->read_buffer_ptr[pData->writepos]), stream, len2);
74                 len3 = len - len2;
75                 if(len3 > 0) {
76                         memset(&(pData->read_buffer_ptr[0]), 0x00, len3);
77                         memcpy(&(pData->read_buffer_ptr[0]), &(stream[len2]), len3);
78                 }
79         } else {
80                 // Not need to wrap
81                 memset(&(pData->read_buffer_ptr[pData->writepos]), 0x00, len);
82                 memcpy(&(pData->read_buffer_ptr[pData->writepos]), stream, len);
83         }
84         pData->writepos += len;
85         if(pData->writepos >= pData->buffer_size) {
86                 pData->writepos -= pData->buffer_size;
87         }
88         pData->writelen += len;
89         if(pData->writelen >= pData->buffer_size) {
90                 pData->writelen = pData->buffer_size;
91         }
92 }
93
94
95 void OSD_BASE::audio_callback(void *udata, Uint8 *stream, int len)
96 {
97         if(len <= 0) return;
98         if(udata == NULL) return;
99         if(stream == NULL) return;
100         int len2, len3;
101         sdl_snddata_t *pData = (sdl_snddata_t *)udata;
102         int sndlen, sndpos, bufsize;
103         int spos = 0;
104         int format_len = 1;
105         
106         len3 = len;
107         memset(stream, 0x00, len);
108         switch(pData->sound_format) {
109         case AUDIO_S16LSB:
110         case AUDIO_S16MSB:
111         case AUDIO_U16LSB:
112         case AUDIO_U16MSB:
113                 format_len = sizeof(int16_t);
114                 break;
115         case AUDIO_S32LSB:
116         case AUDIO_S32MSB:
117                 format_len = sizeof(int32_t);
118                 break;
119         case AUDIO_F32LSB:
120         case AUDIO_F32MSB:
121                 format_len = sizeof(float);
122                 break;
123         }
124         
125         
126         if(pData->p_config->general_sound_level < INT16_MIN) pData->p_config->general_sound_level = INT16_MIN;
127         if(pData->p_config->general_sound_level > INT16_MAX)  pData->p_config->general_sound_level = INT16_MAX;
128         *pData->snd_total_volume = (uint8_t)(((uint32_t)(pData->p_config->general_sound_level + (-INT16_MIN))) >> 9);
129                 
130         do {
131                 sndlen = *(pData->sound_data_len);
132                 bufsize = *(pData->sound_buffer_size);
133                 sndpos = *(pData->sound_write_pos);
134                 if(*pData->sound_exit) {
135                         return;
136                 }
137                 
138                 sndpos = sndpos * format_len;
139                 sndlen = sndlen * format_len; // ToDo: Multiple format
140                 bufsize = bufsize * format_len; // ToDo: Multiple format
141                 
142                 if(sndlen >= len) sndlen = len;
143                 if((sndpos + sndlen) >= bufsize) { // Need to wrap
144                         int len2 = bufsize - sndpos;
145                         uint8_t* p = (uint8_t *)(*pData->sound_buf_ptr);
146                         uint8_t* s = &stream[spos];
147                         p = &p[sndpos];
148 #if defined(USE_SDL2)
149                         SDL_MixAudioFormat(s, p, pData->sound_format, len2, *(pData->snd_total_volume));
150 #else
151                         SDL_MixAudio(s, p, len2, *(pData->snd_total_volume));
152 #endif
153                         spos += len2;
154                         len2 = sndlen - len2;
155                         s = &stream[spos];
156                         *(pData->sound_write_pos) = 0;
157                         if(len2 > 0) {
158                                 p = (uint8_t *)(*pData->sound_buf_ptr);
159                                 p = &p[0];
160 #if defined(USE_SDL2)
161                                 SDL_MixAudioFormat(s, p, pData->sound_format, len2, *(pData->snd_total_volume));
162 #else
163                                 SDL_MixAudio(s, p, len2, *(pData->snd_total_volume));
164 #endif
165                                 *(pData->sound_write_pos) = (len2 / format_len);
166                                 if(*(pData->sound_buffer_size) <= *(pData->sound_write_pos)) {
167                                         *(pData->sound_write_pos) = 0;
168                                 }
169                                 sndpos = len2;
170                                 spos += len2;
171                                 len2 = 0;
172                         }
173                         len -= sndlen;
174                 } else { // No Need to wrap
175                         int len2 = sndlen;
176                         uint8_t* p = (uint8_t *)(*pData->sound_buf_ptr);
177                         uint8_t* s = &stream[spos];
178                         p = &p[sndpos];
179 #if defined(USE_SDL2)
180                         SDL_MixAudioFormat(s, p, pData->sound_format, len2, *(pData->snd_total_volume));
181 #else
182                         SDL_MixAudio(s, p, len2, *(pData->snd_total_volume));
183 #endif
184                         *(pData->sound_write_pos) += (len2 / format_len); 
185                         if(*(pData->sound_buffer_size) <= *(pData->sound_write_pos)) {
186                                 *(pData->sound_write_pos) = 0;
187                         }
188                         spos += len2;
189                         len -= sndlen;
190                 }
191                 *(pData->sound_data_len)  -= (sndlen / format_len);
192                 if(*(pData->sound_data_len) <= 0) return;
193                 if(spos >= len3) return;
194                 // WIP: Do place wait (1ms)?
195         } while(len > 0);
196 }
197
198
199 const _TCHAR *OSD_BASE::get_sound_device_name(int num)
200 {
201         if(num < 0) return NULL;
202         if(num >= sound_device_list.count()) return NULL;
203         QString sdev = sound_device_list.at(num);
204         sdev.truncate(1023);
205         static QByteArray _n;
206         _n.clear();
207         _n = sdev.toUtf8().constData();
208
209         return (const _TCHAR*)(_n.constData());
210 }
211
212 void OSD_BASE::init_sound_device_list()
213 {
214         sound_device_list.clear();
215 #if defined(USE_SDL2)
216         const _TCHAR* drvname = SDL_GetCurrentAudioDriver();
217         if(drvname == nullptr) return;
218         debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND, "Using Sound Driver: %s\n", drvname);
219         for(int i = 0; i < SDL_GetNumAudioDevices(0); i++) {
220                 QString tmps = QString::fromUtf8(SDL_GetAudioDeviceName(i, 0));
221                 debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND,
222                                   "Audio Device #%d: %s", i, tmps.toLocal8Bit().constData());
223                 sound_device_list.append(tmps);
224         }
225 #endif
226 }
227
228 void OSD_BASE::initialize_sound(int rate, int samples, int* presented_rate, int* presented_samples)
229 {
230         std::string devname;
231         int i;
232
233         bool pre_initialized = sound_initialized;
234         if(sound_initialized) {
235                 release_sound();
236         }
237
238         sound_capture_device_list.clear();
239         #if 0
240         for(int ch = 0 ; ch < MAX_CAPTURE_SOUND; ch++) {
241                 // ToDo: Allocation.
242                 // ToDo: Close physical device.
243                 if(!pre_initialized) {
244                         sound_capturing_emu[ch] = false;
245                         
246                         sound_capture_desc[ch].physical_dev = 0;
247                         sound_capture_desc[ch].read_format = AUDIO_S16SYS;
248                         sound_capture_desc[ch].read_rate = 0;
249                         sound_capture_desc[ch].read_channels = 0;
250                         sound_capture_desc[ch].read_samples = 0;
251                         sound_capture_desc[ch].read_silence = 0;
252                         sound_capture_desc[ch].read_size = 0;
253                         sound_capture_desc[ch].read_userdata = NULL;
254                         sound_capture_desc[ch].sample_type = 0; // ToDo : ENUM
255                         sound_capture_desc[ch].rate = 0;
256                         sound_capture_desc[ch].channels = 0;
257                         sound_capture_desc[ch].samples = 0;
258                         sound_capture_desc[ch].write_size = 0;
259                         sound_capture_desc[ch].write_pos = 0;
260                         sound_capture_desc[ch].read_data_len = 0;
261                         sound_capture_desc[ch].read_buffer_len = 0;
262                         sound_capture_desc[ch].read_buffer_ptr = NULL;
263                         sound_capture_desc[ch].out_buffer = NULL;
264                 }
265         }
266         for(int num = 0 ; num < MAX_SOUND_CAPTURE_DEVICES; num++) {
267                 sound_capture_dev_desc[num].format = AUDIO_S16SYS;
268                 sound_capture_dev_desc[num].sample_rate = 0;
269                 sound_capture_dev_desc[num].channels = 0;
270                 sound_capture_dev_desc[num].buffer_samples = 0;
271                 sound_capture_dev_desc[num].silence = 0;
272                 sound_capture_dev_desc[num].size = 0;
273                 sound_capture_dev_desc[num].callback = audio_capture_callback;
274                 sound_capture_dev_desc[num].userdata.format = AUDIO_S16SYS;
275                 sound_capture_dev_desc[num].userdata.buffer_size = 0;
276                 sound_capture_dev_desc[num].userdata.readlen = 0;
277                 sound_capture_dev_desc[num].userdata.writelen = 0;
278                 sound_capture_dev_desc[num].userdata.readpos = 0;
279                 sound_capture_dev_desc[num].userdata.read_buffer_ptr = NULL;
280                 capturing_sound[num] = false;
281         }
282         #endif
283         
284         sound_rate = rate;
285         sound_samples = samples;
286         rec_sound_buffer_ptr = 0;
287         sound_ok = sound_started = now_mute = now_record_sound = false;
288         sound_write_pos = 0;
289         sound_data_len = 0;
290         sound_buffer_size = 0;
291         sound_data_pos = 0;
292         sound_exit = false;
293         sound_debug = false;
294         //sound_debug = true;
295         sound_buf_ptr = NULL;
296         sound_initialized = false;
297         // initialize direct sound
298         
299         snd_total_volume = 127;
300    
301         snddata.sound_buf_ptr = (uint8_t**)(&sound_buf_ptr);
302         snddata.sound_buffer_size = &sound_buffer_size;
303         snddata.sound_write_pos = &sound_write_pos;
304         snddata.sound_data_len = &sound_data_len;
305         snddata.snd_total_volume = &snd_total_volume;
306         snddata.sound_exit = &sound_exit;
307         snddata.sound_debug = &sound_debug;
308         snddata.p_config = p_config;
309         
310         snd_spec_req.format = AUDIO_S16SYS;
311         snd_spec_req.channels = 2;
312         snd_spec_req.freq = sound_rate;
313         //snd_spec_req.samples = ((sound_rate * 100) / 1000);
314         snd_spec_req.samples = samples;
315         snd_spec_req.callback = &(this->audio_callback);
316         snd_spec_req.userdata = (void *)&snddata;
317         #if defined(USE_SDL2)
318         audio_dev_id = 0;
319         if(!(sound_device_list.isEmpty())) {
320                 QString sdev;
321                 if(p_config->sound_device_num >= sound_device_list.count()) {
322                         p_config->sound_device_num = sound_device_list.count() - 1;
323                 }
324                 if(p_config->sound_device_num <= 0) {
325                         p_config->sound_device_num = 0;
326                 }
327                 sdev = sound_device_list.at(p_config->sound_device_num);
328                 audio_dev_id = SDL_OpenAudioDevice(sdev.toUtf8().constData(), 0,
329                                                                                    &snd_spec_req, &snd_spec_presented,
330                                                                                    0);
331                 debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND, "Try to open DEVICE #%d: %s -> %s: DEVID=%d\n",
332                                   p_config->sound_device_num, sdev.toUtf8().constData(), (audio_dev_id <= 0) ? "FAIL" : "SUCCESS", audio_dev_id);
333         } else {
334                 audio_dev_id = SDL_OpenAudioDevice("", 0,
335                                                                                    &snd_spec_req, &snd_spec_presented,
336                                                                                    0);
337                 debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND, "Try to open DEVICE #%d:  %s: DEVID=%d\n",
338                                   p_config->sound_device_num, (audio_dev_id <= 0) ? "FAIL" : "SUCCESS", audio_dev_id);
339
340         }
341         #else
342         audio_dev_id = 1;
343         SDL_OpenAudio(&snd_spec_req, &snd_spec_presented);
344         #endif
345
346         #if defined(USE_SDL2)
347         if(audio_dev_id <= 0) {
348                 debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND,"Failed to initialize sound\n");
349                 if(presented_rate != NULL) {
350                         *presented_rate = sound_rate;
351                 }
352                 if(presented_samples != NULL) {
353                         *presented_samples = sound_samples;
354                 }
355                 sound_initialized = false;
356                 sound_ok = sound_first_half = false;
357                 return;
358         }
359         #endif
360         snddata.sound_format = snd_spec_presented.format;
361         if((snd_spec_presented.freq != sound_rate) ||
362            (snd_spec_presented.samples != sound_samples)) { // DEINI
363                 sound_rate = snd_spec_presented.freq;
364                 sound_samples = snd_spec_presented.samples;
365         }
366         debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND,"Sample rate=%d samples=%d\n", sound_rate, sound_samples);
367         if(presented_rate != NULL) {
368                 *presented_rate = sound_rate;
369         }
370         if(presented_samples != NULL) {
371                 *presented_samples = sound_samples;
372         }
373         // secondary buffer
374         int format_len = 1;
375         switch(snddata.sound_format) {
376         case AUDIO_S16LSB:
377         case AUDIO_S16MSB:
378         case AUDIO_U16LSB:
379         case AUDIO_U16MSB:
380                 format_len = sizeof(int16_t);
381                 break;
382         case AUDIO_S32LSB:
383         case AUDIO_S32MSB:
384                 format_len = sizeof(int32_t);
385                 break;
386         case AUDIO_F32LSB:
387         case AUDIO_F32MSB:
388                 format_len = sizeof(float);
389                 break;
390         }
391         sound_buffer_size = sound_samples * snd_spec_presented.channels * 2;
392         sound_buf_ptr = (uint8_t *)malloc(sound_buffer_size * format_len); 
393         if(sound_buf_ptr == NULL) {
394         #if defined(USE_SDL2)              
395                 SDL_CloseAudioDevice(audio_dev_id);
396         #else      
397                 SDL_CloseAudio();
398         #endif     
399                 return;
400         }
401
402         debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND,
403                                                   "Sound OK: BufSize = %d", sound_buffer_size);
404         memset(sound_buf_ptr, 0x00, sound_buffer_size * format_len);
405         sound_initialized = true;
406         sound_ok = sound_first_half = true;
407 }
408
409 void OSD_BASE::release_sound()
410 {
411         // release SDL sound
412         sound_exit = true;
413         sound_initialized = false;
414         #if 0
415         for(int num = 0; num < MAX_SOUND_CAPTURE_DEVICES; num++) {
416                 if(capturing_sound[num]) {
417                         close_sound_capture_device(num, true);
418                 }
419         }
420         // ToDo: Reopen
421         for(int ch = 0; ch < MAX_CAPTURE_SOUNDS; ch++) {
422                 if(sound_capturing_emu[ch]) {
423                         close_capture_sound_emu(ch);
424                 }
425         }
426         #endif
427         #if defined(USE_SDL2)   
428         //SDL_PauseAudioDevice(audio_dev_id, 1);
429         SDL_CloseAudioDevice(audio_dev_id);
430         #else   
431         SDL_CloseAudio();
432         #endif   
433         stop_record_sound();
434         if(sound_buf_ptr != NULL) free(sound_buf_ptr);
435         sound_buf_ptr = NULL;
436         // stop recording
437 }
438 /* END SDL DRIVER: Temporally disabled */
439 #endif
440
441 /* Note: Below are new sound driver. */
442 #include "./sound-drivers/qt_multimedia/osd_sound_mod_qtmultimedia.h"
443 void OSD_BASE::update_sound(int* extra_frames)
444 {
445         *extra_frames = 0;
446         
447         now_mute = false;
448         if(sound_initialized) {
449                 // Get sound driver 
450                 std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
451                 __UNLIKELY_IF(sound_drv.get() == nullptr) {
452                         // ToDo: Fix delay.
453                         sound_ok = false;
454                         return;
455                 }
456                 __UNLIKELY_IF(!(sound_drv->is_driver_started())) {
457                         // ToDo: Fix delay.
458                         __LIKELY_IF(!(sound_ok)) {
459                                 sound_drv->start();
460                                 __UNLIKELY_IF(p_config != nullptr) {
461                                         sound_drv->set_volume((int)(p_config->general_sound_level));
462                                 }
463                         }
464                         sound_ok = true;
465                         return;
466                 }
467
468                 // Check enough to render accumlated
469                 // source (= by VM) rendering data.
470                 int64_t sound_samples = sound_drv->get_sample_count();
471                 __UNLIKELY_IF(sound_samples <= 0) {
472                         return;
473                 }
474                 int _channels = sound_drv->get_channels();
475                 size_t word_size = sound_drv->get_word_size();
476                 int64_t _left = sound_drv->get_bytes_left();
477                 // Pass 1: Check available to write.
478                 __UNLIKELY_IF((_channels <= 0) || (word_size == 0)) {
479                         return;
480                 }
481                 if(_left < (sound_samples * (int64_t)(word_size * _channels))) {
482                         return;
483                 }
484                 // Pass 2: Check elapsed time.
485                 int64_t latency_us    = sound_drv->get_latency_ms() * 1000;
486                 int64_t elapsed_usec = sound_drv->driver_elapsed_usec() % (latency_us * 2);
487                 //int64_t processed_usec = sound_drv->driver_processed_usec() % (latency_us * 2);
488                 switch(m_sound_period) {
489                 case 0:
490                         if(elapsed_usec > latency_us) {
491                                 return;
492                         }
493                         break;
494                 case 1:
495                         if(elapsed_usec < latency_us) {
496                                 return;
497                         }
498                         break;
499                 }
500                 int16_t* sound_buffer = (int16_t*)create_sound(extra_frames);
501                 if(sound_buffer == nullptr) {
502                         return;
503                 }
504                 if(now_record_sound || now_record_video) {
505                         if(sound_samples > rec_sound_buffer_ptr) {
506                                 int samples = sound_samples - rec_sound_buffer_ptr;
507                                 int length = samples * sizeof(int16_t) * 2; // stereo
508                                 rec_sound_bytes += length;
509                                 if(now_record_video) {
510                                         //AGAR_DebugLog(AGAR_LOG_DEBUG, "Push Sound %d bytes\n", length);
511                                         emit sig_enqueue_audio((int16_t *)(&(sound_buffer[rec_sound_buffer_ptr * 2])), length);
512                                 }
513                                 // record sound
514                                 if(now_record_sound) {
515                                         rec_sound_fio->Fwrite(sound_buffer + rec_sound_buffer_ptr * 2, length, 1);
516                                 }
517                                 //if(now_record_video) {
518                                 //      // sync video recording
519                                 //      static double frames = 0;
520                                 //      static int prev_samples = -1;
521                                 //      static double prev_fps = -1;
522                                 //      double fps = this->vm_frame_rate();
523                                 //      frames = fps * (double)samples / (double)sound_rate;
524                                 //}
525                                 //printf("Wrote %d samples ptr=%d\n", samples, rec_sound_buffer_ptr);
526                                 rec_sound_buffer_ptr += samples;
527                                 if(rec_sound_buffer_ptr >= sound_samples) rec_sound_buffer_ptr = 0;
528                         }
529                 }
530                 // ToDo: Convert sound format.
531                 if(sound_drv.get() != nullptr) {
532                         int64_t _result = 0;
533                         _result = sound_drv->update_sound((void*)sound_buffer, sound_samples);
534                         if(_result > 0) {
535                                 m_sound_period = (m_sound_period + 1) % 2;
536                                 //printf("%d %ld\n", m_sound_period, _result);
537                         }
538                 }
539         }
540 }
541
542 void OSD_BASE::initialize_sound(int rate, int samples, int* presented_rate, int* presented_samples)
543 {
544         // If sound driver hasn't initialized, initialize.
545         if(m_sound_driver.get() == nullptr) {
546                 m_sound_driver.reset(
547                         new SOUND_MODULE::OUTPUT::M_QT_MULTIMEDIA(this,
548                                                                                                          nullptr,
549                                                                                                          rate,
550                                                                                                          (samples * 1000) / rate,
551                                                                                                          2,
552                                                                                                          nullptr,
553                                                                                                          0));
554                 init_sound_device_list();
555                 emit sig_update_sound_output_list();
556                 if(p_config != nullptr) {
557                         m_sound_driver->set_volume((int)(p_config->general_sound_level));
558                 }
559         }
560         std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
561         
562         debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_SOUND,
563                           "OSD::%s rate=%d samples=%d m_sound_driver=%llx", __func__, rate, samples, (uintptr_t)(sound_drv.get()));
564         if(sound_drv.get() != nullptr) {
565                 sound_drv->initialize_sound(rate, samples, presented_rate, presented_samples);
566                 //sound_drv->update_render_point_usec();
567                 m_sound_period = 0;
568                 sound_initialized = true;
569                 sound_ok = false;
570         }
571 }
572 void OSD_BASE::release_sound()
573 {
574         // ToDo: Sound Input
575         // release Qt Multimedia sound
576         sound_exit = true;
577         sound_initialized = false;
578         sound_ok = false;
579         
580         std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
581         if(sound_drv.get() != nullptr) {
582                 //sound_drv->update_render_point_usec();
583                 sound_drv->release_sound();
584         }
585         m_sound_period = 0;
586         
587 }
588
589 void OSD_BASE::do_update_master_volume(int level)
590 {
591         emit sig_set_sound_volume(level);
592 }
593
594 void OSD_BASE::do_set_host_sound_output_device(QString device_name)
595 {
596         if(device_name.isEmpty()) return;
597         emit sig_set_sound_device(device_name);
598 }
599
600 const _TCHAR *OSD_BASE::get_sound_device_name(int num)
601 {
602         std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
603         if(sound_drv.get() != nullptr) {
604                 return sound_drv->get_sound_device_name(num);
605         }
606         return (const _TCHAR *)nullptr;
607 }
608
609 void OSD_BASE::init_sound_device_list()
610 {
611         std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
612         sound_device_list.clear();
613         if(sound_drv.get() != nullptr) {
614                 std::list<std::string> _l = sound_drv->get_sound_devices_list();
615                 int _xi = 1;
616                 for(auto s = _l.begin(); s != _l.end(); ++s) {
617                         sound_device_list.append(QString::fromStdString(*s));
618                         debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_SOUND,
619                                           "SOUND DEVICE#%03d %s", _xi, (*s).c_str());
620                         _xi++;
621                 }
622         }
623 }
624 void OSD_BASE::mute_sound()
625 {
626         if(!now_mute && sound_ok) {
627                 std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
628                 if(sound_drv.get() != nullptr) {
629                         sound_drv->mute_sound();
630                 }
631                 now_mute = true;
632         }
633 }
634 void OSD_BASE::stop_sound()
635 {
636         std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
637         if(sound_drv.get() != nullptr) {
638                 if(sound_ok && sound_drv->is_driver_started()) {
639                         sound_drv->stop_sound();
640                         m_sound_period = 0;
641                 }
642         }
643         //sound_initialized = false;
644         sound_ok = false;
645 }
646
647 int OSD_BASE::get_sound_rate()
648 {
649         std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>sound_drv = m_sound_driver;
650         if(sound_drv.get() != nullptr) {
651                 return sound_drv->get_sample_rate();
652         }
653         return 0;
654 }
655 /* End Note: */
656
657 /* SDL DRIVER: Temporally disabled */
658 #if 0
659 void OSD_BASE::convert_sound_format(uint8_t* dst1, uint8_t* dst2, int16_t* src1, int16_t* src2, int samples1, int samples2)
660 {
661         if(dst1 == NULL) return;
662         if(snddata.sound_format == AUDIO_S16SYS) { // Not Convert
663                 if((src1 != NULL) && (samples1 > 0)) {
664                         my_memcpy(dst1, src1, samples1 * sizeof(int16_t));
665                 }
666                 if((src2 != NULL) && (samples2 > 0) && (dst2 != NULL)) {
667                         my_memcpy(dst2, src2, samples2 * sizeof(int16_t));
668                 }
669                 return;
670         }
671
672         union {
673 #if defined(__LITTLE_ENDIAN__)
674                 uint8_t l, h, h1, h2;
675 #else           
676                 uint8_t h2, h1, h, l;
677 #endif
678                 float f;
679                 uint32_t d;
680         } float_data;
681         
682         switch(snddata.sound_format) {
683                 // S16SYS
684         case AUDIO_S8:
685                 if(src1 != NULL) {
686                         int16_t *q = (int16_t*)src1;
687                         int8_t* p = (int8_t*)dst1;
688                         int dat;
689                         for(int i = 0; i < samples1; i++) {
690                                 dat = q[i];
691                                 dat >>= 8;
692                                 p[i] = dat;
693                         }
694                 }
695                 if((src2 != NULL) && (dst2 != NULL)) {
696                         int16_t *q = (int16_t*)src2;
697                         int8_t* p = (int8_t*)dst2;
698                         int dat;
699                         for(int i = 0; i < samples2; i++) {
700                                 dat = q[i];
701                                 dat >>= 8;
702                                 p[i] = dat;
703                         }
704                 }
705                 break;
706         case AUDIO_U8:
707                 if(src1 != NULL) {
708                         int16_t *q = (int16_t*)src1;
709                         uint8_t* p = (uint8_t*)dst1;
710                         int dat;
711                         for(int i = 0; i < samples1; i++) {
712                                 dat = q[i];
713                                 dat += 32768;
714                                 dat >>= 8;
715                                 p[i] = dat;
716                         }
717                 }
718                 if((src2 != NULL) && (dst2 != NULL)) {
719                         int16_t *q = (int16_t*)src2;
720                         uint8_t* p = (uint8_t*)dst2;
721                         int dat;
722                         for(int i = 0; i < samples2; i++) {
723                                 dat = q[i];
724                                 dat += 32768;
725                                 dat >>= 8;
726                                 p[i] = dat;
727                         }
728                 }
729                 break;
730         case AUDIO_S16LSB:
731                 if(src1 != NULL) {
732                         int16_t *q = (int16_t*)src1;
733                         int16_t* p = (int16_t*)dst1;
734                         pair16_t dat;
735                         for(int i = 0; i < samples1; i++) {
736                                 dat.sw = q[i];
737 #if defined(__LITTLE_ENDIAN__)
738                                 p[i] = dat.sw;
739 #else
740                                 p[i] = dat.get_2bytes_le_to();
741 #endif
742                         }
743                 }
744                 if((src2 != NULL) && (dst2 != NULL)) {
745                         int16_t* q = (int16_t*)src2;
746                         int16_t* p = (int16_t*)dst2;
747                         pair16_t dat;
748                         for(int i = 0; i < samples2; i++) {
749                                 dat.sw = q[i];
750 #if defined(__LITTLE_ENDIAN__)
751                                 p[i] = dat.sw;
752 #else
753                                 p[i] = dat.get_2bytes_le_to();
754 #endif
755                         }
756                 }
757                 break;
758         case AUDIO_U16LSB:
759                 if(src1 != NULL) {
760                         int16_t* q = (int16_t*)src1;
761                         uint16_t* p = (uint16_t*)dst1;
762                         pair16_t dat;
763                         int32_t d2;
764                         for(int i = 0; i < samples1; i++) {
765                                 d2 = q[i];
766                                 d2 = d2 + 32768;
767 #if defined(__LITTLE_ENDIAN__)
768                                 p[i] = d2 & 0xffff;
769 #else
770                                 dat.w = d2 & 0xffff;
771                                 p[i] = dat.get_2bytes_le_to();
772 #endif
773                         }
774                 }
775                 if((src2 != NULL) && (dst2 != NULL)) {
776                         int16_t* q = (int16_t*)src2;
777                         uint16_t* p = (uint16_t*)dst2;
778                         pair16_t dat;
779                         int d2;
780                         for(int i = 0; i < samples2; i++) {
781                                 d2 = q[i];
782                                 d2 = d2 + 32768;
783 #if defined(__LITTLE_ENDIAN__)
784                                 p[i] = d2 & 0xffff;
785 #else
786                                 dat.w = d2 & 0xffff;
787                                 p[i] = dat.get_2bytes_le_to();
788 #endif
789                         }
790                 }
791                 break;
792         case AUDIO_S16MSB:
793                 if(src1 != NULL) {
794                         int16_t *q = (int16_t*)src1;
795                         int16_t* p = (int16_t*)dst1;
796                         pair16_t dat;
797                         for(int i = 0; i < samples1; i++) {
798                                 dat.sw = q[i];
799 #if defined(__LITTLE_ENDIAN__)
800                                 p[i] = dat.get_2bytes_be_to();
801 #else
802                                 p[i] = dat.w;
803 #endif
804                         }
805                 }
806                 if((src2 != NULL) && (dst2 != NULL)) {
807                         int16_t* q = (int16_t*)src2;
808                         int16_t* p = (int16_t*)dst2;
809                         pair16_t dat;
810                         for(int i = 0; i < samples2; i++) {
811                                 dat.sw = q[i];
812 #if defined(__LITTLE_ENDIAN__)
813                                 p[i] = dat.get_2bytes_be_to();
814 #else
815                                 p[i] = dat.w;
816 #endif
817                         }
818                 }
819                 break;
820         case AUDIO_U16MSB:
821                 if(src1 != NULL) {
822                         int16_t* q = (int16_t*)src1;
823                         uint16_t* p = (uint16_t*)dst1;
824                         pair16_t dat;
825                         int d2;
826                         for(int i = 0; i < samples1; i++) {
827                                 d2 = q[i];
828                                 d2 = d2 + 32768;
829 #if defined(__LITTLE_ENDIAN__)
830                                 dat.w = d2 & 0xffff;
831                                 p[i] = dat.get_2bytes_be_to();
832 #else
833                                 p[i] = d2 & 0xffff;
834 #endif
835                         }
836                 }
837                 if((src2 != NULL) && (dst2 != NULL)) {
838                         int16_t* q = (int16_t*)src2;
839                         uint16_t* p = (uint16_t*)dst2;
840                         pair16_t dat;
841                         int d2;
842                         for(int i = 0; i < samples2; i++) {
843                                 d2 = q[i];
844                                 d2 = d2 + 32768;
845 #if defined(__LITTLE_ENDIAN__)
846                                 dat.w = d2 & 0xffff;
847                                 p[i] = dat.get_2bytes_be_to();
848 #else
849                                 p[i] = d2 & 0xffff;
850 #endif
851                         }
852                 }
853                 break;
854         case AUDIO_S32LSB:
855                 if(src1 != NULL) {
856                         uint32_t data;
857                         uint32_t* p = (uint32_t*)dst1;
858                         int32_t* q = (int32_t*)src1;
859                         for(int i = 0; i < samples1; i++) {
860                                 data = q[i];
861                                 data <<= 16;
862                                 p[i] = EndianToLittle_DWORD(data);
863                         }
864                 }
865                 if((src2 != NULL) && (dst2 != NULL)) {
866                         uint32_t data;
867                         uint32_t* p = (uint32_t*)dst2;
868                         int32_t* q = (int32_t*)src2;
869                         for(int i = 0; i < samples2; i++) {
870                                 data = q[i];
871                                 data <<= 16;
872                                 p[i] = EndianToLittle_DWORD(data);
873                         }
874                 }
875                 break;
876         case AUDIO_S32MSB:
877                 if(src1 != NULL) {
878                         uint32_t data;
879                         uint32_t* p = (uint32_t*)dst1;
880                         int32_t* q = (int32_t*)src1;
881                         for(int i = 0; i < samples1; i++) {
882                                 data = q[i];
883                                 data <<= 16;
884                                 p[i] = EndianToBig_DWORD(data);
885                         }
886                 }
887                 if((src2 != NULL) && (dst2 != NULL)) {
888                         uint32_t* p = (uint32_t*)dst2;
889                         int32_t* q = (int32_t*)src2;
890                         uint32_t data;
891                         for(int i = 0; i < samples2; i++) {
892                                 data = q[i];
893                                 data <<= 16;
894                                 p[i] = EndianToBig_DWORD(data);
895                         }
896                 }
897                 break;
898         case AUDIO_F32LSB:
899                 if(src1 != NULL) {
900                         uint32_t* p = (uint32_t*)dst1;
901                         int32_t* q = (int32_t*)src1;
902                         for(int i = 0; i < samples1; i++) {
903                                 float_data.f = q[i];
904                                 float_data.f /= 65536;
905                                 p[i] = EndianToLittle_DWORD(float_data.d);
906                         }
907                 }
908                 if((src2 != NULL) && (dst2 != NULL)) {
909                         uint32_t* p = (uint32_t*)dst2;
910                         int32_t* q = (int32_t*)src2;
911                         for(int i = 0; i < samples2; i++) {
912                                 float_data.f = q[i];
913                                 float_data.f /= 65536;
914                                 p[i] = EndianToLittle_DWORD(float_data.d);
915                         }
916                 }
917                 break;
918         case AUDIO_F32MSB:
919                 if(src1 != NULL) {
920                         uint32_t* p = (uint32_t*)dst1;
921                         int32_t* q = (int32_t*)src1;
922                         for(int i = 0; i < samples1; i++) {
923                                 float_data.f = q[i];
924                                 float_data.f /= 65536;
925                                 p[i] = EndianToBig_DWORD(float_data.d);
926                         }
927                 }
928                 if((src2 != NULL) && (dst2 != NULL)) {
929                         uint32_t* p = (uint32_t*)dst2;
930                         int32_t* q = (int32_t*)src2;
931                         for(int i = 0; i < samples2; i++) {
932                                 float_data.f = q[i];
933                                 float_data.f /= 65536;
934                                 p[i] = EndianToBig_DWORD(float_data.d);
935                         }
936                 }
937                 break;
938         }
939 }
940
941 void OSD_BASE::update_sound(int* extra_frames)
942 {
943         *extra_frames = 0;
944         
945         now_mute = false;
946         if(sound_ok) {
947                 uint32_t play_c, size1, size2;
948                 //uint32_t offset;
949                 uint8_t *ptr1, *ptr2;
950                 
951                 // start play
952                 // check current position
953                 play_c = sound_write_pos;
954                 if(sound_debug) debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_SOUND,
955                                                                                           "Called time=%d sound_write_pos=%d\n", osd_timer.elapsed(), play_c);
956                 if(!sound_first_half) {
957                         if((int)play_c < (sound_buffer_size / 2)) {
958                                 return;
959                         }
960                         //offset = 0;
961                 } else {
962                         if((int)play_c >= (sound_buffer_size / 2)) {
963                                 return;
964                         }
965                         //offset = sound_buffer_size / 2;
966                 }
967                 //SDL_UnlockAudio();
968                 // sound buffer must be updated
969                 Sint16* sound_buffer = (Sint16 *)this->create_sound(extra_frames);
970                 if(now_record_sound || now_record_video) {
971                         if(sound_samples > rec_sound_buffer_ptr) {
972                                 int samples = sound_samples - rec_sound_buffer_ptr;
973                                 int length = samples * sizeof(int16_t) * 2; // stereo
974                                 rec_sound_bytes += length;
975                                 if(now_record_video) {
976                                         //AGAR_DebugLog(AGAR_LOG_DEBUG, "Push Sound %d bytes\n", length);
977                                         emit sig_enqueue_audio((int16_t *)(&(sound_buffer[rec_sound_buffer_ptr * 2])), length);
978                                 }
979                                 // record sound
980                                 if(now_record_sound) {
981                                         rec_sound_fio->Fwrite(sound_buffer + rec_sound_buffer_ptr * 2, length, 1);
982                                 }
983                                 //if(now_record_video) {
984                                 //      // sync video recording
985                                 //      static double frames = 0;
986                                 //      static int prev_samples = -1;
987                                 //      static double prev_fps = -1;
988                                 //      double fps = this->vm_frame_rate();
989                                 //      frames = fps * (double)samples / (double)sound_rate;
990                                 //}
991                                 //printf("Wrote %d samples ptr=%d\n", samples, rec_sound_buffer_ptr);
992                                 rec_sound_buffer_ptr += samples;
993                                 if(rec_sound_buffer_ptr >= sound_samples) rec_sound_buffer_ptr = 0;
994                         }
995                 }
996                 if(sound_buffer) {
997                         int ssize;
998                         int pos;
999                         int pos2;
1000                                 int format_len = 1;
1001                         if(sound_initialized) {
1002                                         switch(snddata.sound_format) {
1003                                         case AUDIO_S16LSB:
1004                                         case AUDIO_S16MSB:
1005                                         case AUDIO_U16LSB:
1006                                         case AUDIO_U16MSB:
1007                                                 format_len = sizeof(int16_t);
1008                                                 break;
1009                                         case AUDIO_S32LSB:
1010                                         case AUDIO_S32MSB:
1011                                                 format_len = sizeof(int32_t);
1012                                                 break;
1013                                         case AUDIO_F32LSB:
1014                                         case AUDIO_F32MSB:
1015                                                 format_len = sizeof(float);
1016                                                 break;
1017                                         }
1018                                         ssize = sound_samples * snd_spec_presented.channels;
1019                                 pos = sound_data_pos;
1020                                 pos2 = pos + ssize;
1021                                 ptr1 = (uint8_t*)(&sound_buf_ptr[pos * format_len]);
1022                                 if(pos2 >= sound_buffer_size) {
1023                                                 size1 = sound_buffer_size  - pos;
1024                                                 size2 = pos2 - sound_buffer_size;
1025                                                 ptr2 = &sound_buf_ptr[0];
1026                                         } else {
1027                                                 size1 = ssize;
1028                                                 size2 = 0;
1029                                                 ptr2 = NULL;
1030                                         }
1031 #if defined(USE_SDL2)   
1032                                         SDL_LockAudioDevice(audio_dev_id);
1033 #else
1034                                         SDL_LockAudio();
1035 #endif
1036 #if 0
1037                                         if(ptr1) {
1038                                                 my_memcpy(ptr1, sound_buffer, size1 * format_len);
1039                                         }
1040                                         if((ptr2) && (size2 > 0)) {
1041                                                 my_memcpy(ptr2, &sound_buffer[size1], size2 * format_len);
1042                                         }
1043 #else
1044                                         convert_sound_format(ptr1, ptr2, sound_buffer, &sound_buffer[size1], size1, size2);
1045 #endif
1046
1047                                         sound_data_len = sound_data_len + ssize;
1048                                         if(sound_data_len >= sound_buffer_size) sound_data_len = sound_buffer_size;
1049                                         sound_data_pos = sound_data_pos + ssize;
1050                                         if(sound_data_pos >= sound_buffer_size) sound_data_pos = sound_data_pos - sound_buffer_size;
1051                                         if(!sound_started) sound_started = true;
1052 #if defined(USE_SDL2)   
1053                                         SDL_UnlockAudioDevice(audio_dev_id);
1054 #else
1055                                         SDL_UnlockAudio();
1056 #endif
1057                                         //SDL_UnlockAudio();
1058                                         SDL_PauseAudioDevice(audio_dev_id, 0);
1059                         }
1060                 }
1061            
1062 //              SDL_PauseAudioDevice(audio_dev_id, 0);
1063                 sound_first_half = !sound_first_half;
1064         }
1065 }
1066
1067 void OSD_BASE::mute_sound()
1068 {
1069         if(!now_mute && sound_ok) {
1070                 // check current position
1071                 uint32_t size1, size2;
1072             
1073                 uint8_t *ptr1, *ptr2;
1074                 // WIP
1075                 int ssize;
1076                 int pos;
1077                 int pos2;
1078 #if defined(USE_SDL2)   
1079                 SDL_LockAudioDevice(audio_dev_id);
1080 #else
1081                 SDL_LockAudio();
1082 #endif
1083                 int format_len = 1;
1084                 switch(snddata.sound_format) {
1085                 case AUDIO_S16LSB:
1086                 case AUDIO_S16MSB:
1087                 case AUDIO_U16LSB:
1088                 case AUDIO_U16MSB:
1089                         format_len = sizeof(int16_t);
1090                         break;
1091                 case AUDIO_S32LSB:
1092                 case AUDIO_S32MSB:
1093                         format_len = sizeof(int32_t);
1094                         break;
1095                 case AUDIO_F32LSB:
1096                 case AUDIO_F32MSB:
1097                         format_len = sizeof(float);
1098                         break;
1099                 }
1100                 ssize = sound_buffer_size / 2;
1101                 pos = sound_data_pos;
1102                 pos2 = pos + ssize;
1103                 ptr1 = &sound_buf_ptr[pos * format_len];
1104                 if(pos2 >= sound_buffer_size) {
1105                         size1 = sound_buffer_size - pos;
1106                         size2 = pos2 - sound_buffer_size;
1107                         ptr2 = &sound_buf_ptr[0];
1108                 } else {
1109                         size1 = ssize;
1110                         size2 = 0;
1111                         ptr2 = NULL;
1112                 }
1113                 
1114                 if(ptr1) {
1115                         memset(ptr1, 0x00, size1 * format_len);
1116                 }
1117                 if((ptr2) && (size2 > 0)){
1118                         memset(ptr2, 0x00, size2 * format_len);
1119                 }
1120                 sound_data_pos = (sound_data_pos + ssize) % sound_buffer_size;
1121 #if defined(USE_SDL2)   
1122                 SDL_UnlockAudioDevice(audio_dev_id);
1123 #else
1124                 SDL_UnlockAudio();
1125 #endif
1126         }
1127         now_mute = true;
1128 }
1129
1130 void OSD_BASE::stop_sound()
1131 {
1132         if(sound_ok && sound_started) {
1133                 //sound_exit = true;
1134 #if defined(USE_SDL2)   
1135                 SDL_PauseAudioDevice(audio_dev_id, 1);
1136 #else   
1137                 SDL_PauseAudio(1);
1138 #endif   
1139                 sound_started = false;
1140                 //sound_exit = false;
1141         }
1142 }
1143
1144 int OSD_BASE::get_sound_rate()
1145 {
1146         return snd_spec_presented.freq;
1147 }
1148
1149
1150 /* END SDL DRIVER: Temporally disabled */
1151 #endif
1152
1153 void OSD_BASE::start_record_sound()
1154 {
1155    
1156         if(!now_record_sound) {
1157                 //LockVM();
1158                 QDateTime nowTime = QDateTime::currentDateTime();
1159                 QString tmps = QString::fromUtf8("Sound_Save_emu");
1160                 tmps = tmps + get_vm_config_name();
1161                 tmps = tmps + QString::fromUtf8("_");
1162                 tmps = tmps + nowTime.toString(QString::fromUtf8("yyyy-MM-dd_hh-mm-ss.zzz"));
1163                 tmps = tmps + QString::fromUtf8(".wav");
1164                 strncpy((char *)sound_file_name, tmps.toLocal8Bit().constData(), sizeof(sound_file_name) - 1);
1165                 // create wave file
1166                 rec_sound_fio = new FILEIO();
1167                 if(rec_sound_fio->Fopen(bios_path(sound_file_name), FILEIO_WRITE_BINARY)) {
1168                         // write dummy wave header
1169                         write_dummy_wav_header((void *)rec_sound_fio);
1170                         
1171                         rec_sound_bytes = 0;
1172                         rec_sound_buffer_ptr = 0;
1173                         now_record_sound = true;
1174                 } else {
1175                         // failed to open the wave file
1176                         delete rec_sound_fio;
1177                 }
1178                 //UnlockVM();
1179         }
1180 }
1181
1182 void OSD_BASE::stop_record_sound()
1183 {
1184         #if 0 /* Temporally Disable  Caoptuing Sound 20220921 K.O */
1185                 if(now_record_sound) {
1186                         //LockVM();
1187                 if(rec_sound_bytes == 0) {
1188                         rec_sound_fio->Fclose();
1189                         rec_sound_fio->RemoveFile(sound_file_name);
1190                 } else {
1191                         // update wave header
1192                         wav_header_t wav_header;
1193                         wav_chunk_t wav_chunk;
1194         #if 0           
1195                         if(!set_wav_header(&wav_header, &wav_chunk, 2, snd_spec_presented.freq, 16,
1196                                                          (size_t)(rec_sound_bytes + sizeof(wav_header) + sizeof(wav_chunk)))) {
1197         #else
1198                         if(!set_wav_header(&wav_header, &wav_chunk, 2, (uint32_t)(m_audioOutputFormat.sampleRate()), 16,
1199                                                          (size_t)(rec_sound_bytes + sizeof(wav_header) + sizeof(wav_chunk)))) {
1200         #endif
1201                                 delete rec_sound_fio;
1202                                 now_record_sound = false;
1203                                 return;
1204                         }
1205                         rec_sound_fio->Fseek(0, FILEIO_SEEK_SET);
1206                         rec_sound_fio->Fwrite(&wav_header, sizeof(wav_header_t), 1);
1207                         rec_sound_fio->Fwrite(&wav_chunk, sizeof(wav_chunk), 1);
1208                         rec_sound_fio->Fclose();
1209                 }
1210                 delete rec_sound_fio;
1211                 now_record_sound = false;
1212                 //UnlockVM();
1213         }
1214         #endif /* Temporally Disable  Caoptuing Sound 20220921 K.O */
1215                 
1216 }
1217
1218 void OSD_BASE::restart_record_sound()
1219 {
1220         bool tmp = now_record_sound;
1221         stop_record_sound();
1222         if(tmp) {
1223                 start_record_sound();
1224         }
1225 }
1226
1227 #if 0 /* Temporally Disable  Caoptuing Sound 20220921 K.O */
1228 int OSD_BASE::get_sound_rate()
1229 {
1230         std::shared_ptr<SOUND_MODULE::OUTPUT::M_BASE>out_driver = m_output_driver;
1231         if(out_driver.get() != nullptr) {
1232                 return out_driver->get_sample_rate();
1233         }
1234         return 48000;
1235 }
1236 #endif /* Temporally Disable  Caoptuing Sound 20220921 K.O */
1237
1238
1239 void OSD_BASE::close_capture_sound_emu(int ch)
1240 {
1241         if(ch < 0) return;
1242         if(ch >= MAX_CAPTURE_SOUNDS) return;
1243         if(sound_capture_desc[ch].out_buffer != NULL) {
1244                 free(sound_capture_desc[ch].out_buffer);
1245         }
1246         sound_capture_desc[ch].out_buffer = NULL;
1247         sound_capturing_emu[ch] = false;
1248 }
1249
1250 void *OSD_BASE::get_capture_sound_buffer(int ch)
1251 {
1252         if(ch < 0) return NULL;
1253         if(ch >= MAX_CAPTURE_SOUNDS) return NULL;
1254         return sound_capture_desc[ch].out_buffer;
1255 }
1256
1257 bool OSD_BASE::is_capture_sound_buffer(int ch)
1258 {
1259         if(ch < 0) return false;
1260         if(ch >= MAX_CAPTURE_SOUNDS) return false;
1261         if(sound_capture_desc[ch].out_buffer == NULL) return false;
1262         return sound_capturing_emu[ch];
1263 }
1264 void *OSD_BASE::open_capture_sound_emu(int ch, int rate, int channels, int sample_type, int samples, int physical_device_num)
1265 {
1266         if(ch < 0) return nullptr;
1267         if(ch >= MAX_CAPTURE_SOUNDS) return nullptr;
1268         
1269         void *p = nullptr;
1270 #if 0   
1271         close_capture_sound_emu(ch);
1272         sound_capture_desc[ch].rate = rate;
1273         sound_capture_desc[ch].channels = channels;
1274         sound_capture_desc[ch].samples = samples;
1275         sound_capture_desc[ch].sample_type = sample_type;
1276         sound_capture_desc[ch].physical_dev = physical_device_num;
1277         bool stat = false;
1278         if((physical_device_num >= 0) && (physical_device_num < sound_capture_device_list.count()) && (physical_device_num < MAX_SOUND_CAPTURE_DEVICES)) {
1279                 if(!(capturing_sound[physical_device_num])) {
1280                         stat = open_sound_capture_device(physical_device_num, (rate < 44100) ? 44100 : rate, (channels > 2) ? channels : 2);
1281                 }
1282         }
1283         
1284
1285         if(stat) {
1286                 switch(sample_type) {
1287                 case SAMPLE_TYPE_UINT8:
1288                 case SAMPLE_TYPE_SINT8:
1289                         p = malloc(sizeof(uint8_t) * channels * (samples + 100));
1290                         break;
1291                 case SAMPLE_TYPE_UINT16_BE:
1292                 case SAMPLE_TYPE_SINT16_BE:
1293                 case SAMPLE_TYPE_UINT16_LE:
1294                 case SAMPLE_TYPE_SINT16_LE:
1295                         p = malloc(sizeof(uint16_t) * channels * (samples + 100));
1296                         break;
1297                 case SAMPLE_TYPE_UINT32_BE:
1298                 case SAMPLE_TYPE_SINT32_BE:
1299                 case SAMPLE_TYPE_UINT32_LE:
1300                 case SAMPLE_TYPE_SINT32_LE:
1301                 p = malloc(sizeof(uint32_t) * channels * (samples + 100));
1302                 break;
1303                 case SAMPLE_TYPE_FLOAT_BE:
1304                 case SAMPLE_TYPE_FLOAT_LE:
1305                         p = malloc(sizeof(float) * channels * (samples + 100));
1306                         break;
1307                 }
1308         }
1309         sound_capture_desc[ch].out_buffer = (uint8_t *)p;
1310         sound_capturing_emu[ch] = true;
1311 #endif
1312         return p;
1313 }
1314         
1315 bool OSD_BASE::open_sound_capture_device(int num, int req_rate, int req_channels)
1316 {
1317         if(num < 0) return false;
1318         if(num >= MAX_SOUND_CAPTURE_DEVICES) return false;
1319         if(sound_capture_device_list.count() <= num) return false;
1320 #if 0   
1321         SDL_AudioSpec req;
1322         SDL_AudioSpec desired;
1323         req.freq = req_rate;
1324         req.channels = req_channels;
1325         req.silence = 0;
1326         req.format = AUDIO_S16SYS;
1327         req.samples = (sizeof(sound_capture_buffer[num]) / sizeof(int16_t)) / req_channels;
1328         req.callback = &(this->audio_capture_callback);
1329         req.userdata = (void *)(&(sound_capture_dev_desc[num].userdata));
1330         
1331         if(!(capturing_sound[num])) {
1332                 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);
1333                 if(sound_capture_desc[num].physical_dev <= 0) {
1334                         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());
1335                         sound_capture_desc[num].physical_dev = -1;
1336                         return false;
1337                 }
1338                 // Device OK
1339                 capturing_sound[num] = true;
1340                 sound_capture_dev_desc[num].format = desired.format;
1341                 sound_capture_dev_desc[num].sample_rate = desired.freq;
1342                 sound_capture_dev_desc[num].channels = desired.channels;
1343                 sound_capture_dev_desc[num].buffer_samples = desired.samples;
1344                 sound_capture_dev_desc[num].size = desired.size;
1345                 sound_capture_dev_desc[num].callback = desired.callback;
1346                 sound_capture_dev_desc[num].silence = desired.silence;
1347                 int buflen = desired.samples * desired.channels;
1348                 switch(desired.format) {
1349                 case AUDIO_S8:
1350                 case AUDIO_U8:
1351                         buflen = buflen * sizeof(int8_t);
1352                         break;
1353                 case AUDIO_S16LSB:
1354                 case AUDIO_S16MSB:
1355                 case AUDIO_U16LSB:
1356                 case AUDIO_U16MSB:
1357                         buflen = buflen * sizeof(int16_t);
1358                         break;
1359                 case AUDIO_S32LSB:
1360                 case AUDIO_S32MSB:
1361                         buflen = buflen * sizeof(int32_t);
1362                         break;
1363                 case AUDIO_F32LSB:
1364                 case AUDIO_F32MSB:
1365                         buflen = buflen * sizeof(float);
1366                         break;
1367                 default:
1368                         break;
1369                 }
1370                 
1371                 sound_capture_dev_desc[num].userdata.buffer_size = buflen;
1372                 sound_capture_dev_desc[num].userdata.format = desired.format;
1373                 sound_capture_dev_desc[num].userdata.readlen = 0;
1374                 sound_capture_dev_desc[num].userdata.writelen = 0;
1375                 sound_capture_dev_desc[num].userdata.readpos = 0;
1376                 sound_capture_dev_desc[num].userdata.writepos = 0;
1377                 sound_capture_dev_desc[num].userdata.read_buffer_ptr = &(sound_capture_buffer[num][0]);
1378                 memset(&(sound_capture_buffer[num][0]), 0x00, buflen);
1379                 
1380                 for(int ch = 0; ch < MAX_SOUND_CAPTURE_DEVICES; ch++) {
1381                         if(sound_capture_desc[ch].physical_dev == num) {
1382                                 sound_capture_desc[ch].read_format = desired.format;
1383                                 sound_capture_desc[ch].read_rate = desired.freq;
1384                                 sound_capture_desc[ch].read_silence = desired.silence;
1385                                 sound_capture_desc[ch].read_size = desired.size;
1386                                 sound_capture_desc[ch].read_channels = desired.channels;
1387                                 sound_capture_desc[ch].read_samples = desired.samples;
1388                                 sound_capture_desc[ch].read_callback = desired.callback;
1389                                 sound_capture_desc[ch].read_userdata = desired.userdata;
1390                                 
1391                                 sound_capture_desc[ch].read_pos = 0;
1392                                 sound_capture_desc[ch].read_data_len = 0;
1393                                 sound_capture_desc[ch].read_buffer_len = buflen;
1394                                 sound_capture_desc[ch].read_buffer_ptr = (uint8_t *)(&(sound_capture_buffer[num][0]));
1395
1396                                 
1397                         }                               
1398                 }
1399         }
1400 #endif
1401         return true;
1402 }
1403
1404 bool OSD_BASE::close_sound_capture_device(int num, bool force)
1405 {
1406         // ToDo: Check capturing entries
1407 #if 0   
1408         if((capturing_sound[num]) && (sound_capture_desc[num].physical_dev > 0)) {
1409                 SDL_CloseAudioDevice(sound_capture_desc[num].physical_dev);
1410         }
1411 #endif
1412         return true;
1413 }