Bug fixes for audio textures

This commit is contained in:
Digital Artifex
2025-08-10 05:06:15 -04:00
parent 396b1cb104
commit 49ae3bb429
7 changed files with 73 additions and 96 deletions

View File

@@ -42,8 +42,8 @@ Item
ImageChannel, ImageChannel,
VideoChannel, VideoChannel,
ShaderChannel, ShaderChannel,
CubeMapChannel CubeMapChannel,
// AudioChannel AudioChannel
} }
property int type: ShaderChannel.Type.ImageChannel property int type: ShaderChannel.Type.ImageChannel
@@ -133,15 +133,15 @@ Item
{ {
loader.sourceComponent: channelShader loader.sourceComponent: channelShader
} }
},
State
{
when: channel.type === ShaderChannel.Type.AudioChannel
PropertyChanges
{
loader.sourceComponent: channelAudio
}
} }
// State
// {
// when: channel.type === ShaderChannel.Type.AudioChannel
// PropertyChanges
// {
// loader.sourceComponent: channelAudio
// }
// }
] ]
transform: Rotation transform: Rotation
@@ -373,80 +373,40 @@ Item
// Supporting this as an mp3 feels kinda silly. Should really figure out how to capture desktop audio with qml // Supporting this as an mp3 feels kinda silly. Should really figure out how to capture desktop audio with qml
// UPDATE: This is not currently supported in QML, so we will need to implement this in C++ later // UPDATE: This is not currently supported in QML, so we will need to implement this in C++ later
// Component Component
// { {
// id: channelAudio id: audioChannel
// Rectangle
// {
// anchors.fill: parent
// color: "black"
// property var audioData: new Array(512).fill(0) Item
// property alias texture: audioTexture {
// MediaDevices Image
// { {
// id: devices id: textureImage
// } source: "image://audiotexture/frame"
anchors.fill: parent
fillMode: Image.PreserveAspectFit
}
// AudioInput Timer
// { {
// id: audioInput property int frame: 0
// device: devices.defaultAudioInput interval: 16
// } repeat: true
triggeredOnStart: true
running: true
// CaptureSession onTriggered:
// { {
// id: captureSession frame++
// audioInput: audioInput textureImage.source = "image://audiotexture/frame" + frame
// } }
}
// Timer Component.onCompleted:
// { {
// interval: 16 // ~60fps update Komplex.AudioModel.startCapture()
// running: true }
// repeat: true }
// onTriggered: }
// {
// // Get audio levels and update texture
// // let buffer = audioInput.probe.audioBuffer()
// // if (buffer)
// // {
// // for (let i = 0; i < Math.min(buffer.length, 512); i++) {
// // audioData[i] = Math.abs(buffer[i])
// // }
// // audioTexture.update()
// // }
// }
// }
// ShaderEffectSource
// {
// id: audioTexture
// width: 512
// height: 1
// format: ShaderEffectSource.Alpha
// smooth: false
// hideSource: true
// sourceItem: Row
// {
// Repeater
// {
// model: 512
// Rectangle
// {
// width: 1
// height: 1
// color: Qt.rgba(1, 1, 1, root.audioData[index])
// }
// }
// }
// }
// Component.onCompleted:
// {
// //captureSession.start()
// }
// }
// }
} }

View File

@@ -88,16 +88,13 @@ Item
{ {
id: selectionModel id: selectionModel
// Commented out Audio channel as it is not implemented yet ListElement
// ListElement {
// { file: true
// file: true name: "Audio"
// name: "Audio" icon: "./icons/audio.svg"
// icon: "qrc:/icons/audio.svg" type: ShaderChannel.Type.AudioChannel
// title: "Select an Audio File" }
// filter: "MP3 Files (*.mp3):WAV Files (*.wav)"
// type: ShaderChannel.Type.AudioChannel
// }
ListElement ListElement
{ {
@@ -271,6 +268,7 @@ Item
RowLayout RowLayout
{ {
visible: window.tmp_type != ShaderChannel.Type.AudioChannel
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
Label Label
@@ -611,6 +609,8 @@ Item
case ShaderChannel.Type.VideoChannel: case ShaderChannel.Type.VideoChannel:
window.currentFolder = window.videoFolder window.currentFolder = window.videoFolder
break; break;
case ShaderChannel.Type.AudioChannel:
break;
} }
// Set the current selection index // Set the current selection index

View File

@@ -5,8 +5,9 @@
#include <QQuickImageProvider> #include <QQuickImageProvider>
#include "AudioModel.h" #include "AudioModel.h"
#include "Komplex_global.h"
class AudioImageProvider : public QQuickImageProvider class KOMPLEX_EXPORT AudioImageProvider : public QQuickImageProvider
{ {
public: public:
explicit AudioImageProvider(); explicit AudioImageProvider();

View File

@@ -120,6 +120,9 @@ AudioModel::~AudioModel()
void AudioModel::startCapture() void AudioModel::startCapture()
{ {
if(!m_instance)
m_instance = new AudioModel();
if(m_thread->isRunning()) if(m_thread->isRunning())
return; return;
@@ -139,6 +142,9 @@ void AudioModel::startCaptureAsync()
QPixmap AudioModel::frame() QPixmap AudioModel::frame()
{ {
if(!m_instance)
return QPixmap();
return m_instance->m_frame; return m_instance->m_frame;
} }
@@ -319,7 +325,8 @@ void AudioModel::on_process(void *userdata)
} }
// Blackman window function // Blackman window function
std::vector<double> AudioModel::createBlackmanWindow(int size) { std::vector<double> AudioModel::createBlackmanWindow(int size)
{
std::vector<double> window(size); std::vector<double> window(size);
const double a0 = 0.42; const double a0 = 0.42;
const double a1 = 0.5; const double a1 = 0.5;

View File

@@ -12,7 +12,7 @@
* https://webaudio.github.io/web-audio-api/#smoothing-over-time * https://webaudio.github.io/web-audio-api/#smoothing-over-time
* *
* The described smoothing method was resulting in inconsistent data. This * The described smoothing method was resulting in inconsistent data. This
* is likely to a poor implementation. A linear smoothing algo seems to work * is likely due to a poor implementation. A linear smoothing algo seems to work
* (at least visually). Will need to revisit the temporal implementation if * (at least visually). Will need to revisit the temporal implementation if
* things do not work as expected. * things do not work as expected.
* *

View File

@@ -7,6 +7,15 @@
#include "ShaderPackModel.h" #include "ShaderPackModel.h"
#include "Komplex_global.h" #include "Komplex_global.h"
AudioModel *komplexAudioSingletonProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
AudioModel *model = new AudioModel();
return model;
}
class KOMPLEX_EXPORT KomplexPlugin : public QQmlExtensionPlugin class KOMPLEX_EXPORT KomplexPlugin : public QQmlExtensionPlugin
{ {
Q_OBJECT Q_OBJECT
@@ -16,7 +25,7 @@ public:
{ {
Q_ASSERT(QLatin1String(uri) == QLatin1String("com.github.digitalartifex.komplex")); Q_ASSERT(QLatin1String(uri) == QLatin1String("com.github.digitalartifex.komplex"));
qmlRegisterType<AudioModel>(uri, 1, 0, "AudioModel"); qmlRegisterSingletonType<AudioModel*>(uri, 1, 0, "AudioModel", komplexAudioSingletonProvider);
qmlRegisterType<ShaderPackModel>(uri, 1, 0, "ShaderPackModel"); qmlRegisterType<ShaderPackModel>(uri, 1, 0, "ShaderPackModel");
} }