aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Input
Commit message (Collapse)AuthorAgeFilesLines
* refactoringtrialuser022020-03-142-16/+9
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9287 90c681e8-e032-0410-971d-27865f9a5e38
* restored .ts filestrialuser022020-03-1428-219/+1059
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9286 90c681e8-e032-0410-971d-27865f9a5e38
* restored cddb supporttrialuser022020-03-148-10/+267
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9285 90c681e8-e032-0410-971d-27865f9a5e38
* updated .ts filestrialuser022020-03-0728-1058/+218
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9275 90c681e8-e032-0410-971d-27865f9a5e38
* cdaudio: removed unused codetrialuser022020-03-074-55/+0
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9273 90c681e8-e032-0410-971d-27865f9a5e38
* removed libcddb supporttrialuser022020-03-078-212/+10
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9271 90c681e8-e032-0410-971d-27865f9a5e38
* ffmpeg: added opus bitrate issue workaroundtrialuser022020-02-241-0/+6
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9246 90c681e8-e032-0410-971d-27865f9a5e38
* fixed build regressiontrialuser022020-02-231-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9244 90c681e8-e032-0410-971d-27865f9a5e38
* show average bitrate for shoutcast/icecast streamstrialuser022020-02-231-0/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9243 90c681e8-e032-0410-971d-27865f9a5e38
* updated .ts filestrialuser022020-02-1728-252/+392
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9229 90c681e8-e032-0410-971d-27865f9a5e38
* mpeg: feature to merge tags (#262)trialuser022020-02-173-52/+74
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9228 90c681e8-e032-0410-971d-27865f9a5e38
* updated copyrighttrialuser022020-02-1182-82/+82
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9224 90c681e8-e032-0410-971d-27865f9a5e38
* updated api documentation, removed empty flagstrialuser022020-02-119-10/+10
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9223 90c681e8-e032-0410-971d-27865f9a5e38
* ffmpeg: refactoringtrialuser022020-01-312-226/+170
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9220 90c681e8-e032-0410-971d-27865f9a5e38
* updated .ts filestrialuser022020-01-2128-112/+112
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9215 90c681e8-e032-0410-971d-27865f9a5e38
* ffmpeg: refactoringtrialuser022020-01-022-22/+36
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9178 90c681e8-e032-0410-971d-27865f9a5e38
* fixed previous committrialuser022020-01-021-1/+0
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9177 90c681e8-e032-0410-971d-27865f9a5e38
* ffmpeg: added 'album artist' and 'composer' tags support (#1028)trialuser022020-01-021-0/+7
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9175 90c681e8-e032-0410-971d-27865f9a5e38
* changed minimal ffmpeg version to 3.2, removed libav supporttrialuser022019-12-313-76/+8
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9174 90c681e8-e032-0410-971d-27865f9a5e38
* updated .ts filestrialuser022019-12-2228-112/+112
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9170 90c681e8-e032-0410-971d-27865f9a5e38
* fixed crash on encrypted archives (#1027)trialuser022019-12-203-4/+18
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9155 90c681e8-e032-0410-971d-27865f9a5e38
* removed unused includestrialuser022019-11-061-2/+0
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9101 90c681e8-e032-0410-971d-27865f9a5e38
* fixed crash on corrupted m4a files (#1021)trialuser022019-11-021-21/+23
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9090 90c681e8-e032-0410-971d-27865f9a5e38
* updated .ts filestrialuser022019-09-22112-532/+532
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9078 90c681e8-e032-0410-971d-27865f9a5e38
* fixed clang buildtrialuser022019-09-211-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9076 90c681e8-e032-0410-971d-27865f9a5e38
* fixed possible regressionstrialuser022019-09-084-16/+15
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9068 90c681e8-e032-0410-971d-27865f9a5e38
* removed foreach macrotrialuser022019-09-077-10/+10
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9067 90c681e8-e032-0410-971d-27865f9a5e38
* fixed possible crashtrialuser022019-08-316-24/+24
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9058 90c681e8-e032-0410-971d-27865f9a5e38
* fixed 'album artist' tag support (#1012)trialuser022019-08-312-0/+14
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9057 90c681e8-e032-0410-971d-27865f9a5e38
* mpeg: improved mp3 determination (#1008)trialuser022019-07-241-1/+5
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9012 90c681e8-e032-0410-971d-27865f9a5e38
* fixed libav supporttrialuser022019-07-212-2/+4
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@9006 90c681e8-e032-0410-971d-27865f9a5e38
* ffmpeg: show format nametrialuser022019-07-042-1/+2
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8991 90c681e8-e032-0410-971d-27865f9a5e38
* added socks5 proxy supporttrialuser022019-06-301-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8971 90c681e8-e032-0410-971d-27865f9a5e38
* updated .ts filestrialuser022019-06-29168-840/+840
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8968 90c681e8-e032-0410-971d-27865f9a5e38
* fixed typo (PCM_UNKNOWM -> PCM_UNKNOWN)trialuser022019-05-191-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8886 90c681e8-e032-0410-971d-27865f9a5e38
* ffmpeg: fixed source formattingtrialuser022019-05-121-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8871 90c681e8-e032-0410-971d-27865f9a5e38
* ffmpeg: return AVERROR_EOF on file end (#1002)trialuser022019-05-121-0/+4
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8870 90c681e8-e032-0410-971d-27865f9a5e38
* cue: fixed regressiontrialuser022019-05-091-5/+10
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8864 90c681e8-e032-0410-971d-27865f9a5e38
* archive: fixed crash on some corrupted archives (#998)trialuser022019-05-062-1/+21
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8861 90c681e8-e032-0410-971d-27865f9a5e38
* archive: fixed memory leaktrialuser022019-05-061-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8860 90c681e8-e032-0410-971d-27865f9a5e38
* ffmpeg: fixed buildtrialuser022019-05-041-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8855 90c681e8-e032-0410-971d-27865f9a5e38
* ffmpeg: fixed crash on streamstrialuser022019-05-032-9/+14
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8843 90c681e8-e032-0410-971d-27865f9a5e38
* mpeg: fixed file type determination by contenttrialuser022019-05-021-7/+12
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8840 90c681e8-e032-0410-971d-27865f9a5e38
* ffmpeg: fixed freezing on some corrupted filestrialuser022019-05-021-2/+5
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8837 90c681e8-e032-0410-971d-27865f9a5e38
* ffmpeg: fixed regressionstrialuser022019-05-022-3/+11
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8836 90c681e8-e032-0410-971d-27865f9a5e38
* flac: optimizationtrialuser022019-05-021-6/+3
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8835 90c681e8-e032-0410-971d-27865f9a5e38
* ffmpeg: added embedded cue sheet supporttrialuser022019-05-026-27/+335
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8834 90c681e8-e032-0410-971d-27865f9a5e38
* mpeg: fixed settings dialog layouttrialuser022019-05-011-2/+15
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8830 90c681e8-e032-0410-971d-27865f9a5e38
* enabled mpg123 under win32trialuser022019-05-011-2/+4
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8828 90c681e8-e032-0410-971d-27865f9a5e38
* cue: fixed regressiontrialuser022019-05-011-6/+6
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@8820 90c681e8-e032-0410-971d-27865f9a5e38
return false; } if ((err = snd_pcm_hw_params_set_buffer_time_near(pcm_handle, hwparams, &buffer_time ,0)) < 0) { qWarning("OutputALSA: Error setting buffer time: %s", snd_strerror(err)); return false; } if ((err = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) { qWarning("OutputALSA: Error setting HW params: %s", snd_strerror(err)); return false; } //read some alsa parameters snd_pcm_uframes_t buffer_size = 0; snd_pcm_uframes_t period_size = 0; if ((err = snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size)) < 0) { qWarning("OutputALSA: Error reading buffer size: %s", snd_strerror(err)); return false; } if ((err = snd_pcm_hw_params_get_period_size(hwparams, &period_size, 0)) < 0) { qWarning("OutputALSA: Error reading period size: %s", snd_strerror(err)); return false; } //swparams snd_pcm_sw_params_alloca(&swparams); snd_pcm_sw_params_current(pcm_handle, swparams); if ((err = snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams, buffer_size - period_size)) < 0) qWarning("OutputALSA: Error setting threshold: %s", snd_strerror(err)); if ((err = snd_pcm_sw_params(pcm_handle, swparams)) < 0) { qWarning("OutputALSA: Error setting SW params: %s", snd_strerror(err)); return false; } //setup needed values m_bits_per_frame = snd_pcm_format_physical_width(alsa_format) * chan; m_chunk_size = period_size; m_can_pause = snd_pcm_hw_params_can_pause(hwparams) && use_pause; qDebug("OutputALSA: can pause: %d", m_can_pause); configure(freq, chan, format); //apply configuration //create alsa prebuffer; m_prebuf_size = /*QMMP_BUFFER_SIZE + */m_bits_per_frame * m_chunk_size / 8; m_prebuf = (uchar *)malloc(m_prebuf_size); m_inited = true; return true; } qint64 OutputALSA::latency() { return m_prebuf_fill * 1000 / sampleRate() / channels() / sampleSize(); } void OutputALSA::drain() { long m = 0; snd_pcm_uframes_t l = snd_pcm_bytes_to_frames(pcm_handle, m_prebuf_fill); 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; memmove(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); } 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) { if((maxSize = qMin(maxSize, m_prebuf_size - m_prebuf_fill)) > 0) { memmove(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); while (l >= m_chunk_size) { snd_pcm_wait(pcm_handle, 10); long m; if ((m = alsa_write(m_prebuf, m_chunk_size)) >= 0) { l -= m; m = snd_pcm_frames_to_bytes(pcm_handle, m); // convert frames to bytes m_prebuf_fill -= m; memmove(m_prebuf, m_prebuf + m, m_prebuf_fill); //move data to begin } else return -1; } return maxSize; } long OutputALSA::alsa_write(unsigned char *data, long size) { long m = snd_pcm_avail_update(pcm_handle); if(m >= 0 && m < size) { snd_pcm_wait(pcm_handle, 500); return 0; } if (m_use_mmap) m = snd_pcm_mmap_writei (pcm_handle, data, size); else m = snd_pcm_writei (pcm_handle, data, size); if (m == -EAGAIN) { snd_pcm_wait(pcm_handle, 500); return 0; } else if (m >= 0) { if (m < size) { snd_pcm_wait(pcm_handle, 500); } return m; } else if (m == -EPIPE) { qDebug ("OutputALSA: buffer underrun!"); if ((m = snd_pcm_prepare(pcm_handle)) < 0) { qDebug ("OutputALSA: Can't recover after underrun: %s", snd_strerror(m)); /* TODO: reopen the device */ return -1; } return 0; } #ifdef ESTRPIPE else if (m == -ESTRPIPE) { qDebug ("OutputALSA: Suspend, trying to resume"); while ((m = snd_pcm_resume(pcm_handle)) == -EAGAIN) sleep (1); if (m < 0) { qDebug ("OutputALSA: Failed, restarting"); if ((m = snd_pcm_prepare(pcm_handle)) < 0) { qDebug ("OutputALSA: Failed to restart device: %s.", snd_strerror(m)); return -1; } } return 0; } #endif qDebug ("OutputALSA: error: %s", snd_strerror(m)); return snd_pcm_prepare (pcm_handle); } void OutputALSA::uninitialize() { if (!m_inited) return; m_inited = false; if (pcm_handle) { snd_pcm_drop(pcm_handle); qDebug("OutputALSA: closing pcm_handle"); snd_pcm_close(pcm_handle); pcm_handle = 0; } if (m_prebuf) free(m_prebuf); m_prebuf = 0; } /* ****** MIXER ******* */ VolumeALSA::VolumeALSA() { //alsa mixer mixer = 0; QSettings settings(Qmmp::configFile(), QSettings::IniFormat); QString card = settings.value("ALSA/mixer_card","hw:0").toString(); QString dev = settings.value("ALSA/mixer_device", "PCM").toString(); setupMixer(card, dev); } VolumeALSA::~VolumeALSA() { if (mixer) snd_mixer_close(mixer); } void VolumeALSA::setVolume(int channel, int value) { if (!pcm_element) return; _snd_mixer_selem_channel_id channel_id = SND_MIXER_SCHN_FRONT_LEFT; if(channel == Volume::RIGHT_CHANNEL) channel_id = SND_MIXER_SCHN_FRONT_RIGHT; snd_mixer_selem_set_playback_volume(pcm_element, channel_id, value); } int VolumeALSA::volume(int channel) { if (!pcm_element) return 0; _snd_mixer_selem_channel_id channel_id = SND_MIXER_SCHN_FRONT_LEFT; if(channel == Volume::RIGHT_CHANNEL) channel_id = SND_MIXER_SCHN_FRONT_RIGHT; long value = 0; snd_mixer_handle_events(mixer); snd_mixer_selem_get_playback_volume(pcm_element, channel_id, &value); return value; } int VolumeALSA::setupMixer(QString card, QString device) { char *name; int err, index; pcm_element = 0; qDebug("OutputALSA: setupMixer()"); if ((err = getMixer(&mixer, card)) < 0) return err; parseMixerName(device.toAscii().data(), &name, &index); pcm_element = getMixerElem(mixer, name, index); free(name); if (!pcm_element) { qWarning("OutputALSA: Failed to find mixer element"); return -1; } if((err = snd_mixer_selem_set_playback_volume_range(pcm_element, 0, 100)) < 0) { qWarning("OutputALSA: Unable to set volume range: %s", snd_strerror(-err)); pcm_element = NULL; return -1; } qDebug("OutputALSA: setupMixer() success"); return 0; } void VolumeALSA::parseMixerName(char *str, char **name, int *index) { char *end; while (isspace(*str)) str++; if ((end = strchr(str, ',')) != NULL) { *name = strndup(str, end - str); end++; *index = atoi(end); } else { *name = strdup(str); *index = 0; } } snd_mixer_elem_t* VolumeALSA::getMixerElem(snd_mixer_t *mixer, char *name, int index) { snd_mixer_selem_id_t* selem_id; snd_mixer_elem_t* elem; snd_mixer_selem_id_alloca(&selem_id); if (index != -1) snd_mixer_selem_id_set_index(selem_id, index); if (name != NULL) snd_mixer_selem_id_set_name(selem_id, name); elem = snd_mixer_find_selem(mixer, selem_id); return elem; } int VolumeALSA::getMixer(snd_mixer_t **mixer, QString card) { char *dev; int err; dev = strdup(card.toAscii().data()); if ((err = snd_mixer_open(mixer, 0)) < 0) { qWarning("OutputALSA: Failed to open empty mixer: %s", snd_strerror(-err)); mixer = NULL; return -1; } if ((err = snd_mixer_attach(*mixer, dev)) < 0) { qWarning("OutputALSA: Attaching to mixer %s failed: %s", dev, snd_strerror(-err)); return -1; } if ((err = snd_mixer_selem_register(*mixer, NULL, NULL)) < 0) { qWarning("OutputALSA: Failed to register mixer: %s", snd_strerror(-err)); return -1; } if ((err = snd_mixer_load(*mixer)) < 0) { qWarning("OutputALSA: Failed to load mixer: %s", snd_strerror(-err)); return -1; } free(dev); return (*mixer != NULL); }