ObjectivelyMVC 0.1.0
Object oriented MVC framework for OpenGL, SDL2 and GNU C
SoundStage.c
Go to the documentation of this file.
1/*
2 * ObjectivelyMVC: Object oriented MVC framework for OpenGL, SDL2 and GNU C.
3 * Copyright (C) 2014 Jay Dolan <jay@jaydolan.com>
4 *
5 * This software is provided 'as-is', without any express or implied
6 * warranty. In no event will the authors be held liable for any damages
7 * arising from the use of this software.
8 *
9 * Permission is granted to anyone to use this software for any purpose,
10 * including commercial applications, and to alter it and redistribute it
11 * freely, subject to the following restrictions:
12 *
13 * 1. The origin of this software must not be misrepresented; you must not
14 * claim that you wrote the original software. If you use this software
15 * in a product, an acknowledgment in the product documentation would be
16 * appreciated but is not required.
17 *
18 * 2. Altered source versions must be plainly marked as such, and must not be
19 * misrepresented as being the original software.
20 *
21 * 3. This notice may not be removed or altered from any source distribution.
22 */
23
24#include <assert.h>
25
26#include <SDL2/SDL_mixer.h>
27
28#include "clack.wav.h"
29#include "click.wav.h"
30
31#include "Log.h"
32#include "SoundStage.h"
33#include "WindowController.h"
34
35#define _Class _SoundStage
36
37#pragma mark - Object
38
42static void dealloc(Object *self) {
43
44 Mix_CloseAudio();
45
46 super(Object, self, dealloc);
47}
48
49#pragma mark - SoundStage
50
55static SoundStage *init(SoundStage *self) {
56
57 self = (SoundStage *) super(Object, self, init);
58 if (self) {
59
60 if (Mix_OpenAudioDevice(48000, AUDIO_S16SYS, 2, 2048, NULL, SDL_AUDIO_ALLOW_ANY_CHANGE) == 0) {
61 MVC_LogInfo("Opened audio device for playback\n");
62 } else {
63 MVC_LogError("Failed to open audio device: %s\n", SDL_GetError());
64 self = release(self);
65 }
66 }
67
68 return self;
69}
70
75static void play(const SoundStage *self, const Sound *sound) {
76 static unsigned int ch;
77
78 assert(sound);
79
80 Mix_PlayChannel(ch++ % MIX_CHANNELS, sound->chunk, 0);
81}
82
83#pragma mark - Class lifecycle
84
87
91static void initialize(Class *clazz) {
92
93 ((ObjectInterface *) clazz->interface)->dealloc = dealloc;
94
95 ((SoundStageInterface *) clazz->interface)->init = init;
96 ((SoundStageInterface *) clazz->interface)->play = play;
97
98 const int init = Mix_Init(0xff);
99 assert(init);
100
101 _click = $$(Sound, soundWithBytes, click_wav, click_wav_len);
102 _clack = $$(Sound, soundWithBytes, clack_wav, clack_wav_len);
103}
104
108static void destroy(Class *clazz) {
109
110 release(_click);
111 release(_clack);
112
113 Mix_Quit();
114}
115
120Class *_SoundStage(void) {
121 static Class *clazz;
122 static Once once;
123
124 do_once(&once, {
125 clazz = _initialize(&(const ClassDef) {
126 .name = "SoundStage",
127 .superclass = _Object(),
128 .instanceSize = sizeof(SoundStage),
129 .interfaceOffset = offsetof(SoundStage, interface),
130 .interfaceSize = sizeof(SoundStageInterface),
132 .destroy = destroy,
133 });
134 });
135
136 return clazz;
137}
138
139#undef _Class
140
142
143 SDL_Window *window = SDL_GL_GetCurrentWindow();
144 assert(window);
145
147 assert(windowController);
149
150 $(windowController->soundStage, play, sound);
151}
View logging facilities via SDL_Log.
#define MVC_LogInfo(fmt,...)
Definition: Log.h:49
#define MVC_LogError(fmt,...)
Definition: Log.h:55
Sound * _clack
Definition: SoundStage.c:86
static void destroy(Class *clazz)
Definition: SoundStage.c:108
Sound * _click
Definition: SoundStage.c:85
static void dealloc(Object *self)
Definition: SoundStage.c:42
static void initialize(Class *clazz)
Definition: SoundStage.c:91
OBJECTIVELYMVC_EXPORT void MVC_PlaySound(const Sound *sound)
Plays the specified Sound through the current SoundStage (if any).
Definition: SoundStage.c:141
Sound playback.
#define OBJECTIVELYMVC_EXPORT
Definition: Types.h:39
A WindowController manages a ViewController and its descendants within an SDL_Window.
CollectionView * init(CollectionView *self, const SDL_Rect *frame)
Initializes this CollectionView with the specified frame and style.
Sound loading and playback.
Definition: Sound.h:45
Mix_Chunk * chunk
The backing audio chunk.
Definition: Sound.h:61
Sound * soundWithBytes(const uint8_t *bytes, size_t length)
Instantiates an Sound with the specified bytes.
Definition: Sound.c:128
The SoundStage type.
Definition: SoundStage.h:40
Class * _SoundStage(void)
The SoundStage archetype.
Definition: SoundStage.c:120
void play(const SoundStage *self, const char *sound)
Enqueues the given Sound for playback.
A WindowController manages a ViewController and its descendants within an SDL_Window.
WindowController * windowController(SDL_Window *window)
SoundStage * soundStage
The SoundStage.