• R/O
  • HTTP
  • SSH
  • HTTPS

cinnamon: Commit

Cinnamon audio library


Commit MetaInfo

Revisiona3f115b38c8e33bdddfdef53aa6be43fc3c37a9f (tree)
Zeit2020-01-05 07:08:05
AutorAlaskanEmily <emily@alas...>
CommiterAlaskanEmily

Log Message

Add Cin_DriverSupports* API implementation for DirectSound

This removes the dummied out implmentation previously used.

Refactor some of the format translation from Cinnamon to DirectSound structures
in cin_dsound_sound so that they can be used from cin_dsound for the
Cin_DriverSupports* API.

Add slightly ugly getter in cin_dsound_driver to allow the IDirectSound8 object
to be used from cin_dsound for the Cin_DriverSupports* API.

Ändern Zusammenfassung

Diff

--- a/src/dsound/cin_dsound.cpp
+++ b/src/dsound/cin_dsound.cpp
@@ -12,6 +12,35 @@
1212
1313 ///////////////////////////////////////////////////////////////////////////////
1414
15+CIN_PRIVATE(bool) cin_supports_format(IDirectSound8 *dsound,
16+ unsigned rate,
17+ unsigned channels,
18+ enum Cin_Format sample_type){
19+
20+ WAVEFORMATEXTENSIBLE fmt;
21+ DSBUFFERDESC buffer_desc;
22+ Cin_Sound::CreateWaveFormat(rate, channels, sample_type, fmt);
23+
24+ buffer_desc.dwSize = sizeof(DSBUFFERDESC);
25+ buffer_desc.dwFlags = DSBCAPS_GLOBALFOCUS;
26+ // Arbitrary, medium-sized power-of-two size
27+ buffer_desc.dwBufferBytes = 4096;
28+ buffer_desc.dwReserved = 0;
29+ buffer_desc.lpwfxFormat = &fmt.Format;
30+ buffer_desc.guid3DAlgorithm = DS3DALG_DEFAULT;
31+
32+ IDirectSoundBuffer *buffer;
33+ if(dsound->CreateSoundBuffer(&buffer_desc, &buffer, NULL) != DS_OK){
34+ return false;
35+ }
36+ else{
37+ buffer->Release();
38+ return true;
39+ }
40+}
41+
42+///////////////////////////////////////////////////////////////////////////////
43+
1544 CIN_EXPORT(unsigned) Cin_StructDriverSize(void){
1645 return sizeof(Cin_Driver);
1746 }
@@ -36,8 +65,26 @@ CIN_EXPORT(enum Cin_DriverError) Cin_DriverSupportsFormat(
3665 enum Cin_Format format,
3766 unsigned num_channels){
3867
39- // TODO!
40- return Cin_eDriverSuccess;
68+ if(drv == NULL)
69+ return Cin_eDriverFailure;
70+
71+ if(IDirectSound8 *const dsound =
72+ const_cast<Cin_Driver*>(drv)->getDirectSound()){
73+
74+ // Try to create a buffer with this format and num channels, at
75+ // either 44100 or 48000 Hz.
76+ if(cin_supports_format(dsound, 44100, num_channels, format) ||
77+ cin_supports_format(dsound, 48000, num_channels, format)){
78+
79+ return Cin_eDriverSuccess;
80+ }
81+ else{
82+ return Cin_eDriverFailure;
83+ }
84+ }
85+ else{
86+ return Cin_eDriverFailure;
87+ }
4188 }
4289
4390 ///////////////////////////////////////////////////////////////////////////////
@@ -46,8 +93,25 @@ CIN_EXPORT(enum Cin_DriverError) Cin_DriverSupportsSampleRate(
4693 const struct Cin_Driver *drv,
4794 unsigned rate){
4895
49- // TODO!
50- return Cin_eDriverSuccess;
96+ if(drv == NULL)
97+ return Cin_eDriverFailure;
98+
99+ if(IDirectSound8 *const dsound =
100+ const_cast<Cin_Driver*>(drv)->getDirectSound()){
101+
102+ // Try to create a buffer with this rate and basic setup
103+ if(cin_supports_format(dsound, rate, 2, Cin_eFormatS16) ||
104+ cin_supports_format(dsound, rate, 2, Cin_eFormatFloat32)){
105+
106+ return Cin_eDriverSuccess;
107+ }
108+ else{
109+ return Cin_eDriverFailure;
110+ }
111+ }
112+ else{
113+ return Cin_eDriverFailure;
114+ }
51115 }
52116
53117 ///////////////////////////////////////////////////////////////////////////////
--- a/src/dsound/cin_dsound_driver.hpp
+++ b/src/dsound/cin_dsound_driver.hpp
@@ -33,6 +33,9 @@ public:
3333 Cin_Driver();
3434 ~Cin_Driver();
3535
36+ // This is only used for testing if a format/sample rate is supported.
37+ inline IDirectSound8 *getDirectSound() { return m_dsound; }
38+
3639 void createSound(Cin_Sound *out, const Cin_Loader &ld);
3740
3841 };
--- a/src/dsound/cin_dsound_sound.cpp
+++ b/src/dsound/cin_dsound_sound.cpp
@@ -17,97 +17,11 @@
1717
1818 Cin_Sound::Cin_Sound(IDirectSound8 *dsound, const Cin_Loader &ld)
1919 : m_dsound(dsound){
20-
21- const unsigned sample_rate = ld.sample_rate;
22- const unsigned channels = ld.channels;
23- const enum Cin_Format format = ld.format;
24-
20+
2521 WAVEFORMATEXTENSIBLE fmt;
26-#ifndef NDEBUG
27- // Poison the uninitialized format
28- memset((void*)&fmt, 0xFF, sizeof(fmt));
29-#endif
30-
31- // Set format tag
32- switch(format){
33- case Cin_eFormatS8:
34- case Cin_eFormatS16:
35- case Cin_eFormatS32:
36- fmt.Format.cbSize = 0;
37- fmt.Format.wFormatTag = WAVE_FORMAT_PCM;
38- break;
39- case Cin_eFormatFloat32:
40- case Cin_eFormatFloat64:
41- case Cin_eFormatULaw8:
42- fmt.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
43- fmt.Format.cbSize = sizeof(fmt) - sizeof(fmt.Format);
44- break;
45- }
46-
47- unsigned bytes_per_sample = 0;
48- switch(format){
49- case Cin_eFormatS8:
50- bytes_per_sample = 1;
51- break;
52- case Cin_eFormatS16:
53- bytes_per_sample = 2;
54- break;
55- case Cin_eFormatS32:
56- bytes_per_sample = 4;
57- break;
58- case Cin_eFormatFloat32:
59- bytes_per_sample = 4;
60- fmt.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
61- fmt.Samples.wValidBitsPerSample = 32;
62- break;
63- case Cin_eFormatFloat64:
64- bytes_per_sample = 8;
65- fmt.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
66- fmt.Samples.wValidBitsPerSample = 64;
67- break;
68- case Cin_eFormatULaw8:
69- bytes_per_sample = 1;
70- fmt.SubFormat = KSDATAFORMAT_SUBTYPE_MULAW;
71- fmt.Samples.wValidBitsPerSample = 8;
72- break;
73- }
74-
75- // Set channels
76- fmt.Format.nChannels = channels;
77- if(fmt.Format.wFormatTag != WAVE_FORMAT_PCM){
78- switch(channels){
79- case 1:
80- fmt.dwChannelMask = KSAUDIO_SPEAKER_MONO;
81- break;
82- case 2:
83- fmt.dwChannelMask = KSAUDIO_SPEAKER_STEREO;
84- break;
85- case 4:
86- fmt.dwChannelMask = KSAUDIO_SPEAKER_QUAD;
87- break;
88- case 6:
89- fmt.dwChannelMask = KSAUDIO_SPEAKER_5POINT1_SURROUND;
90- break;
91- default:
92- fmt.dwChannelMask = 0;
93- }
94- }
95-
96- // Set sample rate
97- fmt.Format.nSamplesPerSec = sample_rate;
98-
99- // Block align
100- const unsigned align = channels * bytes_per_sample;
101- const unsigned bytes_per_sec = align * sample_rate;
102- fmt.Format.nBlockAlign = align;
103-
104- fmt.Format.nAvgBytesPerSec = bytes_per_sec;
105-
106- // Set bits per sample
107- fmt.Format.wBitsPerSample = bytes_per_sample << 3;
108-
22+ CreateWaveFormat(ld.sample_rate, ld.channels, ld.format, fmt);
23+
10924 // Check the size of the loader data.
110-
11125 const unsigned byte_size = ld.bytes_placed;
11226 #ifndef NDEBUG
11327 {
@@ -119,7 +33,6 @@ Cin_Sound::Cin_Sound(IDirectSound8 *dsound, const Cin_Loader &ld)
11933 }
12034 #endif
12135
122-
12336 DSBUFFERDESC descriptor;
12437 descriptor.dwSize = sizeof(DSBUFFERDESC);
12538 descriptor.dwFlags = DSBCAPS_GLOBALFOCUS;
@@ -174,5 +87,95 @@ void Cin_Sound::stop(){
17487 if(m_buffer != NULL)
17588 m_buffer->Stop();
17689 }
90+///////////////////////////////////////////////////////////////////////////////
91+
92+void Cin_Sound::CreateWaveFormat(unsigned sample_rate,
93+ unsigned channels,
94+ enum Cin_Format format,
95+ WAVEFORMATEXTENSIBLE &out_fmt){
96+
97+#ifndef NDEBUG
98+ // Poison the uninitialized format
99+ memset((void*)&out_fmt, 0xFF, sizeof(WAVEFORMATEXTENSIBLE));
100+#endif
101+
102+ // Set format tag
103+ switch(format){
104+ case Cin_eFormatS8:
105+ case Cin_eFormatS16:
106+ case Cin_eFormatS32:
107+ out_fmt.Format.cbSize = 0;
108+ out_fmt.Format.wFormatTag = WAVE_FORMAT_PCM;
109+ break;
110+ case Cin_eFormatFloat32:
111+ case Cin_eFormatFloat64:
112+ case Cin_eFormatULaw8:
113+ out_fmt.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
114+ out_fmt.Format.cbSize = sizeof(out_fmt) - sizeof(out_fmt.Format);
115+ break;
116+ }
117+
118+ unsigned bytes_per_sample = 0;
119+ switch(format){
120+ case Cin_eFormatS8:
121+ bytes_per_sample = 1;
122+ break;
123+ case Cin_eFormatS16:
124+ bytes_per_sample = 2;
125+ break;
126+ case Cin_eFormatS32:
127+ bytes_per_sample = 4;
128+ break;
129+ case Cin_eFormatFloat32:
130+ bytes_per_sample = 4;
131+ out_fmt.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
132+ out_fmt.Samples.wValidBitsPerSample = 32;
133+ break;
134+ case Cin_eFormatFloat64:
135+ bytes_per_sample = 8;
136+ out_fmt.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
137+ out_fmt.Samples.wValidBitsPerSample = 64;
138+ break;
139+ case Cin_eFormatULaw8:
140+ bytes_per_sample = 1;
141+ out_fmt.SubFormat = KSDATAFORMAT_SUBTYPE_MULAW;
142+ out_fmt.Samples.wValidBitsPerSample = 8;
143+ break;
144+ }
145+
146+ // Set channels
147+ out_fmt.Format.nChannels = channels;
148+ if(out_fmt.Format.wFormatTag != WAVE_FORMAT_PCM){
149+ switch(channels){
150+ case 1:
151+ out_fmt.dwChannelMask = KSAUDIO_SPEAKER_MONO;
152+ break;
153+ case 2:
154+ out_fmt.dwChannelMask = KSAUDIO_SPEAKER_STEREO;
155+ break;
156+ case 4:
157+ out_fmt.dwChannelMask = KSAUDIO_SPEAKER_QUAD;
158+ break;
159+ case 6:
160+ out_fmt.dwChannelMask = KSAUDIO_SPEAKER_5POINT1_SURROUND;
161+ break;
162+ default:
163+ out_fmt.dwChannelMask = 0;
164+ }
165+ }
166+
167+ // Set sample rate
168+ out_fmt.Format.nSamplesPerSec = sample_rate;
169+
170+ // Block align
171+ const unsigned align = channels * bytes_per_sample;
172+ const unsigned bytes_per_sec = align * sample_rate;
173+ out_fmt.Format.nBlockAlign = align;
174+
175+ out_fmt.Format.nAvgBytesPerSec = bytes_per_sec;
176+
177+ // Set bits per sample
178+ out_fmt.Format.wBitsPerSample = bytes_per_sample << 3;
179+}
177180
178181 ///////////////////////////////////////////////////////////////////////////////
--- a/src/dsound/cin_dsound_sound.hpp
+++ b/src/dsound/cin_dsound_sound.hpp
@@ -17,6 +17,7 @@
1717 #include <mmsystem.h>
1818 #include <dsound.h>
1919 #include <objbase.h>
20+#include <mmreg.h> // For WAVEFORMATEXTENSIBLE
2021
2122 ///////////////////////////////////////////////////////////////////////////////
2223
@@ -36,6 +37,11 @@ public:
3637
3738 void play(bool loop);
3839 void stop();
40+
41+ static void CreateWaveFormat(unsigned sample_rate,
42+ unsigned channels,
43+ enum Cin_Format format,
44+ WAVEFORMATEXTENSIBLE &out_fmt);
3945 };
4046
4147 ///////////////////////////////////////////////////////////////////////////////
Show on old repository browser