preliminary implementation of Multi-Track Mapping dialog for Waveform Audio editor

This commit is contained in:
Michael Becker 2022-02-07 13:14:33 -05:00
parent 9bfb038efd
commit 58418b635b
No known key found for this signature in database
GPG Key ID: 98C333A81F18C22C
6 changed files with 564 additions and 2 deletions

View File

@ -2,7 +2,13 @@
<Editors>
<Editor ID="{0EE62532-88BF-4A4A-9DA3-43E79F015DF1}" TypeName="UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Audio.Waveform.WaveformAudioEditor">
<Commands>
<Command ID="WaveformAudioEditor_Tools_MultiTrackMapping" Title="Multi-Track _Mapping" />
<Command ID="Tools">
<Items>
<CommandReference InsertBefore="ToolsCustomize" CommandID="WaveformAudioEditor_Tools_MultiTrackMapping" />
<Separator />
</Items>
</Command>
</Commands>
</Editor>
</Editors>

View File

@ -0,0 +1,272 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkAdjustment" id="adjChannelCount">
<property name="lower">1</property>
<property name="upper">256</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
<object class="GtkListStore" id="tmChannelPresets">
<columns>
<!-- column-name colChannelPresetName -->
<column type="gchararray"/>
<!-- column-name colChannelPresetChannelCount -->
<column type="gint"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">Mono</col>
<col id="1">1</col>
</row>
<row>
<col id="0" translatable="yes">Stereo</col>
<col id="1">2</col>
</row>
<row>
<col id="0" translatable="yes">5.1 Surround Sound</col>
<col id="1">6</col>
</row>
<row>
<col id="0" translatable="yes">7.1 Surround Sound</col>
<col id="1">8</col>
</row>
<row>
<col id="0" translatable="yes">Dolby Atmos Basic</col>
<col id="1">10</col>
</row>
<row>
<col id="0" translatable="yes">Dolby Atmos Full</col>
<col id="1">128</col>
</row>
</data>
</object>
<object class="GtkTreeStore" id="tmChannels">
<columns>
<!-- column-name colTrackName -->
<column type="gchararray"/>
<!-- column-name colChannel -->
<column type="gchararray"/>
<!-- column-name colColor -->
<column type="GdkPixbuf"/>
</columns>
</object>
<object class="GtkDialog">
<property name="can-focus">False</property>
<property name="title" translatable="yes">Multi-Track Mapping</property>
<property name="default-width">500</property>
<property name="default-height">400</property>
<property name="type-hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="cmdExport">
<property name="label">gtk-ok</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="use-stock">True</property>
<style>
<class name="suggested-action"/>
</style>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="cmdCancel">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="use-stock">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<!-- n-columns=2 n-rows=3 -->
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-start">16</property>
<property name="margin-end">16</property>
<property name="margin-top">16</property>
<property name="margin-bottom">16</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-end">8</property>
<property name="label" translatable="yes">Preset</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="cboChannelPresets">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-start">8</property>
<property name="margin-end">8</property>
<property name="margin-top">8</property>
<property name="margin-bottom">8</property>
<property name="hexpand">True</property>
<property name="model">tmChannelPresets</property>
<property name="active">1</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
<child>
<object class="GtkCellRendererText">
<property name="text">(</property>
</object>
</child>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
<child>
<object class="GtkCellRendererText">
<property name="text"> channels)</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="shadow-type">in</property>
<child>
<object class="GtkTreeView" id="lvChannels">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="model">tmChannels</property>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="tvcTrackName">
<property name="resizable">True</property>
<property name="title" translatable="yes">Track</property>
<property name="clickable">True</property>
<property name="reorderable">True</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="tvcChannel">
<property name="resizable">True</property>
<property name="title" translatable="yes">Channel</property>
<property name="clickable">True</property>
<property name="reorderable">True</property>
<child>
<object class="GtkCellRendererPixbuf">
<property name="width">96</property>
</object>
<attributes>
<attribute name="pixbuf">2</attribute>
</attributes>
</child>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="lblChannelCount">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-end">8</property>
<property name="label" translatable="yes">Number of channels</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="txtChannelCount">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="margin-start">8</property>
<property name="margin-end">8</property>
<property name="margin-top">8</property>
<property name="margin-bottom">8</property>
<property name="adjustment">adjChannelCount</property>
<property name="value">2</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-5">cmdExport</action-widget>
<action-widget response="-6">cmdCancel</action-widget>
</action-widgets>
</object>
</interface>

View File

@ -0,0 +1,67 @@
<UniversalEditor Version="5.0">
<Editors>
<Editor ID="{0EE62532-88BF-4A4A-9DA3-43E79F015DF1}" TypeName="UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Audio.Waveform.WaveformAudioEditor">
<MultiTrackMapping>
<ChannelPresets>
<ChannelPreset Title="Mono">
<Channels>
<Channel ID="{f455d884-47b2-4d6a-9fa4-8396cbf6d98f}" Index="0" Title="Mono" Color="#ffffff" />
</Channels>
</ChannelPreset>
<ChannelPreset Title="Stereo">
<Channels>
<Channel ID="{f455d884-47b2-4d6a-9fa4-8396cbf6d98f}" Title="Front left" Color="#ffffff" />
<Channel ID="{8acdf52d-a1c6-44ab-8075-fe4ce3d230b9}" Title="Front right" Color="#ff0000" />
</Channels>
</ChannelPreset>
<ChannelPreset Title="Stereo + Center Channel">
<Channels>
<Channel ID="{f455d884-47b2-4d6a-9fa4-8396cbf6d98f}" Title="Front left" Color="#ffffff" />
<Channel ID="{8acdf52d-a1c6-44ab-8075-fe4ce3d230b9}" Title="Front right" Color="#ff0000" />
<Channel ID="{4c7e2beb-594a-4a7c-8cb7-08917d978de4}" Title="Center" Color="#00ff00" />
</Channels>
</ChannelPreset>
<ChannelPreset Title="5.1 Surround Sound">
<Channels>
<Channel ID="{f455d884-47b2-4d6a-9fa4-8396cbf6d98f}" Title="Front left" Color="#ffffff" />
<Channel ID="{8acdf52d-a1c6-44ab-8075-fe4ce3d230b9}" Title="Front right" Color="#ff0000" />
<Channel ID="{4c7e2beb-594a-4a7c-8cb7-08917d978de4}" Title="Center" Color="#00ff00" />
<Channel ID="{a3fd5a4a-dedb-4d22-9811-542c899e8f5a}" Title="Subwoofer" Color="#cc00cc" />
<Channel ID="{f916a814-c431-4ff0-a10d-036210ce4d4d}" Title="Rear left" Color="#8b4513" />
<Channel ID="{b185f3cd-4211-4e3a-908c-ef12f00f854e}" Title="Rear right" Color="#c3b091" />
</Channels>
</ChannelPreset>
<ChannelPreset Title="7.1 Surround Sound">
<Channels>
<Channel ID="{f455d884-47b2-4d6a-9fa4-8396cbf6d98f}" Title="Front left" Color="#ffffff" />
<Channel ID="{8acdf52d-a1c6-44ab-8075-fe4ce3d230b9}" Title="Front right" Color="#ff0000" />
<Channel ID="{4c7e2beb-594a-4a7c-8cb7-08917d978de4}" Title="Center" Color="#00ff00" />
<Channel ID="{a3fd5a4a-dedb-4d22-9811-542c899e8f5a}" Title="Subwoofer" Color="#cc00cc" />
<Channel ID="{4d97045c-981a-4a34-a4d9-602cf5d905e7}" Title="Side left" Color="#0000cc" />
<Channel ID="{81721e05-2ebb-4bd7-94a7-3c7ac9a6cffc}" Title="Side right" Color="#cccccc" />
<Channel ID="{f916a814-c431-4ff0-a10d-036210ce4d4d}" Title="Rear left" Color="#8b4513" />
<Channel ID="{b185f3cd-4211-4e3a-908c-ef12f00f854e}" Title="Rear right" Color="#c3b091" />
</Channels>
</ChannelPreset>
<ChannelPreset Title="11.1 Surround Sound + Height Channels">
<Channels>
<Channel ID="{f455d884-47b2-4d6a-9fa4-8396cbf6d98f}" Title="Front left" Color="#ffffff" />
<Channel ID="{8acdf52d-a1c6-44ab-8075-fe4ce3d230b9}" Title="Front right" Color="#ff0000" />
<Channel ID="{4c7e2beb-594a-4a7c-8cb7-08917d978de4}" Title="Center" Color="#00ff00" />
<Channel ID="{a3fd5a4a-dedb-4d22-9811-542c899e8f5a}" Title="Subwoofer" Color="#cc00cc" />
<Channel ID="{4d97045c-981a-4a34-a4d9-602cf5d905e7}" Title="Side left" Color="#0000cc" />
<Channel ID="{81721e05-2ebb-4bd7-94a7-3c7ac9a6cffc}" Title="Side right" Color="#cccccc" />
<Channel ID="{f916a814-c431-4ff0-a10d-036210ce4d4d}" Title="Rear left" Color="#8b4513" />
<Channel ID="{b185f3cd-4211-4e3a-908c-ef12f00f854e}" Title="Rear right" Color="#c3b091" />
<Channel ID="{478737ed-b218-4846-8a2f-84a5fad301b4}" Title="Left height 1" Color="#ffff00" />
<Channel ID="{478737ed-b218-4846-8a2f-84a5fad301b4}" Title="Right height 1" Color="#ffa500" />
<Channel ID="{478737ed-b218-4846-8a2f-84a5fad301b4}" Title="Left height 2" Color="#ffc0cb" />
<Channel ID="{478737ed-b218-4846-8a2f-84a5fad301b4}" Title="Right height 2" Color="#ff00ff" />
</Channels>
</ChannelPreset>
</ChannelPresets>
</MultiTrackMapping>
</Editor>
</Editors>
</UniversalEditor>

View File

@ -0,0 +1,200 @@
//
// MultiTrackMappingDialog.cs
//
// Author:
// Michael Becker <alcexhim@gmail.com>
//
// Copyright (c) 2022 Mike Becker's Software
//
// 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 3 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. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.Linq;
using MBS.Framework.UserInterface;
using MBS.Framework.UserInterface.Controls;
using MBS.Framework.UserInterface.Controls.ListView;
using UniversalEditor.ObjectModels.Markup;
using UniversalEditor.UserInterface;
namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Audio.Waveform.Dialogs
{
[ContainerLayout("~/Editors/Multimedia/Audio/Waveform/Dialogs/MultiTrackMappingDialog.glade")]
public class MultiTrackMappingDialog : CustomDialog
{
private ComboBox cboChannelPresets;
private ListViewControl lvChannels;
private NumericTextBox txtChannelCount;
private Label lblChannelCount;
private string[][] knownChannelNames = new string[][]
{
new string[] { "Mono" },
new string[] { "Left", "Right" },
new string[] { "Front left", "Front right", "Center", "Rear left", "Rear right" },
new string[] { "Front left", "Front right", "Center", "Rear left", "Rear right" }
};
public Editor Editor { get; internal set; } = null;
private class MultiTrackMappingChannelPreset
{
public string Title { get; }
public List<MultiTrackMappingChannel> Channels { get; } = new List<MultiTrackMappingChannel>();
public MultiTrackMappingChannelPreset(string title, IEnumerable<MultiTrackMappingChannel> list)
{
Title = title;
Channels.AddRange(list);
}
}
private class MultiTrackMappingChannel
{
public Guid ID { get; } = Guid.Empty;
public string Title { get; } = null;
public MBS.Framework.Drawing.Color Color { get; set; } = MBS.Framework.Drawing.Color.Empty;
public MultiTrackMappingChannel(Guid id, string title)
{
ID = id;
Title = title;
}
}
private List<MultiTrackMappingChannelPreset> channelPresets = new List<MultiTrackMappingChannelPreset>();
private TreeModelRow rowCustom = null;
protected override void OnCreated(EventArgs e)
{
base.OnCreated(e);
((DefaultTreeModel)cboChannelPresets.Model).Rows.Clear();
EditorReference _er = Editor?.MakeReference();
if (_er != null)
{
if (_er.Configuration.Elements["MultiTrackMapping"] is MarkupTagElement tagMultiTrackMapping)
{
if (tagMultiTrackMapping.Elements["ChannelPresets"] is MarkupTagElement tagChannelPresets)
{
foreach (MarkupTagElement tagChannelPreset in tagChannelPresets.Elements.OfType<MarkupTagElement>())
{
MarkupAttribute attTitle = tagChannelPreset.Attributes["Title"];
string title = attTitle?.Value;
List<MultiTrackMappingChannel> channels = new List<MultiTrackMappingChannel>();
if (tagChannelPreset.Elements["Channels"] is MarkupTagElement tagChannels)
{
foreach (MarkupTagElement tagChannel in tagChannels.Elements.OfType<MarkupTagElement>())
{
MultiTrackMappingChannel channel = new MultiTrackMappingChannel(new Guid(tagChannel.Attributes["ID"].Value), tagChannel.Attributes["Title"].Value);
string colorName = tagChannel.Attributes["Color"]?.Value;
if (colorName != null)
{
channel.Color = MBS.Framework.Drawing.Color.Parse(colorName);
}
channels.Add(channel);
}
}
MultiTrackMappingChannelPreset preset = new MultiTrackMappingChannelPreset(title, channels);
channelPresets.Add(preset);
TreeModelRow row = new TreeModelRow(new TreeModelRowColumn[]
{
new TreeModelRowColumn(cboChannelPresets.Model.Columns[0], title),
new TreeModelRowColumn(cboChannelPresets.Model.Columns[1], channels.Count)
});
row.SetExtraData("preset", preset);
((DefaultTreeModel)cboChannelPresets.Model).Rows.Add(row);
}
}
}
}
rowCustom = new TreeModelRow(new TreeModelRowColumn[]
{
new TreeModelRowColumn(cboChannelPresets.Model.Columns[0], "(custom)")
});
((DefaultTreeModel)cboChannelPresets.Model).Rows.Add(rowCustom);
cboChannelPresets.SelectedItem = rowCustom;
}
[EventHandler(nameof(cboChannelPresets), nameof(ComboBox.Changed))]
private void cboChannelPresets_Changed(object sender, EventArgs e)
{
inhibitChannelChange = true;
MultiTrackMappingChannelPreset preset = cboChannelPresets.SelectedItem?.GetExtraData<MultiTrackMappingChannelPreset>("preset");
if (preset != null)
{
lblChannelCount.Visible = false;
txtChannelCount.Visible = false;
txtChannelCount.Value = preset.Channels.Count;
}
else
{
lblChannelCount.Visible = true;
txtChannelCount.Visible = true;
}
inhibitChannelChange = false;
UpdateChannels();
}
private bool inhibitChannelChange = false;
[EventHandler(nameof(txtChannelCount), nameof(NumericTextBox.Changed))]
private void txtChannelCount_Changed(object sender, EventArgs e)
{
if (!inhibitChannelChange)
{
cboChannelPresets.SelectedItem = rowCustom;
}
UpdateChannels();
}
private void UpdateChannels()
{
MultiTrackMappingChannelPreset preset = cboChannelPresets.SelectedItem?.GetExtraData<MultiTrackMappingChannelPreset>("preset");
lvChannels.Model.Rows.Clear();
for (int i = 0; i < txtChannelCount.Value; i++)
{
string channelName = String.Format("Channel {0}", (i + 1));
if (preset != null)
{
channelName = preset.Channels[i].Title;
}
MBS.Framework.UserInterface.Drawing.Image channelColorImage = null;
if (preset != null)
{
channelColorImage = MBS.Framework.UserInterface.Drawing.Image.Create(24, 24);
MBS.Framework.UserInterface.Drawing.Graphics g = MBS.Framework.UserInterface.Drawing.Graphics.FromImage(channelColorImage);
g.Clear(preset.Channels[i].Color);
}
TreeModelRow row = new TreeModelRow(new TreeModelRowColumn[]
{
new TreeModelRowColumn(lvChannels.Model.Columns[0], String.Format("Track {0}", (i + 1))),
new TreeModelRowColumn(lvChannels.Model.Columns[1], channelName),
new TreeModelRowColumn(lvChannels.Model.Columns[2], channelColorImage)
});
lvChannels.Model.Rows.Add(row);
}
}
}
}

View File

@ -24,8 +24,11 @@ using MBS.Audio;
using MBS.Audio.PortAudio;
using MBS.Framework.UserInterface;
using MBS.Framework.UserInterface.Layouts;
using UniversalEditor.ObjectModels.Multimedia.Audio.Waveform;
using UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Audio.Waveform.Controls;
using UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Audio.Waveform.Dialogs;
using UniversalEditor.UserInterface;
namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Audio.Waveform
@ -48,6 +51,18 @@ namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Au
public WaveformAudioEditor()
{
Layout = new BoxLayout(Orientation.Vertical);
Context.AttachCommandEventHandler("WaveformAudioEditor_Tools_MultiTrackMapping", WaveformAudioEditor_Tools_MultiTrackMapping);
}
private void WaveformAudioEditor_Tools_MultiTrackMapping(object sender, EventArgs e)
{
MultiTrackMappingDialog dlg = new MultiTrackMappingDialog();
dlg.Editor = this;
if (dlg.ShowDialog() == DialogResult.OK)
{
}
}
protected override void OnObjectModelChanged(EventArgs e)
@ -82,7 +97,7 @@ namespace UniversalEditor.Plugins.Multimedia.UserInterface.Editors.Multimedia.Au
// get the setting "Editors -> Audio -> Waveform -> Synchronize with JACK transport
AudioPlayer player = new AudioPlayer();
player.Play(wave);
return /*true*/;
}

View File

@ -62,6 +62,7 @@
<Compile Include="Editors\Multimedia\Palette\Dialogs\CalculateNeighboringColorsDialog.cs" />
<Compile Include="Plugins\Transport\TransportPlugin.cs" />
<Compile Include="Editors\Multimedia\InstrumentDefinition\InstrumentDefinitionEditor.cs" />
<Compile Include="Editors\Multimedia\Audio\Waveform\Dialogs\MultiTrackMappingDialog.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Editors\" />
@ -88,6 +89,7 @@
<Folder Include="Plugins\" />
<Folder Include="Plugins\Transport\" />
<Folder Include="Editors\Multimedia\InstrumentDefinition\" />
<Folder Include="Editors\Multimedia\Audio\Waveform\Dialogs\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Libraries\UniversalEditor.Core\UniversalEditor.Core.csproj">