aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/Audio/SDL/SDLSource.cpp
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2018-07-29 12:16:17 +0800
committerchai <chaifix@163.com>2018-07-29 12:16:17 +0800
commit5560448bb78ed865aeb77f62cf85a2aed302779d (patch)
tree0381def6419d98b9cbf950db21cbe38d555c5688 /src/libjin/Audio/SDL/SDLSource.cpp
parente9dcb75fb3cdbabd7152b0303af4dc27b4bcca3d (diff)
*update
Diffstat (limited to 'src/libjin/Audio/SDL/SDLSource.cpp')
-rw-r--r--src/libjin/Audio/SDL/SDLSource.cpp94
1 files changed, 46 insertions, 48 deletions
diff --git a/src/libjin/Audio/SDL/SDLSource.cpp b/src/libjin/Audio/SDL/SDLSource.cpp
index 18ba855..c868df5 100644
--- a/src/libjin/Audio/SDL/SDLSource.cpp
+++ b/src/libjin/Audio/SDL/SDLSource.cpp
@@ -3,14 +3,13 @@
#include <exception>
#include <fstream>
-
+#include <climits>
#include "../../math/math.h"
#include "../../utils/macros.h"
#include "SDLSource.h"
#include "../../3rdparty/wav/wav.h"
#define STB_VORBIS_HEADER_ONLY
#include "../../3rdparty/stb/stb_vorbis.c"
-
#include "SDLAudio.h"
namespace jin
@@ -64,9 +63,9 @@ namespace audio
#define Action Command::Action
#define Manager SDLSourceManager
- shared std::queue<Command*> Manager::commands;
- shared std::stack<Command*> Manager::commandsPool;
- shared std::vector<SDLSource*> Manager::sources;
+ //shared std::queue<Command*> Manager::commands;
+ //shared std::stack<Command*> Manager::commandsPool;
+ //shared std::vector<SDLSource*> Manager::sources;
shared Manager* Manager::manager = nullptr;
SDLSource* SDLSource::createSource(const char* file)
@@ -116,6 +115,7 @@ namespace audio
{
memset(&status, 0, sizeof(status));
memset(&raw, 0, sizeof(raw));
+ status.volume = 1;
}
SDLSource::~SDLSource()
@@ -131,12 +131,12 @@ namespace audio
if (wav_read(&wav, mem, size) == 0)
{
raw.data = wav.data;
- raw.length = wav.length * wav.bitdepth / 8;
+ raw.length = wav.length * wav.channels * wav.bitdepth / 8;
+ raw.channels = clamp<int>(wav.channels, CHANNEL::MONO, CHANNEL::STEREO);
raw.end = (char*)raw.data + raw.length;
raw.samplerate = wav.samplerate;
raw.bitdepth = wav.bitdepth;
- raw.samples = raw.length / (wav.bitdepth / 8.f) / wav.channels;
- raw.channels = clamp<int>(wav.channels, CHANNEL::MONO, CHANNEL::STEREO);
+ raw.samples = wav.length;
}
else
throw SourceException();
@@ -159,8 +159,8 @@ namespace audio
raw.channels = channels;
raw.samplerate = samplerate;
raw.data = data;
- raw.samples = samples;
- raw.length = samples * channels * sizeof(short);
+ raw.samples = samples; // һsample
+ raw.length = samples * channels * sizeof(short); // һsample
raw.bitdepth = bitdepth;
raw.end = (char*)data + raw.length;
}
@@ -228,7 +228,7 @@ Manager::get()->pushCommand(cmd); \
void SDLSource::setVolume(float volume)
{
- ActionFloat(SetVolume, volume);
+ ActionFloat(SetVolume, clamp(volume, 0.0f, 1.0f));
}
bool SDLSource::setLoop(bool loop)
@@ -274,7 +274,7 @@ Manager::get()->pushCommand(cmd); \
status.pos = 0;
break;
case Command::Action::SetVolume:
- //float cmd->parameter._float;
+ status.volume = cmd->parameter._float;
break;
case Command::Action::SetLoop:
status.loop = cmd->parameter._boolean;
@@ -285,39 +285,31 @@ Manager::get()->pushCommand(cmd); \
inline void SDLSource::process(void* buf, size_t size)
{
short* buffer = (short*)buf; // AUDIO_S16SYS
- unsigned int samples = size / SDLAUDIO_BYTEDEPTH;
- short* sample;
- short origin;
-
- const char bitdepth = raw.bitdepth;
- const char channles = raw.channels;
-
- int pos = status.pos;
- int pitch = status.pitch;
- int state = status.state;
- bool loop = status.loop;
- int volume = status.volume;
- short* clip16 = nullptr;
- char* clip8 = nullptr;
- int clip = 0;
-
- if (bitdepth == 8)
- clip8 = (char*)raw.data;
- else if (bitdepth == 16)
- clip16 = (short*)raw.data;
-
- for (int i = 0; i < samples; i+=2 /*˫*/)
+ int samples = (size / SDLAUDIO_BYTEDEPTH) >> 1; // ˫
+ const char L = 0, R = 1;
+ for (int i = 0; i < samples; ++i)
{
- /* Ƶļsampleᱻ */
- sample = buffer + i * SDLAUDIO_BYTEDEPTH;
- origin = *sample;
- if (bitdepth == 8)
+ char* source = (char*)raw.data + status.pos * (raw.bitdepth / 8) * raw.channels;
+ short left = 0;
+ short right = 0;
+ if (raw.bitdepth == 16)
+ {
+ left = ((short*)source)[L] * status.volume;
+ right = ((short*)source)[L + raw.channels - 1] * status.volume;
+ }
+ else if (raw.bitdepth == 8)
{
- clip = *clip8;
+ left = source[L] << 8; // << 8 Ŵ16bits
+ right = source[L + raw.channels - 1] << 8;
}
- else if (bitdepth == 16)
- clip = *clip16;
-
+ short* sample = buffer + (i << 1);
+ sample[L] = clamp(sample[L] + left, SHRT_MIN, SHRT_MAX); //
+ sample[R] = clamp(sample[R] + right, SHRT_MIN, SHRT_MAX); //
+ ++status.pos;
+ if (status.pos > raw.samples && status.loop)
+ status.pos = 0; // rewind
+ else if (status.pos > raw.samples && !status.loop)
+ break;
}
}
@@ -326,7 +318,7 @@ Manager::get()->pushCommand(cmd); \
return (manager == nullptr ? manager = new Manager() : manager);
}
- shared void Manager::processCommands()
+ void Manager::processCommands()
{
Command* cmd = nullptr;
SDLSource* source = nullptr;
@@ -344,7 +336,7 @@ Manager::get()->pushCommand(cmd); \
}
/* AUDIO_S16SYS[size>>1] buffer */
- shared void Manager::processSources(void* buf, size_t size)
+ void Manager::processSources(void* buf, size_t size)
{
/* clear render buffer */
memset(buf, 0, size);
@@ -359,7 +351,7 @@ Manager::get()->pushCommand(cmd); \
}
}
- shared void Manager::removeSource(SDLSource* source)
+ void Manager::removeSource(SDLSource* source)
{
std::vector<SDLSource*>::iterator it = sources.begin();
for (it = sources.begin(); it != sources.end(); )
@@ -373,18 +365,23 @@ Manager::get()->pushCommand(cmd); \
}
}
- shared void Manager::pushSource(SDLSource* source)
+ void Manager::removeAllSource()
+ {
+ sources.clear();
+ }
+
+ void Manager::pushSource(SDLSource* source)
{
if(source != nullptr)
sources.push_back(source);
}
- shared void Manager::pushCommand(SDLSourceCommand* cmd)
+ void Manager::pushCommand(SDLSourceCommand* cmd)
{
commands.push(cmd);
}
- shared Command* Manager::getCommand()
+ Command* Manager::getCommand()
{
if (!commandsPool.empty())
{
@@ -395,6 +392,7 @@ Manager::get()->pushCommand(cmd); \
return new Command();
}
+
}
}