1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
#include "../../modules.h"
#if JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO
#include <iostream>
#include "SDLAudio.h"
#include "SDLSource.h"
#include "../../math/math.h"
#include "../../utils/log.h"
namespace jin
{
namespace audio
{
using namespace jin::math;
/* עcallbackƵ̵߳ */
static void defaultCallback(void *userdata, Uint8 *stream, int size)
{
static SDLAudio* audio = static_cast<SDLAudio*>(userdata);
if (!audio->goOnProcess())
return;
audio->lock();
audio->processCommands();
audio->processSources(stream, size);
audio->processBuffer(stream, size);
audio->unlock();
}
onlyonce bool SDLAudio::initSystem(const SettingBase* s)
{
#if JIN_DEBUG
Loghelper::log(Loglevel::LV_INFO, "Init audio system");
#endif
if (SDL_Init(SDL_INIT_AUDIO) < 0)
return false;
SDL_AudioSpec spec;
Setting* setting = (Setting*)s;
if (setting == nullptr)
return false;
unsigned int samplerate = setting->samplerate;
unsigned int samples = clamp<int>(setting->samples, 1, setting->samplerate);
spec.freq = samplerate; // ÿsample,õ 11025, 22050, 44100 and 48000 Hz.
spec.format = AUDIO_S16SYS; // signed 16-bit samples in native byte order
spec.channels = SDLAUDIO_CHANNELS; //
spec.samples = samples; // ÿβʱһã=setting->samplerateÿֻ1
spec.userdata = this;
spec.callback = defaultCallback;
audioDevice = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0);
if (audioDevice == 0)
return false;
/* start audio */
SDL_PauseAudioDevice(audioDevice, 0);
return true;
}
onlyonce void SDLAudio::quitSystem()
{
SDL_CloseAudioDevice(audioDevice);
}
void SDLAudio::lock()
{
SDL_LockAudioDevice(audioDevice);
}
void SDLAudio::unlock()
{
SDL_UnlockAudioDevice(audioDevice);
}
bool SDLAudio::goOnProcess()
{
if (state == SDLAudio::State::STOP)
{
SDLSourceManager::get()->removeAllSource();
pause();
return false;
}
else if (state == SDLAudio::State::PAUSE)
return false;
else
return true;
}
void SDLAudio::processCommands()
{
SDLSourceManager::get()->processCommands();
}
void SDLAudio::processSources(void* buffer, size_t len)
{
SDLSourceManager::get()->processSources(buffer, len);
}
void SDLAudio::processBuffer(void* buff, size_t len)
{
short* buffer = (short*)buff;
int samples = (len / SDLAUDIO_BYTEDEPTH) >> 1; // ˫
const char L = 0, R = 1;
for (int i = 0; i < samples; ++i)
{
short* clip = buffer + (i << 1);
clip[L] *= volume;
clip[R] *= volume;
}
}
void SDLAudio::play()
{
state = State::PLAY;
}
void SDLAudio::stop()
{
state = State::STOP;
}
void SDLAudio::pause()
{
state = State::PAUSE;
}
void SDLAudio::resume()
{
state = State::PLAY;
}
void SDLAudio::setVolume(float volume)
{
this->volume = clamp(volume, 0.0f, 1.0f);
}
}
}
#endif // JIN_MODULES_AUDIO && JIN_AUDIO_SDLAUDIO
|