Skip to content
Snippets Groups Projects
Commit 0c006e09 authored by Elnur Ismailzada's avatar Elnur Ismailzada
Browse files

Added setting playback level

parent 39699064
Branches
No related tags found
No related merge requests found
Showing
with 213 additions and 39 deletions
...@@ -31,6 +31,8 @@ set(MODULE_SRC ...@@ -31,6 +31,8 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/audacity3playback.cpp ${CMAKE_CURRENT_LIST_DIR}/audacity3playback.cpp
${CMAKE_CURRENT_LIST_DIR}/audacity3playback.h ${CMAKE_CURRENT_LIST_DIR}/audacity3playback.h
${CMAKE_CURRENT_LIST_DIR}/iau3wavepainter.h ${CMAKE_CURRENT_LIST_DIR}/iau3wavepainter.h
${CMAKE_CURRENT_LIST_DIR}/iaudacity3playback.h
${CMAKE_CURRENT_LIST_DIR}/iaudacity3audiooutput.h
${CMAKE_CURRENT_LIST_DIR}/mocks/au3settingsmock.cpp ${CMAKE_CURRENT_LIST_DIR}/mocks/au3settingsmock.cpp
${CMAKE_CURRENT_LIST_DIR}/mocks/au3settingsmock.h ${CMAKE_CURRENT_LIST_DIR}/mocks/au3settingsmock.h
...@@ -47,6 +49,8 @@ set(MODULE_SRC ...@@ -47,6 +49,8 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/internal/au3wavepainter.h ${CMAKE_CURRENT_LIST_DIR}/internal/au3wavepainter.h
${CMAKE_CURRENT_LIST_DIR}/internal/WaveformScale.cpp ${CMAKE_CURRENT_LIST_DIR}/internal/WaveformScale.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/WaveformScale.h ${CMAKE_CURRENT_LIST_DIR}/internal/WaveformScale.h
${CMAKE_CURRENT_LIST_DIR}/internal/audacity3audiooutput.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/audacity3audiooutput.h
) )
# ================================== # ==================================
......
...@@ -69,6 +69,8 @@ void Au3WrapModule::onInit(const muse::IApplication::RunMode&) ...@@ -69,6 +69,8 @@ void Au3WrapModule::onInit(const muse::IApplication::RunMode&)
if (!ok) { if (!ok) {
LOGE() << "failed init sql"; LOGE() << "failed init sql";
} }
m_playback->init();
} }
void Au3WrapModule::onDeinit() void Au3WrapModule::onDeinit()
......
...@@ -14,10 +14,17 @@ ...@@ -14,10 +14,17 @@
#include "wxtypes_convert.h" #include "wxtypes_convert.h"
#include "internal/audacity3audiooutput.h"
#include "log.h" #include "log.h"
using namespace au::au3; using namespace au::au3;
void Audacity3Playback::init()
{
m_audioOutputPtr = std::make_shared<Audacity3AudioOutput>();
}
void Audacity3Playback::play() void Audacity3Playback::play()
{ {
//! NOTE: copied from ProjectAudioManager::PlayPlayRegion //! NOTE: copied from ProjectAudioManager::PlayPlayRegion
...@@ -264,6 +271,11 @@ muse::async::Channel<au::audio::PlaybackStatus> Audacity3Playback::playbackStatu ...@@ -264,6 +271,11 @@ muse::async::Channel<au::audio::PlaybackStatus> Audacity3Playback::playbackStatu
return m_playbackStatusChanged; return m_playbackStatusChanged;
} }
IAudacity3AudioOutputPtr Audacity3Playback::audioOutput() const
{
return m_audioOutputPtr;
}
AudacityProject& Audacity3Playback::projectRef() const AudacityProject& Audacity3Playback::projectRef() const
{ {
AudacityProject* project = reinterpret_cast<AudacityProject*>(globalContext()->currentProject()->au3ProjectPtr()); AudacityProject* project = reinterpret_cast<AudacityProject*>(globalContext()->currentProject()->au3ProjectPtr());
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "context/iglobalcontext.h" #include "context/iglobalcontext.h"
#include "iaudacity3playback.h" #include "iaudacity3playback.h"
#include "iaudacity3audiooutput.h"
class AudacityProject; class AudacityProject;
class TrackList; class TrackList;
...@@ -22,6 +23,8 @@ class Audacity3Playback : public IAudacity3Playback, public muse::async::Asyncab ...@@ -22,6 +23,8 @@ class Audacity3Playback : public IAudacity3Playback, public muse::async::Asyncab
muse::Inject<au::context::IGlobalContext> globalContext; muse::Inject<au::context::IGlobalContext> globalContext;
public: public:
void init();
void play() override; void play() override;
void seek(const audio::msecs_t newPositionMsecs) override; void seek(const audio::msecs_t newPositionMsecs) override;
void stop() override; void stop() override;
...@@ -35,6 +38,8 @@ public: ...@@ -35,6 +38,8 @@ public:
muse::async::Channel<audio::msecs_t> playbackPositionMsecs() const override; muse::async::Channel<audio::msecs_t> playbackPositionMsecs() const override;
muse::async::Channel<audio::PlaybackStatus> playbackStatusChanged() const override; muse::async::Channel<audio::PlaybackStatus> playbackStatusChanged() const override;
IAudacity3AudioOutputPtr audioOutput() const override;
private: private:
AudacityProject& projectRef() const; AudacityProject& projectRef() const;
...@@ -43,6 +48,8 @@ private: ...@@ -43,6 +48,8 @@ private:
mutable muse::async::Channel<audio::msecs_t> m_playbackPositionMsecsChanged; mutable muse::async::Channel<audio::msecs_t> m_playbackPositionMsecsChanged;
mutable muse::async::Channel<audio::PlaybackStatus> m_playbackStatusChanged; mutable muse::async::Channel<audio::PlaybackStatus> m_playbackStatusChanged;
IAudacity3AudioOutputPtr m_audioOutputPtr;
}; };
} }
......
/*
* Audacity: A Digital Audio Editor
*/
#ifndef AU_AU3WRAP_IAUDACITYAUDIOOUTPUT_H
#define AU_AU3WRAP_IAUDACITYAUDIOOUTPUT_H
#include <memory>
#include "global/async/promise.h"
#include "global/async/channel.h"
#include "playback/audiotypes.h"
namespace au::au3 {
class IAudacity3AudioOutput
{
public:
virtual ~IAudacity3AudioOutput() = default;
virtual muse::async::Promise<float> playbackVolume() const = 0;
virtual void setPlaybackVolume(float volume) = 0;
virtual muse::async::Channel<float> playbackVolumeChanged() const = 0;
virtual muse::async::Promise<au::audio::AudioSignalChanges> playbackSignalChanges() const = 0;
};
using IAudacity3AudioOutputPtr = std::shared_ptr<IAudacity3AudioOutput>;
}
#endif // AU_AU3WRAP_IAUDACITYAUDIOOUTPUT_H
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "playback/audiotypes.h" #include "playback/audiotypes.h"
class AudacityProject; #include "iaudacity3audiooutput.h"
namespace au::au3 { namespace au::au3 {
class IAudacity3Playback : MODULE_EXPORT_INTERFACE class IAudacity3Playback : MODULE_EXPORT_INTERFACE
...@@ -32,6 +32,8 @@ public: ...@@ -32,6 +32,8 @@ public:
virtual muse::async::Channel<audio::msecs_t> playbackPositionMsecs() const = 0; virtual muse::async::Channel<audio::msecs_t> playbackPositionMsecs() const = 0;
virtual muse::async::Channel<audio::PlaybackStatus> playbackStatusChanged() const = 0; virtual muse::async::Channel<audio::PlaybackStatus> playbackStatusChanged() const = 0;
virtual std::shared_ptr<IAudacity3AudioOutput> audioOutput() const = 0;
}; };
using IAudacity3PlaybackPtr = std::shared_ptr<IAudacity3Playback>; using IAudacity3PlaybackPtr = std::shared_ptr<IAudacity3Playback>;
} }
......
/*
* Audacity: A Digital Audio Editor
*/
#include "audacity3audiooutput.h"
#include "types/ret.h"
#include "global/async/async.h"
#include "libraries/lib-audio-io/AudioIO.h"
#include "log.h"
using namespace muse;
using namespace muse::async;
using namespace au::au3;
muse::async::Promise<au::audio::volume_dbfs_t> Audacity3AudioOutput::playbackVolume() const
{
return muse::async::Promise<float>([](auto resolve, auto /*reject*/) {
float inputVolume;
float outputVolume;
int inputSource;
auto gAudioIO = AudioIO::Get();
gAudioIO->GetMixer(&inputSource, &inputVolume, &outputVolume);
return resolve(outputVolume);
});
}
void Audacity3AudioOutput::setPlaybackVolume(float volume)
{
muse::async::Async::call(this, [this, volume]() {
float inputVolume;
float outputVolume;
int inputSource;
auto gAudioIO = AudioIO::Get();
gAudioIO->GetMixer(&inputSource, &inputVolume, &outputVolume);
gAudioIO->SetMixer(inputSource, inputVolume, volume);
m_playbackVolumeChanged.send(volume);
});
}
muse::async::Channel<au::audio::volume_dbfs_t> Audacity3AudioOutput::playbackVolumeChanged() const
{
return m_playbackVolumeChanged;
}
muse::async::Promise<au::audio::AudioSignalChanges> Audacity3AudioOutput::playbackSignalChanges() const
{
return muse::async::Promise<audio::AudioSignalChanges>([](auto, auto reject) {
muse::Ret ret = make_ret(muse::Ret::Code::NotImplemented);
return reject(ret.code(), ret.text());
});
}
/*
* Audacity: A Digital Audio Editor
*/
#ifndef AU_AU3WRAP_AUDIOOUTPUT_H
#define AU_AU3WRAP_AUDIOOUTPUT_H
#include "global/async/asyncable.h"
#include "../iaudacity3audiooutput.h"
namespace au::au3 {
class Audacity3AudioOutput : public IAudacity3AudioOutput, public muse::async::Asyncable
{
public:
muse::async::Promise<float> playbackVolume() const override;
void setPlaybackVolume(float volume) override;
muse::async::Channel<float> playbackVolumeChanged() const override;
muse::async::Promise<au::audio::AudioSignalChanges> playbackSignalChanges() const override;
private:
mutable muse::async::Channel<float> m_playbackVolumeChanged;
};
}
#endif // AU_AU3WRAP_AUDIOOUTPUT_H
...@@ -157,8 +157,6 @@ Item { ...@@ -157,8 +157,6 @@ Item {
Connections { Connections {
target: btn.mouseArea target: btn.mouseArea
// Make sure we only connect to `pressAndHold` if necessary
// See https://github.com/musescore/MuseScore/issues/16012
enabled: btn.hasMenu && !menuLoader.isMenuOpened enabled: btn.hasMenu && !menuLoader.isMenuOpened
function onPressAndHold() { function onPressAndHold() {
...@@ -210,7 +208,13 @@ Item { ...@@ -210,7 +208,13 @@ Item {
id: playbackLevelComp id: playbackLevelComp
PlaybackLevel { PlaybackLevel {
property var item: loader.itemData
width: 128 width: 128
onVolumeLevelChangeRequested: function(level) {
item.level = level
}
} }
} }
} }
......
...@@ -15,6 +15,8 @@ Item { ...@@ -15,6 +15,8 @@ Item {
height: 32 height: 32
signal volumeLevelChangeRequested(var level)
RowLayout { RowLayout {
anchors.fill: parent anchors.fill: parent
anchors.margins: 6 anchors.margins: 6
...@@ -35,7 +37,7 @@ Item { ...@@ -35,7 +37,7 @@ Item {
Layout.alignment: Qt.AlighVCenter Layout.alignment: Qt.AlighVCenter
onVolumeLevelMoved: function(level) { onVolumeLevelMoved: function(level) {
volumeLevel = Math.round(level * 10) / 10 root.volumeLevelChangeRequested(Math.round(level * 10) / 10)
} }
} }
} }
......
/* /*
* SPDX-License-Identifier: GPL-3.0-only * Audacity: A Digital Audio Editor
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import QtQuick 2.15 import QtQuick 2.15
...@@ -69,7 +51,7 @@ Slider { ...@@ -69,7 +51,7 @@ Slider {
readonly property real indicatorHeight: 6 readonly property real indicatorHeight: 6
readonly property real rulerLineWidth: root.width - handleWidth readonly property real rulerLineWidth: root.width - handleWidth
readonly property real rulerLineHeight: 2 // todo readonly property real rulerLineHeight: 2
readonly property int rulerYPos: margin + indicatorHeight + spacing / 2 readonly property int rulerYPos: margin + indicatorHeight + spacing / 2
...@@ -84,7 +66,7 @@ Slider { ...@@ -84,7 +66,7 @@ Slider {
NavigationControl { NavigationControl {
id: navCtrl id: navCtrl
name: root.objectName != "" ? root.objectName : "VolumeSlider" name: root.objectName !== "" ? root.objectName : "VolumeSlider"
enabled: root.enabled && root.visible enabled: root.enabled && root.visible
accessible.role: MUAccessible.Range accessible.role: MUAccessible.Range
...@@ -201,8 +183,7 @@ Slider { ...@@ -201,8 +183,7 @@ Slider {
onMoved: { onMoved: {
navigation.requestActiveByInteraction() navigation.requestActiveByInteraction()
var newLevel = convertor.volumeLevelFromLocal(value) root.volumeLevelMoved(value)
root.volumeLevelMoved(newLevel)
} }
Component.onCompleted: { Component.onCompleted: {
......
...@@ -24,10 +24,43 @@ ...@@ -24,10 +24,43 @@
#include <QVariantMap> #include <QVariantMap>
using namespace au::playback; using namespace au::playback;
using namespace au::au3;
static int au3VolumeToLocal(float volume)
{
//! convert from range 0-1 to -60-0
float old_max = 1;
float old_min = 0;
int old_range = old_max - old_min;
int new_max = 0;
int new_min = -60;
int new_range = new_max - new_min;
return (((volume - old_min) * new_range) / old_range) + new_min;
}
static float localVolumeToAu3(int volume)
{
//! convert from range -60-0 to 0-1
float old_max = 0;
float old_min = -60;
int old_range = old_max - old_min;
int new_max = 1;
int new_min = 0;
int new_range = new_max - new_min;
return (((volume - old_min) * new_range) / old_range) + new_min;
}
PlaybackToolBarLevelItem::PlaybackToolBarLevelItem(const muse::ui::UiAction& action, const ItemType& type, QObject* parent) PlaybackToolBarLevelItem::PlaybackToolBarLevelItem(const muse::ui::UiAction& action, const ItemType& type, QObject* parent)
: PlaybackToolBarAbstractItem(action, type, parent) : PlaybackToolBarAbstractItem(action, type, parent)
{ {
playback()->audioOutput()->playbackVolumeChanged().onReceive(this, [this](audio::volume_dbfs_t volume){
m_level = au3VolumeToLocal(volume);
emit levelChanged();
});
} }
int PlaybackToolBarLevelItem::level() const int PlaybackToolBarLevelItem::level() const
...@@ -41,6 +74,5 @@ void PlaybackToolBarLevelItem::setLevel(int newLevel) ...@@ -41,6 +74,5 @@ void PlaybackToolBarLevelItem::setLevel(int newLevel)
return; return;
} }
m_level = newLevel; playback()->audioOutput()->setPlaybackVolume(localVolumeToAu3(newLevel));
emit levelChanged();
} }
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
#include <QString> #include <QString>
#include "modularity/ioc.h"
#include "au3wrap/iaudacity3playback.h"
#include "playbacktoolbarabstractitem.h" #include "playbacktoolbarabstractitem.h"
namespace au::playback { namespace au::playback {
...@@ -15,6 +18,8 @@ class PlaybackToolBarLevelItem : public PlaybackToolBarAbstractItem ...@@ -15,6 +18,8 @@ class PlaybackToolBarLevelItem : public PlaybackToolBarAbstractItem
Q_PROPERTY(int level READ level WRITE setLevel NOTIFY levelChanged FINAL) Q_PROPERTY(int level READ level WRITE setLevel NOTIFY levelChanged FINAL)
muse::Inject<au3::IAudacity3Playback> playback;
public: public:
explicit PlaybackToolBarLevelItem(const muse::ui::UiAction& action, const ItemType& type, QObject* parent = nullptr); explicit PlaybackToolBarLevelItem(const muse::ui::UiAction& action, const ItemType& type, QObject* parent = nullptr);
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "internal/playbackuiactions.h" #include "internal/playbackuiactions.h"
#include "view/toolbars/playbacktoolbarabstractitem.h" #include "view/toolbars/playbacktoolbarabstractitem.h"
#include "view/toolbars/playbacktoolbarlevelitem.h"
using namespace muse::uicomponents; using namespace muse::uicomponents;
using namespace muse::ui; using namespace muse::ui;
...@@ -82,8 +83,8 @@ QVariant PlaybackToolBarModel::data(const QModelIndex& index, int role) const ...@@ -82,8 +83,8 @@ QVariant PlaybackToolBarModel::data(const QModelIndex& index, int role) const
return QVariant(); return QVariant();
} }
const PlaybackToolBarAbstractItem* item = m_items[row]; PlaybackToolBarAbstractItem* item = m_items[row];
const ActionCode actionCode = item->action().code; ActionCode actionCode = item->action().code;
switch (role) { switch (role) {
case ItemRole: return QVariant::fromValue(item); case ItemRole: return QVariant::fromValue(item);
...@@ -149,13 +150,12 @@ void PlaybackToolBarModel::updateActions() ...@@ -149,13 +150,12 @@ void PlaybackToolBarModel::updateActions()
muse::ui::ToolConfig playbackConfig muse::ui::ToolConfig playbackConfig
= uiConfiguration()->toolConfig(TOOLBAR_NAME, PlaybackUiActions::defaultPlaybackToolConfig()); = uiConfiguration()->toolConfig(TOOLBAR_NAME, PlaybackUiActions::defaultPlaybackToolConfig());
int section = 0;
for (const muse::ui::ToolConfig::Item& citem : playbackConfig.items) { for (const muse::ui::ToolConfig::Item& citem : playbackConfig.items) {
if (!citem.show) { if (!citem.show) {
continue; continue;
} }
PlaybackToolBarAbstractItem* item = makeItem(uiActionsRegister()->action(citem.action), QString::number(section)); PlaybackToolBarAbstractItem* item = makeItem(uiActionsRegister()->action(citem.action));
if (citem.action == PLAY_ACTION_CODE) { if (citem.action == PLAY_ACTION_CODE) {
item->setAction(playAction()); item->setAction(playAction());
...@@ -176,11 +176,17 @@ bool PlaybackToolBarModel::isMenuSecondary(const muse::actions::ActionCode& acti ...@@ -176,11 +176,17 @@ bool PlaybackToolBarModel::isMenuSecondary(const muse::actions::ActionCode& acti
return false; return false;
} }
PlaybackToolBarAbstractItem* PlaybackToolBarModel::makeItem(const muse::ui::UiAction& action, const QString& section) PlaybackToolBarAbstractItem* PlaybackToolBarModel::makeItem(const muse::ui::UiAction& action)
{ {
PlaybackToolBarAbstractItem* item = new PlaybackToolBarAbstractItem(action, itemType(action.code), this); PlaybackToolBarAbstractItem::ItemType type = itemType(action.code);
item->setSection(section);
return item; switch (type) {
case PlaybackToolBarAbstractItem::PLAYBACK_LEVEL: return new PlaybackToolBarLevelItem(action, type, this);
default:
break;
}
return new PlaybackToolBarAbstractItem(action, type, this);
} }
UiAction PlaybackToolBarModel::playAction() const UiAction PlaybackToolBarModel::playAction() const
......
...@@ -64,7 +64,7 @@ private: ...@@ -64,7 +64,7 @@ private:
bool isMenuSecondary(const muse::actions::ActionCode& actionCode) const; bool isMenuSecondary(const muse::actions::ActionCode& actionCode) const;
PlaybackToolBarAbstractItem* makeItem(const muse::ui::UiAction& action, const QString& section); PlaybackToolBarAbstractItem* makeItem(const muse::ui::UiAction& action);
muse::ui::UiAction playAction() const; muse::ui::UiAction playAction() const;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment