aboutsummaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2010-07-24 07:54:13 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2010-07-24 07:54:13 +0000
commitd2d062fa716a79ccf161fc302e73723f3eb1bb8d (patch)
tree19e594eec9635939305c1084b2ed380d4ed786c0 /src/plugins
parent04f1cf7bd526a9e906131ad35f950aa701f5b4f5 (diff)
downloadqmmp-d2d062fa716a79ccf161fc302e73723f3eb1bb8d.tar.gz
qmmp-d2d062fa716a79ccf161fc302e73723f3eb1bb8d.tar.bz2
qmmp-d2d062fa716a79ccf161fc302e73723f3eb1bb8d.zip
added fast seeking patches (Closes issue 338)
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@1804 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/Output/alsa/outputalsa.cpp104
-rw-r--r--src/plugins/Output/alsa/outputalsa.h8
-rw-r--r--src/plugins/Output/jack/outputjack.cpp5
-rw-r--r--src/plugins/Output/jack/outputjack.h3
-rw-r--r--src/plugins/Output/null/outputnull.cpp5
-rw-r--r--src/plugins/Output/null/outputnull.h3
-rw-r--r--src/plugins/Output/oss/outputoss.cpp140
-rw-r--r--src/plugins/Output/oss/outputoss.h10
-rw-r--r--src/plugins/Output/pulseaudio/outputpulseaudio.cpp10
-rw-r--r--src/plugins/Output/pulseaudio/outputpulseaudio.h3
10 files changed, 129 insertions, 162 deletions
diff --git a/src/plugins/Output/alsa/outputalsa.cpp b/src/plugins/Output/alsa/outputalsa.cpp
index 620d758b2..39d2edf03 100644
--- a/src/plugins/Output/alsa/outputalsa.cpp
+++ b/src/plugins/Output/alsa/outputalsa.cpp
@@ -47,7 +47,6 @@ OutputALSA::OutputALSA(QObject * parent)
m_prebuf = 0;
m_prebuf_size = 0;
m_prebuf_fill = 0;
- m_pause = false;
m_can_pause = false;
}
@@ -123,8 +122,7 @@ void OutputALSA::configure(quint32 freq, int chan, Qmmp::AudioFormat format)
qDebug("OutputALSA: Error setting format: %s", snd_strerror(err));
return;
}
- exact_rate = rate;// = 11000;
- //qDebug("OutputALSA: frequency=%d, channels=%d, bits=%d", rate, chan,prec);
+ exact_rate = rate;
if ((err = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &exact_rate, 0)) < 0)
{
@@ -187,24 +185,10 @@ void OutputALSA::configure(quint32 freq, int chan, Qmmp::AudioFormat format)
qDebug("OutputALSA: can pause: %d", m_can_pause);
Output::configure(freq, chan, format); //apply configuration
//create alsa prebuffer;
- m_prebuf_size = QMMP_BLOCK_SIZE + m_bits_per_frame * m_chunk_size / 8;
+ m_prebuf_size = QMMP_BUFFER_SIZE + m_bits_per_frame * m_chunk_size / 8;
m_prebuf = (uchar *)malloc(m_prebuf_size);
}
-void OutputALSA::reset()
-{
- if (pcm_handle)
- {
- snd_pcm_close(pcm_handle);
- pcm_handle = 0;
- }
- if (snd_pcm_open(&pcm_handle, pcm_name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0)
- {
- qWarning ("OutputALSA: Error opening PCM device %s", pcm_name);
- return;
- }
-}
-
bool OutputALSA::initialize()
{
m_inited = false;
@@ -228,29 +212,55 @@ qint64 OutputALSA::latency()
return m_prebuf_fill * 1000 / sampleRate() / numChannels() / sampleSize();
}
-void OutputALSA::pause()
+void OutputALSA::drain()
{
- m_pause = !m_pause;
- if (m_can_pause)
- snd_pcm_pause(pcm_handle, m_pause);
- else if (m_pause && pcm_handle)
+ long m = 0;
+ snd_pcm_uframes_t l = snd_pcm_bytes_to_frames(pcm_handle, m_prebuf_fill);
+ while (l > 0)
{
- snd_pcm_drop(pcm_handle);
- snd_pcm_prepare(pcm_handle);
+ if ((m = alsa_write(m_prebuf, l)) >= 0)
+ {
+ l -= m;
+ m = snd_pcm_frames_to_bytes(pcm_handle, m); // convert frames to bytes
+ m_prebuf_fill -= m;
+ memcpy(m_prebuf, m_prebuf + m, m_prebuf_fill);
+ }
+ else
+ break;
}
- Output::pause();
+ snd_pcm_nonblock(pcm_handle, 0);
+ snd_pcm_drain(pcm_handle);
+ snd_pcm_nonblock(pcm_handle, 1);
+}
+
+void OutputALSA::reset()
+{
+ m_prebuf_fill = 0;
+ snd_pcm_drop(pcm_handle);
+ snd_pcm_prepare(pcm_handle);
+}
+
+void OutputALSA::suspend()
+{
+ if (m_can_pause)
+ snd_pcm_pause(pcm_handle, 1);
+ snd_pcm_prepare(pcm_handle);
+}
+
+void OutputALSA::resume()
+{
+ if (m_can_pause)
+ snd_pcm_pause(pcm_handle, 0);
+ snd_pcm_prepare(pcm_handle);
}
qint64 OutputALSA::writeAudio(unsigned char *data, qint64 maxSize)
{
- //increase buffer size if needed
- if (m_prebuf_size < m_prebuf_fill + maxSize)
+ if((maxSize = qMin(maxSize, m_prebuf_size - m_prebuf_fill)) > 0)
{
- m_prebuf_size = m_prebuf_fill + maxSize;
- m_prebuf = (uchar*) realloc(m_prebuf, m_prebuf_size);
+ memcpy(m_prebuf + m_prebuf_fill, data, maxSize);
+ m_prebuf_fill += maxSize;
}
- memcpy(m_prebuf + m_prebuf_fill, data, maxSize);
- m_prebuf_fill += maxSize;
snd_pcm_uframes_t l = snd_pcm_bytes_to_frames(pcm_handle, m_prebuf_fill);
@@ -271,28 +281,6 @@ qint64 OutputALSA::writeAudio(unsigned char *data, qint64 maxSize)
return maxSize;
}
-void OutputALSA::flush()
-{
- snd_pcm_uframes_t l = snd_pcm_bytes_to_frames(pcm_handle, m_prebuf_fill);
- long m;
- l = snd_pcm_bytes_to_frames(pcm_handle, l);
- while (l > 0)
- {
- if ((m = alsa_write(m_prebuf, l)) >= 0)
- {
- l -= m;
- m = snd_pcm_frames_to_bytes(pcm_handle, m); // convert frames to bytes
- m_prebuf_fill -= m;
- memcpy(m_prebuf, m_prebuf + m, m_prebuf_fill);
- }
- else
- break;
- }
- snd_pcm_nonblock(pcm_handle, 0);
- snd_pcm_drain(pcm_handle);
- snd_pcm_nonblock(pcm_handle, 1);
-}
-
long OutputALSA::alsa_write(unsigned char *data, long size)
{
long m = 0;
@@ -303,18 +291,18 @@ long OutputALSA::alsa_write(unsigned char *data, long size)
if (m == -EAGAIN)
{
- //mutex()->unlock();
+ mutex()->unlock();
snd_pcm_wait(pcm_handle, 500);
- //mutex()->lock ();
+ mutex()->lock ();
return 0;
}
else if (m >= 0)
{
if (m < size)
{
- //mutex()->unlock();
+ mutex()->unlock();
snd_pcm_wait(pcm_handle, 500);
- //mutex()->lock ();
+ mutex()->lock ();
}
return m;
}
diff --git a/src/plugins/Output/alsa/outputalsa.h b/src/plugins/Output/alsa/outputalsa.h
index b0afcebce..1af62a2ae 100644
--- a/src/plugins/Output/alsa/outputalsa.h
+++ b/src/plugins/Output/alsa/outputalsa.h
@@ -44,15 +44,16 @@ public:
bool initialize();
void configure(quint32, int, Qmmp::AudioFormat format);
qint64 latency();
- void pause();
private:
//output api
qint64 writeAudio(unsigned char *data, qint64 maxSize);
- void flush();
+ void drain();
+ void reset();
+ void suspend();
+ void resume();
// helper functions
- void reset();
long alsa_write(unsigned char *data, long size);
void uninitialize();
@@ -67,7 +68,6 @@ private:
uchar *m_prebuf;
qint64 m_prebuf_size;
qint64 m_prebuf_fill;
- bool m_pause;
bool m_can_pause;
};
diff --git a/src/plugins/Output/jack/outputjack.cpp b/src/plugins/Output/jack/outputjack.cpp
index 1a846070c..39548acd4 100644
--- a/src/plugins/Output/jack/outputjack.cpp
+++ b/src/plugins/Output/jack/outputjack.cpp
@@ -94,6 +94,11 @@ qint64 OutputJACK::writeAudio(unsigned char *data, qint64 maxSize)
return m;
}
+void OutputJACK::reset()
+{
+ JACK_Reset(jack_device);
+}
+
void OutputJACK::uninitialize()
{
if (!m_inited)
diff --git a/src/plugins/Output/jack/outputjack.h b/src/plugins/Output/jack/outputjack.h
index f2d6357b6..5b4e79bcb 100644
--- a/src/plugins/Output/jack/outputjack.h
+++ b/src/plugins/Output/jack/outputjack.h
@@ -46,7 +46,8 @@ public:
private:
//output api
qint64 writeAudio(unsigned char *data, qint64 maxSize);
- void flush(){};
+ void drain(){};
+ void reset();
// helper functions
void uninitialize();
diff --git a/src/plugins/Output/null/outputnull.cpp b/src/plugins/Output/null/outputnull.cpp
index a6cadd615..9b9420cff 100644
--- a/src/plugins/Output/null/outputnull.cpp
+++ b/src/plugins/Output/null/outputnull.cpp
@@ -66,5 +66,8 @@ qint64 OutputNull::writeAudio(unsigned char *data, qint64 maxSize)
return maxSize;
}
-void OutputNull::flush()
+void OutputNull::drain()
+{}
+
+void OutputNull::reset()
{}
diff --git a/src/plugins/Output/null/outputnull.h b/src/plugins/Output/null/outputnull.h
index 32b406271..f99441a0f 100644
--- a/src/plugins/Output/null/outputnull.h
+++ b/src/plugins/Output/null/outputnull.h
@@ -42,7 +42,8 @@ public:
private:
//output api
qint64 writeAudio(unsigned char *data, qint64 maxSize);
- void flush();
+ void drain();
+ void reset();
qint64 m_bytes_per_second;
};
diff --git a/src/plugins/Output/oss/outputoss.cpp b/src/plugins/Output/oss/outputoss.cpp
index 7125dc981..eea53584d 100644
--- a/src/plugins/Output/oss/outputoss.cpp
+++ b/src/plugins/Output/oss/outputoss.cpp
@@ -81,22 +81,13 @@ int OutputOSS::audio_fd()
OutputOSS::~OutputOSS()
{
- m_instance = 0;
- if (m_audio_fd > 0)
- {
- close(m_audio_fd);
- m_audio_fd = -1;
- }
+ uninitialize();
+ m_instance = 0;
}
void OutputOSS::configure(quint32 freq, int chan, Qmmp::AudioFormat format)
{
- // we need to configure
- if (freq != m_frequency || chan != m_channels)
- {
- // we have already configured, but are changing settings...
- // reset the device
- resetDSP();
+
#if SOUND_VERSION >= 0x040000
if (VolumeControlOSS::instance())
{
@@ -108,75 +99,36 @@ void OutputOSS::configure(quint32 freq, int chan, Qmmp::AudioFormat format)
ioctl(m_audio_fd, cmd, &v);
}
#endif
- m_frequency = freq;
- m_channels = chan;
+ m_frequency = freq;
+ m_channels = chan;
- //m_bps = freq * chan * (prec / 8);
+ //m_bps = freq * chan * (prec / 8);
- int p;
- switch (format)
- {
- default:
- case Qmmp::PCM_S16LE:
+ int p;
+ switch (format)
+ {
+ default:
+ case Qmmp::PCM_S16LE:
#if defined(AFMT_S16_NE)
- p = AFMT_S16_NE;
+ p = AFMT_S16_NE;
#else
- p = AFMT_S16_LE;
+ p = AFMT_S16_LE;
#endif
- break;
+ break;
- case Qmmp::PCM_S8:
- p = AFMT_S8;
- break;
+ case Qmmp::PCM_S8:
+ p = AFMT_S8;
+ break;
- }
-
- if (ioctl(m_audio_fd, SNDCTL_DSP_SETFMT, &p) == -1)
- qWarning("OutputOSS: can't set audio format");
- /*if(ioctl(m_audio_fd, SNDCTL_DSP_SAMPLESIZE, &prec) == -1)
- qDebug("OutputOSS: can't set audio format");*/
- int stereo = (chan > 1) ? 1 : 0;
- ioctl(m_audio_fd, SNDCTL_DSP_STEREO, &stereo);
- /*if (ioctl(m_audio_fd, SNDCTL_DSP_SPEED, &m_channels) == -1)
- qWarning("OutputOSS: can't set number of channels");*/
- /*if (chan != m_channels)
- qWarning("OutputOSS: can't set number of channels, using %d instead", m_channels);*/
- if (ioctl(m_audio_fd, SNDCTL_DSP_SPEED, &freq) == -1)
- qWarning("OutputOSS: can't set audio format");
}
- Output::configure(freq, chan, format);
-}
-void OutputOSS::reset()
-{
- if (m_audio_fd > 0)
- {
- close(m_audio_fd);
- m_audio_fd = -1;
- }
-
- m_audio_fd = open(m_audio_device.toAscii(), O_WRONLY, 0);
-
- if (m_audio_fd < 0)
- {
- qWarning("OSSOutput: failed to open output device '%s'", qPrintable(m_audio_device));
- return;
- }
-
- int flags;
- if ((flags = fcntl(m_audio_fd, F_GETFL, 0)) > 0)
- {
- flags &= O_NDELAY;
- fcntl(m_audio_fd, F_SETFL, flags);
- }
-
- fd_set afd;
- FD_ZERO(&afd);
- FD_SET(m_audio_fd, &afd);
- struct timeval tv;
- tv.tv_sec = 0l;
- tv.tv_usec = 50000l;
- do_select = (select(m_audio_fd + 1, 0, &afd, 0, &tv) > 0);
+ if (ioctl(m_audio_fd, SNDCTL_DSP_SETFMT, &p) == -1)
+ qWarning("OutputOSS: can't set audio format");
+ int stereo = (chan > 1) ? 1 : 0;
+ ioctl(m_audio_fd, SNDCTL_DSP_STEREO, &stereo);
+ if (ioctl(m_audio_fd, SNDCTL_DSP_SPEED, &freq) == -1)
+ qWarning("OutputOSS: can't set audio format");
+ Output::configure(freq, chan, format);
}
void OutputOSS::post()
@@ -197,22 +149,29 @@ void OutputOSS::sync()
ioctl(m_audio_fd, SNDCTL_DSP_SYNC, &unused);
}
-
-void OutputOSS::resetDSP()
-{
- if (m_audio_fd < 1)
- return;
-
- int unused;
- ioctl(m_audio_fd, SNDCTL_DSP_RESET, &unused);
-}
-
-
bool OutputOSS::initialize()
{
- reset();
+ m_audio_fd = open(m_audio_device.toAscii(), O_WRONLY, 0);
+
if (m_audio_fd < 0)
+ {
+ qWarning("OSSOutput: failed to open output device '%s'", qPrintable(m_audio_device));
return false;
+ }
+
+ int flags;
+ if ((flags = fcntl(m_audio_fd, F_GETFL, 0)) > 0)
+ {
+ flags &= O_NDELAY;
+ fcntl(m_audio_fd, F_SETFL, flags);
+ }
+ fd_set afd;
+ FD_ZERO(&afd);
+ FD_SET(m_audio_fd, &afd);
+ struct timeval tv;
+ tv.tv_sec = 0l;
+ tv.tv_usec = 50000l;
+ do_select = (select(m_audio_fd + 1, 0, &afd, 0, &tv) > 0);
m_inited = true;
return true;
}
@@ -224,9 +183,9 @@ void OutputOSS::uninitialize()
m_inited = false;
m_frequency = -1;
m_channels = -1;
- resetDSP();
if (m_audio_fd > 0)
{
+ ioctl(m_audio_fd, SNDCTL_DSP_RESET, 0);
close(m_audio_fd);
m_audio_fd = -1;
}
@@ -265,8 +224,17 @@ qint64 OutputOSS::writeAudio(unsigned char *data, qint64 maxSize)
return m;
}
-/***** MIXER *****/
+void OutputOSS::drain()
+{
+ ioctl(m_audio_fd, SNDCTL_DSP_SYNC, 0);
+}
+void OutputOSS::reset()
+{
+ ioctl(m_audio_fd, SNDCTL_DSP_RESET, 0);
+}
+
+/***** MIXER *****/
VolumeControlOSS *VolumeControlOSS::instance()
{
return m_instance;
diff --git a/src/plugins/Output/oss/outputoss.h b/src/plugins/Output/oss/outputoss.h
index 7fb0e4c94..5046b1bc3 100644
--- a/src/plugins/Output/oss/outputoss.h
+++ b/src/plugins/Output/oss/outputoss.h
@@ -44,18 +44,12 @@ public:
private:
//output api
qint64 writeAudio(unsigned char *data, qint64 maxSize);
- void flush(){};
+ void drain();
+ void reset();
private:
- // thread run function
- //void run();
-
- // helper functions
- void reset();
- void resetDSP();
void post();
void sync();
- //void openMixer();
void uninitialize();
QString m_audio_device, m_mixer_device;
diff --git a/src/plugins/Output/pulseaudio/outputpulseaudio.cpp b/src/plugins/Output/pulseaudio/outputpulseaudio.cpp
index f92d33b9c..c867ffbb9 100644
--- a/src/plugins/Output/pulseaudio/outputpulseaudio.cpp
+++ b/src/plugins/Output/pulseaudio/outputpulseaudio.cpp
@@ -82,7 +82,6 @@ bool OutputPulseAudio::initialize()
return true;
}
-
qint64 OutputPulseAudio::latency()
{
if (!m_connection)
@@ -112,13 +111,20 @@ qint64 OutputPulseAudio::writeAudio(unsigned char *data, qint64 maxSize)
return maxSize;
}
-void OutputPulseAudio::flush()
+void OutputPulseAudio::drain()
{
int error;
if (m_connection)
pa_simple_drain(m_connection, &error);
}
+void OutputPulseAudio::reset()
+{
+ int error;
+ if (m_connection)
+ pa_simple_flush(m_connection, &error);
+}
+
void OutputPulseAudio::uninitialize()
{
if (m_connection)
diff --git a/src/plugins/Output/pulseaudio/outputpulseaudio.h b/src/plugins/Output/pulseaudio/outputpulseaudio.h
index 898e25af3..dcff616ff 100644
--- a/src/plugins/Output/pulseaudio/outputpulseaudio.h
+++ b/src/plugins/Output/pulseaudio/outputpulseaudio.h
@@ -44,7 +44,8 @@ public:
private:
//output api
qint64 writeAudio(unsigned char *data, qint64 maxSize);
- void flush();
+ void drain();
+ void reset();
// helper functions
void uninitialize();