add: Audio Info in NowPlayingPanel.cpp ; Includes: Samplerate, bits/sample, and codec
change: opengl dll for windows now is not included, cause it is too large refactor: Spectrogram colors for bars are now in a Header (GradientPresetHeader.h), with accompaning methods
This commit is contained in:
+6
-5
@@ -63,6 +63,7 @@ set(HEADERS
|
|||||||
src/gui/CoverArtWidget.h
|
src/gui/CoverArtWidget.h
|
||||||
src/gui/SpectrogramWidget.h
|
src/gui/SpectrogramWidget.h
|
||||||
src/gui/GradientDialog.h
|
src/gui/GradientDialog.h
|
||||||
|
src/gui/GradientPresetHeader.h
|
||||||
src/gui/EqualizerWidget.h
|
src/gui/EqualizerWidget.h
|
||||||
src/gui/EqualizerPresetManager.h
|
src/gui/EqualizerPresetManager.h
|
||||||
src/gui/FreqCurveWidget.h
|
src/gui/FreqCurveWidget.h
|
||||||
@@ -87,10 +88,10 @@ set(HEADERS
|
|||||||
src/engine/encoder/StageBuffer.h
|
src/engine/encoder/StageBuffer.h
|
||||||
src/engine/encoder/FfmpegGuards.h
|
src/engine/encoder/FfmpegGuards.h
|
||||||
src/engine/encoder/SampleRateUtils.h
|
src/engine/encoder/SampleRateUtils.h
|
||||||
src/engine/encoder/CodecUtils.h # new: pickSampleFormat/pickChannelCount/clampBitrate/ChannelLayoutGuard
|
src/engine/encoder/CodecUtils.h
|
||||||
src/engine/encoder/OutputPathBuilder.h # new: buildOutputPath
|
src/engine/encoder/OutputPathBuilder.h
|
||||||
src/engine/encoder/DecoderPipeline.h # new: input open + decoder context
|
src/engine/encoder/DecoderPipeline.h
|
||||||
src/engine/encoder/EncoderPipeline.h # new: encoder + muxer + SWR + encode frame
|
src/engine/encoder/EncoderPipeline.h
|
||||||
# ffmpeg wrapper
|
# ffmpeg wrapper
|
||||||
src/engine/ffmpeg/FormatContext.h
|
src/engine/ffmpeg/FormatContext.h
|
||||||
src/engine/ffmpeg/CodecContext.h
|
src/engine/ffmpeg/CodecContext.h
|
||||||
@@ -131,7 +132,7 @@ target_include_directories(SubWave PRIVATE
|
|||||||
src/config
|
src/config
|
||||||
src/controllers
|
src/controllers
|
||||||
src/engine
|
src/engine
|
||||||
src/engine/encoder # covers CodecUtils.h, OutputPathBuilder.h, DecoderPipeline.h, EncoderPipeline.h
|
src/engine/encoder
|
||||||
src/engine/ffmpeg
|
src/engine/ffmpeg
|
||||||
src/playlists
|
src/playlists
|
||||||
src/gui
|
src/gui
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
# completely written by chatgpt btw. dont bother for winslop
|
# completely written by chatgpt btw. dont bother for winslop
|
||||||
|
# except one part, which is the dll deletion!
|
||||||
Set-StrictMode -Version Latest
|
Set-StrictMode -Version Latest
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
# this is bullshit, only needed cause QtCreator is needed to compile the App ; which is also bullshit
|
||||||
$BuildDir = Join-Path $env:USERPROFILE "Documents\SubWave\build\Desktop_Qt_6_10_2_MinGW_64_bit-Release"
|
$BuildDir = Join-Path $env:USERPROFILE "Documents\SubWave\build\Desktop_Qt_6_10_2_MinGW_64_bit-Release"
|
||||||
$ZipOutDir = Join-Path $env:USERPROFILE "Documents\SubWave\build"
|
$ZipOutDir = Join-Path $env:USERPROFILE "Documents\SubWave\build"
|
||||||
$QtBin = "C:\Qt\6.10.2\mingw_64\bin"
|
$QtBin = "C:\Qt\6.10.2\mingw_64\bin"
|
||||||
@@ -11,7 +13,7 @@ $AppExe = Join-Path $BuildDir "SubWave.exe"
|
|||||||
|
|
||||||
$StagingDir = Join-Path $env:TEMP "SubWave_staging"
|
$StagingDir = Join-Path $env:TEMP "SubWave_staging"
|
||||||
$ZipPath = Join-Path $ZipOutDir "SubWave.zip"
|
$ZipPath = Join-Path $ZipOutDir "SubWave.zip"
|
||||||
$UnpackedDir = Join-Path $ZipOutDir "SubWave_uncompressed"
|
$UnpackedDir = Join-Path $ZipOutDir "SubWave"
|
||||||
|
|
||||||
function Copy-Dll($src, $dst) {
|
function Copy-Dll($src, $dst) {
|
||||||
if (Test-Path $src) {
|
if (Test-Path $src) {
|
||||||
@@ -125,7 +127,8 @@ $dllsToRemove = @(
|
|||||||
"avdevice-*.dll","libavdevice-*.dll",
|
"avdevice-*.dll","libavdevice-*.dll",
|
||||||
"swscale-*.dll","libswscale-*.dll",
|
"swscale-*.dll","libswscale-*.dll",
|
||||||
"postproc-*.dll","libpostproc-*.dll",
|
"postproc-*.dll","libpostproc-*.dll",
|
||||||
"libfftw3f-3.dll","libfftw3l-3.dll"
|
"libfftw3f-3.dll","libfftw3l-3.dll",
|
||||||
|
"opengl32sw.dll" # opengl is usually shipped withwindows, so we can safely delete it, mesa is not needed
|
||||||
)
|
)
|
||||||
|
|
||||||
foreach ($pattern in $dllsToRemove) {
|
foreach ($pattern in $dllsToRemove) {
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ AudioEngine::State AudioEngine::state() const { return m_state.load(); }
|
|||||||
qint64 AudioEngine::positionFrames() const { return m_posFrames.load(); }
|
qint64 AudioEngine::positionFrames() const { return m_posFrames.load(); }
|
||||||
qint64 AudioEngine::totalFrames() const { return m_totalFrames.load(); }
|
qint64 AudioEngine::totalFrames() const { return m_totalFrames.load(); }
|
||||||
int AudioEngine::sampleRate() const { return m_sampleRate.load(); }
|
int AudioEngine::sampleRate() const { return m_sampleRate.load(); }
|
||||||
|
int AudioEngine::bitsPerSample() const { return m_bitsPerSample.load(); }
|
||||||
|
QString AudioEngine::codecName() const {
|
||||||
|
QMutexLocker lock(&m_metaMtx);
|
||||||
|
return m_codecName;
|
||||||
|
}
|
||||||
|
|
||||||
void AudioEngine::setVolume(float v) {
|
void AudioEngine::setVolume(float v) {
|
||||||
m_volume = std::clamp(v, 0.f, 1.f);
|
m_volume = std::clamp(v, 0.f, 1.f);
|
||||||
@@ -32,6 +37,11 @@ void AudioEngine::play(const engine::Track &track) {
|
|||||||
m_stopReq = false;
|
m_stopReq = false;
|
||||||
m_pauseReq = false;
|
m_pauseReq = false;
|
||||||
m_seekPending = false;
|
m_seekPending = false;
|
||||||
|
m_bitsPerSample = 0;
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&m_metaMtx);
|
||||||
|
m_codecName.clear();
|
||||||
|
}
|
||||||
m_track = track;
|
m_track = track;
|
||||||
m_thread = QThread::create([this]{ playbackLoop(); });
|
m_thread = QThread::create([this]{ playbackLoop(); });
|
||||||
m_thread->setObjectName("subwave-audio");
|
m_thread->setObjectName("subwave-audio");
|
||||||
@@ -99,6 +109,11 @@ void AudioEngine::playbackLoop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_sampleRate = decoder.sampleRate();
|
m_sampleRate = decoder.sampleRate();
|
||||||
|
m_bitsPerSample = decoder.bitsPerSample();
|
||||||
|
{
|
||||||
|
QMutexLocker lock(&m_metaMtx);
|
||||||
|
m_codecName = decoder.codecName();
|
||||||
|
}
|
||||||
m_eq.setSampleRate(m_sampleRate);
|
m_eq.setSampleRate(m_sampleRate);
|
||||||
m_eq.reset();
|
m_eq.reset();
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ public:
|
|||||||
qint64 positionFrames() const;
|
qint64 positionFrames() const;
|
||||||
qint64 totalFrames() const;
|
qint64 totalFrames() const;
|
||||||
int sampleRate() const;
|
int sampleRate() const;
|
||||||
|
int bitsPerSample() const;
|
||||||
|
QString codecName() const;
|
||||||
|
|
||||||
void setVolume(float v);
|
void setVolume(float v);
|
||||||
void play(const engine::Track &track);
|
void play(const engine::Track &track);
|
||||||
@@ -55,6 +57,7 @@ private:
|
|||||||
std::atomic<qint64> m_posFrames { 0 };
|
std::atomic<qint64> m_posFrames { 0 };
|
||||||
std::atomic<qint64> m_totalFrames { 0 };
|
std::atomic<qint64> m_totalFrames { 0 };
|
||||||
std::atomic<int> m_sampleRate { 44100 };
|
std::atomic<int> m_sampleRate { 44100 };
|
||||||
|
std::atomic<int> m_bitsPerSample { 0 };
|
||||||
std::atomic<bool> m_stopReq { false };
|
std::atomic<bool> m_stopReq { false };
|
||||||
std::atomic<bool> m_pauseReq { false };
|
std::atomic<bool> m_pauseReq { false };
|
||||||
std::atomic<bool> m_seekPending { false };
|
std::atomic<bool> m_seekPending { false };
|
||||||
@@ -67,8 +70,10 @@ private:
|
|||||||
|
|
||||||
QMutex m_pauseMtx;
|
QMutex m_pauseMtx;
|
||||||
QWaitCondition m_pauseCv;
|
QWaitCondition m_pauseCv;
|
||||||
|
mutable QMutex m_metaMtx;
|
||||||
|
|
||||||
engine::Track m_track;
|
engine::Track m_track;
|
||||||
|
QString m_codecName;
|
||||||
engine::EqProcessor m_eq;
|
engine::EqProcessor m_eq;
|
||||||
|
|
||||||
float m_eqGainDb[EQ_BANDS] {};
|
float m_eqGainDb[EQ_BANDS] {};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
|
#include <libavutil/samplefmt.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace engine::ffmpeg {
|
namespace engine::ffmpeg {
|
||||||
@@ -64,4 +65,18 @@ int CodecContext::channels() const {
|
|||||||
return m_ctx ? m_ctx->ch_layout.nb_channels : 0;
|
return m_ctx ? m_ctx->ch_layout.nb_channels : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CodecContext::bitsPerSample() const {
|
||||||
|
if (!m_ctx) return 0;
|
||||||
|
|
||||||
|
if (m_ctx->bits_per_raw_sample > 0)
|
||||||
|
return m_ctx->bits_per_raw_sample;
|
||||||
|
|
||||||
|
if (m_ctx->sample_fmt != AV_SAMPLE_FMT_NONE && m_ctx->sample_fmt != AV_SAMPLE_FMT_NB) {
|
||||||
|
const int bytesPerSample = av_get_bytes_per_sample(m_ctx->sample_fmt);
|
||||||
|
return bytesPerSample > 0 ? bytesPerSample * 8 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace engine::ffmpeg
|
} // namespace engine::ffmpeg
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ public:
|
|||||||
bool isOpen() const { return m_ctx != nullptr; }
|
bool isOpen() const { return m_ctx != nullptr; }
|
||||||
int sampleRate()const;
|
int sampleRate()const;
|
||||||
int channels() const;
|
int channels() const;
|
||||||
|
int bitsPerSample() const;
|
||||||
|
|
||||||
const AVCodecContext *get() const { return m_ctx.get(); }
|
const AVCodecContext *get() const { return m_ctx.get(); }
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,28 @@ void FFmpegDecoder::seek(double fraction) {
|
|||||||
m_codec.flush();
|
m_codec.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString FFmpegDecoder::codecName() const {
|
||||||
|
const AVCodecParameters *par = m_format.audioCodecPar();
|
||||||
|
if (!par) return {};
|
||||||
|
|
||||||
|
const AVCodecDescriptor *desc = avcodec_descriptor_get(par->codec_id);
|
||||||
|
if (!desc) {
|
||||||
|
const char *fallback = avcodec_get_name(par->codec_id);
|
||||||
|
return fallback ? QString::fromUtf8(fallback).toUpper() : QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString name = QString::fromUtf8(desc->long_name && desc->long_name[0] ? desc->long_name : desc->name);
|
||||||
|
const int parenPos = name.indexOf(" (");
|
||||||
|
if (parenPos >= 0)
|
||||||
|
name.truncate(parenPos);
|
||||||
|
|
||||||
|
return name.trimmed().toUpper();
|
||||||
|
}
|
||||||
|
|
||||||
|
int FFmpegDecoder::bitsPerSample() const {
|
||||||
|
return m_codec.bitsPerSample();
|
||||||
|
}
|
||||||
|
|
||||||
bool FFmpegDecoder::decodeNext(AudioBuffer &buf) {
|
bool FFmpegDecoder::decodeNext(AudioBuffer &buf) {
|
||||||
if (!m_format.isOpen()) return false;
|
if (!m_format.isOpen()) return false;
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ public:
|
|||||||
int channels() const { return m_codec.channels(); }
|
int channels() const { return m_codec.channels(); }
|
||||||
double durationSeconds() const { return m_format.durationSecs(); }
|
double durationSeconds() const { return m_format.durationSecs(); }
|
||||||
qint64 totalFrames() const { return m_totalFrames; }
|
qint64 totalFrames() const { return m_totalFrames; }
|
||||||
|
QString codecName() const;
|
||||||
|
int bitsPerSample() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FormatContext m_format;
|
FormatContext m_format;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "GradientDialog.h"
|
#include "GradientDialog.h"
|
||||||
|
#include "GradientPresetHeader.h"
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
@@ -8,47 +9,6 @@
|
|||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
|
||||||
static QVector<QColor> makePreset4(const QColor &c0, const QColor &c1,
|
|
||||||
const QColor &c2, const QColor &c3,
|
|
||||||
const QColor &c4)
|
|
||||||
{
|
|
||||||
return { c0, c2, c3, c4 };
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Preset {
|
|
||||||
QString name;
|
|
||||||
QVector<QColor> colors;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Presets are defined in a Vector for simplicity of adding new ones
|
|
||||||
static const QVector<Preset> PRESETS = {
|
|
||||||
{ "Default",
|
|
||||||
{ QColor("#078D70"), QColor("#26CEAA"), QColor("#98E8C1"), QColor("#FFFFFF") } },
|
|
||||||
|
|
||||||
{ "Pastels",
|
|
||||||
makePreset4(QColor("#92ccdd"), QColor("#c7eff0"),
|
|
||||||
QColor("#f5d5fd"), QColor("#fdc4ec"), QColor("#ffc2cb")) },
|
|
||||||
|
|
||||||
{ "Raddish",
|
|
||||||
makePreset4(QColor("#ff0000"), QColor("#b40000"),
|
|
||||||
QColor("#890000"), QColor("#540000"), QColor("#240000")) },
|
|
||||||
|
|
||||||
{ "Blau",
|
|
||||||
makePreset4(QColor("#72c8dd"), QColor("#43b5d2"),
|
|
||||||
QColor("#14a3c7"), QColor("#1293b3"), QColor("#10829f")) },
|
|
||||||
|
|
||||||
{ "Turquoise",
|
|
||||||
makePreset4(QColor("#d8f2f6"), QColor("#8bd9ef"),
|
|
||||||
QColor("#3ec1d5"), QColor("#319aaa"), QColor("#25737f")) },
|
|
||||||
|
|
||||||
{ "Aqua",
|
|
||||||
makePreset4(QColor("#2278FB"), QColor("#3A9AF0"),
|
|
||||||
QColor("#53BDE6"), QColor("#6BDFDB"), QColor("#1A5BB8")) },
|
|
||||||
|
|
||||||
{ "Peaches",
|
|
||||||
makePreset4(QColor("#FFCAA6"), QColor("#FDA8A0"),
|
|
||||||
QColor("#FA879A"), QColor("#F86594"), QColor("#FFE0CC")) }
|
|
||||||
};
|
|
||||||
|
|
||||||
static int findPresetIndex(const QVector<QColor> &stops)
|
static int findPresetIndex(const QVector<QColor> &stops)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QVector>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
/** preset function */
|
||||||
|
inline QVector<QColor> makePreset4(const QColor &c0, const QColor &c1,
|
||||||
|
const QColor &c2, const QColor &c3,
|
||||||
|
const QColor &c4)
|
||||||
|
{
|
||||||
|
// if you dont define c1 as #FFFF worry, cause it does NOT get used!
|
||||||
|
return { c0, c2, c3, c4 };
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Preset Struct */
|
||||||
|
struct Preset {
|
||||||
|
QString name;
|
||||||
|
QVector<QColor> colors;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Defined Presets */
|
||||||
|
inline const QVector<Preset> PRESETS = {
|
||||||
|
{ "Default",
|
||||||
|
{ QColor("#078D70"), QColor("#26CEAA"), QColor("#98E8C1"), QColor("#FFFFFF") } },
|
||||||
|
|
||||||
|
{ "Pastels",
|
||||||
|
makePreset4(QColor("#92ccdd"), QColor("#c7eff0"),
|
||||||
|
QColor("#f5d5fd"), QColor("#fdc4ec"), QColor("#ffc2cb")) },
|
||||||
|
|
||||||
|
{ "Raddish",
|
||||||
|
makePreset4(QColor("#ff0000"), QColor("#b40000"),
|
||||||
|
QColor("#890000"), QColor("#540000"), QColor("#240000")) },
|
||||||
|
|
||||||
|
{ "Blau",
|
||||||
|
makePreset4(QColor("#72c8dd"), QColor("#43b5d2"),
|
||||||
|
QColor("#14a3c7"), QColor("#1293b3"), QColor("#10829f")) },
|
||||||
|
|
||||||
|
{ "Turquoise",
|
||||||
|
makePreset4(QColor("#d8f2f6"), QColor("#8bd9ef"),
|
||||||
|
QColor("#3ec1d5"), QColor("#319aaa"), QColor("#25737f")) },
|
||||||
|
|
||||||
|
{ "Aqua",
|
||||||
|
makePreset4(QColor("#2278FB"), QColor("#3A9AF0"),
|
||||||
|
QColor("#53BDE6"), QColor("#6BDFDB"), QColor("#1A5BB8")) },
|
||||||
|
|
||||||
|
{ "Peaches",
|
||||||
|
makePreset4(QColor("#FFCAA6"), QColor("#FDA8A0"),
|
||||||
|
QColor("#FA879A"), QColor("#F86594"), QColor("#FFE0CC")) },
|
||||||
|
|
||||||
|
{ "Windows Green",
|
||||||
|
makePreset4(QColor("#BFFFE3"), QColor("#7FFFC2"),
|
||||||
|
QColor("#43FFAC"), QColor("#27FF97"), QColor("#0EDB7D")) },
|
||||||
|
};
|
||||||
@@ -48,6 +48,10 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
e->positionFrames(),
|
e->positionFrames(),
|
||||||
e->totalFrames(),
|
e->totalFrames(),
|
||||||
float(e->sampleRate()));
|
float(e->sampleRate()));
|
||||||
|
m_nowPlaying->updateAudioInfo(
|
||||||
|
e->sampleRate(),
|
||||||
|
e->bitsPerSample(),
|
||||||
|
e->codecName());
|
||||||
|
|
||||||
if (e->state() == AudioEngine::State::Stopped)
|
if (e->state() == AudioEngine::State::Stopped)
|
||||||
m_nowPlaying->setPlaybackActive(false);
|
m_nowPlaying->setPlaybackActive(false);
|
||||||
|
|||||||
@@ -60,11 +60,22 @@ void NowPlayingPanel::buildLayout()
|
|||||||
transport->addWidget(new QLabel("Volume:"));
|
transport->addWidget(new QLabel("Volume:"));
|
||||||
transport->addWidget(m_volSlider);
|
transport->addWidget(m_volSlider);
|
||||||
|
|
||||||
|
auto *metaRow = new QHBoxLayout;
|
||||||
|
metaRow->setSpacing(8);
|
||||||
|
metaRow->addWidget(new QLabel("Sample rate:"));
|
||||||
|
metaRow->addWidget(m_lblSampleRate);
|
||||||
|
metaRow->addWidget(new QLabel("Bits/Sample:"));
|
||||||
|
metaRow->addWidget(m_lblBitsPerSample);
|
||||||
|
metaRow->addWidget(new QLabel("Codec:"));
|
||||||
|
metaRow->addWidget(m_lblCodec);
|
||||||
|
metaRow->addStretch();
|
||||||
|
|
||||||
auto *right = new QVBoxLayout;
|
auto *right = new QVBoxLayout;
|
||||||
right->setSpacing(4);
|
right->setSpacing(4);
|
||||||
right->addWidget(m_lblTitle);
|
right->addWidget(m_lblTitle);
|
||||||
right->addWidget(m_lblArtist);
|
right->addWidget(m_lblArtist);
|
||||||
right->addWidget(m_lblAlbum);
|
right->addWidget(m_lblAlbum);
|
||||||
|
right->addLayout(metaRow);
|
||||||
right->addLayout(seekRow);
|
right->addLayout(seekRow);
|
||||||
right->addLayout(transport);
|
right->addLayout(transport);
|
||||||
|
|
||||||
@@ -73,14 +84,25 @@ void NowPlayingPanel::buildLayout()
|
|||||||
hlay->addLayout(right, 1);
|
hlay->addLayout(right, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NowPlayingPanel::clearAudioInfo()
|
||||||
|
{
|
||||||
|
m_lblSampleRate->setText("-");
|
||||||
|
m_lblBitsPerSample->setText("-");
|
||||||
|
m_lblCodec->setText("-");
|
||||||
|
}
|
||||||
|
|
||||||
void NowPlayingPanel::updateTrack(const engine::Track *t)
|
void NowPlayingPanel::updateTrack(const engine::Track *t)
|
||||||
{
|
{
|
||||||
if (!t) return;
|
if (!t) {
|
||||||
|
clearAudioInfo();
|
||||||
|
return;
|
||||||
|
}
|
||||||
m_cover->setTrack(t);
|
m_cover->setTrack(t);
|
||||||
m_lblTitle->setText(t->displayTitle());
|
m_lblTitle->setText(t->displayTitle());
|
||||||
m_lblArtist->setText(t->artist);
|
m_lblArtist->setText(t->artist);
|
||||||
m_lblAlbum->setText(t->album +
|
m_lblAlbum->setText(t->album +
|
||||||
(t->year > 0 ? " (" + QString::number(t->year) + ")" : ""));
|
(t->year > 0 ? " (" + QString::number(t->year) + ")" : ""));
|
||||||
|
clearAudioInfo();
|
||||||
m_seekBar->setValue(0);
|
m_seekBar->setValue(0);
|
||||||
m_btnPlay->setText("Pause");
|
m_btnPlay->setText("Pause");
|
||||||
}
|
}
|
||||||
@@ -101,6 +123,13 @@ void NowPlayingPanel::updatePosition(qint64 posFrames, qint64 totalFrames, float
|
|||||||
m_seekBar->setValue(int(posFrames * 1000 / totalFrames));
|
m_seekBar->setValue(int(posFrames * 1000 / totalFrames));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NowPlayingPanel::updateAudioInfo(int sampleRate, int bitsPerSample, const QString &codec)
|
||||||
|
{
|
||||||
|
m_lblSampleRate->setText(sampleRate > 0 ? QString("%1 Hz").arg(sampleRate) : "-");
|
||||||
|
m_lblBitsPerSample->setText(bitsPerSample > 0 ? QString("%1").arg(bitsPerSample) : "-");
|
||||||
|
m_lblCodec->setText(!codec.isEmpty() ? codec : "-");
|
||||||
|
}
|
||||||
|
|
||||||
void NowPlayingPanel::setPlaybackActive(bool playing)
|
void NowPlayingPanel::setPlaybackActive(bool playing)
|
||||||
{
|
{
|
||||||
m_btnPlay->setText(playing ? "Pause" : "Play");
|
m_btnPlay->setText(playing ? "Pause" : "Play");
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ public:
|
|||||||
public slots:
|
public slots:
|
||||||
void updateTrack(const engine::Track *track);
|
void updateTrack(const engine::Track *track);
|
||||||
void updatePosition(qint64 posFrames, qint64 totalFrames, float sampleRate);
|
void updatePosition(qint64 posFrames, qint64 totalFrames, float sampleRate);
|
||||||
void setPlaybackActive(bool playing);
|
void updateAudioInfo(int sampleRate, int bitsPerSample, const QString &codec);
|
||||||
|
void setPlaybackActive(bool playing);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void playPauseClicked();
|
void playPauseClicked();
|
||||||
@@ -31,12 +32,16 @@ signals:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void buildLayout();
|
void buildLayout();
|
||||||
|
void clearAudioInfo();
|
||||||
|
|
||||||
CoverArtWidget *m_cover;
|
CoverArtWidget *m_cover;
|
||||||
QLabel *m_lblTitle = new QLabel("No track selected");
|
QLabel *m_lblTitle = new QLabel("No track selected");
|
||||||
QLabel *m_lblArtist = new QLabel(" ");
|
QLabel *m_lblArtist = new QLabel(" ");
|
||||||
QLabel *m_lblAlbum = new QLabel(" ");
|
QLabel *m_lblAlbum = new QLabel(" ");
|
||||||
QLabel *m_lblTime = new QLabel("0:00 / 0:00");
|
QLabel *m_lblTime = new QLabel("0:00 / 0:00");
|
||||||
|
QLabel *m_lblSampleRate = new QLabel("—");
|
||||||
|
QLabel *m_lblBitsPerSample = new QLabel("-");
|
||||||
|
QLabel *m_lblCodec = new QLabel("—");
|
||||||
QSlider *m_seekBar = new QSlider(Qt::Horizontal);
|
QSlider *m_seekBar = new QSlider(Qt::Horizontal);
|
||||||
QPushButton *m_btnPrev = new QPushButton("|<");
|
QPushButton *m_btnPrev = new QPushButton("|<");
|
||||||
QPushButton *m_btnPlay = new QPushButton("Play");
|
QPushButton *m_btnPlay = new QPushButton("Play");
|
||||||
|
|||||||
Reference in New Issue
Block a user