You can subscribe to this list here.
| 2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(25) |
Jul
(288) |
Aug
(119) |
Sep
(31) |
Oct
(59) |
Nov
(458) |
Dec
(359) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2010 |
Jan
(268) |
Feb
(26) |
Mar
(36) |
Apr
(48) |
May
(119) |
Jun
(37) |
Jul
(173) |
Aug
(429) |
Sep
(137) |
Oct
(156) |
Nov
(59) |
Dec
(45) |
| 2011 |
Jan
(398) |
Feb
(257) |
Mar
(49) |
Apr
(5) |
May
(34) |
Jun
(11) |
Jul
(38) |
Aug
(12) |
Sep
(1) |
Oct
(49) |
Nov
(5) |
Dec
(10) |
| 2012 |
Jan
(21) |
Feb
(32) |
Mar
(20) |
Apr
(1) |
May
(2) |
Jun
|
Jul
(173) |
Aug
|
Sep
(25) |
Oct
(6) |
Nov
(44) |
Dec
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:53:24
|
Module: performous
Branch: joinmenu
Commit: 7b038c5d9b01a797067b531f51c3c5cea852d263
Author: Vincent Le Ligeour <yo...@us...>
Date: Fri Aug 13 00:55:06 2010 +0200
Fixed ebuild for new portaudio audio code
---
.../games-arcade/performous/performous-9999.ebuild | 15 ++-------------
1 files changed, 2 insertions(+), 13 deletions(-)
diff --git a/portage-overlay/games-arcade/performous/performous-9999.ebuild b/portage-overlay/games-arcade/performous/performous-9999.ebuild
index 05a3313..5532ccd 100644
--- a/portage-overlay/games-arcade/performous/performous-9999.ebuild
+++ b/portage-overlay/games-arcade/performous/performous-9999.ebuild
@@ -34,7 +34,7 @@ LICENSE="GPL-2
SLOT="0"
KEYWORDS="~amd64 ~x86"
-IUSE="alsa debug editor gstreamer jack midi portaudio pulseaudio songs tools webcam"
+IUSE="debug editor midi songs tools webcam"
RDEPEND="gnome-base/librsvg
>=dev-libs/boost-1.39.0
@@ -48,11 +48,7 @@ RDEPEND="gnome-base/librsvg
editor? ( media-gfx/imagemagick[png] )
webcam? ( media-libs/opencv[v4l] )
>=media-video/ffmpeg-0.4.9_p20070616-r20
- alsa? ( media-libs/alsa-lib )
- jack? ( media-sound/jack-audio-connection-kit )
- portaudio? ( media-libs/portaudio )
- gstreamer? ( media-libs/gstreamer )
- pulseaudio? ( media-sound/pulseaudio )
+ media-libs/portaudio
sys-apps/help2man
!games-arcade/ultrastar-ng"
# Waiting for portmidi to enter portage (#90614)
@@ -77,19 +73,12 @@ src_unpack() {
src_configure() {
local mycmakeargs="
- $(cmake-utils_use alsa LibDA_PLUGIN_ALSA)
- $(cmake-utils_use jack LibDA_PLUGIN_JACK)
- $(cmake-utils_use gstreamer LibDA_PLUGIN_GSTREAMER)
- $(cmake-utils_use portaudio LibDA_PLUGIN_PORTAUDIO)
- $(cmake-utils_use pulseaudio LibDA_PLUGIN_PULSEAUDIO)
$(cmake-utils_use_enable tools TOOLS)
$(cmake-utils_use_enable editor EDITOR)
$(cmake-utils_use_no webcam WEBCAM)
-DCMAKE_INSTALL_PREFIX=${GAMES_PREFIX}
-DSHARE_INSTALL=share/performous
-DLOCALE_DIR=/usr/share
- -DLIBDA_AUTODETECT_PLUGINS=false
- -DLIBDA_PLUGIN_TESTING=false
-DCMAKE_BUILD_TYPE=Release"
# local mycmakeargs="
# $(cmake-utils_use_no midi MIDI)
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:53:22
|
Module: performous Branch: joinmenu Commit: 5bac66a8438f845bc1048ce319d6281944d43a47 Author: Lasse Karkkainen <tro...@tr...> Date: Fri Aug 13 01:44:19 2010 +0300 Merge branch 'portaudio' Conflicts: libs/libda/plugins/audio_dev_alsa.cpp libs/libda/plugins/audio_dev_pa19.cpp --- |
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:53:20
|
Module: performous Branch: joinmenu Commit: fcd25d5a9b71be47c5f99612ae794e2f51241b47 Author: Tapio Vierros <tap...@gm...> Date: Thu Aug 12 17:17:07 2010 +0300 Merge branch 'master' into portaudio Conflicts: game/audio.cc game/audio.hh game/main.cc game/screen_practice.cc --- |
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:53:17
|
Module: performous Branch: joinmenu Commit: 7f4450f014ab90c03e0eeafcf4bb36206353669d Author: Tapio Vierros <tap...@gm...> Date: Wed Aug 4 18:00:04 2010 +0300 Merge branch 'master' into portaudio --- |
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:53:15
|
Module: performous
Branch: joinmenu
Commit: a6fd1f98cedfdd849955bb63efc8ffc791d7f1ce
Author: Tapio Vierros <tap...@gm...>
Date: Tue Aug 3 21:25:08 2010 +0300
Simple time code correction for smoother gameplay.
---
game/audio.cc | 17 +++++++++++++++--
1 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 27c499a..bfba389 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -60,12 +60,20 @@ class Music {
Tracks tracks; ///< Audio decoders
double srate; ///< Sample rate
int64_t m_pos; ///< Current sample position
+ boost::posix_time::ptime m_syncTime; ///< Time of the previous audio timeSync
bool m_preview;
+
+ static boost::posix_time::ptime getTime() { return boost::posix_time::microsec_clock::universal_time(); }
+ double pos_internal() const { return double(m_pos) / srate / 2.0; }
+ double seconds(boost::posix_time::time_duration const& d) const { return 1e-6 * d.total_microseconds(); }
+ /// Do stuff for correcting time codes
+ void timeSync() { m_syncTime = getTime(); }
+
public:
double fadeLevel;
double fadeRate;
typedef std::map<std::string,std::string> Files;
- Music(Files const& filenames, unsigned int sr, bool preview): srate(sr), m_pos(), m_preview(preview), fadeLevel(), fadeRate() {
+ Music(Files const& filenames, unsigned int sr, bool preview): srate(sr), m_pos(), m_syncTime(getTime()), m_preview(preview), fadeLevel(), fadeRate() {
for (Files::const_iterator it = filenames.begin(), end = filenames.end(); it != end; ++it) {
tracks.insert(it->first, std::auto_ptr<Track>(new Track(it->second, sr)));
}
@@ -79,6 +87,7 @@ public:
if (t.mpeg.audioQueue(&*mixbuf.begin(), &*mixbuf.end(), m_pos, t.fadeLevel)) eof = false;
}
m_pos += end - begin;
+ timeSync(); // Keep audio synced
for (size_t i = 0, iend = mixbuf.size(); i != iend; ++i) {
if (i % 2 == 0) {
fadeLevel += fadeRate;
@@ -91,7 +100,11 @@ public:
}
void seek(double time) { m_pos = time * srate * 2.0; }
/// Get current position in seconds
- double pos() const { return double(m_pos) / srate / 2.0; }
+ double pos() {
+ double delay = seconds(getTime() - m_syncTime); // Delay since last sync
+ if (delay > 0.150) delay = 0; // If delay gets long, something is fishy (or pause is on)
+ return pos_internal() + delay; // Adjust internal time
+ }
double duration() const {
double dur = 0.0;
for (Tracks::const_iterator it = tracks.begin(), itend = tracks.end(); it != itend; ++it) {
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:53:12
|
Module: performous Branch: joinmenu Commit: 395e40fc605c707dbcc2cb9bb28260c5c458028f Author: Tapio Vierros <tap...@gm...> Date: Thu Jul 22 18:31:24 2010 +0300 Merge branch 'master' into portaudio --- |
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:53:10
|
Module: performous
Branch: joinmenu
Commit: b068521bce1700d3a5fdaedd142d64e89d344e4d
Author: Lasse Karkkainen <tro...@tr...>
Date: Sun Jul 18 22:50:44 2010 +0300
Audio config cleanup (removed in= setting) and simple support for mic assignments.
---
data/schema.xml | 6 +++---
game/audio.cc | 33 ++++++++++++++++++---------------
2 files changed, 21 insertions(+), 18 deletions(-)
diff --git a/data/schema.xml b/data/schema.xml
index 26ebb9f..1c293f8 100644
--- a/data/schema.xml
+++ b/data/schema.xml
@@ -179,9 +179,9 @@ to save the current settings to XML.
</locale>
</entry>
<entry name="audio/devices" type="string_list">
- <stringvalue>in=2 dev="default" mics="blue,red"</stringvalue><!-- SingStar mics -->
- <stringvalue>in=1 dev="Microphone"</stringvalue><!-- Rock Band branded Logitech mic -->
- <stringvalue>in=1</stringvalue><!-- Any other microphone -->
+ <stringvalue>dev="USBMIC" mics="blue,red"</stringvalue><!-- SingStar mics -->
+ <stringvalue>dev="Microphone" mics="*"</stringvalue><!-- Rock Band branded Logitech mic -->
+ <stringvalue>mics="blue"</stringvalue><!-- Any other microphone (only if blue is still free) -->
<stringvalue>out=2</stringvalue><!-- Any stereo output device -->
<locale name="C">
<short>Audio devices</short>
diff --git a/game/audio.cc b/game/audio.cc
index d29cebd..27c499a 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -298,16 +298,15 @@ struct Audio::Impl {
boost::ptr_vector<Analyzer> analyzers;
bool playback;
Impl(): playback() {
- int mic_count = 0;
// Parse audio devices from config
ConfigItem::StringList devs = config["audio/devices"].sl();
for (ConfigItem::StringList::const_iterator it = devs.begin(), end = devs.end(); it != end; ++it) {
try {
struct Params {
- int in, out;
+ int out;
unsigned int rate;
std::string dev;
- std::vector<int> mics;
+ std::vector<std::string> mics;
} params = Params();
params.rate = 48000;
// Break into tokens:
@@ -318,14 +317,11 @@ struct Audio::Impl {
std::string key = it2->first;
std::istringstream iss(it2->second);
if (key == "out") iss >> params.out;
- else if (key == "in") iss >> params.in;
else if (key == "rate") iss >> params.rate;
else if (key == "dev") std::getline(iss, params.dev);
else if (key == "mics") {
// Parse a comma-separated list of mics
- for (std::string mic; std::getline(iss, mic, ','); ) {
- params.mics.push_back(0); // TODO/FIXME: implement
- }
+ for (std::string mic; std::getline(iss, mic, ','); params.mics.push_back(mic)) {}
}
else throw std::runtime_error("Unknown device parameter " + key);
if (!iss.eof()) throw std::runtime_error("Syntax error parsing device parameter " + key);
@@ -333,7 +329,7 @@ struct Audio::Impl {
int count = Pa_GetDeviceCount();
int dev = -1;
// Handle empty device
- if (params.dev.empty()) dev = params.in ? Pa_GetDefaultInputDevice() : Pa_GetDefaultOutputDevice();
+ if (params.dev.empty()) dev = (params.out == 0 ? Pa_GetDefaultInputDevice() : Pa_GetDefaultOutputDevice());
// Try numeric value
if (dev < 0) {
std::istringstream iss(params.dev);
@@ -344,31 +340,38 @@ struct Audio::Impl {
bool found = false;
// Try exact match first, then partial
for (int match_partial = 0; match_partial < 2 && !skip_partial; ++match_partial) {
- // Loop through the devices and try everyting that matches the name
+ // Loop through the devices and try everything that matches the name
for (int i = -1; i < count && (dev < 0 || i == -1); ++i) {
if (dev > 0 && i == -1) i = dev;
else if (i == -1) continue;
PaDeviceInfo const* info = Pa_GetDeviceInfo(i);
if (!info) continue;
- if (params.in && info->maxInputChannels == 0) continue;
- if (params.out && info->maxOutputChannels == 0) continue;
+ if (info->maxInputChannels < int(params.mics.size())) continue;
+ if (info->maxOutputChannels < params.out) continue;
if (!match_partial && info->name != params.dev) continue;
if (match_partial && std::string(info->name).find(params.dev) == std::string::npos) continue;
// Match found if we got here
bool device_init_threw = true;
try {
- devices.push_back(new Device(params.in, params.out, params.rate, i));
+ devices.push_back(new Device(params.mics.size(), params.out, params.rate, i));
Device& d = devices.back();
device_init_threw = false;
// Start capture/playback on this device
d.start();
- // Assign mics for all channels of the device (TODO: proper assignments)
+ // Assign mics for all channels of the device
for (unsigned int j = 0; j < d.in; ++j) {
- if (mic_count + 1 > 4) break; // Too many mics
+ if (analyzers.size() >= 4) break; // Too many mics
+ std::string const& m = params.mics[j];
+ if (m.empty()) continue; // Input channel not used
+ // TODO: allow assignment in any order (not sequentially like the following code does)
+ if (m == "blue" && analyzers.size() != 0) continue;
+ if (m == "red" && analyzers.size() != 1) continue;
+ if (m == "green" && analyzers.size() != 2) continue;
+ if (m == "orange" && analyzers.size() != 3) continue;
+ // Add the new analyzer
Analyzer* a = new Analyzer(d.rate);
analyzers.push_back(a);
d.mics[j] = a;
- mic_count++;
}
// Assign playback output for the first available stereo output
if (!playback && d.out == 2) { d.outptr = &output; playback = true; }
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:53:08
|
Module: performous
Branch: joinmenu
Commit: f17a382e841b283ce7bad5bc09aef1141abe17d3
Author: Tapio Vierros <tap...@gm...>
Date: Sun Jul 18 20:43:16 2010 +0300
Device string matching moved to audio.cc, also try until working one is found.
---
game/audio.cc | 78 ++++++++++++++++++++++++--------
libs/libda/include/libda/portaudio.hpp | 39 ----------------
2 files changed, 59 insertions(+), 58 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 4c9ccd5..d29cebd 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -5,6 +5,7 @@
#include <boost/ptr_container/ptr_map.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/thread/mutex.hpp>
+#include <boost/lexical_cast.hpp>
#include <libda/fft.hpp> // For M_PI
#include <libda/portaudio.hpp>
#include <cmath>
@@ -254,14 +255,14 @@ struct Device {
// Init
const unsigned int in, out;
const double rate;
- const std::string dev;
+ const unsigned int dev;
portaudio::Stream stream;
std::vector<Analyzer*> mics;
Output* outptr;
- Device(unsigned int in, unsigned int out, double rate, std::string dev):
+ Device(unsigned int in, unsigned int out, double rate, unsigned int dev):
in(in), out(out), rate(rate), dev(dev),
- stream(*this, in ? portaudio::Params().channelCount(in).device(dev, true) : (const PaStreamParameters*)NULL, (out ? portaudio::Params().channelCount(out).device(dev, false) : (const PaStreamParameters*)NULL), rate),
+ stream(*this, in ? portaudio::Params().channelCount(in).device(dev) : (const PaStreamParameters*)NULL, (out ? portaudio::Params().channelCount(out).device(dev) : (const PaStreamParameters*)NULL), rate),
outptr()
{
mics.resize(in);
@@ -269,7 +270,8 @@ struct Device {
void start() {
PaError err = Pa_StartStream(stream);
- if (err != paNoError) throw std::runtime_error("Cannot start PortAudio audio stream " + dev + ": " + Pa_GetErrorText(err));
+ if (err != paNoError) throw std::runtime_error("Cannot start PortAudio audio stream "
+ + boost::lexical_cast<std::string>(dev) + ": " + Pa_GetErrorText(err));
}
int operator()(void const* input, void* output, unsigned long frames, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags) try {
@@ -288,6 +290,7 @@ struct Device {
}
};
+
struct Audio::Impl {
Output output;
portaudio::Init init;
@@ -327,23 +330,60 @@ struct Audio::Impl {
else throw std::runtime_error("Unknown device parameter " + key);
if (!iss.eof()) throw std::runtime_error("Syntax error parsing device parameter " + key);
}
- devices.push_back(new Device(params.in, params.out, params.rate, params.dev));
- Device& d = devices.back();
- // Assign mics for all channels of the device (TODO: proper assignments)
- for (unsigned int i = 0; i < d.in; ++i) {
- if (mic_count + i + 1 > 4) break; // Too many mics
- Analyzer* a = new Analyzer(d.rate);
- analyzers.push_back(a);
- d.mics[i] = a;
+ int count = Pa_GetDeviceCount();
+ int dev = -1;
+ // Handle empty device
+ if (params.dev.empty()) dev = params.in ? Pa_GetDefaultInputDevice() : Pa_GetDefaultOutputDevice();
+ // Try numeric value
+ if (dev < 0) {
+ std::istringstream iss(params.dev);
+ int tmp;
+ if (iss >> tmp && iss.get() == EOF && tmp >= 0 && tmp < count) dev = tmp;
}
- // Assign playback output for the first available stereo output
- if (!playback && d.out == 2) {
- d.outptr = &output;
- playback = true;
+ bool skip_partial = false;
+ bool found = false;
+ // Try exact match first, then partial
+ for (int match_partial = 0; match_partial < 2 && !skip_partial; ++match_partial) {
+ // Loop through the devices and try everyting that matches the name
+ for (int i = -1; i < count && (dev < 0 || i == -1); ++i) {
+ if (dev > 0 && i == -1) i = dev;
+ else if (i == -1) continue;
+ PaDeviceInfo const* info = Pa_GetDeviceInfo(i);
+ if (!info) continue;
+ if (params.in && info->maxInputChannels == 0) continue;
+ if (params.out && info->maxOutputChannels == 0) continue;
+ if (!match_partial && info->name != params.dev) continue;
+ if (match_partial && std::string(info->name).find(params.dev) == std::string::npos) continue;
+ // Match found if we got here
+ bool device_init_threw = true;
+ try {
+ devices.push_back(new Device(params.in, params.out, params.rate, i));
+ Device& d = devices.back();
+ device_init_threw = false;
+ // Start capture/playback on this device
+ d.start();
+ // Assign mics for all channels of the device (TODO: proper assignments)
+ for (unsigned int j = 0; j < d.in; ++j) {
+ if (mic_count + 1 > 4) break; // Too many mics
+ Analyzer* a = new Analyzer(d.rate);
+ analyzers.push_back(a);
+ d.mics[j] = a;
+ mic_count++;
+ }
+ // Assign playback output for the first available stereo output
+ if (!playback && d.out == 2) { d.outptr = &output; playback = true; }
+ } catch (...) {
+ if (!device_init_threw) devices.pop_back();
+ if (dev > 0) { skip_partial = true; break; } // Numeric, end search
+ continue;
+ }
+ skip_partial = true;
+ found = true;
+ break;
+ }
}
- // Start capture/playback on this device
- d.start();
- mic_count += d.in;
+ // Error handling
+ if (!found) throw std::runtime_error("Not found or already in use.");
} catch(std::runtime_error& e) {
std::cerr << "Audio device '" << *it << "': " << e.what() << std::endl;
}
diff --git a/libs/libda/include/libda/portaudio.hpp b/libs/libda/include/libda/portaudio.hpp
index cf0775f..fb2a575 100644
--- a/libs/libda/include/libda/portaudio.hpp
+++ b/libs/libda/include/libda/portaudio.hpp
@@ -48,45 +48,6 @@ namespace portaudio {
}
Params& channelCount(int val) { params.channelCount = val; return *this; }
Params& device(PaDeviceIndex val) { params.device = val; return *this; }
- Params& device(std::string const& name, bool inputDevice) {
- static std::vector<bool> used_devices(Pa_GetDeviceCount(), false);
- int count = Pa_GetDeviceCount();
- int val = -1;
- if (name.empty()) val = inputDevice ? Pa_GetDefaultInputDevice() : Pa_GetDefaultOutputDevice();
- if (val >= 0 && used_devices.at(val)) val = -1; // Don't use default device if it is already in use
- // Try numeric value
- if (val < 0) {
- std::istringstream iss(name);
- int tmp;
- if (iss >> tmp && iss.get() == EOF && tmp >= 0 && tmp < count && !used_devices.at(tmp)) val = tmp;
- }
- // Try matching exact name
- if (val < 0) for (int i = 0; i != count; ++i) {
- if (used_devices.at(i)) continue;
- PaDeviceInfo const* info = Pa_GetDeviceInfo(i);
- if (!info) continue;
- if (inputDevice && info->maxInputChannels == 0) continue;
- if (!inputDevice && info->maxOutputChannels == 0) continue;
- if (info->name == name) { val = i; break; }
- }
- // Try matching partial name
- if (val < 0) for (int i = 0; i != count; ++i) {
- if (used_devices.at(i)) continue;
- PaDeviceInfo const* info = Pa_GetDeviceInfo(i);
- if (!info) continue;
- if (inputDevice && info->maxInputChannels == 0) continue;
- if (!inputDevice && info->maxOutputChannels == 0) continue;
- if (std::string(info->name).find(name) != std::string::npos) { val = i; break; }
- }
- // Error handling
- std::string dir = inputDevice ? "input" : "output";
- if (val < 0) throw std::runtime_error(name.empty() ? "No PortAudio default " + dir + " device found" : "No matching PortAudio " + dir + " device (" + name + ") found");
- PaDeviceInfo const* info = Pa_GetDeviceInfo(val);
- if (!info) throw std::runtime_error("The specified " + dir + " device (" + name + ") does not exist."); // FIXME: When does this happen?
- if ((inputDevice ? info->maxInputChannels : info->maxOutputChannels) == 0) throw std::runtime_error("The PortAudio " + dir + " device specified (" + name + ") has no " + dir + " channels");
- // Set the device
- return device(val);
- }
Params& sampleFormat(PaSampleFormat val) { params.sampleFormat = val; return *this; }
Params& suggestedLatency(PaTime val) { params.suggestedLatency = val; return *this; }
Params& hostApiSpecificStreamInfo(void* val) { params.hostApiSpecificStreamInfo = val; return *this; }
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:53:05
|
Module: performous
Branch: joinmenu
Commit: 1bf5c55883193d8f6d1e573e7ba28cb45846006e
Author: Vincent Le Ligeour <yo...@us...>
Date: Sun Jul 18 18:38:25 2010 +0200
Disabled synth on stop and fade out
---
game/audio.cc | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 458ee35..4c9ccd5 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -395,11 +395,23 @@ void Audio::playMusic(std::string const& filename, bool preview, double fadeTime
void Audio::stopMusic() {
std::map<std::string,std::string> m;
playMusic(m, false, 0.0);
+ {
+ Output& o = self->output;
+ // stop synth when music is stopped
+ boost::mutex::scoped_lock l(o.synth_mutex);
+ o.synth.reset();
+ }
}
void Audio::fadeout(double fadeTime) {
std::map<std::string,std::string> m;
playMusic(m, false, fadeTime);
+ {
+ Output& o = self->output;
+ // stop synth when music is stopped
+ boost::mutex::scoped_lock l(o.synth_mutex);
+ o.synth.reset();
+ }
}
double Audio::getPosition() const {
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:53:01
|
Module: performous
Branch: joinmenu
Commit: 07e9e2fa72fc060cf47a0bfc4476b26052689e17
Author: Lasse Karkkainen <tro...@tr...>
Date: Sun Jul 18 19:08:15 2010 +0300
Implement sample iterators and multichannel capture
---
game/audio.cc | 9 +++++----
libs/libda/include/libda/sample.hpp | 16 ++++++++++++++++
2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index b92e325..458ee35 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -273,13 +273,14 @@ struct Device {
}
int operator()(void const* input, void* output, unsigned long frames, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags) try {
- float const* in = static_cast<float const*>(input);
- float* out = static_cast<float*>(output);
+ float const* inbuf = static_cast<float const*>(input);
+ float* outbuf = static_cast<float*>(output);
for (std::size_t i = 0; i < mics.size(); ++i) {
if (!mics[i]) continue; // No analyzer? -> Channel not used
- mics[i]->input(in, in + 1 * frames); // FIXME: needs libda iterators for multiple channel support
+ da::sample_const_iterator it = da::sample_const_iterator(inbuf + i, in);
+ mics[i]->input(it, it + frames);
}
- if (outptr) outptr->callback(out, out + 2 * frames);
+ if (outptr) outptr->callback(outbuf, outbuf + 2 * frames);
return paContinue;
} catch (std::exception& e) {
std::cerr << "Exception in audio callback: " << e.what() << std::endl;
diff --git a/libs/libda/include/libda/sample.hpp b/libs/libda/include/libda/sample.hpp
index 58502e0..29383e7 100644
--- a/libs/libda/include/libda/sample.hpp
+++ b/libs/libda/include/libda/sample.hpp
@@ -49,6 +49,22 @@ namespace da {
static inline int conv_to_s16_fast(sample_t s) { return static_cast<int>(s * max_s16); }
static inline int conv_to_s24_fast(sample_t s) { return static_cast<int>(s * max_s24); }
static inline int conv_to_s32_fast(sample_t s) { return static_cast<int>(s * max_s32); }
+
+ template <typename ValueType> class step_iterator: public std::iterator<std::random_access_iterator_tag, ValueType> {
+ ValueType* m_pos;
+ std::ptrdiff_t m_step;
+ public:
+ step_iterator(ValueType* pos, std::ptrdiff_t step): m_pos(pos), m_step(step) {}
+ ValueType& operator*() { return *m_pos; }
+ step_iterator operator+(std::ptrdiff_t rhs) { return step_iterator(m_pos + m_step * rhs, m_step); }
+ step_iterator& operator++() { m_pos += m_step; return *this; }
+ bool operator!=(step_iterator const& rhs) const { return m_pos != rhs.m_pos; }
+ std::ptrdiff_t operator-(step_iterator const& rhs) const { return (m_pos - rhs.m_pos) / m_step; }
+ // TODO: more operators
+ };
+
+ typedef step_iterator<sample_t> sample_iterator;
+ typedef step_iterator<sample_t const> sample_const_iterator;
}
#endif
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:52:58
|
Module: performous
Branch: joinmenu
Commit: 23c1b6546d236b08953cb504fa88233055c25c93
Author: Tapio Vierros <tap...@gm...>
Date: Sun Jul 18 17:55:06 2010 +0300
Only match the same device once.
---
libs/libda/include/libda/portaudio.hpp | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/libs/libda/include/libda/portaudio.hpp b/libs/libda/include/libda/portaudio.hpp
index c1ab993..cf0775f 100644
--- a/libs/libda/include/libda/portaudio.hpp
+++ b/libs/libda/include/libda/portaudio.hpp
@@ -49,17 +49,20 @@ namespace portaudio {
Params& channelCount(int val) { params.channelCount = val; return *this; }
Params& device(PaDeviceIndex val) { params.device = val; return *this; }
Params& device(std::string const& name, bool inputDevice) {
+ static std::vector<bool> used_devices(Pa_GetDeviceCount(), false);
int count = Pa_GetDeviceCount();
int val = -1;
if (name.empty()) val = inputDevice ? Pa_GetDefaultInputDevice() : Pa_GetDefaultOutputDevice();
+ if (val >= 0 && used_devices.at(val)) val = -1; // Don't use default device if it is already in use
// Try numeric value
if (val < 0) {
std::istringstream iss(name);
int tmp;
- if (iss >> tmp && iss.get() == EOF && tmp >= 0 && tmp < count) val = tmp;
+ if (iss >> tmp && iss.get() == EOF && tmp >= 0 && tmp < count && !used_devices.at(tmp)) val = tmp;
}
// Try matching exact name
if (val < 0) for (int i = 0; i != count; ++i) {
+ if (used_devices.at(i)) continue;
PaDeviceInfo const* info = Pa_GetDeviceInfo(i);
if (!info) continue;
if (inputDevice && info->maxInputChannels == 0) continue;
@@ -68,6 +71,7 @@ namespace portaudio {
}
// Try matching partial name
if (val < 0) for (int i = 0; i != count; ++i) {
+ if (used_devices.at(i)) continue;
PaDeviceInfo const* info = Pa_GetDeviceInfo(i);
if (!info) continue;
if (inputDevice && info->maxInputChannels == 0) continue;
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:52:56
|
Module: performous
Branch: joinmenu
Commit: 05aaf1dc2011ac1756fe72bb90d07cad14b360d3
Author: Tapio Vierros <tap...@gm...>
Date: Sun Jul 18 17:14:53 2010 +0300
Limit the number of mics.
---
game/audio.cc | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index b92264f..b92e325 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -294,6 +294,7 @@ struct Audio::Impl {
boost::ptr_vector<Analyzer> analyzers;
bool playback;
Impl(): playback() {
+ int mic_count = 0;
// Parse audio devices from config
ConfigItem::StringList devs = config["audio/devices"].sl();
for (ConfigItem::StringList::const_iterator it = devs.begin(), end = devs.end(); it != end; ++it) {
@@ -327,8 +328,9 @@ struct Audio::Impl {
}
devices.push_back(new Device(params.in, params.out, params.rate, params.dev));
Device& d = devices.back();
- // Assign mics for all channels of the device (TODO: proper assignments and limit the number of mics)
+ // Assign mics for all channels of the device (TODO: proper assignments)
for (unsigned int i = 0; i < d.in; ++i) {
+ if (mic_count + i + 1 > 4) break; // Too many mics
Analyzer* a = new Analyzer(d.rate);
analyzers.push_back(a);
d.mics[i] = a;
@@ -340,6 +342,7 @@ struct Audio::Impl {
}
// Start capture/playback on this device
d.start();
+ mic_count += d.in;
} catch(std::runtime_error& e) {
std::cerr << "Audio device '" << *it << "': " << e.what() << std::endl;
}
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:52:54
|
Module: performous
Branch: joinmenu
Commit: 89d958378a472a339bf38db6c2ff6a81ec5c7451
Author: Tapio Vierros <tap...@gm...>
Date: Sun Jul 18 17:05:09 2010 +0300
Audio device matching by name, first exact, then if not found, partial.
---
libs/libda/include/libda/portaudio.hpp | 13 ++++++++++---
1 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/libs/libda/include/libda/portaudio.hpp b/libs/libda/include/libda/portaudio.hpp
index d6e33b1..c1ab993 100644
--- a/libs/libda/include/libda/portaudio.hpp
+++ b/libs/libda/include/libda/portaudio.hpp
@@ -58,14 +58,21 @@ namespace portaudio {
int tmp;
if (iss >> tmp && iss.get() == EOF && tmp >= 0 && tmp < count) val = tmp;
}
- // Try name matching
+ // Try matching exact name
if (val < 0) for (int i = 0; i != count; ++i) {
PaDeviceInfo const* info = Pa_GetDeviceInfo(i);
if (!info) continue;
if (inputDevice && info->maxInputChannels == 0) continue;
if (!inputDevice && info->maxOutputChannels == 0) continue;
- val = i;
- break;
+ if (info->name == name) { val = i; break; }
+ }
+ // Try matching partial name
+ if (val < 0) for (int i = 0; i != count; ++i) {
+ PaDeviceInfo const* info = Pa_GetDeviceInfo(i);
+ if (!info) continue;
+ if (inputDevice && info->maxInputChannels == 0) continue;
+ if (!inputDevice && info->maxOutputChannels == 0) continue;
+ if (std::string(info->name).find(name) != std::string::npos) { val = i; break; }
}
// Error handling
std::string dir = inputDevice ? "input" : "output";
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:52:52
|
Module: performous
Branch: joinmenu
Commit: e94fa6f85f83b4490ec5a6873e5a4d8d38277677
Author: Tapio Vierros <tap...@gm...>
Date: Sun Jul 18 16:45:32 2010 +0300
Allow spaces before key start in key=value parser.
---
game/audio.cc | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 3d34946..b92264f 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -29,11 +29,11 @@ namespace {
continue;
}
// Space in key (bad)
- if (st[i] == ' ' && parsing_key)
- throw std::logic_error("Error: Space in key in string: " + st);
+ if (st[i] == ' ' && parsing_key && !key.empty())
+ throw std::logic_error("Space in key in string: " + st);
// Value start
if (st[i] == '=' && !inside_quotes) {
- if (key.empty()) throw std::logic_error("Error: Empty key in string: " + st);
+ if (key.empty()) throw std::logic_error("Empty key in string: " + st);
parsing_key = false;
continue;
}
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:52:49
|
Module: performous
Branch: joinmenu
Commit: 10510c64c4bed76a1b7c4a3c3cdb5087625c0164
Author: Tapio Vierros <tap...@gm...>
Date: Sun Jul 18 16:42:05 2010 +0300
Parse quoted strings.
---
game/audio.cc | 64 +++++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 51 insertions(+), 13 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 3d85777..3d34946 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -9,6 +9,45 @@
#include <libda/portaudio.hpp>
#include <cmath>
#include <iostream>
+#include <map>
+
+namespace {
+ std::map<std::string, std::string> parseKeyValuePairs(const std::string& st) {
+ std::map<std::string, std::string> ret;
+ bool inside_quotes = false;
+ int parsing_key = true;
+ std::string key = "", value = "";
+ for (size_t i = 0; i < st.size(); ++i) {
+ // Quotes
+ if (st[i] == '"') { inside_quotes = !inside_quotes; continue; }
+ // Value end
+ if (st[i] == ' ' && !inside_quotes && !parsing_key) {
+ if (value.empty()) continue; // Skip whitespace after equals sign
+ ret[key] = value;
+ key = ""; value = "";
+ parsing_key = true;
+ continue;
+ }
+ // Space in key (bad)
+ if (st[i] == ' ' && parsing_key)
+ throw std::logic_error("Error: Space in key in string: " + st);
+ // Value start
+ if (st[i] == '=' && !inside_quotes) {
+ if (key.empty()) throw std::logic_error("Error: Empty key in string: " + st);
+ parsing_key = false;
+ continue;
+ }
+ // Key start
+ if (st[i] != ' ' && parsing_key) { key += st[i]; continue; }
+ // If we got here, it is value
+ value += st[i];
+ }
+ // Handle last key
+ if (!key.empty()) ret[key] = value;
+ return ret;
+ }
+}
+
class Music {
struct Track {
@@ -267,25 +306,24 @@ struct Audio::Impl {
} params = Params();
params.rate = 48000;
// Break into tokens:
- std::istringstream iss(*it);
- for (std::string token; std::getline(iss, token, ' '); ) {
- // Parse key=value
- std::istringstream iss2(token);
- std::string key;
- std::getline(iss2, key, '=');
- if (key == "out") iss2 >> params.out;
- else if (key == "in") iss2 >> params.in;
- else if (key == "rate") iss2 >> params.rate;
- else if (key == "dev") std::getline(iss2, params.dev);
+ std::map<std::string, std::string> keyvalues = parseKeyValuePairs(*it);
+ for (std::map<std::string, std::string>::const_iterator it2 = keyvalues.begin();
+ it2 != keyvalues.end(); ++it2) {
+ // Handle keys
+ std::string key = it2->first;
+ std::istringstream iss(it2->second);
+ if (key == "out") iss >> params.out;
+ else if (key == "in") iss >> params.in;
+ else if (key == "rate") iss >> params.rate;
+ else if (key == "dev") std::getline(iss, params.dev);
else if (key == "mics") {
// Parse a comma-separated list of mics
- for (std::string mic; std::getline(iss2, mic, ','); ) {
+ for (std::string mic; std::getline(iss, mic, ','); ) {
params.mics.push_back(0); // TODO/FIXME: implement
}
-
}
else throw std::runtime_error("Unknown device parameter " + key);
- if (!iss2.eof()) throw std::runtime_error("Syntax error parsing device parameter " + key);
+ if (!iss.eof()) throw std::runtime_error("Syntax error parsing device parameter " + key);
}
devices.push_back(new Device(params.in, params.out, params.rate, params.dev));
Device& d = devices.back();
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:52:47
|
Module: performous
Branch: joinmenu
Commit: cb9219b0dfb92e14d7a6798a5d887e5dac149413
Author: Lasse Karkkainen <tro...@tr...>
Date: Sun Jul 18 10:18:40 2010 +0300
Fix init order bug that caused segfault on Alt+F4 from singing screen
---
game/audio.cc | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 81eec71..3d85777 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -249,10 +249,10 @@ struct Device {
};
struct Audio::Impl {
+ Output output;
portaudio::Init init;
boost::ptr_vector<Device> devices;
boost::ptr_vector<Analyzer> analyzers;
- Output output;
bool playback;
Impl(): playback() {
// Parse audio devices from config
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:52:44
|
Module: performous
Branch: joinmenu
Commit: c0db3b7c1d3a2bfd0245e335844e325cede35ab3
Author: Lasse Karkkainen <tro...@tr...>
Date: Sun Jul 18 10:12:40 2010 +0300
Another way of struct initialization avoids GCC compile warnings.
---
tools/itg_pck.cc | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/itg_pck.cc b/tools/itg_pck.cc
index 0593e37..0dbe4cf 100644
--- a/tools/itg_pck.cc
+++ b/tools/itg_pck.cc
@@ -46,7 +46,7 @@ struct Extract {
std::string ext;
if (file.mode == 1) {
std::vector<char> buf2(file.size);
- z_stream strm = {};
+ z_stream strm = z_stream();
strm.avail_in = buffer.size();
strm.next_in = reinterpret_cast<Bytef*>(&buffer[0]);
strm.avail_out = buf2.size();
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:52:40
|
Module: performous Branch: joinmenu Commit: a5e395fde064c89588a393d577ace04a50ea4f11 Author: Lasse Karkkainen <tro...@tr...> Date: Sun Jul 18 09:37:44 2010 +0300 Merge branch 'master' into portaudio Conflicts: game/main.cc game/screen_intro.hh game/screen_practice.cc game/screen_practice.hh --- |
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:52:36
|
Module: performous
Branch: joinmenu
Commit: d28fe6660eae95b465e5f58c35d3afde8129680c
Author: Lasse Karkkainen <tro...@tr...>
Date: Sun Jul 18 09:22:36 2010 +0300
Audio device configuration implemented (mostly)
---
data/schema.xml | 2 +-
game/audio.cc | 74 ++++++++++++++++++++++++++++++++++++++++--------------
2 files changed, 56 insertions(+), 20 deletions(-)
diff --git a/data/schema.xml b/data/schema.xml
index c41c864..26ebb9f 100644
--- a/data/schema.xml
+++ b/data/schema.xml
@@ -178,7 +178,7 @@ to save the current settings to XML.
<long>Affects instruments and dancing only. The total of USB (guitar or dance pad) latency combined with audio output latency. Adjust so that you can hit the notes best when playing by ear (not looking on screen). Use Ctrl+F5/F6 to adjust while performing.</long>
</locale>
</entry>
- <entry name="audio/device" type="string_list">
+ <entry name="audio/devices" type="string_list">
<stringvalue>in=2 dev="default" mics="blue,red"</stringvalue><!-- SingStar mics -->
<stringvalue>in=1 dev="Microphone"</stringvalue><!-- Rock Band branded Logitech mic -->
<stringvalue>in=1</stringvalue><!-- Any other microphone -->
diff --git a/game/audio.cc b/game/audio.cc
index 2c6a3b4..7071e50 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -213,9 +213,9 @@ struct Output {
struct Device {
// Init
- unsigned int in, out;
- double rate;
- std::string dev;
+ const unsigned int in, out;
+ const double rate;
+ const std::string dev;
portaudio::Stream stream;
std::vector<Analyzer*> mics;
Output* outptr;
@@ -236,8 +236,8 @@ struct Device {
float const* in = static_cast<float const*>(input);
float* out = static_cast<float*>(output);
for (std::size_t i = 0; i < mics.size(); ++i) {
- if (!mics[i]) continue; // Channel not used
- mics[i]->input(in, in + 1 * frames);
+ if (!mics[i]) continue; // No analyzer? -> Channel not used
+ mics[i]->input(in, in + 1 * frames); // FIXME: needs libda iterators for multiple channel support
}
if (outptr) outptr->callback(out, out + 2 * frames);
return paContinue;
@@ -253,21 +253,57 @@ struct Audio::Impl {
boost::ptr_vector<Analyzer> analyzers;
Output output;
bool playback;
- Impl() {
- devices.push_back(new Device(1, 2, 48000.0, ""));
- // One analyzer for mono input (TODO: fix callbackInput to allow more)
- analyzers.push_back(new Analyzer(48000.0));
- devices[0].mics[0] = &analyzers[0];
- playback = false;
- for (size_t i = 0; i < devices.size(); ++i) {
- Device& d = devices[i];
- // Assign playback output for the first available stereo output
- if (!playback && d.out == 2) {
- d.outptr = &output;
- playback = true;
+ Impl(): playback() {
+ // Parse audio devices from config
+ ConfigItem::StringList devs = config["audio/devices"].sl();
+ for (ConfigItem::StringList::const_iterator it = devs.begin(), end = devs.end(); it != end; ++it) {
+ try {
+ struct Params {
+ int in, out;
+ unsigned int rate;
+ std::string dev;
+ std::vector<int> mics;
+ } params = Params();
+ params.rate = 48000;
+ // Break into tokens:
+ std::istringstream iss(*it);
+ for (std::string token; std::getline(iss, token, ' '); ) {
+ // Parse key=value
+ std::istringstream iss2(token);
+ std::string key;
+ std::getline(iss2, key, '=');
+ if (key == "out") iss2 >> params.out;
+ else if (key == "in") iss2 >> params.in;
+ else if (key == "rate") iss2 >> params.rate;
+ else if (key == "dev") std::getline(iss2, params.dev);
+ else if (key == "mics") {
+ // Parse a comma-separated list of mics
+ for (std::string mic; std::getline(iss2, mic, ','); ) {
+ params.mics.push_back(0); // TODO/FIXME: implement
+ }
+
+ }
+ else throw std::runtime_error("Unknown device parameter " + key);
+ if (!iss2.eof()) throw std::runtime_error("Syntax error parsing device parameter " + key);
+ }
+ devices.push_back(new Device(params.in, params.out, params.rate, params.dev));
+ Device& d = devices.back();
+ // Assign mics for all channels of the device (TODO: proper assignments and limit the number of mics)
+ for (unsigned int i = 0; i < d.in; ++i) {
+ Analyzer* a = new Analyzer(d.rate);
+ analyzers.push_back(a);
+ d.mics[i] = a;
+ }
+ // Assign playback output for the first available stereo output
+ if (!playback && d.out == 2) {
+ d.outptr = &output;
+ playback = true;
+ }
+ // Start capture/playback on this device
+ d.start();
+ } catch(std::runtime_error& e) {
+ std::cerr << "Audio device '" << *it << "': " << e.what() << std::endl;
}
- // Start capture/playback on this device
- d.start();
}
}
};
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:52:34
|
Module: performous
Branch: joinmenu
Commit: aa42591f3f8fa2dfc4f072e836205f24f6774215
Author: Lasse Karkkainen <tro...@tr...>
Date: Sun Jul 18 00:51:55 2010 +0300
Replace mics/pdev command line options with --audio
---
game/main.cc | 11 +++--------
1 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/game/main.cc b/game/main.cc
index f466381..a297f0d 100644
--- a/game/main.cc
+++ b/game/main.cc
@@ -254,8 +254,7 @@ int main(int argc, char** argv) try {
std::ios::sync_with_stdio(false); // We do not use C stdio
std::srand(std::time(NULL));
// Parse commandline options
- std::vector<std::string> mics;
- std::vector<std::string> pdevs;
+ std::vector<std::string> devices;
std::vector<std::string> songdirs;
namespace po = boost::program_options;
po::options_description opt1("Generic options");
@@ -266,10 +265,7 @@ int main(int argc, char** argv) try {
("songlist", po::value<std::string>(&songlist), "save a list of songs in the specified folder");
po::options_description opt2("Configuration options");
opt2.add_options()
- ("mics", po::value<std::vector<std::string> >(&mics)->composing(), "specify the microphones to use")
- ("pdev", po::value<std::vector<std::string> >(&pdevs)->composing(), "specify the playback device")
- ("michelp", "detailed help and device list for --mics")
- ("pdevhelp", "detailed help and device list for --pdev")
+ ("audio", po::value<std::vector<std::string> >(&devices)->composing(), "specify an audio device to use")
("jstest", "utility to get joystick button mappings");
po::options_description opt3("Hidden options");
opt3.add_options()
@@ -312,8 +308,7 @@ int main(int argc, char** argv) try {
}
// Override XML config for options that were specified from commandline or performous.conf
confOverride(songdirs, "system/path_songs");
- confOverride(mics, "audio/capture");
- confOverride(pdevs, "audio/playback");
+ confOverride(devices, "audio/devices");
getPaths(); // Initialize paths before other threads start
if (vm.count("jstest")) { // Joystick test program
std::cout << std::endl << "Joystick utility - Touch your joystick to see buttons here" << std::endl
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:52:31
|
Module: performous
Branch: joinmenu
Commit: 63476ceedd38feb0ff2c34328e8085c42bab56ad
Author: Tapio Vierros <tap...@gm...>
Date: Thu Jul 15 20:31:17 2010 +0300
Output PA devices to console.
---
game/audio.cc | 4 ++++
game/audio.hh | 13 +++++++------
libs/libda/include/libda/portaudio.hpp | 13 ++++++++++++-
3 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 1cb771a..2c6a3b4 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -150,6 +150,7 @@ struct Output {
std::vector<Command> commands;
volatile bool paused;
Output(): paused(false) {}
+
void callbackUpdate() {
boost::mutex::scoped_try_lock l(mutex);
if (!l.owns_lock()) return; // No update now, try again later (cannot stop and wait for mutex to be released)
@@ -174,6 +175,7 @@ struct Output {
}
commands.clear();
}
+
void callback(float* begin, float* end) {
callbackUpdate();
std::fill(begin, end, 0.0f);
@@ -224,10 +226,12 @@ struct Device {
{
mics.resize(in);
}
+
void start() {
PaError err = Pa_StartStream(stream);
if (err != paNoError) throw std::runtime_error("Cannot start PortAudio audio stream " + dev + ": " + Pa_GetErrorText(err));
}
+
int operator()(void const* input, void* output, unsigned long frames, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags) try {
float const* in = static_cast<float const*>(input);
float* out = static_cast<float*>(output);
diff --git a/game/audio.hh b/game/audio.hh
index dab6770..27018f8 100644
--- a/game/audio.hh
+++ b/game/audio.hh
@@ -27,15 +27,15 @@ public:
* @param startPos starting position
*/
void playMusic(std::string const& filename, bool preview = false, double fadeTime = 0.5, double startPos = 0.0);
- /// plays a list of songs
+ /** Plays a list of songs **/
void playMusic(std::map<std::string,std::string> const& filenames, bool preview = false, double fadeTime = 0.5, double startPos = 0.0);
- /// loads/plays/unloads a sample
+ /** Loads/plays/unloads a sample **/
void loadSample(std::string const& streamId, std::string const& filename);
void playSample(std::string const& streamId);
void unloadSample(std::string const& streamId);
- /// stops music
+ /** Stops music **/
void stopMusic();
- /// fades music out
+ /** Fades music out **/
void fadeout(double time = 1.0);
/** Get the length of the currently playing song, in seconds. **/
double getLength() const;
@@ -54,8 +54,9 @@ public:
void togglePause() { pause(!isPaused()); }
void pause(bool state = true);
bool isPaused() const;
- void toggleSynth(Notes const&); ///< toggles synth playback
- /// Adjust volume level of a single track (used for muting incorrectly played instruments). Range 0.0 to 1.0.
+ /** Toggle synth playback **/
+ void toggleSynth(Notes const&);
+ /** Adjust volume level of a single track (used for muting incorrectly played instruments). Range 0.0 to 1.0. **/
void streamFade(std::string track, double volume);
double getSR() const { return 48000.0; }
};
diff --git a/libs/libda/include/libda/portaudio.hpp b/libs/libda/include/libda/portaudio.hpp
index 8add471..d6e33b1 100644
--- a/libs/libda/include/libda/portaudio.hpp
+++ b/libs/libda/include/libda/portaudio.hpp
@@ -25,7 +25,18 @@ namespace portaudio {
}
struct Init {
- Init() { PORTAUDIO_CHECKED(Pa_Initialize, ()); }
+ Init()
+ {
+ PORTAUDIO_CHECKED(Pa_Initialize, ());
+ // Print the devices
+ std::cout << "PortAudio devices:\n";
+ for (int i = 0, end = Pa_GetDeviceCount(); i != end; ++i) {
+ PaDeviceInfo const* info = Pa_GetDeviceInfo(i);
+ if (!info) continue;
+ std::cout << " " << i << " " << info->name << " (" << info->maxInputChannels << " in, " << info->maxOutputChannels << " out)\n";
+ }
+ std::cout << std::endl;
+ }
~Init() { Pa_Terminate(); }
};
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:52:29
|
Module: performous
Branch: joinmenu
Commit: 7b5d9e1559f236a44c38e8c82675f1d627423d94
Author: Vincent Le Ligeour <yo...@us...>
Date: Mon Jul 5 21:26:46 2010 +0200
Added note synth to audio code
---
game/audio.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++
game/audio.hh | 2 +-
2 files changed, 46 insertions(+), 1 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index ac93f15..1cb771a 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -102,6 +102,36 @@ struct Sample {
}
};
+struct Synth {
+ private:
+ Notes m_notes;
+ double srate; ///< Sample rate
+ public:
+ Synth(Notes const& notes, unsigned int sr) : m_notes(notes), srate(sr) {};
+ void operator()(float* begin, float* end, double position) {
+ static double phase = 0.0;
+ for (float *i = begin; i < end; ++i) *i *= 0.3; // Decrease music volume
+
+ std::vector<float> mixbuf(end - begin);
+ Notes::const_iterator it = m_notes.begin();
+
+ while (it != m_notes.end() && it->end < position) ++it;
+ if (it == m_notes.end() || it->type == Note::SLEEP || it->begin > position) { phase = 0.0; return; }
+ int note = it->note % 12;
+ double d = (note + 1) / 13.0;
+ double freq = MusicalScale().getNoteFreq(note + 12);
+ double value = 0.0;
+ // Synthesize tones
+ for (size_t i = 0, iend = mixbuf.size(); i != iend; ++i) {
+ if (i % 2 == 0) {
+ value = d * 0.2 * std::sin(phase) + 0.2 * std::sin(2 * phase) + (1.0 - d) * 0.2 * std::sin(4 * phase);
+ phase += 2.0 * M_PI * freq / srate;
+ }
+ begin[i] += value;
+ }
+ }
+};
+
struct Command {
enum { TRACK_FADE, SAMPLE_RESET } type;
@@ -112,6 +142,8 @@ struct Command {
struct Output {
boost::mutex mutex;
boost::mutex samples_mutex;
+ boost::mutex synth_mutex;
+ std::auto_ptr<Synth> synth;
std::auto_ptr<Music> preloading;
boost::ptr_vector<Music> playing, disposing;
boost::ptr_map<std::string, Sample> samples;
@@ -167,6 +199,13 @@ struct Output {
}
}
}
+ // Mix synth if available (should be done at the end)
+ {
+ boost::mutex::scoped_try_lock l(synth_mutex, boost::defer_lock);
+ if(l.try_lock() && synth.get() && !playing.empty()) {
+ (*synth.get())(begin, end, playing[0].pos());
+ }
+ }
}
};
@@ -326,5 +365,11 @@ void Audio::streamFade(std::string track, double fadeLevel) {
o.commands.push_back(cmd);
}
+void Audio::toggleSynth(Notes const& notes) {
+ Output& o = self->output;
+ boost::mutex::scoped_lock l(o.synth_mutex);
+ o.synth.get() ? o.synth.reset() : o.synth.reset(new Synth(notes, getSR()));
+}
+
boost::ptr_vector<Analyzer>& Audio::analyzers() { return self->analyzers; }
diff --git a/game/audio.hh b/game/audio.hh
index 1087c8f..dab6770 100644
--- a/game/audio.hh
+++ b/game/audio.hh
@@ -54,7 +54,7 @@ public:
void togglePause() { pause(!isPaused()); }
void pause(bool state = true);
bool isPaused() const;
- void toggleSynth(Notes const&) { /*m_notes = (m_notes ? NULL : ¬es); */} ///< toggles synth playback
+ void toggleSynth(Notes const&); ///< toggles synth playback
/// Adjust volume level of a single track (used for muting incorrectly played instruments). Range 0.0 to 1.0.
void streamFade(std::string track, double volume);
double getSR() const { return 48000.0; }
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:52:26
|
Module: performous
Branch: joinmenu
Commit: 34aaed0a09c83565b5481f6744cb3ba0f7c4c486
Author: Vincent Le Ligeour <yo...@us...>
Date: Mon Jul 5 19:58:53 2010 +0200
Implemented audio volume
---
game/audio.cc | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 67b1ec9..ac93f15 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -45,7 +45,7 @@ public:
if (fadeLevel <= 0.0) return false;
if (fadeLevel > 1.0) { fadeLevel = 1.0; fadeRate = 0.0; }
}
- begin[i] += mixbuf[i] * fadeLevel;
+ begin[i] += mixbuf[i] * fadeLevel * static_cast<float>(m_preview ? config["audio/preview_volume"].i() : config["audio/music_volume"].i())/100.0;
}
return !eof;
}
@@ -92,7 +92,7 @@ struct Sample {
eof = true;
}
for (size_t i = 0, iend = end - begin; i != iend; ++i) {
- begin[i] += mixbuf[i];
+ begin[i] += mixbuf[i] * static_cast<float>(config["audio/fail_volume"].i())/100.0;
}
m_pos += end - begin;
}
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:52:23
|
Module: performous
Branch: joinmenu
Commit: 7bc30cc15ec978b178cca13be2892401ba7c868d
Author: Vincent Le Ligeour <yo...@us...>
Date: Mon Jul 5 19:08:46 2010 +0200
Fixed audio sample thread model
---
game/audio.cc | 45 ++++++++++++++++++++++++++++-----------------
1 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 97feaaf..67b1ec9 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -20,11 +20,12 @@ class Music {
Tracks tracks; ///< Audio decoders
double srate; ///< Sample rate
int64_t m_pos; ///< Current sample position
+ bool m_preview;
public:
double fadeLevel;
double fadeRate;
typedef std::map<std::string,std::string> Files;
- Music(Files const& filenames, unsigned int sr): srate(sr), m_pos(), fadeLevel(), fadeRate() {
+ Music(Files const& filenames, unsigned int sr, bool preview): srate(sr), m_pos(), m_preview(preview), fadeLevel(), fadeRate() {
for (Files::const_iterator it = filenames.begin(), end = filenames.end(); it != end; ++it) {
tracks.insert(it->first, std::auto_ptr<Track>(new Track(it->second, sr)));
}
@@ -73,15 +74,14 @@ public:
}
};
-// rename to Sample once totally implemented
-struct SampleNew {
+struct Sample {
private:
unsigned int srate;
double m_pos;
FFmpeg mpeg;
bool eof;
public:
- SampleNew(std::string const& filename, unsigned sr) : srate(sr), m_pos(), mpeg(false, true, filename, sr), eof(true) { }
+ Sample(std::string const& filename, unsigned sr) : srate(sr), m_pos(), mpeg(false, true, filename, sr), eof(true) { }
void operator()(float* begin, float* end) {
if(eof) {
// No more data to play in this sample
@@ -104,16 +104,17 @@ struct SampleNew {
struct Command {
- enum { TRACK_FADE } type;
+ enum { TRACK_FADE, SAMPLE_RESET } type;
std::string track;
double fadeLevel;
};
struct Output {
boost::mutex mutex;
+ boost::mutex samples_mutex;
std::auto_ptr<Music> preloading;
boost::ptr_vector<Music> playing, disposing;
- boost::ptr_map<std::string, SampleNew> samples;
+ boost::ptr_map<std::string, Sample> samples;
std::vector<Command> commands;
volatile bool paused;
Output(): paused(false) {}
@@ -132,6 +133,11 @@ struct Output {
case Command::TRACK_FADE:
if (!playing.empty()) playing[0].trackFade(cmd.track, cmd.fadeLevel);
break;
+ case Command::SAMPLE_RESET:
+ boost::ptr_map<std::string, Sample>::iterator it = samples.find(cmd.track);
+ if (it != samples.end())
+ it->second->reset();
+ break;
}
}
commands.clear();
@@ -152,9 +158,14 @@ struct Output {
++i;
}
// Mix in the samples currently playing
- for(boost::ptr_map<std::string, SampleNew>::iterator it = samples.begin() ; it != samples.end() ; ++it) {
- boost::mutex::scoped_try_lock l(mutex);
- (*it->second)(begin, end);
+ {
+ // samples should not be created/destroyed on the fly
+ boost::mutex::scoped_try_lock l(samples_mutex, boost::defer_lock);
+ if(l.try_lock()) {
+ for(boost::ptr_map<std::string, Sample>::iterator it = samples.begin() ; it != samples.end() ; ++it) {
+ (*it->second)(begin, end);
+ }
+ }
}
}
};
@@ -226,19 +237,19 @@ bool Audio::isOpen() const {
}
void Audio::loadSample(std::string const& streamId, std::string const& filename) {
- boost::mutex::scoped_lock l(self->output.mutex);
- self->output.samples.insert(streamId, std::auto_ptr<SampleNew>(new SampleNew(filename, getSR())));
+ boost::mutex::scoped_lock l(self->output.samples_mutex);
+ self->output.samples.insert(streamId, std::auto_ptr<Sample>(new Sample(filename, getSR())));
}
void Audio::playSample(std::string const& streamId) {
- boost::mutex::scoped_lock l(self->output.mutex);
- boost::ptr_map<std::string, SampleNew>::iterator it = self->output.samples.find(streamId);
- if (it == self->output.samples.end()) throw std::runtime_error("Cannot play sample : " + streamId);
- it->second->reset();
+ Output& o = self->output;
+ boost::mutex::scoped_lock l(o.mutex);
+ Command cmd = { Command::SAMPLE_RESET, streamId, 0.0 };
+ o.commands.push_back(cmd);
}
void Audio::unloadSample(std::string const& streamId) {
- boost::mutex::scoped_lock l(self->output.mutex);
+ boost::mutex::scoped_lock l(self->output.samples_mutex);
self->output.samples.erase(streamId);
}
@@ -246,7 +257,7 @@ void Audio::playMusic(std::map<std::string,std::string> const& filenames, bool p
Output& o = self->output;
boost::mutex::scoped_lock l(o.mutex);
o.disposing.clear(); // Delete disposed streams
- o.preloading.reset(new Music(filenames, getSR()));
+ o.preloading.reset(new Music(filenames, getSR(), preview));
Music& m = *o.preloading.get();
m.seek(startPos);
m.fadeRate = 1.0 / getSR() / fadeTime;
|
|
From: Yoda-JM <yo...@us...> - 2010-08-15 14:52:21
|
Module: performous
Branch: joinmenu
Commit: 3e2ae0eeceb114895884c11851f818fead791188
Author: Vincent Le Ligeour <yo...@us...>
Date: Mon Jul 5 16:02:29 2010 +0200
Moved all samples loading to init
---
game/audio.cc | 4 ++--
game/guitargraph.cc | 31 +++++++++++++------------------
game/guitargraph.hh | 2 +-
game/main.cc | 14 ++++++++++++++
game/screen_practice.cc | 20 +++++++-------------
game/screen_practice.hh | 2 +-
libs/libda/include/libda/portaudio.hpp | 4 ++--
7 files changed, 40 insertions(+), 37 deletions(-)
diff --git a/game/audio.cc b/game/audio.cc
index 0d9b7a5..97feaaf 100644
--- a/game/audio.cc
+++ b/game/audio.cc
@@ -167,10 +167,10 @@ struct Device {
portaudio::Stream stream;
std::vector<Analyzer*> mics;
Output* outptr;
-
+
Device(unsigned int in, unsigned int out, double rate, std::string dev):
in(in), out(out), rate(rate), dev(dev),
- stream(*this, in ? portaudio::Params().channelCount(in).device(dev, true) : NULL, out ? portaudio::Params().channelCount(out).device(dev, false) : NULL, rate)
+ stream(*this, in ? portaudio::Params().channelCount(in).device(dev, true) : (const PaStreamParameters*)NULL, (out ? portaudio::Params().channelCount(out).device(dev, false) : (const PaStreamParameters*)NULL), rate)
{
mics.resize(in);
}
diff --git a/game/guitargraph.cc b/game/guitargraph.cc
index d9e3383..86b5e32 100644
--- a/game/guitargraph.cc
+++ b/game/guitargraph.cc
@@ -100,25 +100,20 @@ GuitarGraph::GuitarGraph(Audio& audio, Song const& song, bool drums, int number,
// Score calculator (TODO a better one)
m_scoreText.reset(new SvgTxtThemeSimple(getThemePath("sing_score_text.svg"), config["graphic/text_lod"].f()));
m_streakText.reset(new SvgTxtThemeSimple(getThemePath("sing_score_text.svg"), config["graphic/text_lod"].f()));
- // Load fail sounds
if (m_drums) {
- m_samples.push_back(std::make_pair("drum bass", getPath("sounds/drum_bass.ogg")));
- m_samples.push_back(std::make_pair("drum snare", getPath("sounds/drum_snare.ogg")));
- m_samples.push_back(std::make_pair("drum hi-hat", getPath("sounds/drum_hi-hat.ogg")));
- m_samples.push_back(std::make_pair("drum tom1", getPath("sounds/drum_tom1.ogg")));
- m_samples.push_back(std::make_pair("drum cymbal", getPath("sounds/drum_cymbal.ogg")));
- //m_samples.push_back(std::make_pair("drum tom2", getPath("sounds/drum_tom2.ogg")));
+ m_samples.push_back("drum bass");
+ m_samples.push_back("drum snare");
+ m_samples.push_back("drum hi-hat");
+ m_samples.push_back("drum tom1");
+ m_samples.push_back("drum cymbal");
+ //m_samples.push_back("drum tom2");
} else {
- m_samples.push_back(std::make_pair("guitar fail1", getPath("sounds/guitar_fail1.ogg")));
- m_samples.push_back(std::make_pair("guitar fail2", getPath("sounds/guitar_fail2.ogg")));
- m_samples.push_back(std::make_pair("guitar fail3", getPath("sounds/guitar_fail3.ogg")));
- m_samples.push_back(std::make_pair("guitar fail4", getPath("sounds/guitar_fail4.ogg")));
- m_samples.push_back(std::make_pair("guitar fail5", getPath("sounds/guitar_fail5.ogg")));
- m_samples.push_back(std::make_pair("guitar fail6", getPath("sounds/guitar_fail6.ogg")));
- }
- // Warning the sample are shared between Guitargraphs, do not unload them
- for(unsigned int i = 0 ; i < m_samples.size() ; i++) {
- m_audio.loadSample(m_samples[i].first, m_samples[i].second);
+ m_samples.push_back("guitar fail1");
+ m_samples.push_back("guitar fail2");
+ m_samples.push_back("guitar fail3");
+ m_samples.push_back("guitar fail4");
+ m_samples.push_back("guitar fail5");
+ m_samples.push_back("guitar fail6");
}
for (int i = 0; i < 6; ++i) m_pressed_anim[i].setRate(5.0);
for (int i = 0; i < 5; ++i) m_holds[i] = 0;
@@ -409,7 +404,7 @@ void GuitarGraph::fail(double time, int fret) {
// Reduce points and play fail sample only when GodMode is deactivated
m_events.push_back(Event(time, 0, fret));
if (fret < 0) fret = std::rand();
- m_audio.playSample(m_samples[unsigned(fret) % m_samples.size()].first);
+ m_audio.playSample(m_samples[unsigned(fret) % m_samples.size()]);
// remove equivalent of 1 perfect hit for every note
// kids tend to play a lot of extra notes just for the fun of it.
// need to make sure they don't end up with a score of zero
diff --git a/game/guitargraph.hh b/game/guitargraph.hh
index 9e53408..0a41db2 100644
--- a/game/guitargraph.hh
+++ b/game/guitargraph.hh
@@ -88,7 +88,7 @@ class GuitarGraph: public InstrumentGraph {
glutil::Color m_neckglowColor;
Object3d m_fretObj; /// 3d object for regular note
Object3d m_tappableObj; /// 3d object for the HOPO note cap
- std::vector<std::pair<std::string, std::string> > m_samples; /// sound effects
+ std::vector<std::string> m_samples; /// sound effects
boost::scoped_ptr<Texture> m_neck; /// necks
boost::scoped_ptr<SvgTxtThemeSimple> m_scoreText;
boost::scoped_ptr<SvgTxtThemeSimple> m_streakText;
diff --git a/game/main.cc b/game/main.cc
index fcc41ec..f466381 100644
--- a/game/main.cc
+++ b/game/main.cc
@@ -117,6 +117,20 @@ void mainLoop(std::string const& songlist) {
boost::scoped_ptr<input::MidiDrums> midiDrums;
// TODO: Proper error handling...
try { midiDrums.reset(new input::MidiDrums); } catch (std::runtime_error&) {}
+ // Load audio samples
+ audio.loadSample("drum bass", getPath("sounds/drum_bass.ogg"));
+ audio.loadSample("drum snare", getPath("sounds/drum_snare.ogg"));
+ audio.loadSample("drum hi-hat", getPath("sounds/drum_hi-hat.ogg"));
+ audio.loadSample("drum tom1", getPath("sounds/drum_tom1.ogg"));
+ audio.loadSample("drum cymbal", getPath("sounds/drum_cymbal.ogg"));
+ //audio.loadSample("drum tom2", getPath("sounds/drum_tom2.ogg"));
+ audio.loadSample("guitar fail1", getPath("sounds/guitar_fail1.ogg"));
+ audio.loadSample("guitar fail2", getPath("sounds/guitar_fail2.ogg"));
+ audio.loadSample("guitar fail3", getPath("sounds/guitar_fail3.ogg"));
+ audio.loadSample("guitar fail4", getPath("sounds/guitar_fail4.ogg"));
+ audio.loadSample("guitar fail5", getPath("sounds/guitar_fail5.ogg"));
+ audio.loadSample("guitar fail6", getPath("sounds/guitar_fail6.ogg"));
+ // Load screens
sm.addScreen(new ScreenIntro("Intro", audio));
sm.addScreen(new ScreenSongs("Songs", audio, songs, database));
sm.addScreen(new ScreenSing("Sing", audio, database, backgrounds));
diff --git a/game/screen_practice.cc b/game/screen_practice.cc
index d0b2896..d48afd1 100644
--- a/game/screen_practice.cc
+++ b/game/screen_practice.cc
@@ -18,21 +18,15 @@ void ScreenPractice::enter() {
m_vumeters.push_back(b = new ProgressBar(getThemePath("vumeter_bg.svg"), getThemePath("vumeter_fg.svg"), ProgressBar::VERTICAL, 0.136, 0.023));
b->dimensions.screenBottom().left(-0.4 + i * 0.2).fixedWidth(0.04);
}
- m_samples.push_back(std::make_pair("drum bass", getPath("sounds/drum_bass.ogg")));
- m_samples.push_back(std::make_pair("drum snare", getPath("sounds/drum_snare.ogg")));
- m_samples.push_back(std::make_pair("drum hi-hat", getPath("sounds/drum_hi-hat.ogg")));
- m_samples.push_back(std::make_pair("drum tom1", getPath("sounds/drum_tom1.ogg")));
- m_samples.push_back(std::make_pair("drum cymbal", getPath("sounds/drum_cymbal.ogg")));
- //m_samples.push_back(std::make_pair("drum tom2", getPath("sounds/drum_tom2.ogg")));
- for(unsigned int i = 0 ; i < m_samples.size() ; i++) {
- m_audio.loadSample(m_samples[i].first, m_samples[i].second);
- }
+ m_samples.push_back("drum bass");
+ m_samples.push_back("drum snare");
+ m_samples.push_back("drum hi-hat");
+ m_samples.push_back("drum tom1");
+ m_samples.push_back("drum cymbal");
+ //m_samples.push_back("drum tom2");
}
void ScreenPractice::exit() {
- for(unsigned int i = 0 ; i < m_samples.size() ; i++) {
- m_audio.unloadSample(m_samples[i].first);
- }
m_vumeters.clear();
m_samples.clear();
theme.reset();
@@ -47,7 +41,7 @@ void ScreenPractice::manageEvent(SDL_Event event) {
else if (event.type == SDL_JOYBUTTONDOWN // Play drum sounds here
&& input::detail::devices[event.jbutton.which].type_match(input::DRUMS)) {
int b = input::buttonFromSDL(input::detail::devices[event.jbutton.which].type(), event.jbutton.button);
- if (b != -1) m_audio.playSample(m_samples[unsigned(b) % m_samples.size()].first);
+ if (b != -1) m_audio.playSample(m_samples[unsigned(b) % m_samples.size()]);
}
}
diff --git a/game/screen_practice.hh b/game/screen_practice.hh
index 2d472d2..f8156f5 100644
--- a/game/screen_practice.hh
+++ b/game/screen_practice.hh
@@ -23,7 +23,7 @@ class ScreenPractice : public Screen {
private:
Audio& m_audio;
- std::vector<std::pair<std::string, std::string> > m_samples;
+ std::vector<std::string> m_samples;
boost::ptr_vector<ProgressBar> m_vumeters;
boost::scoped_ptr<ThemePractice> theme;
};
diff --git a/libs/libda/include/libda/portaudio.hpp b/libs/libda/include/libda/portaudio.hpp
index a7987b9..8add471 100644
--- a/libs/libda/include/libda/portaudio.hpp
+++ b/libs/libda/include/libda/portaudio.hpp
@@ -19,7 +19,7 @@ namespace portaudio {
PaError m_code;
char const* m_func;
};
-
+
namespace internal {
void check(PaError code, char const* func) { if (code != paNoError) throw Error(code, func); }
}
@@ -70,7 +70,7 @@ namespace portaudio {
Params& hostApiSpecificStreamInfo(void* val) { params.hostApiSpecificStreamInfo = val; return *this; }
operator PaStreamParameters const*() const { return ¶ms; }
};
-
+
template <typename Functor> int functorCallback(void const* input, void* output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void* userData) {
return (*static_cast<Functor*>(userData))(input, output, frameCount, timeInfo, statusFlags);
}
|