diff --git a/CMakeLists.txt b/CMakeLists.txt index 65363d2..913942c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ option(TALCS_FORMAT "Build talcs::Format library" ON) option(TALCS_MIDI "Build talcs::Midi library" ON) option(TALCS_REMOTE "Build talcs::Remote library" ON) option(TALCS_JUCE_ADAPTER "Build talcs::JuceAdapter library" OFF) +option(TALCS_DSPX "Build talcs::Dspx library" OFF) # ---------------------------------- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 851a46e..e7b1622 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -127,6 +127,10 @@ if(TALCS_JUCE_ADAPTER) add_subdirectory(juceadapter) endif() +if(TALCS_DSPX) + add_subdirectory(dspx) +endif() + if(TALCS_INSTALL) # Add install target set(_install_dir ${CMAKE_INSTALL_LIBDIR}/cmake/${TALCS_INSTALL_NAME}) diff --git a/src/dspx/CMakeLists.txt b/src/dspx/CMakeLists.txt new file mode 100644 index 0000000..8eb7179 --- /dev/null +++ b/src/dspx/CMakeLists.txt @@ -0,0 +1,9 @@ +project(TalcsDspx VERSION ${TALCS_VERSION} LANGUAGES CXX) + +file(GLOB_RECURSE _src *.h *.cpp) + +talcs_add_library(${PROJECT_NAME} AUTOGEN + SOURCES ${_src} + LINKS talcs::Core talcs::Format + QT_INCLUDE_PRIVATE Core +) diff --git a/src/dspx/DspxAudioClipContext.cpp b/src/dspx/DspxAudioClipContext.cpp new file mode 100644 index 0000000..f616284 --- /dev/null +++ b/src/dspx/DspxAudioClipContext.cpp @@ -0,0 +1,178 @@ +/****************************************************************************** + * Copyright (c) 2024 CrSjimo * + * * + * This file is part of TALCS. * + * * + * TALCS is free software: you can redistribute it and/or modify it under the * + * terms of the GNU Lesser General Public License as published by the Free * + * Software Foundation, either version 3 of the License, or (at your option) * + * any later version. * + * * + * TALCS 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 Lesser General Public License for * + * more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with TALCS. If not, see . * + ******************************************************************************/ + +#include "DspxAudioClipContext.h" +#include "DspxAudioClipContext_p.h" + +#include +#include + +#include +#include +#include + +#include +#include + +namespace talcs { + + DspxAudioClipContext::DspxAudioClipContext(DspxTrackContext *trackContext) : QObject(trackContext), d_ptr(new DspxAudioClipContextPrivate) { + Q_D(DspxAudioClipContext); + d->q_ptr = this; + + d->controlMixer = std::make_unique(); + d->clipMixer = std::make_unique(); + + d->controlMixer->addSource(d->clipMixer.get()); + + d->trackContext = trackContext; + } + + DspxAudioClipContext::~DspxAudioClipContext() { + + } + + PositionableMixerAudioSource *DspxAudioClipContext::controlMixer() const { + Q_D(const DspxAudioClipContext); + return d->controlMixer.get(); + } + + PositionableMixerAudioSource *DspxAudioClipContext::clipMixer() const { + Q_D(const DspxAudioClipContext); + return d->clipMixer.get(); + } + + BufferingAudioSource *DspxAudioClipContext::contentSource() const { + Q_D(const DspxAudioClipContext); + return d->contentSource.get(); + } + + DspxTrackContext *DspxAudioClipContext::trackContext() const { + Q_D(const DspxAudioClipContext); + return d->trackContext; + } + + void DspxAudioClipContext::setStart(int tick) { + Q_D(DspxAudioClipContext); + if (d->startTick != tick) { + d->startTick = tick; + updatePosition(); + } + } + + int DspxAudioClipContext::start() const { + Q_D(const DspxAudioClipContext); + return d->startTick; + } + + void DspxAudioClipContext::setClipStart(int tick) { + Q_D(DspxAudioClipContext); + if (d->clipStartTick != tick) { + d->clipStartTick = tick; + updatePosition(); + } + } + + int DspxAudioClipContext::clipStart() const { + Q_D(const DspxAudioClipContext); + return d->clipStartTick; + } + + void DspxAudioClipContext::setClipLen(int tick) { + Q_D(DspxAudioClipContext); + if (d->clipLenTick != tick) { + d->clipLenTick = tick; + updatePosition(); + } + } + + int DspxAudioClipContext::clipLen() const { + Q_D(const DspxAudioClipContext); + return d->clipLenTick; + } + + void DspxAudioClipContextPrivate::handleIO(AbstractAudioFormatIO *io) { + auto rawSource_ = std::make_unique(io, true); + if (contentSource) + clipMixer->removeSource(contentSource.get()); + contentSource.reset(trackContext->projectContext()->makeBufferable(rawSource_.get(), 2)); + rawSource = std::move(rawSource_); + clipMixer->prependSource(contentSource.get()); + } + + bool DspxAudioClipContext::setPathLoad(const QString &path, const QVariant &data) { + Q_D(DspxAudioClipContext); + auto formatManager = d->trackContext->projectContext()->formatManager(); + if (!formatManager) + return false; + auto io = formatManager->getFormatLoad(path, data); + if (!io) + return false; + d->handleIO(io); + d->path = path; + return true; + } + + bool DspxAudioClipContext::setPathOpen(const QString &path, const QString &filter, QVariant &data) { + Q_D(DspxAudioClipContext); + auto formatManager = d->trackContext->projectContext()->formatManager(); + if (!formatManager) + return false; + AbstractAudioFormatIO *io = nullptr; + for (auto entry : formatManager->entries()) { + if (filter.isEmpty() || entry->filters().contains(filter)) { + io = entry->getFormatLoad(path, data); + if (io) + break; + } + } + if (!io) + return false; + d->handleIO(io); + d->path = path; + return true; + } + + QString DspxAudioClipContext::path() const { + Q_D(const DspxAudioClipContext); + return d->path; + } + + void DspxAudioClipContext::updatePosition() { + Q_D(DspxAudioClipContext); + auto clipSeries = d->trackContext->clipSeries(); + auto convertTime = d->trackContext->projectContext()->timeConverter(); + auto startSample = convertTime(d->clipStartTick); + clipSeries->setClipStartPos(d->clipView, startSample); + auto firstSample = convertTime(d->startTick + d->clipStartTick); + auto lastSample = convertTime(d->startTick + d->clipStartTick + d->clipLenTick); + clipSeries->setClipRange(d->clipView, firstSample, qMax(qint64(1), lastSample - firstSample)); + } + + void DspxAudioClipContext::setData(const QVariant &data) { + Q_D(DspxAudioClipContext); + d->data = data; + } + + QVariant DspxAudioClipContext::data() const { + Q_D(const DspxAudioClipContext); + return d->data; + } + +} // talcs \ No newline at end of file diff --git a/src/dspx/DspxAudioClipContext.h b/src/dspx/DspxAudioClipContext.h new file mode 100644 index 0000000..1bafde7 --- /dev/null +++ b/src/dspx/DspxAudioClipContext.h @@ -0,0 +1,76 @@ +/****************************************************************************** + * Copyright (c) 2024 CrSjimo * + * * + * This file is part of TALCS. * + * * + * TALCS is free software: you can redistribute it and/or modify it under the * + * terms of the GNU Lesser General Public License as published by the Free * + * Software Foundation, either version 3 of the License, or (at your option) * + * any later version. * + * * + * TALCS 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 Lesser General Public License for * + * more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with TALCS. If not, see . * + ******************************************************************************/ + +#ifndef TALCS_DSPXAUDIOCLIPCONTEXT_H +#define TALCS_DSPXAUDIOCLIPCONTEXT_H + +#include +#include + +#include + +namespace talcs { + + class PositionableMixerAudioSource; + class BufferingAudioSource; + + class DspxTrackContext; + + class DspxAudioClipContextPrivate; + + class TALCSDSPX_EXPORT DspxAudioClipContext : public QObject { + Q_OBJECT + Q_DECLARE_PRIVATE(DspxAudioClipContext) + friend class DspxTrackContext; + public: + explicit DspxAudioClipContext(DspxTrackContext *trackContext); + ~DspxAudioClipContext() override; + + PositionableMixerAudioSource *controlMixer() const; + PositionableMixerAudioSource *clipMixer() const; + BufferingAudioSource *contentSource() const; + + DspxTrackContext *trackContext() const; + + void setStart(int tick); + int start() const; + + void setClipStart(int tick); + int clipStart() const; + + void setClipLen(int tick); + int clipLen() const; + + bool setPathLoad(const QString &path, const QVariant &data = {}); + bool setPathOpen(const QString &path, const QString &selectedFilter, QVariant &data); + QString path() const; + + void updatePosition(); + + void setData(const QVariant &data); + QVariant data() const; + + private: + QScopedPointer d_ptr; + + }; + +} // talcs + +#endif //TALCS_DSPXAUDIOCLIPCONTEXT_H diff --git a/src/dspx/DspxAudioClipContext_p.h b/src/dspx/DspxAudioClipContext_p.h new file mode 100644 index 0000000..98cc1f5 --- /dev/null +++ b/src/dspx/DspxAudioClipContext_p.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * Copyright (c) 2024 CrSjimo * + * * + * This file is part of TALCS. * + * * + * TALCS is free software: you can redistribute it and/or modify it under the * + * terms of the GNU Lesser General Public License as published by the Free * + * Software Foundation, either version 3 of the License, or (at your option) * + * any later version. * + * * + * TALCS 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 Lesser General Public License for * + * more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with TALCS. If not, see . * + ******************************************************************************/ + +#ifndef TALCS_DSPXAUDIOCLIPCONTEXT_P_H +#define TALCS_DSPXAUDIOCLIPCONTEXT_P_H + +#include + +#include + +#include + +namespace talcs { + + class AbstractAudioFormatIO; + + class DspxAudioClipContextPrivate { + Q_DECLARE_PUBLIC(DspxAudioClipContext); + public: + DspxAudioClipContext *q_ptr; + + std::unique_ptr rawSource; + std::unique_ptr contentSource; + std::unique_ptr clipMixer; + std::unique_ptr controlMixer; + + DspxTrackContext *trackContext; + + AudioSourceClipSeries::ClipView clipView; + + int startTick = 0; + int clipStartTick = 0; + int clipLenTick = 0; + QString path; + + QVariant data; + + void handleIO(AbstractAudioFormatIO *io); + + }; +} + +#endif //TALCS_DSPXAUDIOCLIPCONTEXT_P_H diff --git a/src/dspx/DspxProjectContext.cpp b/src/dspx/DspxProjectContext.cpp new file mode 100644 index 0000000..8b6391c --- /dev/null +++ b/src/dspx/DspxProjectContext.cpp @@ -0,0 +1,170 @@ +/****************************************************************************** + * Copyright (c) 2024 CrSjimo * + * * + * This file is part of TALCS. * + * * + * TALCS is free software: you can redistribute it and/or modify it under the * + * terms of the GNU Lesser General Public License as published by the Free * + * Software Foundation, either version 3 of the License, or (at your option) * + * any later version. * + * * + * TALCS 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 Lesser General Public License for * + * more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with TALCS. If not, see . * + ******************************************************************************/ + +#include "DspxProjectContext.h" +#include "DspxProjectContext_p.h" + +#include +#include +#include + +#include + +namespace talcs { + + DspxProjectContextBufferingAudioSourceObject::DspxProjectContextBufferingAudioSourceObject(PositionableAudioSource *src, int channelCount, qint64 readAheadSize, QObject *parent) + : QObject(parent), BufferingAudioSource(src, channelCount, readAheadSize) { + } + + DspxProjectContextBufferingAudioSourceObject::~DspxProjectContextBufferingAudioSourceObject() = default; + + DspxProjectContext::DspxProjectContext(QObject *parent) : QObject(parent), d_ptr(new DspxProjectContextPrivate) { + Q_D(DspxProjectContext); + d->q_ptr = this; + + d->preMixer = std::make_unique(); + d->transport = std::make_unique(); + d->postMixer = std::make_unique(); + d->masterControlMixer = std::make_unique(); + d->masterTrackMixer = std::make_unique(); + + d->masterControlMixer->addSource(d->masterTrackMixer.get()); + d->postMixer->addSource(d->masterControlMixer.get()); + d->transport->setSource(d->postMixer.get()); + d->preMixer->addSource(d->transport.get()); + } + + DspxProjectContext::~DspxProjectContext() = default; + + MixerAudioSource *DspxProjectContext::preMixer() const { + Q_D(const DspxProjectContext); + return d->preMixer.get(); + } + + TransportAudioSource *DspxProjectContext::transport() const { + Q_D(const DspxProjectContext); + return d->transport.get(); + } + + PositionableMixerAudioSource *DspxProjectContext::postMixer() const { + Q_D(const DspxProjectContext); + return d->postMixer.get(); + } + + PositionableMixerAudioSource *DspxProjectContext::masterControlMixer() const { + Q_D(const DspxProjectContext); + return d->masterControlMixer.get(); + } + + PositionableMixerAudioSource *DspxProjectContext::masterTrackMixer() const { + Q_D(const DspxProjectContext); + return d->masterTrackMixer.get(); + } + + void DspxProjectContext::setFormatManager(FormatManager *formatManager) { + Q_D(DspxProjectContext); + d->formatManager = formatManager; + } + + FormatManager *DspxProjectContext::formatManager() const { + Q_D(const DspxProjectContext); + return d->formatManager; + } + + void DspxProjectContext::setTimeConverter(const std::function &converter) { + Q_D(DspxProjectContext); + d->timeConverter = converter; + } + + std::function DspxProjectContext::timeConverter() const { + Q_D(const DspxProjectContext); + return d->timeConverter; + } + + void DspxProjectContext::setBufferingReadAheadSize(qint64 size) { + Q_D(DspxProjectContext); + if (size != d->bufferingReadAheadSize) { + d->bufferingReadAheadSize = size; + emit d->readAheadSizeChanged(size); + } + } + + qint64 DspxProjectContext::bufferingReadAheadSize() const { + Q_D(const DspxProjectContext); + return d->bufferingReadAheadSize; + } + + BufferingAudioSource *DspxProjectContext::makeBufferable(PositionableAudioSource *source, int channelCount) { + Q_D(DspxProjectContext); + auto bufSrc = new DspxProjectContextBufferingAudioSourceObject(source, channelCount, d->bufferingReadAheadSize); + connect(d, &DspxProjectContextPrivate::readAheadSizeChanged, bufSrc, [bufSrc](qint64 size) { + bufSrc->setReadAheadSize(size); + }); + return bufSrc; + } + + DspxTrackContext *DspxProjectContext::addTrack(int index) { + Q_D(DspxProjectContext); + Q_ASSERT(index >= 0 && index <= d->tracks.size()); + auto track = new DspxTrackContext(this); + d->tracks.insert(index, track); + d->masterTrackMixer->insertSource(d->masterTrackMixer->sourceAt(index), track->controlMixer()); + return track; + } + + void DspxProjectContext::removeTrack(int index) { + Q_D(DspxProjectContext); + Q_ASSERT(index >= 0 && index < d->tracks.size()); + auto track = d->tracks.at(index); + d->tracks.removeAt(index); + d->masterTrackMixer->removeSource(track->controlMixer()); + delete track; + } + + void DspxProjectContext::moveTrack(int index, int count, int dest) { + Q_D(DspxProjectContext); + Q_ASSERT(index >= 0 && index < d->tracks.size() && count > 0 && index + count <= d->tracks.size() && dest >= 0 && dest <= d->tracks.size()); + + QVector tmp; + tmp.resize(count); + std::copy(d->tracks.begin() + index, d->tracks.begin() + index + count, tmp.begin()); + int correctDest; + if (dest > index) { + correctDest = dest - count; + auto sz = correctDest - index; + for (int i = 0; i < sz; ++i) { + d->tracks[index + i] = d->tracks[index + count + i]; + } + } else { + correctDest = dest; + auto sz = index - dest; + for (int i = sz - 1; i >= 0; --i) { + d->tracks[dest + count + i] = d->tracks[dest + i]; + } + } + std::copy(tmp.begin(), tmp.end(), d->tracks.begin() + correctDest); + + d->masterTrackMixer->moveSource(d->masterTrackMixer->sourceAt(dest), d->masterTrackMixer->sourceAt(index), d->masterTrackMixer->sourceAt(index + count)); + } + + QList DspxProjectContext::tracks() const { + Q_D(const DspxProjectContext); + return d->tracks; + } +} \ No newline at end of file diff --git a/src/dspx/DspxProjectContext.h b/src/dspx/DspxProjectContext.h new file mode 100644 index 0000000..e52218a --- /dev/null +++ b/src/dspx/DspxProjectContext.h @@ -0,0 +1,78 @@ +/****************************************************************************** + * Copyright (c) 2024 CrSjimo * + * * + * This file is part of TALCS. * + * * + * TALCS is free software: you can redistribute it and/or modify it under the * + * terms of the GNU Lesser General Public License as published by the Free * + * Software Foundation, either version 3 of the License, or (at your option) * + * any later version. * + * * + * TALCS 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 Lesser General Public License for * + * more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with TALCS. If not, see . * + ******************************************************************************/ + +#ifndef TALCS_DSPXPROJECTCONTEXT_H +#define TALCS_DSPXPROJECTCONTEXT_H + +#include + +#include + +#include + +namespace talcs { + + class MixerAudioSource; + class TransportAudioSource; + class PositionableMixerAudioSource; + class PositionableAudioSource; + class BufferingAudioSource; + + class FormatManager; + + class DspxTrackContext; + + class DspxProjectContextPrivate; + + class TALCSDSPX_EXPORT DspxProjectContext : public QObject { + Q_OBJECT + Q_DECLARE_PRIVATE(DspxProjectContext) + public: + explicit DspxProjectContext(QObject *parent = nullptr); + ~DspxProjectContext() override; + + MixerAudioSource *preMixer() const; + TransportAudioSource *transport() const; + PositionableMixerAudioSource *postMixer() const; + PositionableMixerAudioSource *masterControlMixer() const; + PositionableMixerAudioSource *masterTrackMixer() const; + + void setFormatManager(FormatManager *formatManager); + FormatManager *formatManager() const; + + void setTimeConverter(const std::function &converter); + std::function timeConverter() const; + + void setBufferingReadAheadSize(qint64 size); + qint64 bufferingReadAheadSize() const; + BufferingAudioSource *makeBufferable(PositionableAudioSource *source, int channelCount); + + DspxTrackContext *addTrack(int index); + void removeTrack(int index); + void moveTrack(int index, int count, int dest); + + QList tracks() const; + + private: + QScopedPointer d_ptr; + }; + +} // talcs + +#endif //TALCS_DSPXPROJECTCONTEXT_H diff --git a/src/dspx/DspxProjectContext_p.h b/src/dspx/DspxProjectContext_p.h new file mode 100644 index 0000000..453a6cd --- /dev/null +++ b/src/dspx/DspxProjectContext_p.h @@ -0,0 +1,61 @@ +/****************************************************************************** + * Copyright (c) 2024 CrSjimo * + * * + * This file is part of TALCS. * + * * + * TALCS is free software: you can redistribute it and/or modify it under the * + * terms of the GNU Lesser General Public License as published by the Free * + * Software Foundation, either version 3 of the License, or (at your option) * + * any later version. * + * * + * TALCS 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 Lesser General Public License for * + * more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with TALCS. If not, see . * + ******************************************************************************/ + +#ifndef TALCS_DSPXPROJECTCONTEXT_P_H +#define TALCS_DSPXPROJECTCONTEXT_P_H + +#include + +#include + +#include + +namespace talcs { + + class DspxProjectContextBufferingAudioSourceObject : public QObject, public BufferingAudioSource { + Q_OBJECT + public: + explicit DspxProjectContextBufferingAudioSourceObject(PositionableAudioSource *src, int channelCount, qint64 readAheadSize, QObject *parent = nullptr); + ~DspxProjectContextBufferingAudioSourceObject() override; + }; + + class DspxProjectContextPrivate : public QObject { + Q_OBJECT + Q_DECLARE_PUBLIC(DspxProjectContext); + public: + DspxProjectContext *q_ptr; + + std::unique_ptr masterTrackMixer; + std::unique_ptr masterControlMixer; + std::unique_ptr postMixer; + std::unique_ptr transport; + std::unique_ptr preMixer; + + FormatManager *formatManager = nullptr; + std::function timeConverter = [](int) { return 0; }; + qint64 bufferingReadAheadSize = 0; + + QList tracks; + + signals: + void readAheadSizeChanged(qint64 readAheadSize); + }; +} + +#endif //TALCS_DSPXPROJECTCONTEXT_P_H diff --git a/src/dspx/DspxTrackContext.cpp b/src/dspx/DspxTrackContext.cpp new file mode 100644 index 0000000..737efee --- /dev/null +++ b/src/dspx/DspxTrackContext.cpp @@ -0,0 +1,104 @@ +/****************************************************************************** + * Copyright (c) 2024 CrSjimo * + * * + * This file is part of TALCS. * + * * + * TALCS is free software: you can redistribute it and/or modify it under the * + * terms of the GNU Lesser General Public License as published by the Free * + * Software Foundation, either version 3 of the License, or (at your option) * + * any later version. * + * * + * TALCS 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 Lesser General Public License for * + * more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with TALCS. If not, see . * + ******************************************************************************/ + +#include "DspxTrackContext.h" +#include "DspxTrackContext_p.h" + +#include + +#include +#include +#include + +namespace talcs { + DspxTrackContext::DspxTrackContext(DspxProjectContext *projectContext) : QObject(projectContext), d_ptr(new DspxTrackContextPrivate) { + Q_D(DspxTrackContext); + d->q_ptr = this; + + d->controlMixer = std::make_unique(); + d->trackMixer = std::make_unique(); + d->clipSeries = std::make_unique(); + + d->trackMixer->addSource(d->clipSeries.get()); + d->controlMixer->addSource(d->trackMixer.get()); + + d->projectContext = projectContext; + } + + DspxTrackContext::~DspxTrackContext() { + + } + + PositionableMixerAudioSource *DspxTrackContext::controlMixer() const { + Q_D(const DspxTrackContext); + return d->controlMixer.get(); + } + + PositionableMixerAudioSource *DspxTrackContext::trackMixer() const { + Q_D(const DspxTrackContext); + return d->trackMixer.get(); + } + + AudioSourceClipSeries *DspxTrackContext::clipSeries() const { + Q_D(const DspxTrackContext); + return d->clipSeries.get(); + } + + DspxProjectContext *DspxTrackContext::projectContext() const { + Q_D(const DspxTrackContext); + return d->projectContext; + } + + void DspxTrackContext::setData(const QVariant &data) { + Q_D(DspxTrackContext); + d->data = data; + } + + QVariant DspxTrackContext::data() const { + Q_D(const DspxTrackContext); + return d->data; + } + + DspxAudioClipContext *DspxTrackContext::addAudioClip(int id) { + Q_D(DspxTrackContext); + auto clip = new DspxAudioClipContext(this); + auto clipView = d->clipSeries->insertClip(clip->controlMixer(), 0, 0, 1); + d->clips.insert(id, {clip, clipView}); + clip->d_func()->clipView = clipView; + return clip; + } + + void DspxTrackContext::removeAudioClip(int id) { + Q_D(DspxTrackContext); + Q_ASSERT(d->clips.contains(id)); + auto clip = d->clips.value(id); + d->clips.remove(id); + d->clipSeries->removeClip(clip.second); + } + + QList DspxTrackContext::clips() const { + Q_D(const DspxTrackContext); + QList list; + list.reserve(d->clips.size()); + for (const auto &[clip, _] : d->clips.values()) { + list.append(clip); + } + return list; + } +} // talcs \ No newline at end of file diff --git a/src/dspx/DspxTrackContext.h b/src/dspx/DspxTrackContext.h new file mode 100644 index 0000000..9e3d74d --- /dev/null +++ b/src/dspx/DspxTrackContext.h @@ -0,0 +1,64 @@ +/****************************************************************************** + * Copyright (c) 2024 CrSjimo * + * * + * This file is part of TALCS. * + * * + * TALCS is free software: you can redistribute it and/or modify it under the * + * terms of the GNU Lesser General Public License as published by the Free * + * Software Foundation, either version 3 of the License, or (at your option) * + * any later version. * + * * + * TALCS 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 Lesser General Public License for * + * more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with TALCS. If not, see . * + ******************************************************************************/ + +#ifndef TALCS_DSPXTRACKCONTEXT_H +#define TALCS_DSPXTRACKCONTEXT_H + +#include + +#include + +namespace talcs { + + class PositionableMixerAudioSource; + class AudioSourceClipSeries; + + class DspxProjectContext; + class DspxAudioClipContext; + + class DspxTrackContextPrivate; + + class TALCSDSPX_EXPORT DspxTrackContext : public QObject { + Q_OBJECT + Q_DECLARE_PRIVATE(DspxTrackContext) + public: + explicit DspxTrackContext(DspxProjectContext *projectContext); + ~DspxTrackContext() override; + + PositionableMixerAudioSource *controlMixer() const; + PositionableMixerAudioSource *trackMixer() const; + AudioSourceClipSeries *clipSeries() const; + + DspxProjectContext *projectContext() const; + + void setData(const QVariant &data); + QVariant data() const; + + DspxAudioClipContext *addAudioClip(int id); + void removeAudioClip(int id); + + QList clips() const; + + private: + QScopedPointer d_ptr; + }; + +} // talcs + +#endif //TALCS_DSPXTRACKCONTEXT_H diff --git a/src/dspx/DspxTrackContext_p.h b/src/dspx/DspxTrackContext_p.h new file mode 100644 index 0000000..3c8df07 --- /dev/null +++ b/src/dspx/DspxTrackContext_p.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * Copyright (c) 2024 CrSjimo * + * * + * This file is part of TALCS. * + * * + * TALCS is free software: you can redistribute it and/or modify it under the * + * terms of the GNU Lesser General Public License as published by the Free * + * Software Foundation, either version 3 of the License, or (at your option) * + * any later version. * + * * + * TALCS 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 Lesser General Public License for * + * more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with TALCS. If not, see . * + ******************************************************************************/ + +#ifndef TALCS_DSPXTRACKCONTEXT_P_H +#define TALCS_DSPXTRACKCONTEXT_P_H + +#include + +#include + +#include + +#include + +namespace talcs { + class DspxTrackContextPrivate { + Q_DECLARE_PUBLIC(DspxTrackContext) + public: + DspxTrackContext *q_ptr; + + std::unique_ptr clipSeries; + std::unique_ptr trackMixer; + std::unique_ptr controlMixer; + + DspxProjectContext *projectContext = nullptr; + + QVariant data; + + QMap> clips; + + }; +} + +#endif //TALCS_DSPXTRACKCONTEXT_P_H diff --git a/src/dspx/TalcsDspxGlobal.h b/src/dspx/TalcsDspxGlobal.h new file mode 100644 index 0000000..4d369f5 --- /dev/null +++ b/src/dspx/TalcsDspxGlobal.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * Copyright (c) 2024 CrSjimo * + * * + * This file is part of TALCS. * + * * + * TALCS is free software: you can redistribute it and/or modify it under the * + * terms of the GNU Lesser General Public License as published by the Free * + * Software Foundation, either version 3 of the License, or (at your option) * + * any later version. * + * * + * TALCS 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 Lesser General Public License for * + * more details. * + * * + * You should have received a copy of the GNU Lesser General Public License * + * along with TALCS. If not, see . * + ******************************************************************************/ + +#ifndef TALCS_TALCSDSPXGLOBAL_H +#define TALCS_TALCSDSPXGLOBAL_H + +#include + +#ifndef TALCSDSPX_EXPORT +# ifdef TALCSDSPX_STATIC +# define TALCSDSPX_EXPORT +# else +# ifdef TALCSDSPX_LIBRARY +# define TALCSDSPX_EXPORT Q_DECL_EXPORT +# else +# define TALCSDSPX_EXPORT Q_DECL_IMPORT +# endif +# endif +#endif + +#endif //TALCS_TALCSDSPXGLOBAL_H