Finish porting the alsa player from 2.1.9 so that it actually compiles

Originally committed to SVN as r5825.
This commit is contained in:
Thomas Goyne 2011-11-07 05:24:46 +00:00
parent 0aa553eb7c
commit 8b5545c98f
3 changed files with 80 additions and 89 deletions

View file

@ -513,10 +513,10 @@ fi
AC_ARG_WITH(alsa, [ --without-alsa build without ALSA audio provider. (default: auto)], alsa_disabled="(disabled)") AC_ARG_WITH(alsa, [ --without-alsa build without ALSA audio provider. (default: auto)], alsa_disabled="(disabled)")
AC_ARG_VAR([ALSA_CFLAGS], [CFLAGS to use for ALSA (default: CPPFLAGS)]) AC_ARG_VAR([ALSA_CFLAGS], [CFLAGS to use for ALSA (default: CPPFLAGS)])
AC_ARG_VAR([ALSA_LDFLAGS], [LDFLAGS to use for ALSA (default: -lasound)]) AC_ARG_VAR([ALSA_LDFLAGS], [LDFLAGS to use for ALSA (default: -lasound -lrt)])
if test -z "$ALSA_LDFLAGS"; then if test -z "$ALSA_LDFLAGS"; then
ALSA_LDFLAGS="-lasound"; ALSA_LDFLAGS="-lasound -lrt";
fi fi
if test -z "$ALSA_CFLAGS"; then if test -z "$ALSA_CFLAGS"; then

View file

@ -41,10 +41,14 @@
#include <libaegisub/log.h> #include <libaegisub/log.h>
#include "audio_player_alsa.h" #include "audio_player_alsa.h"
#include "include/aegisub/audio_provider.h"
#include "compat.h" #include "compat.h"
#include "frame_main.h" #include "frame_main.h"
#include "options.h" #include "main.h"
#ifndef AGI_PRE
#include <algorithm> #include <algorithm>
#endif
class PthreadMutexLocker { class PthreadMutexLocker {
pthread_mutex_t &mutex; pthread_mutex_t &mutex;
@ -142,36 +146,6 @@ struct PlaybackState {
} }
}; };
class AlsaPlayer : public AudioPlayer {
private:
PlaybackState ps;
pthread_t thread;
bool open;
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);
double GetVolume();
};
void *playback_thread(void *arg) void *playback_thread(void *arg)
{ {
// This is exception-free territory! // This is exception-free territory!
@ -183,7 +157,7 @@ void *playback_thread(void *arg)
snd_pcm_t *pcm = 0; snd_pcm_t *pcm = 0;
if (snd_pcm_open(&pcm, ps.device_name.c_str(), SND_PCM_STREAM_PLAYBACK, 0) != 0) if (snd_pcm_open(&pcm, ps.device_name.c_str(), SND_PCM_STREAM_PLAYBACK, 0) != 0)
return "snd_pcm_open"; return (void*)"snd_pcm_open";
printf("alsa_player: opened pcm\n"); printf("alsa_player: opened pcm\n");
do_setup: do_setup:
@ -200,7 +174,7 @@ do_setup:
break; break;
default: default:
snd_pcm_close(pcm); snd_pcm_close(pcm);
return "snd_pcm_format_t"; return (void*)"snd_pcm_format_t";
} }
if (snd_pcm_set_params(pcm, if (snd_pcm_set_params(pcm,
pcm_format, pcm_format,
@ -210,7 +184,7 @@ do_setup:
1, // allow resample 1, // allow resample
100*1000 // 100 milliseconds latency 100*1000 // 100 milliseconds latency
) != 0) ) != 0)
return "snd_pcm_set_params"; return (void*)"snd_pcm_set_params";
printf("alsa_player: set pcm params\n"); printf("alsa_player: set pcm params\n");
size_t framesize = ps.provider->GetChannels() * ps.provider->GetBytesPerSample(); size_t framesize = ps.provider->GetChannels() * ps.provider->GetBytesPerSample();
@ -252,7 +226,7 @@ do_setup:
delete[] buf; delete[] buf;
snd_pcm_close(pcm); snd_pcm_close(pcm);
printf("alsa_player: error filling buffer\n"); printf("alsa_player: error filling buffer\n");
return "snd_pcm_writei"; return (void*)"snd_pcm_writei";
} }
} }
delete[] buf; delete[] buf;
@ -309,8 +283,8 @@ do_setup:
{ {
delete[] buf; delete[] buf;
snd_pcm_close(pcm); snd_pcm_close(pcm);
printf("alsa_player: error filling buffer, written=%d\n", written); printf("alsa_player: error filling buffer, written=%d\n", (int)written);
return "snd_pcm_writei"; return (void*)"snd_pcm_writei";
} }
} }
delete[] buf; delete[] buf;
@ -344,7 +318,7 @@ do_setup:
case SND_PCM_STATE_DISCONNECTED: case SND_PCM_STATE_DISCONNECTED:
// lost device, close the handle and return error // lost device, close the handle and return error
snd_pcm_close(pcm); snd_pcm_close(pcm);
return "SND_PCM_STATE_DISCONNECTED"; return (void*)"SND_PCM_STATE_DISCONNECTED";
default: default:
// everything else should either be fine or impossible (here) // everything else should either be fine or impossible (here)
@ -361,8 +335,8 @@ do_setup:
AlsaPlayer::AlsaPlayer() AlsaPlayer::AlsaPlayer()
: ps(new PlaybackState)
{ {
ps.Reset();
open = false; open = false;
} }
@ -379,13 +353,13 @@ void AlsaPlayer::OpenStream()
CloseStream(); CloseStream();
ps.Reset(); ps->Reset();
ps.provider = GetProvider(); ps->provider = GetProvider();
wxString device_name = lagi_wxString(OPT_GET("Player/Audio/ALSA/Device")->GetString()); wxString device_name = lagi_wxString(OPT_GET("Player/Audio/ALSA/Device")->GetString());
ps.device_name = std::string(device_name.utf8_str()); ps->device_name = std::string(device_name.utf8_str());
if (pthread_create(&thread, 0, &playback_thread, &ps) == 0) if (pthread_create(&thread, 0, &playback_thread, ps.get()) == 0)
{ {
open = true; open = true;
} }
@ -401,11 +375,11 @@ void AlsaPlayer::CloseStream()
if (!open) return; if (!open) return;
{ {
PthreadMutexLocker ml(ps.mutex); PthreadMutexLocker ml(ps->mutex);
ps.signal_stop = true; ps->signal_stop = true;
ps.signal_close = true; ps->signal_close = true;
printf("AlsaPlayer: close stream, stop+close signal\n"); printf("AlsaPlayer: close stream, stop+close signal\n");
pthread_cond_signal(&ps.cond); pthread_cond_signal(&ps->cond);
} }
pthread_join(thread, 0); // FIXME: check for errors pthread_join(thread, 0); // FIXME: check for errors
@ -419,12 +393,12 @@ void AlsaPlayer::Play(int64_t start, int64_t count)
OpenStream(); OpenStream();
{ {
PthreadMutexLocker ml(ps.mutex); PthreadMutexLocker ml(ps->mutex);
ps.signal_start = true; ps->signal_start = true;
ps.signal_stop = true; // make sure to stop any ongoing playback first ps->signal_stop = true; // make sure to stop any ongoing playback first
ps.start_position = start; ps->start_position = start;
ps.end_position = start + count; ps->end_position = start + count;
pthread_cond_signal(&ps.cond); pthread_cond_signal(&ps->cond);
} }
if (displayTimer && !displayTimer->IsRunning()) displayTimer->Start(15); if (displayTimer && !displayTimer->IsRunning()) displayTimer->Start(15);
@ -436,10 +410,10 @@ void AlsaPlayer::Stop(bool timerToo)
if (!open) return; if (!open) return;
{ {
PthreadMutexLocker ml(ps.mutex); PthreadMutexLocker ml(ps->mutex);
ps.signal_stop = true; ps->signal_stop = true;
printf("AlsaPlayer: stop stream, stop signal\n"); printf("AlsaPlayer: stop stream, stop signal\n");
pthread_cond_signal(&ps.cond); pthread_cond_signal(&ps->cond);
} }
if (timerToo && displayTimer) { if (timerToo && displayTimer) {
@ -449,15 +423,15 @@ void AlsaPlayer::Stop(bool timerToo)
bool AlsaPlayer::IsPlaying() bool AlsaPlayer::IsPlaying()
{ {
return open && ps.playing; return open && ps->playing;
} }
void AlsaPlayer::SetEndPosition(int64_t pos) void AlsaPlayer::SetEndPosition(int64_t pos)
{ {
if (!open) return; if (!open) return;
PthreadMutexLocker ml(ps.mutex); PthreadMutexLocker ml(ps->mutex);
ps.end_position = pos; ps->end_position = pos;
} }
@ -465,27 +439,27 @@ void AlsaPlayer::SetCurrentPosition(int64_t pos)
{ {
if (!open) return; if (!open) return;
PthreadMutexLocker ml(ps.mutex); PthreadMutexLocker ml(ps->mutex);
if (!ps.playing) return; if (!ps->playing) return;
ps.start_position = pos; ps->start_position = pos;
ps.signal_start = true; ps->signal_start = true;
ps.signal_stop = true; ps->signal_stop = true;
printf("AlsaPlayer: set position, stop+start signal\n"); printf("AlsaPlayer: set position, stop+start signal\n");
pthread_cond_signal(&ps.cond); pthread_cond_signal(&ps->cond);
} }
int64_t AlsaPlayer::GetStartPosition() int64_t AlsaPlayer::GetStartPosition()
{ {
if (!open) return 0; if (!open) return 0;
return ps.start_position; return ps->start_position;
} }
int64_t AlsaPlayer::GetEndPosition() int64_t AlsaPlayer::GetEndPosition()
{ {
if (!open) return 0; if (!open) return 0;
return ps.end_position; return ps->end_position;
} }
@ -498,10 +472,10 @@ int64_t AlsaPlayer::GetCurrentPosition()
int64_t samplerate; int64_t samplerate;
{ {
//PthreadMutexLocker ml(ps.mutex); //PthreadMutexLocker ml(ps->mutex);
lastpos = ps.last_position; lastpos = ps->last_position;
lasttime = ps.last_position_time; lasttime = ps->last_position_time;
samplerate = ps.provider->GetSampleRate(); samplerate = ps->provider->GetSampleRate();
} }
timespec now; timespec now;
@ -522,26 +496,18 @@ int64_t AlsaPlayer::GetCurrentPosition()
void AlsaPlayer::SetVolume(double vol) void AlsaPlayer::SetVolume(double vol)
{ {
if (!open) return; if (!open) return;
PthreadMutexLocker ml(ps.mutex); PthreadMutexLocker ml(ps->mutex);
ps.volume = vol; ps->volume = vol;
ps.signal_volume = true; ps->signal_volume = true;
pthread_cond_signal(&ps.cond); pthread_cond_signal(&ps->cond);
} }
double AlsaPlayer::GetVolume() double AlsaPlayer::GetVolume()
{ {
if (!open) return 1.0; if (!open) return 1.0;
PthreadMutexLocker ml(ps.mutex); PthreadMutexLocker ml(ps->mutex);
return ps.volume; return ps->volume;
}
// The factory method
AudioPlayer * AlsaPlayerFactory::CreatePlayer()
{
return new AlsaPlayer();
} }
#endif // WITH_ALSA #endif // WITH_ALSA

View file

@ -40,9 +40,34 @@
#include "include/aegisub/audio_player.h" #include "include/aegisub/audio_player.h"
class AlsaPlayerFactory : public AudioPlayerFactory { #include <libaegisub/scoped_ptr.h>
struct PlaybackState;
class AlsaPlayer : public AudioPlayer {
agi::scoped_ptr<PlaybackState> ps;
pthread_t thread;
bool open;
public: public:
AudioPlayer *CreatePlayer(); 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);
double GetVolume();
}; };
#endif #endif