@pro-gram/flux 1.6.1 → 1.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -44,7 +44,7 @@ Editor opens by default. File contains New, Open session, Save, Save as and Add
44
44
 
45
45
  The compact header puts navigation beside the logo. Grid and zoom share one toolbar, and playback/output selection share the bottom strip. Export settings and extra range/import options expand when needed, keeping more tracks visible on smaller displays.
46
46
 
47
- The editor supports 16 tracks, multiple audio regions, selected/all-track edits, mute/solo, levels, split, cut/copy/paste, undo/redo, saved `.dbedit` sessions and PCM/float mix export. Original audio stays unchanged.
47
+ The editor supports 16 tracks, multiple audio regions, selected/all-track edits, a live mixer, split, cut/copy/paste, undo/redo, saved `.dbedit` sessions and PCM/float mix export. Original audio stays unchanged.
48
48
 
49
49
  Select audio, press **Ctrl+C**, press **Backspace** to delete that section, place the playhead and press **Ctrl+V**. Deleting preserves the timeline gap and the internal audio clipboard. Delete is also available as an editable alternate; Ctrl+X still cuts. Paste starts exactly at the playhead. The Cut/Copy/Paste toolbar buttons are removed.
50
50
 
@@ -56,13 +56,27 @@ Drag a clip's header to move it; selected groups retain their time/track offsets
56
56
 
57
57
  Moves, trims, slip, clip mute and fades are non-destructive and undoable. Fades affect playback and exported mixes; splitting/copying inside a fade preserves the original envelope. Escape cancels a clip drag. The editor's select/slip/fade modes and all default commands have editable keybindings.
58
58
 
59
+ **Ctrl+Left / Ctrl+Right** moves the playhead to the nearest bar line strictly left/right using the project tempo and time signature. From an exact bar line, it moves to the previous/next bar. Playback continues when jumping within the audio; a paused jump stays silent. **Enter** returns to the beginning, and **Home** remains available. These bindings appear in Settings > Keybinds. Text fields retain their normal editing keys.
60
+
61
+ ### Mixer
62
+
63
+ Open **Mixer** from the editor toolbar or **View > Mixer**. Each of the 16 tracks has a **−60 to +24 dB fader**, numeric gain entry, pan/stereo balance, mute and solo. A pinned master strip provides **−60 to +12 dB gain**, mute and stereo output metering. Changes take effect while playback continues, support undo/redo, save with the session and apply to exported mixes. Original audio stays unchanged.
64
+
65
+ **File peak** shows the loaded source level independently of mixer gain. Choose **Before fader** to inspect incoming track levels, including muted tracks, or **After fader** to see the adjusted signal. Stereo peak readouts turn red at 0 dBFS and stay latched until cleared. **Monitor** controls listening volume only; it changes neither exports nor mixer readings.
66
+
67
+ During recording, the registered strips show the selected raw input channels. Set capture gain on the input device. The mixer changes playback/export levels after recording; use hardware direct monitoring during capture.
68
+
69
+ Scroll across the tracks while the master remains visible. Resize the panel, choose Side/Bottom, or collapse it to recover timeline space.
70
+
59
71
  ### Editor zoom
60
72
 
61
73
  The visible **- / + buttons and slider** zoom the timeline from a full-project overview to individual samples. **Ctrl+mouse wheel** zooms around the time under the pointer; **Shift+wheel** scrolls sideways. **Fit** shows the full project, and **Selection** fills the pane with the selected time range.
62
74
 
63
75
  **Ctrl+Plus / Ctrl+Minus** zoom (including Ctrl+= and numeric-keypad keys), **Ctrl+0** fits the project and **Ctrl+Shift+0** fits the selection. These shortcuts are editable in Settings > Keybinds. At close zoom, waveform detail is read from decoded audio in the background, preserving positive/negative peaks and float headroom. The ruler displays fractional seconds when a close-up contains no labeled beat. Zoom changes the view without changing audio, the playhead or undo history.
64
76
 
65
- Record options contains microphone/input channels, sample rate and PCM/float format. Recording saves original takes and inserts them at the starting playhead on the selected track; separate input channels use consecutive tracks. Use hardware direct monitoring. Software overdub latency alignment is not included.
77
+ Record options contains microphone/input channels, sample rate and PCM/float format. **Record** or **R** reserves the selected track (consecutive tracks for separate input files) and shows a one-bar countdown at the project tempo and time signature. The countdown displays the destination tracks and selected input. Press Record again, Stop, or Escape to cancel it before capture starts.
78
+
79
+ After the final beat, capture starts through the selected input. A red playhead, growing recording highlights and elapsed timer follow the audio actually received. **Stop & save** preserves the original take and inserts it at the registered starting point; the playhead stays at the end of the take. Bar lines display **1, 2, 3**; detailed beat labels remain available when zoomed in. Use hardware direct monitoring. Software overdub latency alignment is not included.
66
80
 
67
81
  Recording controls, converter output settings and Media Player gain have draggable dividers, Collapse/Show and Side/Bottom positioning.
68
82
 
@@ -118,7 +132,8 @@ The Zoom R16 conversion preset writes classic 44.1 kHz 16/24-bit PCM WAV with sh
118
132
  | Save / save as | Ctrl+S / Ctrl+Shift+S |
119
133
  | Open / new session | Ctrl+O / Ctrl+N |
120
134
  | Import / export | Ctrl+I / Ctrl+E |
121
- | Start / end | Home / End |
135
+ | Start / end | Enter or Home / End |
136
+ | Previous / next bar | Ctrl+Left / Ctrl+Right |
122
137
  | Zoom in / out | Ctrl+= / Ctrl+- |
123
138
  | Fit project / selection | Ctrl+0 / Ctrl+Shift+0 |
124
139
  | Home / Editor / Converter / Player | Ctrl+1 / Ctrl+2 / Ctrl+3 / Ctrl+4 |
package/bin/flux.js CHANGED
@@ -10,7 +10,7 @@ const { needsUpdate } = require('../scripts/version.js');
10
10
  const arg = process.argv[2];
11
11
  if (arg === '--version' || arg === '-v') { console.log(pkg.version); return; }
12
12
  if (arg === '--help' || arg === '-h') {
13
- console.log('Flux ' + pkg.version + ' for Windows\n\nflux Open Flux\nflux --setup Install or repair Flux\nflux --audio-diagnostics Save an audio device report\nflux --version Show the npm package version\n\nAudio: H5studio native 32-bit float recording; 16/24-bit PCM recording and export.\nWindows/Realtek/USB microphones use 16-bit PCM input.\nWorkspaces: PCM/float Media Player and 16-track timeline Editor with recording.\nTempo grid: BPM, time signatures, 1/1 to 1/256 subdivisions, triplets and independent grid/edge snapping.\nCtrl+C copies; Backspace deletes selection; Ctrl+V pastes at the playhead.\nDark/light themes, Converter and editable keybind settings.\nUpdate: close Flux, then npm.cmd install -g @pro-gram/flux@latest\nRun flux.cmd afterward to finish setup if npm skipped the install script.'); return;
13
+ console.log('Flux ' + pkg.version + ' for Windows\n\nflux Open Flux\nflux --setup Install or repair Flux\nflux --audio-diagnostics Save an audio device report\nflux --version Show the npm package version\n\nAudio: H5studio native 32-bit float recording; 16/24-bit PCM recording and export.\nWindows/Realtek/USB microphones use 16-bit PCM input.\nWorkspaces: PCM/float Media Player and 16-track timeline Editor with recording.\nRecording: one-bar visual count-in, reserved input tracks and a moving recording playhead.\nTempo grid: BPM, time signatures, 1/1 to 1/256 subdivisions, triplets and independent grid/edge snapping.\nCtrl+C copies; Backspace deletes selection; Ctrl+V pastes at the playhead.\nDark/light themes, Converter and editable keybind settings.\nUpdate: close Flux, then npm.cmd install -g @pro-gram/flux@latest\nRun flux.cmd afterward to finish setup if npm skipped the install script.'); return;
14
14
  }
15
15
  if (process.platform !== 'win32' || process.arch !== 'x64') throw new Error('Flux needs Windows x64.');
16
16
  const root = installRoot();
package/dependencies.json CHANGED
@@ -1,15 +1,15 @@
1
- {
2
- "ffmpeg": {
3
- "url": "https://www.gyan.dev/ffmpeg/builds/packages/ffmpeg-9.0.2-essentials_build.zip",
4
- "file": "ffmpeg-9.0.2.zip",
5
- "sha256": "60f467265b1e312373dbcd92200c2618a74850f98d3d078e94296bb3fa2047ba"
6
- },
7
- "panel": {
8
- "url": "https://zoomcorp.com/media/original_images/R16_list_0.png",
9
- "file": "r16-panel.png",
10
- "sha256": "315a71e8942a445c903b2d1aedb703b64aab30f054e46199a2bac447d3d03cb2",
11
- "alternateSha256": "5564fa622f101dc27ea402c399c5b9b1e1e039b8771daf40b185dab9772adf38"
12
- },
13
- "installerSha256": "3d36d86c4bc3e83276811a59778c2fc0e3fe7368dcb6b0ecbc7658ea99220929",
14
- "bundledAssets": true
15
- }
1
+ {
2
+ "ffmpeg": {
3
+ "url": "https://www.gyan.dev/ffmpeg/builds/packages/ffmpeg-9.0.2-essentials_build.zip",
4
+ "file": "ffmpeg-9.0.2.zip",
5
+ "sha256": "60f467265b1e312373dbcd92200c2618a74850f98d3d078e94296bb3fa2047ba"
6
+ },
7
+ "panel": {
8
+ "url": "https://zoomcorp.com/media/original_images/R16_list_0.png",
9
+ "file": "r16-panel.png",
10
+ "sha256": "315a71e8942a445c903b2d1aedb703b64aab30f054e46199a2bac447d3d03cb2",
11
+ "alternateSha256": "5564fa622f101dc27ea402c399c5b9b1e1e039b8771daf40b185dab9772adf38"
12
+ },
13
+ "installerSha256": "c30e7d28feca44ba1116d70e2cd1a66443b5fbf2296d3a800ec59320d75c0a77",
14
+ "bundledAssets": true
15
+ }
package/package.json CHANGED
@@ -1,60 +1,61 @@
1
- {
2
- "name": "@pro-gram/flux",
3
- "version": "1.6.1",
4
- "description": "Flux: a 16-track Windows audio studio with native shared playback, float/PCM recording, clip editing tools, tempo grids and bundled audio codecs.",
5
- "license": "MIT",
6
- "author": "pro-gram",
7
- "os": [
8
- "win32"
9
- ],
10
- "cpu": [
11
- "x64"
12
- ],
13
- "engines": {
14
- "node": ">=18"
15
- },
16
- "bin": {
17
- "flux": "bin/flux.js"
18
- },
19
- "scripts": {
20
- "postinstall": "echo If npm skips setup, run flux --setup && node scripts/install.js",
21
- "test": "node --test test/*.test.js"
22
- },
23
- "files": [
24
- "bin/flux.js",
25
- "scripts/",
26
- "test/",
27
- "payload/DrumBuddy-Setup.exe",
28
- "dependencies.json",
29
- "source/",
30
- "LICENSE",
31
- "NOTICE.txt"
32
- ],
33
- "keywords": [
34
- "audio-editor",
35
- "media-player",
36
- "multitrack",
37
- "zoom-h5studio",
38
- "32-bit-float",
39
- "pcm",
40
- "zoom-r16",
41
- "drums",
42
- "audio",
43
- "midi",
44
- "wav",
45
- "windows",
46
- "recording",
47
- "fluxtempo",
48
- "realtek",
49
- "audio-workstation",
50
- "flux",
51
- "tempo-grid",
52
- "beat-grid",
53
- "snap-to-grid"
54
- ],
55
- "publishConfig": {
56
- "access": "public",
57
- "registry": "https://registry.npmjs.org/"
58
- },
59
- "homepage": "https://fluxtempo.ca"
60
- }
1
+ {
2
+ "name": "@pro-gram/flux",
3
+ "version": "1.6.4",
4
+ "description": "Flux: a 16-track Windows audio studio with a live mixer, float/PCM recording, clip editing, tempo grids and bundled audio codecs.",
5
+ "license": "MIT",
6
+ "author": "pro-gram",
7
+ "os": [
8
+ "win32"
9
+ ],
10
+ "cpu": [
11
+ "x64"
12
+ ],
13
+ "engines": {
14
+ "node": ">=18"
15
+ },
16
+ "bin": {
17
+ "flux": "bin/flux.js"
18
+ },
19
+ "scripts": {
20
+ "postinstall": "echo If npm skips setup, run flux --setup && node scripts/install.js",
21
+ "test": "node --test test/*.test.js"
22
+ },
23
+ "files": [
24
+ "bin/flux.js",
25
+ "scripts/",
26
+ "test/",
27
+ "payload/DrumBuddy-Setup.exe",
28
+ "dependencies.json",
29
+ "source/",
30
+ "LICENSE",
31
+ "NOTICE.txt"
32
+ ],
33
+ "keywords": [
34
+ "audio-editor",
35
+ "media-player",
36
+ "multitrack",
37
+ "zoom-h5studio",
38
+ "32-bit-float",
39
+ "pcm",
40
+ "zoom-r16",
41
+ "drums",
42
+ "audio",
43
+ "midi",
44
+ "wav",
45
+ "windows",
46
+ "recording",
47
+ "fluxtempo",
48
+ "realtek",
49
+ "audio-workstation",
50
+ "flux",
51
+ "tempo-grid",
52
+ "beat-grid",
53
+ "snap-to-grid",
54
+ "mixer"
55
+ ],
56
+ "publishConfig": {
57
+ "access": "public",
58
+ "registry": "https://registry.npmjs.org/"
59
+ },
60
+ "homepage": "https://fluxtempo.ca"
61
+ }
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/payload/DrumBuddy-Setup.exe
3
- size: 42842624 bytes
4
- sha256: 3d36d86c4bc3e83276811a59778c2fc0e3fe7368dcb6b0ecbc7658ea99220929
3
+ size: 41809920 bytes
4
+ sha256: c30e7d28feca44ba1116d70e2cd1a66443b5fbf2296d3a800ec59320d75c0a77
@@ -21,7 +21,7 @@ namespace DrumBuddySetup
21
21
  if(File.Exists(target) && expected.Contains(Hash(target),StringComparer.OrdinalIgnoreCase))return target;
22
22
  string temporary=target+"."+Guid.NewGuid().ToString("N")+".partial";
23
23
  try {
24
- using(var client=new WebClient()) { client.Headers[HttpRequestHeader.UserAgent]="DrumBuddy/1.6.1";client.DownloadFile(url,temporary); }
24
+ using(var client=new WebClient()) { client.Headers[HttpRequestHeader.UserAgent]="DrumBuddy/1.6.4";client.DownloadFile(url,temporary); }
25
25
  if(!expected.Contains(Hash(temporary),StringComparer.OrdinalIgnoreCase))throw new IOException("A downloaded component failed its integrity check. Please retry setup or obtain a newer Drum Buddy release.");
26
26
  File.Copy(temporary,target,true);return target;
27
27
  }finally { if(File.Exists(temporary))File.Delete(temporary); }
@@ -1,4 +1,4 @@
1
- Flux 1.6.1 bundled FFmpeg audio decoders
1
+ Flux 1.6.4 bundled FFmpeg audio decoders
2
2
  These decode imported files without Windows Media Player codecs.
3
3
 
4
4
  A..... = Audio
package/source/Audio.cs CHANGED
@@ -282,6 +282,7 @@ namespace DrumBuddy
282
282
  private Task writing;
283
283
  private readonly object gate = new object();
284
284
  private bool accepting;
285
+ private Action beginCapture;
285
286
  private int captureChannels, selectedInput, savedChannels;
286
287
  private bool separate, requireFloatInput;
287
288
  private readonly List<IRecordingWriter> writers = new List<IRecordingWriter>();
@@ -300,18 +301,27 @@ namespace DrumBuddy
300
301
 
301
302
  public void Start(InputChoice input, int mode, int bits, string folder, int rate)
302
303
  {
303
- if (input.Driver != null) { Start(input.Driver, mode, bits, folder, rate); return; }
304
+ Prepare(input, mode, bits, folder, rate); BeginCapture();
305
+ }
306
+
307
+ // Prepare drivers on the UI thread before the count-in, without capturing audio
308
+ // or creating a take. ASIO COM objects must stay on this thread.
309
+ public void Prepare(InputChoice input, int mode, int bits, string folder, int rate)
310
+ {
311
+ if (input == null) throw new ArgumentNullException("input");
312
+ if (device != null || windowsInput != null || queue != null || beginCapture != null) throw new InvalidOperationException("This recorder is already prepared.");
313
+ if (input.Driver != null) { PrepareAsio(input.Driver, mode, bits, folder, rate); return; }
304
314
  try {
305
315
  windowsChannels = AudioInputs.Channels(input);
306
316
  var layout = CaptureLayout.Create(windowsChannels, mode);
317
+ captureChannels = layout.Channels;
307
318
  windowsInput = new WaveInEvent { DeviceNumber = AudioInputs.Device(input), WaveFormat = new WaveFormat(rate, 16, windowsChannels), BufferMilliseconds = 50, NumberOfBuffers = 3 };
308
- StartBuffered(layout, bits, folder, rate, false);
309
319
  SourceFormat = "Windows 16-bit PCM"; SourceIsFloat = false;
310
320
  windowsInput.DataAvailable += delegate(object sender, WaveInEventArgs e) { ProcessWindowsPcm(e.Buffer, e.BytesRecorded, windowsChannels); };
311
321
  windowsInput.RecordingStopped += delegate(object sender, StoppedEventArgs e) {
312
322
  lock (gate) { if (accepting && Error == null) Error = e.Exception ?? new IOException("The microphone stopped. Check its connection and Windows microphone permissions."); }
313
323
  };
314
- windowsInput.StartRecording();
324
+ beginCapture = delegate { StartBuffered(layout, bits, folder, rate, false); windowsInput.StartRecording(); };
315
325
  }
316
326
  catch { Stop(); throw; }
317
327
  }
@@ -341,19 +351,30 @@ namespace DrumBuddy
341
351
  }
342
352
 
343
353
  public void Start(string driver, int mode, int bits, string folder, int rate)
354
+ { Start(new InputChoice { Driver = driver, Name = driver }, mode, bits, folder, rate); }
355
+
356
+ public void BeginCapture()
357
+ {
358
+ var start = beginCapture;
359
+ if (start == null) throw new InvalidOperationException("Prepare a recording input before starting capture.");
360
+ beginCapture = null;
361
+ try { start(); } catch { Stop(); throw; }
362
+ }
363
+
364
+ private void PrepareAsio(string driver, int mode, int bits, string folder, int rate)
344
365
  {
345
366
  try {
346
367
  device = new AsioOut(driver);
347
368
  var layout = CaptureLayout.Create(device.DriverInputChannelCount, mode);
369
+ captureChannels = layout.Channels;
348
370
  if (!device.IsSampleRateSupported(rate)) throw new IOException("This device does not support " + rate + " Hz in its current mode. Choose a supported rate, or set the recorder to Audio I/F Only.");
349
371
  device.InputChannelOffset = layout.FirstInput;
350
372
  device.InitRecordAndPlayback(null, layout.Channels, rate);
351
- StartBuffered(layout, bits, folder, rate, bits == 32 && CaptureLayout.IsH5studio(driver));
352
373
  device.AudioAvailable += Captured;
353
374
  device.PlaybackStopped += delegate(object sender, StoppedEventArgs e) {
354
375
  lock (gate) { if (accepting && Error == null) Error = e.Exception ?? new IOException("The recording device stopped sending audio. Check its USB connection."); }
355
376
  };
356
- device.Play();
377
+ beginCapture = delegate { StartBuffered(layout, bits, folder, rate, bits == 32 && CaptureLayout.IsH5studio(driver)); device.Play(); };
357
378
  }
358
379
  catch { Stop(); throw; }
359
380
  }
@@ -427,6 +448,7 @@ namespace DrumBuddy
427
448
  // Call on the UI thread: ASIO COM objects have thread affinity.
428
449
  public void Stop()
429
450
  {
451
+ beginCapture = null;
430
452
  lock (gate) accepting = false;
431
453
  if (windowsInput != null) {
432
454
  try { windowsInput.StopRecording(); } catch (Exception ex) { if (Error == null) Error = ex; }
@@ -1,4 +1,4 @@
1
- FLUX SOURCE (DRUM BUDDY COMPATIBLE UPDATE)
1
+ FLUX SOURCE
2
2
 
3
3
  Build on Windows 10/11 x64 with .NET Framework 4.8.
4
4
  No Visual Studio or .NET SDK is required: Build.ps1 uses the C# compiler
@@ -18,6 +18,8 @@ Verification:
18
18
  DrumBuddy.exe --tools-self-test "C:\path\to\new-tool-test-folder"
19
19
  DrumBuddy.exe --workspace-self-test "C:\path\to\new-editor-test-folder"
20
20
  DrumBuddy.exe --float-self-test "C:\path\to\new-float-test-folder"
21
+ DrumBuddy.exe --mixer-self-test "C:\path\to\new-mixer-test-folder"
22
+ DrumBuddy.exe --recording-self-test "C:\path\to\new-recording-test-folder"
21
23
  DrumBuddy.exe --output-self-test "C:\path\to\new-output-test-folder"
22
24
  DrumBuddy.exe --editor-playback-self-test "C:\path\to\new-playback-test-folder"
23
25
  DrumBuddy.exe --interface-self-test "C:\path\to\new-interface-test-folder"
@@ -40,6 +42,12 @@ exposed. The output suite queries microphone formats without opening capture.
40
42
  The editor-playback suite imports float/PCM files and exercises the actual
41
43
  editor transport with muted listening, plus native pause/resume/drain checks.
42
44
  Windows microphone buffer tests cover routing, saved samples and queue draining.
45
+ The recording suite covers count-in timing/cancellation, frozen input and track
46
+ routing, captured-frame playhead progress, recording visuals, take insertion
47
+ and preserved originals using generated input buffers.
48
+ The mixer suite checks live track/master gain, pan, mute/solo, source/output
49
+ meters, session compatibility, undo, exported levels and dark/light layouts.
50
+ It exercises native playback with the monitor volume at zero.
43
51
  The interface suite checks keybind capture, saved/unsaved settings, theme
44
52
  switching, integrated recording insertion and dark/light/compact layouts.
45
53
  The general-conversion suite checks original-rate float/PCM WAV, FLAC,
package/source/Build.ps1 CHANGED
@@ -100,6 +100,8 @@ $appArgs += Join-Path $PSScriptRoot 'EditorSelectionTests.cs'
100
100
  $appArgs += @('EditorTools.cs','EditorToolInteractions.cs') | ForEach-Object { Join-Path $PSScriptRoot $_ }
101
101
  $appArgs += Join-Path $PSScriptRoot 'EditorToolsTests.cs'
102
102
  $appArgs += Join-Path $PSScriptRoot 'EditorCompactLayout.cs'
103
+ $appArgs += @('RecordingSession.cs','EditorRecording.cs','RecordingTests.cs') | ForEach-Object { Join-Path $PSScriptRoot $_ }
104
+ $appArgs += @('TimelineMixer.cs','EditorMixer.cs','EditorMixerTests.cs') | ForEach-Object { Join-Path $PSScriptRoot $_ }
103
105
  & $compiler @appArgs
104
106
  if ($LASTEXITCODE -ne 0) { throw 'App compilation failed.' }
105
107
  $iconVersion = [Reflection.AssemblyName]::GetAssemblyName((Join-Path $package 'DrumBuddy.exe')).Version.ToString(3)
@@ -119,7 +121,11 @@ if (Test-Path -LiteralPath $payload) { Remove-Item -LiteralPath $payload }
119
121
  [IO.Compression.ZipFile]::CreateFromDirectory($package,$payload,[IO.Compression.CompressionLevel]::Optimal,$false)
120
122
  $manifest = Get-ChildItem -LiteralPath $package -Recurse -File | ForEach-Object {
121
123
  $relative = $_.FullName.Substring($package.Length + 1).Replace('\','/')
122
- (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash + ' ' + $relative
124
+ $payloadStream = [IO.File]::OpenRead($_.FullName)
125
+ $payloadHasher = [Security.Cryptography.SHA256]::Create()
126
+ try { $payloadHash = [BitConverter]::ToString($payloadHasher.ComputeHash($payloadStream)).Replace('-','') }
127
+ finally { $payloadStream.Dispose(); $payloadHasher.Dispose() }
128
+ $payloadHash + ' ' + $relative
123
129
  }
124
130
  $manifestPath = Join-Path $BuildFolder 'payload.sha256'
125
131
  [IO.File]::WriteAllLines($manifestPath,[string[]]$manifest,(New-Object Text.UTF8Encoding($false)))
@@ -26,7 +26,7 @@ namespace DrumBuddy
26
26
  play.MinWidth = 52;
27
27
  foreach (var button in transport.Children.OfType<Button>()) { button.FontSize = 12; button.MinHeight = 26; button.Padding = new Thickness(6, 2, 6, 2); button.Margin = new Thickness(0, 0, 4, 4); }
28
28
  positionText.FontSize = 12; positionText.Margin = new Thickness(3, 0, 9, 4); volume.Width = 80; volume.Margin = new Thickness(0, 0, 8, 4);
29
- foreach (var text in transport.Children.OfType<TextBlock>().Where(t => t != positionText)) { text.FontSize = 12; if (text.Text.StartsWith("Listen")) text.Text = "Volume "; }
29
+ foreach (var text in transport.Children.OfType<TextBlock>().Where(t => t != positionText)) { text.FontSize = 12; if (text.Text.StartsWith("Monitor")) text.Text = "Monitor "; }
30
30
  bottom.Children.Remove(outputPicker); outputPicker.UseCompactLayout(); transport.Children.Add(outputPicker);
31
31
  selectionText.FontSize = 11; selectionText.MaxWidth = 220; selectionText.Margin = new Thickness(5, 0, 0, 4); transport.Children.Add(selectionText);
32
32
  foreach (var control in exports.Children.OfType<Control>()) { control.FontSize = 12; control.MinHeight = 26; control.Margin = new Thickness(0, 0, 8, 3); }