From e33b15c0bd75c1a115bf4d9f4159839368cceb13 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 22 Jan 2010 11:11:24 +0100 Subject: Make qtspotify work with latest version of despotify MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add ALSA backend written by Jørgen Lind --- audiooutput.cpp | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ audiooutput.h | 42 ++++++++++++++++++++++ qtspotify.pro | 8 +++-- qtspotifymain.cpp | 17 ++++----- qtspotifymain.h | 2 ++ 5 files changed, 160 insertions(+), 11 deletions(-) create mode 100644 audiooutput.cpp create mode 100644 audiooutput.h diff --git a/audiooutput.cpp b/audiooutput.cpp new file mode 100644 index 0000000..03f3c5c --- /dev/null +++ b/audiooutput.cpp @@ -0,0 +1,102 @@ +#include "audiooutput.h" + +#include + +AudioOutput::AudioOutput() + : QThread(), m_despotifySession(0), + frameSize(16 * 2 / 8), m_channels(2), m_bitrate(44100), m_state(Pause) +{ + int rc; + snd_pcm_hw_params_t *params; + int dir; + /* Open PCM device for playback. */ + rc = snd_pcm_open(&m_alsaHandle, "default", + SND_PCM_STREAM_PLAYBACK, 0); + if (rc < 0) { + qWarning() << "unable to open pcm device: " << snd_strerror(rc); + } + + /* Allocate a hardware parameters object. */ + snd_pcm_hw_params_alloca(¶ms); + + /* Fill it in with default values. */ + snd_pcm_hw_params_any(m_alsaHandle, params); + + /* Set the desired hardware parameters. */ + + /* Interleaved mode */ + snd_pcm_hw_params_set_access(m_alsaHandle, params, + SND_PCM_ACCESS_RW_INTERLEAVED); + + /* Signed 16-bit little-endian format */ + snd_pcm_hw_params_set_format(m_alsaHandle, params, + SND_PCM_FORMAT_S16); + + /* Two channels (stereo) */ + snd_pcm_hw_params_set_channels(m_alsaHandle, params, m_channels); + + /* 44100 bits/second sampling rate (CD quality) */ + snd_pcm_hw_params_set_rate_near(m_alsaHandle, params, + &m_bitrate, &dir); + + /* Write the parameters to the driver */ + rc = snd_pcm_hw_params(m_alsaHandle, params); + if (rc < 0) { + qWarning() << "unable to set hw parameters: " << snd_strerror(rc); + } + snd_pcm_prepare(m_alsaHandle); + + start(); + +} + +AudioOutput::~AudioOutput() +{ + snd_pcm_close (m_alsaHandle); +} + +void AudioOutput::setDespotifySession(despotify_session *ds) +{ + pause(); + m_despotifySession = ds; +} + +void AudioOutput::play() +{ + if (m_state != Play) { + m_state = Play; + m_isPlaying.wakeAll(); + } +} + +void AudioOutput::pause() +{ + if (m_state != Pause) { + m_state = Pause; + QMutex lock; + lock.lock(); + m_isPause.wait(&lock); + } +} + +void AudioOutput::run() +{ + QMutex lock; + lock.lock(); + forever { + switch (m_state) { + case Pause: + m_isPause.wakeAll(); + m_isPlaying.wait(&lock); + break; + case Play: + pcm_data pcm; + despotify_get_pcm(m_despotifySession,&pcm); + int frames = pcm.len / frameSize; + int framesWritten = snd_pcm_writei(m_alsaHandle,pcm.buf,frames); + if (framesWritten != frames) + snd_pcm_prepare(m_alsaHandle); + break; + } + } +} diff --git a/audiooutput.h b/audiooutput.h new file mode 100644 index 0000000..0534c43 --- /dev/null +++ b/audiooutput.h @@ -0,0 +1,42 @@ +#ifndef AUDIOOUTPUT_H +#define AUDIOOUTPUT_H + +#include +#include +#include + +#include + +#include + +class AudioOutput : public QThread +{ +public: + AudioOutput(); + ~AudioOutput(); + void setDespotifySession(despotify_session *ds); + void play(); + void pause(); + void flush(); + +protected: + enum State { Play, Pause }; + void run(); + +private: + QWaitCondition m_isPlaying; + QWaitCondition m_isPause; + snd_pcm_t *m_alsaHandle; + despotify_session *m_despotifySession; + + //is going to be 16 * 2 / 8 + //bitwidth * channels + int frameSize; + + uint m_channels; + uint m_bitrate; + + State m_state; +}; + +#endif // AUDIOOUTPUT_H diff --git a/qtspotify.pro b/qtspotify.pro index 061cbe5..dccbb2a 100644 --- a/qtspotify.pro +++ b/qtspotify.pro @@ -5,7 +5,8 @@ HEADERS += qtspotifymain.h \ storedplaylistmodel.h \ coverdatabase.h \ searchdialog.h \ - searchmodel.h + searchmodel.h \ + audiooutput.h SOURCES += qtspotifymain.cpp \ main.cpp \ logindialog.cpp \ @@ -13,8 +14,9 @@ SOURCES += qtspotifymain.cpp \ storedplaylistmodel.cpp \ coverdatabase.cpp \ searchdialog.cpp \ - searchmodel.cpp + searchmodel.cpp \ + audiooutput.cpp FORMS += qtspotify.ui \ logindialog.ui \ searchdialog.ui -LIBS += -ldespotify +LIBS += -ldespotify -lasound diff --git a/qtspotifymain.cpp b/qtspotifymain.cpp index deb9546..9a06b1b 100644 --- a/qtspotifymain.cpp +++ b/qtspotifymain.cpp @@ -68,7 +68,7 @@ static void callback(despotify_session *session, int signal, void *data, void *c return; switch (signal) { - case DESPOTIFY_TRACK_CHANGE: + case DESPOTIFY_NEW_TRACK: { track *t = reinterpret_cast(data); QtSpotifyMain *qsm = reinterpret_cast(session->client_callback_data); @@ -81,7 +81,7 @@ QtSpotifyMain::QtSpotifyMain(QWidget *parent) : QMainWindow(parent), m_session(0), m_machine(new QStateMachine), m_debugging(false), m_authenticationWatcher(0), m_retrievingPlayListWatcher(0) { - m_session = despotify_init_client(callback, this, true); + m_session = despotify_init_client(callback, this, true, true); if (m_session != 0) { initUi(); @@ -297,39 +297,39 @@ void QtSpotifyMain::search() void QtSpotifyMain::stop() { debug(tr("Stopping")); + m_audio.pause(); despotify_stop(m_session); } void QtSpotifyMain::pause() { debug(tr("Pausing")); - if (!despotify_pause(m_session)) { - QMessageBox::warning(this, tr("Error when pausing track"), - tr("Despotify error: %1").arg(QString::fromUtf8(m_session->last_error))); - } + m_audio.pause(); } void QtSpotifyMain::resume() { debug(tr("Resuming")); - despotify_resume(m_session); + m_audio.play(); } void QtSpotifyMain::play() { if (m_ui.playList->currentItem() == 0) { qWarning("Nothing to play"); - return ; + return; } QVariant data = m_ui.playList->currentItem()->data(0, Qt::UserRole); track *t = data.value(); if (t != 0) { + m_audio.pause(); debug(tr("Playing '%1'").arg(t->title)); if (!despotify_play(m_session, t, true)) { QMessageBox::information(this, tr("Error when playing track"), tr("Despotify error: %1").arg(QString::fromUtf8(m_session->last_error))); } else { + m_audio.play(); setNewTrack(t); } } else { @@ -362,6 +362,7 @@ void QtSpotifyMain::decideLoginResult() { if (m_authenticationWatcher->result()) { debug(tr("Login succeeded")); + m_audio.setDespotifySession(m_session); emit loggedIn(); } else { QMessageBox::warning(this, tr("Failed to log in"), diff --git a/qtspotifymain.h b/qtspotifymain.h index e2bdf1e..2541a8c 100644 --- a/qtspotifymain.h +++ b/qtspotifymain.h @@ -26,6 +26,7 @@ #define QTSPOTIFYMAIN_H #include "ui_qtspotify.h" +#include "audiooutput.h" #include @@ -144,6 +145,7 @@ private: LogInDialog *m_logInDialog; + AudioOutput m_audio; }; #endif // QTSPOTIFYMAIN_H -- cgit v1.2.3