Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDL2: fix mixer errors, mixer.init(..., allowchanges=0) #861

Merged
merged 9 commits into from Mar 4, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions docs/reST/ref/mixer.rst
Expand Up @@ -42,7 +42,7 @@ change the default buffer by calling :func:`pygame.mixer.pre_init` before
.. function:: init

| :sl:`initialize the mixer module`
| :sg:`init(frequency=22050, size=-16, channels=2, buffer=4096, devicename=None, allowedchanges=0) -> None`
| :sg:`init(frequency=22050, size=-16, channels=2, buffer=4096, devicename=None, allowedchanges=AUDIO_ALLOW_FREQUENCY_CHANGE | AUDIO_ALLOW_CHANNELS_CHANGE) -> None`

Initialize the mixer module for Sound loading and playback. The default
arguments can be overridden to provide specific audio mixing. Keyword
Expand Down Expand Up @@ -87,7 +87,9 @@ change the default buffer by calling :func:`pygame.mixer.pre_init` before
- AUDIO_ALLOW_CHANNELS_CHANGE
- AUDIO_ALLOW_ANY_CHANGE

.. versionadded:: 2 allowedchanges added for SDL2. Only allowedchanges=0 works with SDL1.
.. versionadded:: 2 allowedchanges added for SDL2.
This has no effect with SDL1 (i.e. the requested format
may always differ from the returned format).


It is safe to call this more than once, but after the mixer is initialized
Expand Down
4 changes: 2 additions & 2 deletions src_c/doc/mixer_doc.h
@@ -1,6 +1,6 @@
/* Auto generated file: with makeref.py . Docs go in docs/reST/ref/ . */
#define DOC_PYGAMEMIXER "pygame module for loading and playing sounds"
#define DOC_PYGAMEMIXERINIT "init(frequency=22050, size=-16, channels=2, buffer=4096, devicename=None, allowedchanges=0) -> None\ninitialize the mixer module"
#define DOC_PYGAMEMIXERINIT "init(frequency=22050, size=-16, channels=2, buffer=4096, devicename=None, allowedchanges=AUDIO_ALLOW_FREQUENCY_CHANGE | AUDIO_ALLOW_CHANNELS_CHANGE) -> None\ninitialize the mixer module"
#define DOC_PYGAMEMIXERPREINIT "pre_init(frequency=22050, size=-16, channels=2, buffersize=4096, devicename=None) -> None\npreset the mixer init arguments"
#define DOC_PYGAMEMIXERQUIT "quit() -> None\nuninitialize the mixer"
#define DOC_PYGAMEMIXERGETINIT "get_init() -> (frequency, format, channels)\ntest if the mixer is initialized"
Expand Down Expand Up @@ -46,7 +46,7 @@ pygame.mixer
pygame module for loading and playing sounds

pygame.mixer.init
init(frequency=22050, size=-16, channels=2, buffer=4096, devicename=None, allowedchanges=0) -> None
init(frequency=22050, size=-16, channels=2, buffer=4096, devicename=None, allowedchanges=AUDIO_ALLOW_FREQUENCY_CHANGE | AUDIO_ALLOW_CHANNELS_CHANGE) -> None
initialize the mixer module

pygame.mixer.pre_init
Expand Down
52 changes: 31 additions & 21 deletions src_c/mixer.c
Expand Up @@ -65,7 +65,12 @@ const PG_sample_format_t PG_SAMPLE_CHAR_SIGN = (char)0xff > 0 ? 0 : 0x10000u;
#define PYGAME_MIXER_DEFAULT_SIZE -16
#define PYGAME_MIXER_DEFAULT_CHANNELS 2
#define PYGAME_MIXER_DEFAULT_CHUNKSIZE 4096
#define PYGAME_MIXER_DEFAULT_ALLOWEDCHANGES 0
#if IS_SDLv2
#define PYGAME_MIXER_DEFAULT_ALLOWEDCHANGES SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | \
SDL_AUDIO_ALLOW_CHANNELS_CHANGE
#else
#define PYGAME_MIXER_DEFAULT_ALLOWEDCHANGES -1
#endif

static PyTypeObject pgSound_Type;
static PyTypeObject pgChannel_Type;
Expand Down Expand Up @@ -346,28 +351,36 @@ _init(int freq, int size, int channels, int chunk, char *devicename, int allowed
size = request_size;
}

if (allowedchanges == -1) {
allowedchanges = request_allowedchanges;
}

if (!channels) {
channels = request_channels;
}
#if IS_SDLv1
switch (channels) {
case 1:
case 2:
break;
default:
PyErr_SetString(PyExc_ValueError, "'channels' must be 1 (mono) or 2 (stereo)");
return NULL;
}
channels = channels <= 1 ? 1 : 2;
#else /* IS_SDLv2 */
switch (channels) {
case 1:
case 2:
case 4:
case 6:
break;
default:
PyErr_SetString(PyExc_ValueError, "'channels' must be 1, 2, 4, or 6");
return NULL;
if (allowedchanges & SDL_AUDIO_ALLOW_CHANNELS_CHANGE) {
if (channels <= 1)
channels = 1;
else if (channels <= 3)
channels = 2;
else if (channels <= 5)
channels = 4;
else
channels = 6;
} else {
switch (channels) {
case 1:
case 2:
case 4:
case 6:
break;
default:
PyErr_SetString(PyExc_ValueError, "'channels' must be 1, 2, 4, or 6");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#113 can be closed since channels > 2 are supported in SDL2.

return NULL;
}
}
#endif /* IS_SDLv2 */

Expand All @@ -378,9 +391,6 @@ _init(int freq, int size, int channels, int chunk, char *devicename, int allowed
if (!devicename) {
devicename = request_devicename;
}
if (allowedchanges == -1) {
allowedchanges = request_allowedchanges;
}

/* printf("size:%d:\n", size); */

Expand Down
4 changes: 2 additions & 2 deletions test/mixer_test.py
Expand Up @@ -78,7 +78,7 @@ def test_pre_init__zero_values(self):
def test_init__zero_values(self):
# Ensure that argument values of 0 are replaced with
# preset values. No way to check buffer size though.
mixer.pre_init(44100, 8, 1) # None default values
mixer.pre_init(44100, 8, 1, allowedchanges=0) # None default values
mixer.init(0, 0, 0)
self.assertEqual(mixer.get_init(), (44100, 8, 1))

Expand Down Expand Up @@ -311,7 +311,7 @@ def _test_array_interface_fail(self, a):
self.assertRaises(ValueError, mixer.Sound, array=a)

def test_array_interface(self):
mixer.init(22050, -16, 1)
mixer.init(22050, -16, 1, allowedchanges=0)
snd = mixer.Sound(buffer=as_bytes('\x00\x7f') * 20)
d = snd.__array_interface__
self.assertTrue(isinstance(d, dict))
Expand Down