diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2010-07-24 07:54:13 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2010-07-24 07:54:13 +0000 |
| commit | d2d062fa716a79ccf161fc302e73723f3eb1bb8d (patch) | |
| tree | 19e594eec9635939305c1084b2ed380d4ed786c0 /src/plugins | |
| parent | 04f1cf7bd526a9e906131ad35f950aa701f5b4f5 (diff) | |
| download | qmmp-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.cpp | 104 | ||||
| -rw-r--r-- | src/plugins/Output/alsa/outputalsa.h | 8 | ||||
| -rw-r--r-- | src/plugins/Output/jack/outputjack.cpp | 5 | ||||
| -rw-r--r-- | src/plugins/Output/jack/outputjack.h | 3 | ||||
| -rw-r--r-- | src/plugins/Output/null/outputnull.cpp | 5 | ||||
| -rw-r--r-- | src/plugins/Output/null/outputnull.h | 3 | ||||
| -rw-r--r-- | src/plugins/Output/oss/outputoss.cpp | 140 | ||||
| -rw-r--r-- | src/plugins/Output/oss/outputoss.h | 10 | ||||
| -rw-r--r-- | src/plugins/Output/pulseaudio/outputpulseaudio.cpp | 10 | ||||
| -rw-r--r-- | src/plugins/Output/pulseaudio/outputpulseaudio.h | 3 |
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(); |
