1
// -*- Mode: C++; tab-width:2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2
// vi:tw=80:et:ts=2:sts=2
4
// -----------------------------------------------------------------------
6
// This file is part of RLVM, a RealLive virtual machine clone.
8
// -----------------------------------------------------------------------
10
// Copyright (C) 2007 Elliot Glaysher
12
// This program is free software; you can redistribute it and/or modify
13
// it under the terms of the GNU General Public License as published by
14
// the Free Software Foundation; either version 3 of the License, or
15
// (at your option) any later version.
17
// This program is distributed in the hope that it will be useful,
18
// but WITHOUT ANY WARRANTY; without even the implied warranty of
19
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
// GNU General Public License for more details.
22
// You should have received a copy of the GNU General Public License
23
// along with this program; if not, write to the Free Software
24
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
26
// -----------------------------------------------------------------------
28
#include "Systems/SDL/SDLSoundChunk.hpp"
30
#include <SDL/SDL_mixer.h>
31
#include <boost/algorithm/string.hpp>
33
#include "Systems/Base/SoundSystem.hpp"
34
#include "Systems/SDL/SDLAudioLocker.hpp"
35
#include "xclannad/wavfile.h"
37
SDLSoundChunk::PlayingTable SDLSoundChunk::s_playing_table;
39
SDLSoundChunk::SDLSoundChunk(const boost::filesystem::path& path)
40
: sample_(loadSample(path)) {
43
SDLSoundChunk::SDLSoundChunk(char* data, int length)
44
: sample_(Mix_LoadWAV_RW(SDL_RWFromMem(data, length+0x2c), 1)),
48
SDLSoundChunk::~SDLSoundChunk() {
49
Mix_FreeChunk(sample_);
53
Mix_Chunk* SDLSoundChunk::loadSample(const boost::filesystem::path& path) {
54
if (boost::iequals(path.extension(), ".nwa")) {
55
// Hack to load NWA sounds into a MixChunk. I was resisted doing this
56
// because I assumed there was a better way, but this is essentially what
57
// jagarl does in xclannad too :(
58
FILE* f = fopen(path.external_file_string().c_str(), "r");
62
char* data = NWAFILE::ReadAll(f, size);
65
Mix_Chunk* chunk = Mix_LoadWAV_RW(SDL_RWFromMem(data, size), 1);
70
return Mix_LoadWAV(path.external_file_string().c_str());
74
void SDLSoundChunk::playChunkOn(int channel, int loops) {
76
SDLAudioLocker locker;
77
s_playing_table[channel] = shared_from_this();
80
if (Mix_PlayChannel(channel, sample_, loops) == -1) {
81
// TODO: Throw something here.
85
void SDLSoundChunk::fadeInChunkOn(int channel, int loops, int ms) {
87
SDLAudioLocker locker;
88
s_playing_table[channel] = shared_from_this();
91
if (Mix_FadeInChannel(channel, sample_, loops, ms) == -1) {
92
// TODO: Throw something here.
97
void SDLSoundChunk::SoundChunkFinishedPlayback(int channel) {
98
// Don't need an SDLAudioLocker because we're in the audio callback right
101
// Decrease the refcount of the SDLSoundChunk that just finished
103
s_playing_table[channel].reset();
107
int SDLSoundChunk::FindNextFreeExtraChannel() {
108
SDLAudioLocker locker;
110
for (int i = NUM_BASE_CHANNELS;
111
i < NUM_BASE_CHANNELS + NUM_EXTRA_WAVPLAY_CHANNELS; ++i) {
112
if (s_playing_table[i].get() == 0)
120
void SDLSoundChunk::StopChannel(int channel) {
121
Mix_HaltChannel(channel);
124
void SDLSoundChunk::StopAllChannels() {
128
void SDLSoundChunk::FadeOut(const int channel, const int fadetime) {
129
Mix_FadeOutChannel(channel, fadetime);