110
include/AudioBusHandle.h
Normal file
110
include/AudioBusHandle.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* AudioBusHandle.h - ThreadableJob between PlayHandle and MixerChannel
|
||||
*
|
||||
* Copyright (c) 2005-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2025 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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 (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LMMS_AUDIO_BUS_HANDLE_H
|
||||
#define LMMS_AUDIO_BUS_HANDLE_H
|
||||
|
||||
#include <memory>
|
||||
#include <QString>
|
||||
#include <QMutex>
|
||||
|
||||
#include "PlayHandle.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
class EffectChain;
|
||||
class FloatModel;
|
||||
class BoolModel;
|
||||
|
||||
/**
|
||||
@brief Job between @ref PlayHandle and @ref MixerChannel
|
||||
|
||||
A @ref ThreadableJob class located at the exit point of each @ref PlayHandle into a @ref MixerChannel
|
||||
(or into an audio device, in case of @ref AudioJack, but this is not supported in AudioBusHandle yet).
|
||||
It contains an optional @ref EffectChain which is e.g. visualized in the
|
||||
@ref InstrumentTrackWindow or @ref SampleTrackWindow.
|
||||
For processing, it adds all input play handles into an internal buffer,
|
||||
processes the @ref EffectChain (if existing) on that buffer
|
||||
and finally merges the buffer into its @ref MixerChannel.
|
||||
*/
|
||||
class AudioBusHandle : public ThreadableJob
|
||||
{
|
||||
public:
|
||||
AudioBusHandle(const QString& name, bool hasEffectChain = true,
|
||||
FloatModel* volumeModel = nullptr, FloatModel* panningModel = nullptr,
|
||||
BoolModel* mutedModel = nullptr);
|
||||
virtual ~AudioBusHandle();
|
||||
|
||||
SampleFrame* buffer() { return m_buffer; }
|
||||
|
||||
// indicate whether JACK & Co should provide output-buffer at ext. port
|
||||
bool extOutputEnabled() const { return m_extOutputEnabled; }
|
||||
void setExtOutputEnabled(bool enabled);
|
||||
|
||||
// next mixer-channel after this audio-bus-handle
|
||||
// (-1 = none 0 = master)
|
||||
mix_ch_t nextMixerChannel() const { return m_nextMixerChannel; }
|
||||
void setNextMixerChannel(const mix_ch_t chnl) { m_nextMixerChannel = chnl; }
|
||||
|
||||
const QString& name() const { return m_name; }
|
||||
void setName(const QString& newName);
|
||||
|
||||
EffectChain* effects() { return m_effects.get(); }
|
||||
bool processEffects();
|
||||
|
||||
// ThreadableJob stuff
|
||||
void doProcessing() override;
|
||||
bool requiresProcessing() const override { return true; }
|
||||
|
||||
void addPlayHandle(PlayHandle* handle);
|
||||
void removePlayHandle(PlayHandle* handle);
|
||||
|
||||
private:
|
||||
volatile bool m_bufferUsage;
|
||||
|
||||
SampleFrame* const m_buffer;
|
||||
|
||||
bool m_extOutputEnabled;
|
||||
mix_ch_t m_nextMixerChannel;
|
||||
|
||||
QString m_name;
|
||||
|
||||
std::unique_ptr<EffectChain> m_effects;
|
||||
|
||||
PlayHandleList m_playHandles;
|
||||
QMutex m_playHandleLock;
|
||||
|
||||
FloatModel* m_volumeModel;
|
||||
FloatModel* m_panningModel;
|
||||
BoolModel* m_mutedModel;
|
||||
|
||||
friend class AudioEngine;
|
||||
friend class AudioEngineWorkerThread;
|
||||
};
|
||||
|
||||
} // namespace lmms
|
||||
|
||||
#endif // LMMS_AUDIO_BUS_HANDLE_H
|
||||
@@ -36,7 +36,7 @@ namespace lmms
|
||||
{
|
||||
|
||||
class AudioEngine;
|
||||
class AudioPort;
|
||||
class AudioBusHandle;
|
||||
class SampleFrame;
|
||||
|
||||
|
||||
@@ -57,13 +57,13 @@ public:
|
||||
}
|
||||
|
||||
|
||||
// if audio-driver supports ports, classes inherting AudioPort
|
||||
// if audio-driver supports ports, classes inherting AudioBusHandle
|
||||
// (e.g. channel-tracks) can register themselves for making
|
||||
// audio-driver able to collect their individual output and provide
|
||||
// them at a specific port - currently only supported by JACK
|
||||
virtual void registerPort( AudioPort * _port );
|
||||
virtual void unregisterPort( AudioPort * _port );
|
||||
virtual void renamePort( AudioPort * _port );
|
||||
virtual void registerPort(AudioBusHandle* port);
|
||||
virtual void unregisterPort(AudioBusHandle* port);
|
||||
virtual void renamePort(AudioBusHandle* port);
|
||||
|
||||
inline bool supportsCapture() const
|
||||
{
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace lmms
|
||||
|
||||
class AudioDevice;
|
||||
class MidiClient;
|
||||
class AudioPort;
|
||||
class AudioBusHandle;
|
||||
class AudioEngineWorkerThread;
|
||||
|
||||
|
||||
@@ -172,15 +172,15 @@ public:
|
||||
}
|
||||
|
||||
|
||||
// audio-port-stuff
|
||||
inline void addAudioPort(AudioPort * port)
|
||||
// audio-bus-handle-stuff
|
||||
inline void addAudioBusHandle(AudioBusHandle* busHandle)
|
||||
{
|
||||
requestChangeInModel();
|
||||
m_audioPorts.push_back(port);
|
||||
m_audioBusHandles.push_back(busHandle);
|
||||
doneChangeInModel();
|
||||
}
|
||||
|
||||
void removeAudioPort(AudioPort * port);
|
||||
void removeAudioBusHandle(AudioBusHandle* busHandle);
|
||||
|
||||
|
||||
// MIDI-client-stuff
|
||||
@@ -366,7 +366,7 @@ private:
|
||||
|
||||
bool m_renderOnly;
|
||||
|
||||
std::vector<AudioPort *> m_audioPorts;
|
||||
std::vector<AudioBusHandle*> m_audioBusHandles;
|
||||
|
||||
fpp_t m_framesPerPeriod;
|
||||
|
||||
|
||||
@@ -36,9 +36,15 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
#ifdef AUDIO_BUS_HANDLE_SUPPORT
|
||||
#include <QMap>
|
||||
#endif
|
||||
|
||||
#include "AudioDevice.h"
|
||||
#include "AudioDeviceSetupWidget.h"
|
||||
#ifdef AUDIO_BUS_HANDLE_SUPPORT
|
||||
#include "AudioBusHandle.h"
|
||||
#endif
|
||||
|
||||
class QLineEdit;
|
||||
|
||||
@@ -94,9 +100,9 @@ private:
|
||||
void startProcessing() override;
|
||||
void stopProcessing() override;
|
||||
|
||||
void registerPort(AudioPort* port) override;
|
||||
void unregisterPort(AudioPort* port) override;
|
||||
void renamePort(AudioPort* port) override;
|
||||
void registerPort(AudioBusHandle* port) override;
|
||||
void unregisterPort(AudioBusHandle* port) override;
|
||||
void renamePort(AudioBusHandle* port) override;
|
||||
|
||||
int processCallback(jack_nframes_t nframes);
|
||||
|
||||
@@ -116,13 +122,13 @@ private:
|
||||
f_cnt_t m_framesDoneInCurBuf;
|
||||
f_cnt_t m_framesToDoInCurBuf;
|
||||
|
||||
#ifdef AUDIO_PORT_SUPPORT
|
||||
#ifdef AUDIO_BUS_HANDLE_SUPPORT
|
||||
struct StereoPort
|
||||
{
|
||||
jack_port_t* ports[2];
|
||||
};
|
||||
|
||||
using JackPortMap = QMap<AudioPort*, StereoPort>;
|
||||
using JackPortMap = QMap<AudioBusHandle*, StereoPort>;
|
||||
JackPortMap m_portMap;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* AudioPort.h - base-class for objects providing sound at a port
|
||||
*
|
||||
* Copyright (c) 2005-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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 (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LMMS_AUDIO_PORT_H
|
||||
#define LMMS_AUDIO_PORT_H
|
||||
|
||||
#include <memory>
|
||||
#include <QString>
|
||||
#include <QMutex>
|
||||
|
||||
#include "PlayHandle.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
class EffectChain;
|
||||
class FloatModel;
|
||||
class BoolModel;
|
||||
|
||||
class AudioPort : public ThreadableJob
|
||||
{
|
||||
public:
|
||||
AudioPort( const QString & _name, bool _has_effect_chain = true,
|
||||
FloatModel * volumeModel = nullptr, FloatModel * panningModel = nullptr,
|
||||
BoolModel * mutedModel = nullptr );
|
||||
virtual ~AudioPort();
|
||||
|
||||
inline SampleFrame* buffer()
|
||||
{
|
||||
return m_portBuffer;
|
||||
}
|
||||
|
||||
inline void lockBuffer()
|
||||
{
|
||||
m_portBufferLock.lock();
|
||||
}
|
||||
|
||||
inline void unlockBuffer()
|
||||
{
|
||||
m_portBufferLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
// indicate whether JACK & Co should provide output-buffer at ext. port
|
||||
inline bool extOutputEnabled() const
|
||||
{
|
||||
return m_extOutputEnabled;
|
||||
}
|
||||
|
||||
void setExtOutputEnabled( bool _enabled );
|
||||
|
||||
|
||||
// next mixer-channel after this audio-port
|
||||
// (-1 = none 0 = master)
|
||||
inline mix_ch_t nextMixerChannel() const
|
||||
{
|
||||
return m_nextMixerChannel;
|
||||
}
|
||||
|
||||
inline EffectChain * effects()
|
||||
{
|
||||
return m_effects.get();
|
||||
}
|
||||
|
||||
void setNextMixerChannel( const mix_ch_t _chnl )
|
||||
{
|
||||
m_nextMixerChannel = _chnl;
|
||||
}
|
||||
|
||||
|
||||
const QString & name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void setName( const QString & _new_name );
|
||||
|
||||
|
||||
bool processEffects();
|
||||
|
||||
// ThreadableJob stuff
|
||||
void doProcessing() override;
|
||||
bool requiresProcessing() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void addPlayHandle( PlayHandle * handle );
|
||||
void removePlayHandle( PlayHandle * handle );
|
||||
|
||||
private:
|
||||
volatile bool m_bufferUsage;
|
||||
|
||||
SampleFrame* m_portBuffer;
|
||||
QMutex m_portBufferLock;
|
||||
|
||||
bool m_extOutputEnabled;
|
||||
mix_ch_t m_nextMixerChannel;
|
||||
|
||||
QString m_name;
|
||||
|
||||
std::unique_ptr<EffectChain> m_effects;
|
||||
|
||||
PlayHandleList m_playHandles;
|
||||
QMutex m_playHandleLock;
|
||||
|
||||
FloatModel * m_volumeModel;
|
||||
FloatModel * m_panningModel;
|
||||
BoolModel * m_mutedModel;
|
||||
|
||||
friend class AudioEngine;
|
||||
friend class AudioEngineWorkerThread;
|
||||
|
||||
} ;
|
||||
|
||||
} // namespace lmms
|
||||
|
||||
#endif // LMMS_AUDIO_PORT_H
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "AudioPort.h"
|
||||
#include "AudioBusHandle.h"
|
||||
#include "InstrumentFunctions.h"
|
||||
#include "InstrumentSoundShaping.h"
|
||||
#include "Microtuner.h"
|
||||
@@ -144,9 +144,9 @@ public:
|
||||
const Plugin::Descriptor::SubPluginFeatures::Key* key = nullptr,
|
||||
bool keyFromDnd = false);
|
||||
|
||||
AudioPort * audioPort()
|
||||
AudioBusHandle* audioBusHandle()
|
||||
{
|
||||
return &m_audioPort;
|
||||
return &m_audioBusHandle;
|
||||
}
|
||||
|
||||
MidiPort * midiPort()
|
||||
@@ -293,7 +293,7 @@ private:
|
||||
FloatModel m_volumeModel;
|
||||
FloatModel m_panningModel;
|
||||
|
||||
AudioPort m_audioPort;
|
||||
AudioBusHandle m_audioBusHandle;
|
||||
|
||||
FloatModel m_pitchModel;
|
||||
IntModel m_pitchRangeModel;
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace lmms
|
||||
{
|
||||
|
||||
class Track;
|
||||
class AudioPort;
|
||||
class AudioBusHandle;
|
||||
class SampleFrame;
|
||||
|
||||
class LMMS_EXPORT PlayHandle : public ThreadableJob
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
m_offset = p.m_offset;
|
||||
m_affinity = p.m_affinity;
|
||||
m_usesBuffer = p.m_usesBuffer;
|
||||
m_audioPort = p.m_audioPort;
|
||||
m_audioBusHandle = p.m_audioBusHandle;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -134,14 +134,14 @@ public:
|
||||
m_usesBuffer = b;
|
||||
}
|
||||
|
||||
AudioPort * audioPort()
|
||||
AudioBusHandle* audioBusHandle()
|
||||
{
|
||||
return m_audioPort;
|
||||
return m_audioBusHandle;
|
||||
}
|
||||
|
||||
void setAudioPort( AudioPort * port )
|
||||
void setAudioBusHandle(AudioBusHandle* busHandle)
|
||||
{
|
||||
m_audioPort = port;
|
||||
m_audioBusHandle = busHandle;
|
||||
}
|
||||
|
||||
void releaseBuffer();
|
||||
@@ -156,7 +156,7 @@ private:
|
||||
SampleFrame* m_playHandleBuffer;
|
||||
bool m_bufferReleased;
|
||||
bool m_usesBuffer;
|
||||
AudioPort * m_audioPort;
|
||||
AudioBusHandle* m_audioBusHandle;
|
||||
} ;
|
||||
|
||||
using PlayHandleList = QList<PlayHandle*>;
|
||||
|
||||
@@ -38,13 +38,13 @@ namespace lmms
|
||||
class PatternTrack;
|
||||
class SampleClip;
|
||||
class Track;
|
||||
class AudioPort;
|
||||
class AudioBusHandle;
|
||||
|
||||
|
||||
class LMMS_EXPORT SamplePlayHandle : public PlayHandle
|
||||
{
|
||||
public:
|
||||
SamplePlayHandle(Sample* sample, bool ownAudioPort = true);
|
||||
SamplePlayHandle(Sample* sample, bool ownAudioBusHandle = true);
|
||||
SamplePlayHandle( const QString& sampleFile );
|
||||
SamplePlayHandle( SampleClip* clip );
|
||||
~SamplePlayHandle() override;
|
||||
@@ -88,7 +88,7 @@ private:
|
||||
f_cnt_t m_frame;
|
||||
Sample::PlaybackState m_state;
|
||||
|
||||
const bool m_ownAudioPort;
|
||||
const bool m_ownAudioBusHandle;
|
||||
|
||||
FloatModel m_defaultVolumeModel;
|
||||
FloatModel * m_volumeModel;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#ifndef LMMS_SAMPLE_TRACK_H
|
||||
#define LMMS_SAMPLE_TRACK_H
|
||||
|
||||
#include "AudioPort.h"
|
||||
#include "AudioBusHandle.h"
|
||||
#include "Track.h"
|
||||
|
||||
|
||||
@@ -62,9 +62,9 @@ public:
|
||||
return &m_mixerChannelModel;
|
||||
}
|
||||
|
||||
inline AudioPort * audioPort()
|
||||
inline AudioBusHandle* audioBusHandle()
|
||||
{
|
||||
return &m_audioPort;
|
||||
return &m_audioBusHandle;
|
||||
}
|
||||
|
||||
QString nodeName() const override
|
||||
@@ -95,7 +95,7 @@ private:
|
||||
FloatModel m_volumeModel;
|
||||
FloatModel m_panningModel;
|
||||
IntModel m_mixerChannelModel;
|
||||
AudioPort m_audioPort;
|
||||
AudioBusHandle m_audioBusHandle;
|
||||
bool m_isPlaying;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user