|
From: Lasse Kärkkäi. <tr...@us...> - 2009-07-25 03:30:55
|
Module: performous
Branch: master
Commit: 10ba2a454d5d549e700a24e7b5ddd1b13697ca04
Author: Lasse Karkkainen <tro...@tr...>
Date: Sat Jul 25 06:29:26 2009 +0300
Added da::select which works as a switch-case for streams.
Implemented pause.
Removed old AudioSample code.
---
game/audio.cc | 12 ++++++--
game/audio.hh | 52 +----------------------------------
libs/libda/include/libda/mixer.hpp | 30 ++++++++++++++++++++-
3 files changed, 40 insertions(+), 54 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index e5c5fc8..5a89b93 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -70,7 +70,7 @@ void Audio::playMusic(std::vector<std::string> const& filenames, bool preview, d
}
da::lock_holder l2 = m_mixer.lock();
for (size_t i = 0; i < m_streams.size(); ++i) m_mixer.add(da::shared_ref(m_streams[i]));
- if (!preview) m_paused = false;
+ if (!preview) pause(false);
}
void Audio::playMusic(std::string const& filename, bool preview, double fadeTime, double startPos) {
@@ -113,13 +113,19 @@ void Audio::seek(double offset) {
Stream& s = *m_streams[i];
s.seek(clamp(s.pos() + offset, 0.0, s.duration()));
}
- m_paused = false;
+ pause(false);
}
void Audio::seekPos(double pos) {
boost::recursive_mutex::scoped_lock l(m_mutex);
da::lock_holder l2 = m_mixer.lock();
for (size_t i = 0; i < m_streams.size(); ++i) m_streams[i]->seek(pos);
- m_paused = false;
+ pause(false);
+}
+
+void Audio::pause(bool state) {
+ m_paused = state;
+ da::lock_holder l2 = m_mixer.lock();
+ m_mixer.pause(m_paused);
}
diff --git a/game/audio.hh b/game/audio.hh
index b3125d3..0cf1b0e 100644
--- a/game/audio.hh
+++ b/game/audio.hh
@@ -13,55 +13,6 @@
using boost::int16_t;
-#if 0
-/// audiosamples for songfiles
-struct AudioSample {
- /// sample rate
- double srate;
- /// volume
- double volume;
- /// sample
- std::vector<int16_t> sample;
- /// current position in the sample
- unsigned int offset;
- AudioSample() {}
- /// constructor
- AudioSample(std::string const& filename, unsigned int sr): srate(sr), volume(), sample(), offset() {
- FFmpeg mpeg(false, true, filename, sr);
- while( !mpeg.audioQueue.eof() ) {
- std::vector<int16_t> buffer;
- mpeg.audioQueue.tryPop(buffer, 1024);
- sample.insert(sample.end(), buffer.begin(), buffer.end());
- if( sample.size() > 1024 * 256 ) break; // do not authorized sample > 256k
- }
- std:: cout << "Loading sample " << filename << " done (size: " << sample.size() << ")" << std::endl;
- }
- /// resets audio position
- void reset_position() {
- offset = 0;
- }
- /** plays and mixes samples
- */
- bool operator()(da::pcm_data& data) {
- std::size_t maxSamples = data.channels * data.frames;
- if( offset >= sample.size() ) return false;
- if( sample.size() - offset < maxSamples ) {
- // not enough data in sample
- for (size_t i = offset; i < sample.size(); ++i) {
- data.rawbuf[i-offset] += da::conv_from_s16(sample[i]);
- }
- offset = sample.size();
- } else {
- for (size_t i = offset; i < offset + maxSamples; ++i) {
- data.rawbuf[i-offset] += da::conv_from_s16(sample[i]);
- }
- offset += maxSamples;
- }
- return true;
- }
-};
-#endif
-
/// audiostream
/** allows buffering, fading and mixing of audiostreams
*/
@@ -150,7 +101,8 @@ class Audio {
/// callback for the audio backend (libda)
bool operator()(da::pcm_data& areas);
/// pauses and unpauses playback
- void togglePause() { m_paused = !m_paused; }
+ void togglePause() { pause(!m_paused); }
+ void pause(bool state = true);
/// toggles synth playback (F4)
void toggleSynth(Notes const& notes) { m_notes = (m_notes ? NULL : ¬es); }
diff --git a/libs/libda/include/libda/mixer.hpp b/libs/libda/include/libda/mixer.hpp
index 2153853..366bff3 100644
--- a/libs/libda/include/libda/mixer.hpp
+++ b/libs/libda/include/libda/mixer.hpp
@@ -155,10 +155,36 @@ namespace da {
};
typedef std::auto_ptr<scoped_lock> lock_holder;
+
+ template <typename Key> class select {
+ typedef std::map<Key, callback_t> streams;
+ public:
+ void choose(Key const& k) {
+ typename streams::iterator it = m_streams.find(k);
+ if (it == m_streams.end()) throw std::logic_error("da::select::key: Invalid key");
+ m_key = k;
+ m_stream = it->second;
+ }
+ void insert(Key const& k, callback_t const& cb) {
+ m_streams[k] = cb;
+ }
+ bool operator()(pcm_data& data) {
+ if (!m_stream) return false;
+ return m_stream(data);
+ }
+ private:
+ streams m_streams;
+ Key m_key;
+ callback_t m_stream;
+ };
class mixer {
public:
- mixer(): m_chain(zero), m_mutex(boost::ref(m_chain)) {}
+ mixer(): m_chain(zero), m_mutex(boost::ref(m_select)) {
+ m_select.insert("paused", zero);
+ m_select.insert("normal", boost::ref(m_chain));
+ pause(false);
+ }
mixer(settings& s): m_chain(zero), m_mutex(boost::ref(m_chain)) { start(s); }
void start(settings& s) { m_settings = s; start(); s = m_settings; }
void start() {
@@ -180,9 +206,11 @@ namespace da {
m_chain.streams.erase(m_chain.streams.begin() + 1, m_chain.streams.end());
m_chain.add(shared_ref(new fadeout(shared_ref(ch.release()), time)));
}
+ void pause(bool p) { m_select.choose(p ? "paused" : "normal"); }
settings get_settings() { return m_settings; }
lock_holder lock() { return lock_holder(new scoped_lock(m_mutex)); }
private:
+ select<std::string> m_select;
chain m_chain;
mutex_stream m_mutex;
settings m_settings;
|