forked from mia/Aegisub
Made audio players register manually.
Originally committed to SVN as r1893.
This commit is contained in:
parent
30d1aeb551
commit
ee61192c43
12 changed files with 669 additions and 376 deletions
|
@ -39,6 +39,21 @@
|
||||||
#include <wx/wxprec.h>
|
#include <wx/wxprec.h>
|
||||||
#include "audio_player.h"
|
#include "audio_player.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
#ifdef WITH_ALSA
|
||||||
|
#include "audio_player_alsa.h"
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_DIRECTSOUND
|
||||||
|
#include "audio_player_dsound.h"
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_OPENAL
|
||||||
|
#include "audio_player_openal.h"
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_PORTAUDIO
|
||||||
|
#include "audio_player_portaudio.h"
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_PULSEAUDIO
|
||||||
|
#include "audio_player_pulse.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
|
@ -112,6 +127,12 @@ void AudioPlayer::OnStopAudio(wxCommandEvent &event) {
|
||||||
//////////////
|
//////////////
|
||||||
// Get player
|
// Get player
|
||||||
AudioPlayer* AudioPlayerFactory::GetAudioPlayer() {
|
AudioPlayer* AudioPlayerFactory::GetAudioPlayer() {
|
||||||
|
// Register factories
|
||||||
|
// HACK: fix me
|
||||||
|
static bool init = false;
|
||||||
|
if (!init) RegisterFactories();
|
||||||
|
init = true;
|
||||||
|
|
||||||
// List of providers
|
// List of providers
|
||||||
wxArrayString list = GetFactoryList(Options.AsText(_T("Audio player")));
|
wxArrayString list = GetFactoryList(Options.AsText(_T("Audio player")));
|
||||||
|
|
||||||
|
@ -135,6 +156,27 @@ AudioPlayer* AudioPlayerFactory::GetAudioPlayer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
// Register all factories
|
||||||
|
void AudioPlayerFactory::RegisterFactories() {
|
||||||
|
#ifdef WITH_ALSA
|
||||||
|
new AlsaPlayerFactory();
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_DIRECTSOUND
|
||||||
|
new DirectSoundPlayerFactory();
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_OPENAL
|
||||||
|
new OpenALPlayerFactory();
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_PORTAUDIO
|
||||||
|
new PortAudioPlayerFactory();
|
||||||
|
#endif
|
||||||
|
#ifdef WITH_PULSEAUDIO
|
||||||
|
new PulseAudioPlayerFactory();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////
|
//////////
|
||||||
// Static
|
// Static
|
||||||
template <class AudioPlayerFactory> std::map<wxString,AudioPlayerFactory*>* AegisubFactory<AudioPlayerFactory>::factories=NULL;
|
template <class AudioPlayerFactory> std::map<wxString,AudioPlayerFactory*>* AegisubFactory<AudioPlayerFactory>::factories=NULL;
|
||||||
|
|
|
@ -104,6 +104,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
virtual ~AudioPlayerFactory() {}
|
virtual ~AudioPlayerFactory() {}
|
||||||
static AudioPlayer *GetAudioPlayer();
|
static AudioPlayer *GetAudioPlayer();
|
||||||
|
static void RegisterFactories();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,75 +45,10 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "frame_main.h"
|
#include "frame_main.h"
|
||||||
#include "audio_player.h"
|
#include "audio_player_alsa.h"
|
||||||
#include <alsa/asoundlib.h>
|
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
|
|
||||||
///////////////
|
|
||||||
// Alsa player
|
|
||||||
class AlsaPlayer : public AudioPlayer {
|
|
||||||
private:
|
|
||||||
bool open;
|
|
||||||
volatile bool playing;
|
|
||||||
volatile float volume;
|
|
||||||
|
|
||||||
volatile unsigned long start_frame; // first frame of playback
|
|
||||||
volatile unsigned long cur_frame; // last written frame + 1
|
|
||||||
volatile unsigned long end_frame; // last frame to play
|
|
||||||
unsigned long bpf; // bytes per frame
|
|
||||||
|
|
||||||
AudioProvider *provider;
|
|
||||||
snd_pcm_t *pcm_handle; // device handle
|
|
||||||
snd_pcm_stream_t stream; // stream direction
|
|
||||||
snd_async_handler_t *pcm_callback;
|
|
||||||
|
|
||||||
snd_pcm_format_t sample_format;
|
|
||||||
unsigned int rate; // sample rate of audio
|
|
||||||
unsigned int real_rate; // actual sample rate played back
|
|
||||||
unsigned int period_len; // length of period in microseconds
|
|
||||||
unsigned int buflen; // length of buffer in microseconds
|
|
||||||
snd_pcm_uframes_t period; // size of period in frames
|
|
||||||
snd_pcm_uframes_t bufsize; // size of buffer in frames
|
|
||||||
|
|
||||||
void SetUpHardware();
|
|
||||||
void SetUpAsync();
|
|
||||||
|
|
||||||
static void async_write_handler(snd_async_handler_t *pcm_callback);
|
|
||||||
|
|
||||||
public:
|
|
||||||
AlsaPlayer();
|
|
||||||
~AlsaPlayer();
|
|
||||||
|
|
||||||
void OpenStream();
|
|
||||||
void CloseStream();
|
|
||||||
|
|
||||||
void Play(int64_t start,int64_t count);
|
|
||||||
void Stop(bool timerToo=true);
|
|
||||||
bool IsPlaying();
|
|
||||||
|
|
||||||
int64_t GetStartPosition();
|
|
||||||
int64_t GetEndPosition();
|
|
||||||
int64_t GetCurrentPosition();
|
|
||||||
void SetEndPosition(int64_t pos);
|
|
||||||
void SetCurrentPosition(int64_t pos);
|
|
||||||
|
|
||||||
void SetVolume(double vol) { volume = vol; }
|
|
||||||
double GetVolume() { return volume; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////
|
|
||||||
// Factory
|
|
||||||
class AlsaPlayerFactory : public AudioPlayerFactory {
|
|
||||||
public:
|
|
||||||
AudioPlayer *CreatePlayer() { return new AlsaPlayer(); }
|
|
||||||
AlsaPlayerFactory() : AudioPlayerFactory(_T("alsa")) {}
|
|
||||||
} registerAlsaPlayer;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
AlsaPlayer::AlsaPlayer()
|
AlsaPlayer::AlsaPlayer()
|
||||||
|
|
115
aegisub/audio_player_alsa.h
Normal file
115
aegisub/audio_player_alsa.h
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
// Copyright (c) 2007, Niels Martin Hansen
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer in the documentation
|
||||||
|
// and/or other materials provided with the distribution.
|
||||||
|
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||||
|
// may be used to endorse or promote products derived from this software
|
||||||
|
// without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// AEGISUB
|
||||||
|
//
|
||||||
|
// Website: http://aegisub.cellosoft.com
|
||||||
|
// Contact: mailto:jiifurusu@gmail.com
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WITH_ALSA
|
||||||
|
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// Headers
|
||||||
|
#include <wx/wxprec.h>
|
||||||
|
#include "audio_player.h"
|
||||||
|
#include "audio_provider.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "frame_main.h"
|
||||||
|
#include "audio_player.h"
|
||||||
|
#include <alsa/asoundlib.h>
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
// Alsa player
|
||||||
|
class AlsaPlayer : public AudioPlayer {
|
||||||
|
private:
|
||||||
|
bool open;
|
||||||
|
volatile bool playing;
|
||||||
|
volatile float volume;
|
||||||
|
|
||||||
|
volatile unsigned long start_frame; // first frame of playback
|
||||||
|
volatile unsigned long cur_frame; // last written frame + 1
|
||||||
|
volatile unsigned long end_frame; // last frame to play
|
||||||
|
unsigned long bpf; // bytes per frame
|
||||||
|
|
||||||
|
AudioProvider *provider;
|
||||||
|
snd_pcm_t *pcm_handle; // device handle
|
||||||
|
snd_pcm_stream_t stream; // stream direction
|
||||||
|
snd_async_handler_t *pcm_callback;
|
||||||
|
|
||||||
|
snd_pcm_format_t sample_format;
|
||||||
|
unsigned int rate; // sample rate of audio
|
||||||
|
unsigned int real_rate; // actual sample rate played back
|
||||||
|
unsigned int period_len; // length of period in microseconds
|
||||||
|
unsigned int buflen; // length of buffer in microseconds
|
||||||
|
snd_pcm_uframes_t period; // size of period in frames
|
||||||
|
snd_pcm_uframes_t bufsize; // size of buffer in frames
|
||||||
|
|
||||||
|
void SetUpHardware();
|
||||||
|
void SetUpAsync();
|
||||||
|
|
||||||
|
static void async_write_handler(snd_async_handler_t *pcm_callback);
|
||||||
|
|
||||||
|
public:
|
||||||
|
AlsaPlayer();
|
||||||
|
~AlsaPlayer();
|
||||||
|
|
||||||
|
void OpenStream();
|
||||||
|
void CloseStream();
|
||||||
|
|
||||||
|
void Play(int64_t start,int64_t count);
|
||||||
|
void Stop(bool timerToo=true);
|
||||||
|
bool IsPlaying();
|
||||||
|
|
||||||
|
int64_t GetStartPosition();
|
||||||
|
int64_t GetEndPosition();
|
||||||
|
int64_t GetCurrentPosition();
|
||||||
|
void SetEndPosition(int64_t pos);
|
||||||
|
void SetCurrentPosition(int64_t pos);
|
||||||
|
|
||||||
|
void SetVolume(double vol) { volume = vol; }
|
||||||
|
double GetVolume() { return volume; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// Factory
|
||||||
|
class AlsaPlayerFactory : public AudioPlayerFactory {
|
||||||
|
public:
|
||||||
|
AudioPlayer *CreatePlayer() { return new AlsaPlayer(); }
|
||||||
|
AlsaPlayerFactory() : AudioPlayerFactory(_T("alsa")) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -44,101 +44,7 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "frame_main.h"
|
#include "frame_main.h"
|
||||||
#include "audio_player.h"
|
#include "audio_player_dsound.h"
|
||||||
#include <mmsystem.h>
|
|
||||||
#include <dsound.h>
|
|
||||||
|
|
||||||
|
|
||||||
//////////////
|
|
||||||
// Prototypes
|
|
||||||
class DirectSoundPlayer;
|
|
||||||
|
|
||||||
|
|
||||||
//////////
|
|
||||||
// Thread
|
|
||||||
class DirectSoundPlayerThread : public wxThread {
|
|
||||||
private:
|
|
||||||
DirectSoundPlayer *parent;
|
|
||||||
HANDLE stopnotify;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void Stop(); // Notify thread to stop audio playback. Thread safe.
|
|
||||||
DirectSoundPlayerThread(DirectSoundPlayer *parent);
|
|
||||||
~DirectSoundPlayerThread();
|
|
||||||
|
|
||||||
wxThread::ExitCode Entry();
|
|
||||||
};
|
|
||||||
/*
|
|
||||||
TODO: Rewrite playback thread to manage all of the buffer, and properly marshal the IDirectSound8
|
|
||||||
object into the thread for creating the buffer there.
|
|
||||||
The thread should own the buffer and manage all of the playback.
|
|
||||||
It must be created with start and duration set, and begins playback at the given position.
|
|
||||||
New functions:
|
|
||||||
* Seek(pos) : Restart playback from the given position
|
|
||||||
* SetEnd(pos) : Set new end point
|
|
||||||
* GetPosition() : Get the current sample number being played
|
|
||||||
* Stop() : Stop playback immediately
|
|
||||||
|
|
||||||
Instead of using a stop event, use a playback parameters changed event. When that one's fired,
|
|
||||||
detect which were actually changed and act accordingly.
|
|
||||||
All but GetPosition() set appropriate fields and then raise the parameters changed event.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////
|
|
||||||
// Portaudio player
|
|
||||||
class DirectSoundPlayer : public AudioPlayer {
|
|
||||||
friend class DirectSoundPlayerThread;
|
|
||||||
|
|
||||||
private:
|
|
||||||
volatile bool playing;
|
|
||||||
float volume;
|
|
||||||
int offset;
|
|
||||||
DWORD bufSize;
|
|
||||||
|
|
||||||
volatile int64_t playPos;
|
|
||||||
int64_t startPos;
|
|
||||||
volatile int64_t endPos;
|
|
||||||
DWORD startTime;
|
|
||||||
|
|
||||||
IDirectSound8 *directSound;
|
|
||||||
IDirectSoundBuffer8 *buffer;
|
|
||||||
|
|
||||||
bool FillBuffer(bool fill);
|
|
||||||
|
|
||||||
DirectSoundPlayerThread *thread;
|
|
||||||
|
|
||||||
public:
|
|
||||||
DirectSoundPlayer();
|
|
||||||
~DirectSoundPlayer();
|
|
||||||
|
|
||||||
void OpenStream();
|
|
||||||
void CloseStream();
|
|
||||||
|
|
||||||
void Play(int64_t start,int64_t count);
|
|
||||||
void Stop(bool timerToo=true);
|
|
||||||
bool IsPlaying() { return playing; }
|
|
||||||
|
|
||||||
int64_t GetStartPosition() { return startPos; }
|
|
||||||
int64_t GetEndPosition() { return endPos; }
|
|
||||||
int64_t GetCurrentPosition();
|
|
||||||
void SetEndPosition(int64_t pos);
|
|
||||||
void SetCurrentPosition(int64_t pos);
|
|
||||||
|
|
||||||
void SetVolume(double vol) { volume = vol; }
|
|
||||||
double GetVolume() { return volume; }
|
|
||||||
|
|
||||||
//wxMutex *GetMutex() { return &DSMutex; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///////////
|
|
||||||
// Factory
|
|
||||||
class DirectSoundPlayerFactory : public AudioPlayerFactory {
|
|
||||||
public:
|
|
||||||
AudioPlayer *CreatePlayer() { return new DirectSoundPlayer(); }
|
|
||||||
DirectSoundPlayerFactory() : AudioPlayerFactory(_T("dsound")) {}
|
|
||||||
} registerDirectSoundPlayer;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
|
|
143
aegisub/audio_player_dsound.h
Normal file
143
aegisub/audio_player_dsound.h
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
// Copyright (c) 2006, Rodrigo Braz Monteiro
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer in the documentation
|
||||||
|
// and/or other materials provided with the distribution.
|
||||||
|
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||||
|
// may be used to endorse or promote products derived from this software
|
||||||
|
// without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// AEGISUB
|
||||||
|
//
|
||||||
|
// Website: http://aegisub.cellosoft.com
|
||||||
|
// Contact: mailto:zeratul@cellosoft.com
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// Headers
|
||||||
|
#ifdef WITH_DIRECTSOUND
|
||||||
|
|
||||||
|
#include <wx/wxprec.h>
|
||||||
|
#include "audio_player.h"
|
||||||
|
#include "audio_provider.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "frame_main.h"
|
||||||
|
#include "audio_player.h"
|
||||||
|
#include <mmsystem.h>
|
||||||
|
#include <dsound.h>
|
||||||
|
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
// Prototypes
|
||||||
|
class DirectSoundPlayer;
|
||||||
|
|
||||||
|
|
||||||
|
//////////
|
||||||
|
// Thread
|
||||||
|
class DirectSoundPlayerThread : public wxThread {
|
||||||
|
private:
|
||||||
|
DirectSoundPlayer *parent;
|
||||||
|
HANDLE stopnotify;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void Stop(); // Notify thread to stop audio playback. Thread safe.
|
||||||
|
DirectSoundPlayerThread(DirectSoundPlayer *parent);
|
||||||
|
~DirectSoundPlayerThread();
|
||||||
|
|
||||||
|
wxThread::ExitCode Entry();
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
TODO: Rewrite playback thread to manage all of the buffer, and properly marshal the IDirectSound8
|
||||||
|
object into the thread for creating the buffer there.
|
||||||
|
The thread should own the buffer and manage all of the playback.
|
||||||
|
It must be created with start and duration set, and begins playback at the given position.
|
||||||
|
New functions:
|
||||||
|
* Seek(pos) : Restart playback from the given position
|
||||||
|
* SetEnd(pos) : Set new end point
|
||||||
|
* GetPosition() : Get the current sample number being played
|
||||||
|
* Stop() : Stop playback immediately
|
||||||
|
|
||||||
|
Instead of using a stop event, use a playback parameters changed event. When that one's fired,
|
||||||
|
detect which were actually changed and act accordingly.
|
||||||
|
All but GetPosition() set appropriate fields and then raise the parameters changed event.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////
|
||||||
|
// Portaudio player
|
||||||
|
class DirectSoundPlayer : public AudioPlayer {
|
||||||
|
friend class DirectSoundPlayerThread;
|
||||||
|
|
||||||
|
private:
|
||||||
|
volatile bool playing;
|
||||||
|
float volume;
|
||||||
|
int offset;
|
||||||
|
DWORD bufSize;
|
||||||
|
|
||||||
|
volatile int64_t playPos;
|
||||||
|
int64_t startPos;
|
||||||
|
volatile int64_t endPos;
|
||||||
|
DWORD startTime;
|
||||||
|
|
||||||
|
IDirectSound8 *directSound;
|
||||||
|
IDirectSoundBuffer8 *buffer;
|
||||||
|
|
||||||
|
bool FillBuffer(bool fill);
|
||||||
|
|
||||||
|
DirectSoundPlayerThread *thread;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DirectSoundPlayer();
|
||||||
|
~DirectSoundPlayer();
|
||||||
|
|
||||||
|
void OpenStream();
|
||||||
|
void CloseStream();
|
||||||
|
|
||||||
|
void Play(int64_t start,int64_t count);
|
||||||
|
void Stop(bool timerToo=true);
|
||||||
|
bool IsPlaying() { return playing; }
|
||||||
|
|
||||||
|
int64_t GetStartPosition() { return startPos; }
|
||||||
|
int64_t GetEndPosition() { return endPos; }
|
||||||
|
int64_t GetCurrentPosition();
|
||||||
|
void SetEndPosition(int64_t pos);
|
||||||
|
void SetCurrentPosition(int64_t pos);
|
||||||
|
|
||||||
|
void SetVolume(double vol) { volume = vol; }
|
||||||
|
double GetVolume() { return volume; }
|
||||||
|
|
||||||
|
//wxMutex *GetMutex() { return &DSMutex; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// Factory
|
||||||
|
class DirectSoundPlayerFactory : public AudioPlayerFactory {
|
||||||
|
public:
|
||||||
|
AudioPlayer *CreatePlayer() { return new DirectSoundPlayer(); }
|
||||||
|
DirectSoundPlayerFactory() : AudioPlayerFactory(_T("dsound")) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -45,7 +45,7 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "frame_main.h"
|
#include "frame_main.h"
|
||||||
#include "audio_player.h"
|
#include "audio_player_openal.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <OpenAL/AL.h>
|
#include <OpenAL/AL.h>
|
||||||
|
@ -62,73 +62,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/////////////////
|
|
||||||
// OpenAL player
|
|
||||||
class OpenALPlayer : public AudioPlayer, wxTimer {
|
|
||||||
private:
|
|
||||||
bool open;
|
|
||||||
volatile bool playing;
|
|
||||||
volatile float volume;
|
|
||||||
|
|
||||||
static const ALsizei num_buffers = 8;
|
|
||||||
ALsizei buffer_length;
|
|
||||||
ALsizei samplerate;
|
|
||||||
|
|
||||||
volatile unsigned long start_frame; // first frame of playback
|
|
||||||
volatile unsigned long cur_frame; // last written frame + 1
|
|
||||||
volatile unsigned long end_frame; // last frame to play
|
|
||||||
unsigned long bpf; // bytes per frame
|
|
||||||
|
|
||||||
AudioProvider *provider;
|
|
||||||
ALCdevice *device; // device handle
|
|
||||||
ALCcontext *context; // sound context
|
|
||||||
ALuint buffers[num_buffers]; // sound buffers
|
|
||||||
ALuint source; // playback source
|
|
||||||
|
|
||||||
ALsizei buf_first_free; // index into buffers, first free (unqueued) buffer
|
|
||||||
ALsizei buf_first_queued; // index into buffers, first queued (non-free) buffer
|
|
||||||
ALsizei buffers_free; // number of free buffers
|
|
||||||
ALsizei buffers_played;
|
|
||||||
wxStopWatch playback_segment_timer;
|
|
||||||
|
|
||||||
void FillBuffers(ALsizei count);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void Notify(); // from wxTimer
|
|
||||||
|
|
||||||
public:
|
|
||||||
OpenALPlayer();
|
|
||||||
~OpenALPlayer();
|
|
||||||
|
|
||||||
void OpenStream();
|
|
||||||
void CloseStream();
|
|
||||||
|
|
||||||
void Play(int64_t start,int64_t count);
|
|
||||||
void Stop(bool timerToo=true);
|
|
||||||
bool IsPlaying();
|
|
||||||
|
|
||||||
int64_t GetStartPosition();
|
|
||||||
int64_t GetEndPosition();
|
|
||||||
int64_t GetCurrentPosition();
|
|
||||||
void SetEndPosition(int64_t pos);
|
|
||||||
void SetCurrentPosition(int64_t pos);
|
|
||||||
|
|
||||||
void SetVolume(double vol) { volume = vol; }
|
|
||||||
double GetVolume() { return volume; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////
|
|
||||||
// Factory
|
|
||||||
class OpenALPlayerFactory : public AudioPlayerFactory {
|
|
||||||
public:
|
|
||||||
AudioPlayer *CreatePlayer() { return new OpenALPlayer(); }
|
|
||||||
OpenALPlayerFactory() : AudioPlayerFactory(_T("openal")) {}
|
|
||||||
} registerOALPlayer;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
OpenALPlayer::OpenALPlayer()
|
OpenALPlayer::OpenALPlayer()
|
||||||
|
|
124
aegisub/audio_player_openal.h
Normal file
124
aegisub/audio_player_openal.h
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
// Copyright (c) 2007, Niels Martin Hansen
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer in the documentation
|
||||||
|
// and/or other materials provided with the distribution.
|
||||||
|
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||||
|
// may be used to endorse or promote products derived from this software
|
||||||
|
// without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// AEGISUB
|
||||||
|
//
|
||||||
|
// Website: http://aegisub.cellosoft.com
|
||||||
|
// Contact: mailto:jiifurusu@gmail.com
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WITH_OPENAL
|
||||||
|
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// Headers
|
||||||
|
#include <wx/wxprec.h>
|
||||||
|
#include "audio_player.h"
|
||||||
|
#include "audio_provider.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "frame_main.h"
|
||||||
|
#include "audio_player.h"
|
||||||
|
#include "options.h"
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <OpenAL/AL.h>
|
||||||
|
#include <OpenAL/ALC.h>
|
||||||
|
#else
|
||||||
|
#include <al.h>
|
||||||
|
#include <alc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
// OpenAL player
|
||||||
|
class OpenALPlayer : public AudioPlayer, wxTimer {
|
||||||
|
private:
|
||||||
|
bool open;
|
||||||
|
volatile bool playing;
|
||||||
|
volatile float volume;
|
||||||
|
|
||||||
|
static const ALsizei num_buffers = 8;
|
||||||
|
ALsizei buffer_length;
|
||||||
|
ALsizei samplerate;
|
||||||
|
|
||||||
|
volatile unsigned long start_frame; // first frame of playback
|
||||||
|
volatile unsigned long cur_frame; // last written frame + 1
|
||||||
|
volatile unsigned long end_frame; // last frame to play
|
||||||
|
unsigned long bpf; // bytes per frame
|
||||||
|
|
||||||
|
AudioProvider *provider;
|
||||||
|
ALCdevice *device; // device handle
|
||||||
|
ALCcontext *context; // sound context
|
||||||
|
ALuint buffers[num_buffers]; // sound buffers
|
||||||
|
ALuint source; // playback source
|
||||||
|
|
||||||
|
ALsizei buf_first_free; // index into buffers, first free (unqueued) buffer
|
||||||
|
ALsizei buf_first_queued; // index into buffers, first queued (non-free) buffer
|
||||||
|
ALsizei buffers_free; // number of free buffers
|
||||||
|
ALsizei buffers_played;
|
||||||
|
wxStopWatch playback_segment_timer;
|
||||||
|
|
||||||
|
void FillBuffers(ALsizei count);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void Notify(); // from wxTimer
|
||||||
|
|
||||||
|
public:
|
||||||
|
OpenALPlayer();
|
||||||
|
~OpenALPlayer();
|
||||||
|
|
||||||
|
void OpenStream();
|
||||||
|
void CloseStream();
|
||||||
|
|
||||||
|
void Play(int64_t start,int64_t count);
|
||||||
|
void Stop(bool timerToo=true);
|
||||||
|
bool IsPlaying();
|
||||||
|
|
||||||
|
int64_t GetStartPosition();
|
||||||
|
int64_t GetEndPosition();
|
||||||
|
int64_t GetCurrentPosition();
|
||||||
|
void SetEndPosition(int64_t pos);
|
||||||
|
void SetCurrentPosition(int64_t pos);
|
||||||
|
|
||||||
|
void SetVolume(double vol) { volume = vol; }
|
||||||
|
double GetVolume() { return volume; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// Factory
|
||||||
|
class OpenALPlayerFactory : public AudioPlayerFactory {
|
||||||
|
public:
|
||||||
|
AudioPlayer *CreatePlayer() { return new OpenALPlayer(); }
|
||||||
|
OpenALPlayerFactory() : AudioPlayerFactory(_T("openal")) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -39,12 +39,9 @@
|
||||||
|
|
||||||
///////////
|
///////////
|
||||||
// Headers
|
// Headers
|
||||||
#include "audio_player.h"
|
#include "audio_player_portaudio.h"
|
||||||
#include "audio_provider.h"
|
#include "audio_provider.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
extern "C" {
|
|
||||||
#include <portaudio.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_PA_GETSTREAMTIME
|
#ifdef HAVE_PA_GETSTREAMTIME
|
||||||
#define Pa_StreamTime Pa_GetStreamTime /* PortAudio v19 */
|
#define Pa_StreamTime Pa_GetStreamTime /* PortAudio v19 */
|
||||||
|
@ -59,66 +56,6 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
////////////////////
|
|
||||||
// Portaudio player
|
|
||||||
class PortAudioPlayer : public AudioPlayer {
|
|
||||||
private:
|
|
||||||
static int pa_refcount;
|
|
||||||
wxMutex PAMutex;
|
|
||||||
volatile bool stopping;
|
|
||||||
//bool softStop;
|
|
||||||
bool playing;
|
|
||||||
float volume;
|
|
||||||
|
|
||||||
volatile int64_t playPos;
|
|
||||||
volatile int64_t startPos;
|
|
||||||
volatile int64_t endPos;
|
|
||||||
void *stream;
|
|
||||||
PaTimestamp paStart;
|
|
||||||
volatile int64_t realPlayPos;
|
|
||||||
|
|
||||||
#ifndef HAVE_PA_GETSTREAMTIME
|
|
||||||
static int paCallback(void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, PaTimestamp outTime, void *userData);
|
|
||||||
#else
|
|
||||||
static int paCallback(const void *inputBuffer, void *outputBuffer,
|
|
||||||
unsigned long framesPerBuffer,
|
|
||||||
const PaStreamCallbackTimeInfo *timei,
|
|
||||||
PaStreamCallbackFlags flags, void *userData);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
|
||||||
PortAudioPlayer();
|
|
||||||
~PortAudioPlayer();
|
|
||||||
|
|
||||||
void OpenStream();
|
|
||||||
void CloseStream();
|
|
||||||
|
|
||||||
void Play(int64_t start,int64_t count);
|
|
||||||
void Stop(bool timerToo=true);
|
|
||||||
bool IsPlaying() { return playing; }
|
|
||||||
|
|
||||||
int64_t GetStartPosition() { return startPos; }
|
|
||||||
int64_t GetEndPosition() { return endPos; }
|
|
||||||
int64_t GetCurrentPosition() { return realPlayPos; }
|
|
||||||
void SetEndPosition(int64_t pos) { endPos = pos; }
|
|
||||||
void SetCurrentPosition(int64_t pos) { playPos = pos; realPlayPos = pos; }
|
|
||||||
|
|
||||||
void SetVolume(double vol) { volume = vol; }
|
|
||||||
double GetVolume() { return volume; }
|
|
||||||
|
|
||||||
wxMutex *GetMutex() { return &PAMutex; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///////////
|
|
||||||
// Factory
|
|
||||||
class PortAudioPlayerFactory : public AudioPlayerFactory {
|
|
||||||
public:
|
|
||||||
AudioPlayer *CreatePlayer() { return new PortAudioPlayer(); }
|
|
||||||
PortAudioPlayerFactory() : AudioPlayerFactory(_T("portaudio")) {}
|
|
||||||
} registerPortAudioPlayer;
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////
|
/////////////////////
|
||||||
// Reference counter
|
// Reference counter
|
||||||
int PortAudioPlayer::pa_refcount = 0;
|
int PortAudioPlayer::pa_refcount = 0;
|
||||||
|
|
109
aegisub/audio_player_portaudio.h
Normal file
109
aegisub/audio_player_portaudio.h
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
// Copyright (c) 2005-2007, Rodrigo Braz Monteiro
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer in the documentation
|
||||||
|
// and/or other materials provided with the distribution.
|
||||||
|
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||||
|
// may be used to endorse or promote products derived from this software
|
||||||
|
// without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// AEGISUB
|
||||||
|
//
|
||||||
|
// Website: http://aegisub.cellosoft.com
|
||||||
|
// Contact: mailto:zeratul@cellosoft.com
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WITH_PORTAUDIO
|
||||||
|
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// Headers
|
||||||
|
#include "audio_player.h"
|
||||||
|
#include "audio_provider.h"
|
||||||
|
#include "utils.h"
|
||||||
|
extern "C" {
|
||||||
|
#include <portaudio.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////
|
||||||
|
// Portaudio player
|
||||||
|
class PortAudioPlayer : public AudioPlayer {
|
||||||
|
private:
|
||||||
|
static int pa_refcount;
|
||||||
|
wxMutex PAMutex;
|
||||||
|
volatile bool stopping;
|
||||||
|
//bool softStop;
|
||||||
|
bool playing;
|
||||||
|
float volume;
|
||||||
|
|
||||||
|
volatile int64_t playPos;
|
||||||
|
volatile int64_t startPos;
|
||||||
|
volatile int64_t endPos;
|
||||||
|
void *stream;
|
||||||
|
PaTimestamp paStart;
|
||||||
|
volatile int64_t realPlayPos;
|
||||||
|
|
||||||
|
#ifndef HAVE_PA_GETSTREAMTIME
|
||||||
|
static int paCallback(void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, PaTimestamp outTime, void *userData);
|
||||||
|
#else
|
||||||
|
static int paCallback(const void *inputBuffer, void *outputBuffer,
|
||||||
|
unsigned long framesPerBuffer,
|
||||||
|
const PaStreamCallbackTimeInfo *timei,
|
||||||
|
PaStreamCallbackFlags flags, void *userData);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
PortAudioPlayer();
|
||||||
|
~PortAudioPlayer();
|
||||||
|
|
||||||
|
void OpenStream();
|
||||||
|
void CloseStream();
|
||||||
|
|
||||||
|
void Play(int64_t start,int64_t count);
|
||||||
|
void Stop(bool timerToo=true);
|
||||||
|
bool IsPlaying() { return playing; }
|
||||||
|
|
||||||
|
int64_t GetStartPosition() { return startPos; }
|
||||||
|
int64_t GetEndPosition() { return endPos; }
|
||||||
|
int64_t GetCurrentPosition() { return realPlayPos; }
|
||||||
|
void SetEndPosition(int64_t pos) { endPos = pos; }
|
||||||
|
void SetCurrentPosition(int64_t pos) { playPos = pos; realPlayPos = pos; }
|
||||||
|
|
||||||
|
void SetVolume(double vol) { volume = vol; }
|
||||||
|
double GetVolume() { return volume; }
|
||||||
|
|
||||||
|
wxMutex *GetMutex() { return &PAMutex; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// Factory
|
||||||
|
class PortAudioPlayerFactory : public AudioPlayerFactory {
|
||||||
|
public:
|
||||||
|
AudioPlayer *CreatePlayer() { return new PortAudioPlayer(); }
|
||||||
|
PortAudioPlayerFactory() : AudioPlayerFactory(_T("portaudio")) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -41,92 +41,10 @@
|
||||||
// Headers
|
// Headers
|
||||||
#include <wx/wxprec.h>
|
#include <wx/wxprec.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "audio_player.h"
|
#include "audio_player_pulse.h"
|
||||||
#include "audio_provider.h"
|
#include "audio_provider.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include <pulse/pulseaudio.h>
|
|
||||||
|
|
||||||
|
|
||||||
//////////////
|
|
||||||
// Prototypes
|
|
||||||
class PulseAudioPlayer;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////
|
|
||||||
// Pulse Audio player
|
|
||||||
class PulseAudioPlayer : public AudioPlayer {
|
|
||||||
private:
|
|
||||||
float volume;
|
|
||||||
bool open;
|
|
||||||
bool is_playing;
|
|
||||||
|
|
||||||
// Audio data info
|
|
||||||
volatile unsigned long start_frame;
|
|
||||||
volatile unsigned long cur_frame;
|
|
||||||
volatile unsigned long end_frame;
|
|
||||||
unsigned long bpf; // bytes per frame
|
|
||||||
|
|
||||||
// Used for synchronising with async events
|
|
||||||
wxSemaphore context_notify;
|
|
||||||
wxSemaphore context_success;
|
|
||||||
volatile int context_success_val;
|
|
||||||
wxSemaphore stream_notify;
|
|
||||||
wxSemaphore stream_success;
|
|
||||||
volatile int stream_success_val;
|
|
||||||
|
|
||||||
// PulseAudio data
|
|
||||||
pa_threaded_mainloop *mainloop; // pulseaudio mainloop handle
|
|
||||||
pa_context *context; // connection context
|
|
||||||
volatile pa_context_state_t cstate;
|
|
||||||
pa_stream *stream;
|
|
||||||
volatile pa_stream_state_t sstate;
|
|
||||||
volatile pa_usec_t play_start_time; // timestamp when playback was started
|
|
||||||
int paerror;
|
|
||||||
|
|
||||||
// Called by PA to notify about contetxt operation completion
|
|
||||||
static void pa_context_success(pa_context *c, int success, PulseAudioPlayer *thread);
|
|
||||||
// Called by PA to notify about other context-related stuff
|
|
||||||
static void pa_context_notify(pa_context *c, PulseAudioPlayer *thread);
|
|
||||||
// Called by PA when a stream operation completes
|
|
||||||
static void pa_stream_success(pa_stream *p, int success, PulseAudioPlayer *thread);
|
|
||||||
// Called by PA to request more data written to stream
|
|
||||||
static void pa_stream_write(pa_stream *p, size_t length, PulseAudioPlayer *thread);
|
|
||||||
// Called by PA to notify about other stream-related stuff
|
|
||||||
static void pa_stream_notify(pa_stream *p, PulseAudioPlayer *thread);
|
|
||||||
|
|
||||||
public:
|
|
||||||
PulseAudioPlayer();
|
|
||||||
~PulseAudioPlayer();
|
|
||||||
|
|
||||||
void OpenStream();
|
|
||||||
void CloseStream();
|
|
||||||
|
|
||||||
void Play(int64_t start,int64_t count);
|
|
||||||
void Stop(bool timerToo=true);
|
|
||||||
bool IsPlaying();
|
|
||||||
|
|
||||||
int64_t GetStartPosition();
|
|
||||||
int64_t GetEndPosition();
|
|
||||||
int64_t GetCurrentPosition();
|
|
||||||
void SetEndPosition(int64_t pos);
|
|
||||||
void SetCurrentPosition(int64_t pos);
|
|
||||||
|
|
||||||
void SetVolume(double vol) { volume = vol; }
|
|
||||||
double GetVolume() { return volume; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////
|
|
||||||
// Factory
|
|
||||||
class PulseAudioPlayerFactory : public AudioPlayerFactory {
|
|
||||||
public:
|
|
||||||
AudioPlayer *CreatePlayer() { return new PulseAudioPlayer(); }
|
|
||||||
PulseAudioPlayerFactory() : AudioPlayerFactory(_T("pulse")) {}
|
|
||||||
} registerPulsePlayer;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
|
|
130
aegisub/audio_player_pulse.h
Normal file
130
aegisub/audio_player_pulse.h
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
// Copyright (c) 2007, Niels Martin Hansen
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer in the documentation
|
||||||
|
// and/or other materials provided with the distribution.
|
||||||
|
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||||
|
// may be used to endorse or promote products derived from this software
|
||||||
|
// without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// AEGISUB
|
||||||
|
//
|
||||||
|
// Website: http://aegisub.cellosoft.com
|
||||||
|
// Contact: mailto:jiifurusu@gmail.com
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WITH_PULSEAUDIO
|
||||||
|
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// Headers
|
||||||
|
#include <wx/wxprec.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "audio_player.h"
|
||||||
|
#include "audio_provider.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "options.h"
|
||||||
|
#include <pulse/pulseaudio.h>
|
||||||
|
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
// Prototypes
|
||||||
|
class PulseAudioPlayer;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////
|
||||||
|
// Pulse Audio player
|
||||||
|
class PulseAudioPlayer : public AudioPlayer {
|
||||||
|
private:
|
||||||
|
float volume;
|
||||||
|
bool open;
|
||||||
|
bool is_playing;
|
||||||
|
|
||||||
|
// Audio data info
|
||||||
|
volatile unsigned long start_frame;
|
||||||
|
volatile unsigned long cur_frame;
|
||||||
|
volatile unsigned long end_frame;
|
||||||
|
unsigned long bpf; // bytes per frame
|
||||||
|
|
||||||
|
// Used for synchronising with async events
|
||||||
|
wxSemaphore context_notify;
|
||||||
|
wxSemaphore context_success;
|
||||||
|
volatile int context_success_val;
|
||||||
|
wxSemaphore stream_notify;
|
||||||
|
wxSemaphore stream_success;
|
||||||
|
volatile int stream_success_val;
|
||||||
|
|
||||||
|
// PulseAudio data
|
||||||
|
pa_threaded_mainloop *mainloop; // pulseaudio mainloop handle
|
||||||
|
pa_context *context; // connection context
|
||||||
|
volatile pa_context_state_t cstate;
|
||||||
|
pa_stream *stream;
|
||||||
|
volatile pa_stream_state_t sstate;
|
||||||
|
volatile pa_usec_t play_start_time; // timestamp when playback was started
|
||||||
|
int paerror;
|
||||||
|
|
||||||
|
// Called by PA to notify about contetxt operation completion
|
||||||
|
static void pa_context_success(pa_context *c, int success, PulseAudioPlayer *thread);
|
||||||
|
// Called by PA to notify about other context-related stuff
|
||||||
|
static void pa_context_notify(pa_context *c, PulseAudioPlayer *thread);
|
||||||
|
// Called by PA when a stream operation completes
|
||||||
|
static void pa_stream_success(pa_stream *p, int success, PulseAudioPlayer *thread);
|
||||||
|
// Called by PA to request more data written to stream
|
||||||
|
static void pa_stream_write(pa_stream *p, size_t length, PulseAudioPlayer *thread);
|
||||||
|
// Called by PA to notify about other stream-related stuff
|
||||||
|
static void pa_stream_notify(pa_stream *p, PulseAudioPlayer *thread);
|
||||||
|
|
||||||
|
public:
|
||||||
|
PulseAudioPlayer();
|
||||||
|
~PulseAudioPlayer();
|
||||||
|
|
||||||
|
void OpenStream();
|
||||||
|
void CloseStream();
|
||||||
|
|
||||||
|
void Play(int64_t start,int64_t count);
|
||||||
|
void Stop(bool timerToo=true);
|
||||||
|
bool IsPlaying();
|
||||||
|
|
||||||
|
int64_t GetStartPosition();
|
||||||
|
int64_t GetEndPosition();
|
||||||
|
int64_t GetCurrentPosition();
|
||||||
|
void SetEndPosition(int64_t pos);
|
||||||
|
void SetCurrentPosition(int64_t pos);
|
||||||
|
|
||||||
|
void SetVolume(double vol) { volume = vol; }
|
||||||
|
double GetVolume() { return volume; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// Factory
|
||||||
|
class PulseAudioPlayerFactory : public AudioPlayerFactory {
|
||||||
|
public:
|
||||||
|
AudioPlayer *CreatePlayer() { return new PulseAudioPlayer(); }
|
||||||
|
PulseAudioPlayerFactory() : AudioPlayerFactory(_T("pulse")) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue