Relicensing audaspace under GPL 2 or later.
[blender.git] / intern / audaspace / SDL / AUD_SDLDevice.cpp
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * Copyright 2009-2011 Jörg Hermann Müller
7  *
8  * This file is part of AudaSpace.
9  *
10  * Audaspace is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * AudaSpace is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Audaspace; if not, write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 #include "AUD_SDLDevice.h"
28 #include "AUD_IReader.h"
29
30 void AUD_SDLDevice::SDL_mix(void *data, Uint8* buffer, int length)
31 {
32         AUD_SDLDevice* device = (AUD_SDLDevice*)data;
33
34         device->mix((data_t*)buffer,length/AUD_DEVICE_SAMPLE_SIZE(device->m_specs));
35 }
36
37 static const char* open_error = "AUD_SDLDevice: Device couldn't be opened.";
38 static const char* format_error = "AUD_SDLDevice: Obtained unsupported sample "
39                                                                   "format.";
40
41 AUD_SDLDevice::AUD_SDLDevice(AUD_DeviceSpecs specs, int buffersize)
42 {
43         if(specs.channels == AUD_CHANNELS_INVALID)
44                 specs.channels = AUD_CHANNELS_STEREO;
45         if(specs.format == AUD_FORMAT_INVALID)
46                 specs.format = AUD_FORMAT_S16;
47         if(specs.rate == AUD_RATE_INVALID)
48                 specs.rate = AUD_RATE_44100;
49
50         m_specs = specs;
51
52         SDL_AudioSpec format, obtained;
53
54         format.freq = m_specs.rate;
55         if(m_specs.format == AUD_FORMAT_U8)
56                 format.format = AUDIO_U8;
57         else
58                 format.format = AUDIO_S16SYS;
59         format.channels = m_specs.channels;
60         format.samples = buffersize;
61         format.callback = AUD_SDLDevice::SDL_mix;
62         format.userdata = this;
63
64         if(SDL_OpenAudio(&format, &obtained) != 0)
65                 AUD_THROW(AUD_ERROR_SDL, open_error);
66
67         m_specs.rate = (AUD_SampleRate)obtained.freq;
68         m_specs.channels = (AUD_Channels)obtained.channels;
69         if(obtained.format == AUDIO_U8)
70                 m_specs.format = AUD_FORMAT_U8;
71         else if(obtained.format == AUDIO_S16LSB || obtained.format == AUDIO_S16MSB)
72                 m_specs.format = AUD_FORMAT_S16;
73         else
74         {
75                 SDL_CloseAudio();
76                 AUD_THROW(AUD_ERROR_SDL, format_error);
77         }
78
79         create();
80 }
81
82 AUD_SDLDevice::~AUD_SDLDevice()
83 {
84         lock();
85         SDL_CloseAudio();
86         unlock();
87
88         destroy();
89 }
90
91 void AUD_SDLDevice::playing(bool playing)
92 {
93         SDL_PauseAudio(playing ? 0 : 1);
94 }