summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--audiooutput.cpp102
-rw-r--r--audiooutput.h42
-rw-r--r--qtspotify.pro8
-rw-r--r--qtspotifymain.cpp17
-rw-r--r--qtspotifymain.h2
5 files changed, 160 insertions, 11 deletions
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 <QDebug>
+
+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(&params);
+
+ /* 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 <QThread>
+#include <QMutex>
+#include <QWaitCondition>
+
+#include <alsa/asoundlib.h>
+
+#include <despotify_cpp.h>
+
+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<track *>(data);
QtSpotifyMain *qsm = reinterpret_cast<QtSpotifyMain*>(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<track *>();
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 <QtGui/QMainWindow>
@@ -144,6 +145,7 @@ private:
LogInDialog *m_logInDialog;
+ AudioOutput m_audio;
};
#endif // QTSPOTIFYMAIN_H