@pro-gram/flux 0.0.0-stage → 1.6.0
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/LICENSE +23 -0
- package/NOTICE.txt +33 -0
- package/README.md +125 -2
- package/bin/flux.js +29 -0
- package/dependencies.json +15 -0
- package/package.json +60 -6
- package/payload/DrumBuddy-Setup.exe +4 -0
- package/scripts/install.js +60 -0
- package/scripts/version.js +12 -0
- package/source/AssetBootstrap.cs +49 -0
- package/source/Audio Decoders.txt +230 -0
- package/source/Audio.cs +453 -0
- package/source/AudioDeviceSettings.cs +126 -0
- package/source/AudioEndpointWatcher.cs +25 -0
- package/source/AudioInputs.cs +50 -0
- package/source/AudioOutputs.cs +307 -0
- package/source/AudioWorkspace.cs +72 -0
- package/source/BrandArtwork.cs +71 -0
- package/source/Build Instructions.txt +65 -0
- package/source/Build.ps1 +135 -0
- package/source/ControlMode.cs +687 -0
- package/source/ControlTests.cs +88 -0
- package/source/ConversionFormats.cs +59 -0
- package/source/ConversionTests.cs +66 -0
- package/source/DockablePane.cs +95 -0
- package/source/DriverSetup.cs +28 -0
- package/source/EditorCompactLayout.cs +36 -0
- package/source/EditorPlaybackTests.cs +87 -0
- package/source/EditorSelectionTests.cs +73 -0
- package/source/EditorToolInteractions.cs +227 -0
- package/source/EditorTools.cs +78 -0
- package/source/EditorToolsTests.cs +93 -0
- package/source/EditorView.cs +798 -0
- package/source/Fetch-Dependencies.ps1 +15 -0
- package/source/FloatRecording.cs +99 -0
- package/source/FloatRecordingTests.cs +170 -0
- package/source/Flux-Logo.png +0 -0
- package/source/Flux-Mark.svg +49 -0
- package/source/FluxTempo Logo Prompt.txt +3 -0
- package/source/FluxTempo-Mark.svg +49 -0
- package/source/HomeView.cs +32 -0
- package/source/InterfaceSettings.cs +225 -0
- package/source/InterfaceTests.cs +172 -0
- package/source/LICENSE.txt +23 -0
- package/source/Logo Prompt.txt +16 -0
- package/source/Main.cs +787 -0
- package/source/Main.xaml +289 -0
- package/source/MediaPlayerView.cs +274 -0
- package/source/MidiControl.cs +113 -0
- package/source/MidiPerformance.cs +125 -0
- package/source/Mixer.cs +280 -0
- package/source/NativeMemory.cs +165 -0
- package/source/PanelFeedback.cs +75 -0
- package/source/PlaybackTests.cs +141 -0
- package/source/Quick Start.txt +96 -0
- package/source/SelfTest.cs +78 -0
- package/source/SettingsWindow.cs +209 -0
- package/source/Setup.cs +196 -0
- package/source/Setup.xaml +28 -0
- package/source/ShellStyles.xaml +99 -0
- package/source/TempoGrid.cs +95 -0
- package/source/TempoGridTests.cs +108 -0
- package/source/Third Party Notices.txt +33 -0
- package/source/Timeline.cs +268 -0
- package/source/TimelineGestures.cs +57 -0
- package/source/TimelineZoom.cs +21 -0
- package/source/Uninstall.cs +69 -0
- package/source/WaveformDetail.cs +104 -0
- package/source/WindowsAudioPlayer.cs +137 -0
- package/source/WorkspaceTests.cs +202 -0
- package/source/ZoomTests.cs +95 -0
- package/source/app.manifest +7 -0
- package/source/brand-archive/Drum-Buddy-Black-Hair.png +0 -0
- package/source/dependency-lock.json +62 -0
- package/source/fluxtempo-mark.png +0 -0
- package/source/logo.png +0 -0
- package/source/r16-panel.png +0 -0
- package/source/references/R16 Format Research.txt +16 -0
- package/test/package.test.js +55 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Drum Buddy contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
Third-party programs, libraries and the Zoom driver retain their own licenses.
|
package/NOTICE.txt
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Flux 1.6.0 - third-party components
|
|
2
|
+
|
|
3
|
+
FFmpeg 9.0.2, release essentials build by Gyan Doshi
|
|
4
|
+
Used as a separate command-line decoding process.
|
|
5
|
+
GPL version 3. See licenses\FFmpeg-GPLv3.txt and FFmpeg-build.txt.
|
|
6
|
+
Binary: https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip
|
|
7
|
+
Build information and corresponding upstream source links:
|
|
8
|
+
https://www.gyan.dev/ffmpeg/builds/
|
|
9
|
+
https://github.com/FFmpeg/FFmpeg/tree/946fcce07b
|
|
10
|
+
The build README lists linked third-party libraries and their versions.
|
|
11
|
+
|
|
12
|
+
NAudio.Core, NAudio.Asio, NAudio.WinMM, NAudio.Wasapi 2.2.1
|
|
13
|
+
Copyright (c) Mark Heath and contributors. MIT license.
|
|
14
|
+
See licenses\NAudio-MIT.txt.
|
|
15
|
+
Source: https://github.com/naudio/NAudio/tree/v2.2.1
|
|
16
|
+
|
|
17
|
+
Microsoft.Win32.Registry, System.Security.AccessControl,
|
|
18
|
+
System.Security.Principal.Windows 4.7.0
|
|
19
|
+
Copyright (c) .NET Foundation and Contributors. MIT license.
|
|
20
|
+
https://github.com/dotnet/runtime/blob/main/LICENSE.TXT
|
|
21
|
+
|
|
22
|
+
Zoom H5studio and R16/R24 drivers: linked from Zoom's official support pages, not bundled.
|
|
23
|
+
R16 reference panel image: copyright Zoom Corporation. The reference image
|
|
24
|
+
is included from Zoom's public product website; its source URL and SHA-256
|
|
25
|
+
are recorded in dependency-lock.json.
|
|
26
|
+
Zoom and R16 are trademarks of Zoom Corporation. This is an independent app.
|
|
27
|
+
|
|
28
|
+
The original drummer mascot was generated for Drum Buddy using OpenAI's
|
|
29
|
+
built-in image-generation tool, then revised to have long curly black hair.
|
|
30
|
+
|
|
31
|
+
The FluxTempo wave/tempo emblem was generated with OpenAI's built-in
|
|
32
|
+
image-generation tool. The original Drum Buddy mascot is preserved in
|
|
33
|
+
the source archive under brand-archive.
|
package/README.md
CHANGED
|
@@ -1,3 +1,126 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Flux
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Flux is a compact Windows audio studio with a 16-track editor/recorder, a Media Player and a separate file converter. Near-black surfaces, blue/purple accents, editable keybinds and tempo-grid editing.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
Close the running audio application, then:
|
|
8
|
+
|
|
9
|
+
```powershell
|
|
10
|
+
npm.cmd install -g @pro-gram/flux@latest
|
|
11
|
+
flux.cmd
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Windows 10/11 x64 is supported. macOS is planned. Basic tools work locally without an account.
|
|
15
|
+
|
|
16
|
+
### Moving from Drum Buddy / FluxTempo
|
|
17
|
+
|
|
18
|
+
Remove the older npm launcher before installing Flux:
|
|
19
|
+
|
|
20
|
+
```powershell
|
|
21
|
+
npm.cmd uninstall -g @pro-gram/drumbuddy
|
|
22
|
+
npm.cmd install -g @pro-gram/flux@latest
|
|
23
|
+
flux.cmd
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Removing that npm package leaves its separate desktop installation and audio files in place. Flux updates the existing desktop installation and uses its saved folders/settings. The launch command is now `flux.cmd`; older launchers belong to the old npm package and should be removed during migration.
|
|
27
|
+
|
|
28
|
+
If npm skipped the install script, the first launch completes setup. `flux.cmd --setup` repairs the installation. The Windows executable is unsigned. The npm and standalone installers both include FFmpeg and the R16 panel assets, with payload integrity checks. There is no separate codec download during setup. Vendor audio drivers are linked from their official support pages.
|
|
29
|
+
|
|
30
|
+
## Editor and recording
|
|
31
|
+
|
|
32
|
+
Editor opens by default. File contains New, Open session, Save, Save as and Add audio. Home and View open Converter, Media Player and the R16 workspace.
|
|
33
|
+
|
|
34
|
+
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.
|
|
35
|
+
|
|
36
|
+
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.
|
|
37
|
+
|
|
38
|
+
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.
|
|
39
|
+
|
|
40
|
+
**V** selects the pointer tool; **S** splits at the playhead. Click a region to select it; Shift-click adds/removes clips, and dragging selects a time range. Selected clips use a brighter purple fill and border. Drag the upper ruler for the playhead and the lower-ruler selection handles to adjust a range. Range exposes numeric selection controls.
|
|
41
|
+
|
|
42
|
+
Drag a clip's header to move it; selected groups retain their time/track offsets. Drag the left/right edges to trim within the source audio. The waveform body remains available for range selection. **Y** switches to slip editing, which shifts source contents inside a trimmed clip; **F** switches to the fade tool. Selected clips also show fade handles.
|
|
43
|
+
|
|
44
|
+
**Ctrl+D** duplicates selected clips or time; **Ctrl+L** repeats the selection with a chosen number of additional copies. **M** mutes/unmutes selected clips or isolates and mutes a time range. **X** crossfades two staggered, overlapping clips on the same track. Right-click audio for these tools, clipboard actions and Clear fades. The scissors/split toolbar buttons are removed.
|
|
45
|
+
|
|
46
|
+
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.
|
|
47
|
+
|
|
48
|
+
### Editor zoom
|
|
49
|
+
|
|
50
|
+
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.
|
|
51
|
+
|
|
52
|
+
**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.
|
|
53
|
+
|
|
54
|
+
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.
|
|
55
|
+
|
|
56
|
+
Recording controls, converter output settings and Media Player gain have draggable dividers, Collapse/Show and Side/Bottom positioning.
|
|
57
|
+
|
|
58
|
+
## Tempo grid and snapping
|
|
59
|
+
|
|
60
|
+
Use the BPM/division controls in Editor or **Settings > Timeline / grid**. Settings has explicit Save and prompts before leaving with unsaved changes.
|
|
61
|
+
|
|
62
|
+
- Tempo: 20–400 quarter-note BPM, with fractional values.
|
|
63
|
+
- Time signatures: 1–32 beats per bar; beat units from 1/1 through 1/32.
|
|
64
|
+
- Grid divisions: 1/1, 1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128 and 1/256.
|
|
65
|
+
- Straight and triplet subdivisions; bars/beats or seconds ruler.
|
|
66
|
+
- Snap to grid and snap to clip edges can be switched independently.
|
|
67
|
+
- Hold Alt to bypass both for free placement/cuts at the editor's working sample rate.
|
|
68
|
+
|
|
69
|
+
The grid restarts at bar boundaries in odd meters. Nearby clip edges take priority when enabled. Fine grid lines simplify when zoomed out; snapping retains the chosen resolution. Zoom in to see every subdivision. Finer-than-grid edits remain possible with snapping off or Alt held.
|
|
70
|
+
|
|
71
|
+
Tempo changes the grid, without stretching existing audio. Tempo, meter, division and ruler are saved in each project and support undo. Settings also supplies defaults for new sessions. Older projects open with a 120 BPM, 4/4 grid. Custom keybinds are preserved when upgrading defaults.
|
|
72
|
+
|
|
73
|
+
## Audio devices
|
|
74
|
+
|
|
75
|
+
Settings > Audio selects speakers/headphones and recording input. Playback output is shared between Editor and Media Player. Windows default displays the current Windows output and resolves it again when playback starts. Named entries select active Windows endpoints; installed ASIO drivers are listed separately. Device changes refresh the selector automatically. Retired compatibility selections migrate to the corresponding real endpoint.
|
|
76
|
+
|
|
77
|
+
Windows playback uses one shared WASAPI renderer with device activation, initialization, buffering and release on its own audio thread. Audio is resampled/adapted to the endpoint's exact mix format, without an extra Windows automatic converter or WinMM playback fallback. Initialization and runtime errors retain the actual failing stage in diagnostics.
|
|
78
|
+
|
|
79
|
+
Ordinary Windows/Realtek/USB microphones capture 16-bit PCM. Saving that input in a float or 24-bit container adds no input precision or native float headroom. H5studio ASIO preserves native 32-bit float when the Zoom driver supplies it. Install Drivers links to official H5studio/R16 support. R16 ASIO recording remains available.
|
|
80
|
+
|
|
81
|
+
Test speakers plays a short quiet tone. Save diagnostics exports device formats and recent output errors without recording. Playback buffer is adjustable from 40 to 250 ms; actual latency depends on hardware and drivers.
|
|
82
|
+
|
|
83
|
+
## Media Player and Converter
|
|
84
|
+
|
|
85
|
+
Media Player decodes PCM/float WAV, AIFF, FLAC, MP3 and audio from video without Windows Media Player codecs. Gain / Save provides +/-36 dB adjustment, safe level, protection and compact Save copy for PCM or float WAV. Gain affects playback and saved copies; listening volume affects playback only. Copies receive new names instead of overwriting originals or exports.
|
|
86
|
+
|
|
87
|
+
The bundled FFmpeg build contains 227 audio decoders, including integer PCM and IEEE float. Both installation paths include the decoder executable. No Windows Media Player codec pack is required. Protected, damaged or unsupported files can still be rejected; supported decoders are listed in the release's audio-decoder inventory.
|
|
88
|
+
|
|
89
|
+
Open **View > Converter**, drop audio/video, choose the target type and convert. WAV PCM, WAV float, AIFF, FLAC, MP3 and AAC/M4A are supported, including MP3 -> AIFF and AIFF -> WAV. Preserve source rate or choose 44.1/48/96 kHz; MP3 uses at most 48 kHz. Converter contains no gain amplifier or navigation tab.
|
|
90
|
+
|
|
91
|
+
The Zoom R16 conversion preset writes classic 44.1 kHz 16/24-bit PCM WAV with short compatible filenames. R16 Control also retains the hardware panel, mixer/EQ, MIDI control, MIDI recording/playback and native project-copy tools. Verify edited R16 projects on the hardware. Zoom's internal effect DSP is not emulated.
|
|
92
|
+
|
|
93
|
+
## Default shortcuts
|
|
94
|
+
|
|
95
|
+
| Action | Shortcut |
|
|
96
|
+
|---|---|
|
|
97
|
+
| Play/pause; stop active recording | Space |
|
|
98
|
+
| Stop | Shift+Space |
|
|
99
|
+
| Record | R |
|
|
100
|
+
| Split / selection cursor | S / V |
|
|
101
|
+
| Slip / fade tool | Y / F |
|
|
102
|
+
| Duplicate / repeat | Ctrl+D / Ctrl+L |
|
|
103
|
+
| Clip mute / crossfade | M / X |
|
|
104
|
+
| Copy / paste / cut | Ctrl+C / Ctrl+V / Ctrl+X |
|
|
105
|
+
| Delete selected section | Backspace or Delete |
|
|
106
|
+
| Undo / redo | Ctrl+Z / Ctrl+Y |
|
|
107
|
+
| Save / save as | Ctrl+S / Ctrl+Shift+S |
|
|
108
|
+
| Open / new session | Ctrl+O / Ctrl+N |
|
|
109
|
+
| Import / export | Ctrl+I / Ctrl+E |
|
|
110
|
+
| Start / end | Home / End |
|
|
111
|
+
| Zoom in / out | Ctrl+= / Ctrl+- |
|
|
112
|
+
| Fit project / selection | Ctrl+0 / Ctrl+Shift+0 |
|
|
113
|
+
| Home / Editor / Converter / Player | Ctrl+1 / Ctrl+2 / Ctrl+3 / Ctrl+4 |
|
|
114
|
+
| Settings | Ctrl+, |
|
|
115
|
+
|
|
116
|
+
Keybind Edit immediately focuses/selects the capture field. Save commits changes; leaving unsaved prompts Yes/No. Duplicate shortcuts prevent saving. The defaults preserve normal text-field editing.
|
|
117
|
+
|
|
118
|
+
## Notes
|
|
119
|
+
|
|
120
|
+
The editor's working timeline is 44.1 kHz float. Mix exports support 16/24-bit PCM or 32-bit float WAV, with a 4 GB limit. Source-rate conversion reads the original file. Keep original sources alongside saved sessions.
|
|
121
|
+
|
|
122
|
+
The new Flux PNG is used in the app, executable and versioned shortcut icons. A refined SVG alternative and the original black-haired Drum Buddy mascot are preserved in source; the mascot is archived in `source/brand-archive`. Brand website: https://fluxtempo.ca
|
|
123
|
+
|
|
124
|
+
Physical H5studio/R16 capture and audible playback on the affected Realtek PC require connected-device acceptance. Automated tests cover generated samples, native project fixtures, grid math, editing workflows, settings and local silent output probes.
|
|
125
|
+
|
|
126
|
+
Source, build instructions and dependency licence notices are included. Premium authentication/billing is not implemented.
|
package/bin/flux.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { spawn, execFileSync } = require('node:child_process');
|
|
6
|
+
const pkg = require('../package.json');
|
|
7
|
+
const { install, installRoot } = require('../scripts/install.js');
|
|
8
|
+
const { needsUpdate } = require('../scripts/version.js');
|
|
9
|
+
(async () => {
|
|
10
|
+
const arg = process.argv[2];
|
|
11
|
+
if (arg === '--version' || arg === '-v') { console.log(pkg.version); return; }
|
|
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;
|
|
14
|
+
}
|
|
15
|
+
if (process.platform !== 'win32' || process.arch !== 'x64') throw new Error('Flux needs Windows x64.');
|
|
16
|
+
const root = installRoot();
|
|
17
|
+
const marker = path.join(root, 'npm-version.txt');
|
|
18
|
+
if (arg === '--setup' || needsUpdate(fs.existsSync(marker) ? fs.readFileSync(marker, 'utf8') : null, pkg.version) || !fs.existsSync(path.join(root, 'tools', 'ffmpeg.exe')) || !fs.existsSync(path.join(root, 'DrumBuddy.exe'))) await install();
|
|
19
|
+
if (arg === '--setup') return;
|
|
20
|
+
if (arg === '--audio-diagnostics') {
|
|
21
|
+
const report = path.resolve(process.argv[3] || 'Flux-Audio-Diagnostics.txt');
|
|
22
|
+
execFileSync(path.join(root, 'DrumBuddy.exe'), ['--audio-diagnostics', report], { windowsHide: true, stdio: 'inherit' });
|
|
23
|
+
console.log('Audio device report saved: ' + report);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const child = spawn(path.join(root, 'DrumBuddy.exe'), [], { detached: true, stdio: 'ignore', windowsHide: false });
|
|
27
|
+
child.on('error', err => { console.error('Flux: ' + err.message); process.exitCode = 1; });
|
|
28
|
+
child.unref();
|
|
29
|
+
})().catch(err => { console.error('Flux: ' + err.message); process.exitCode = 1; });
|
|
@@ -0,0 +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": "0a57d2459fdb2c5c0c2917df12ca907b47c5a966006d2680e9d160d16bdfed9c",
|
|
14
|
+
"bundledAssets": true
|
|
15
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,60 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@pro-gram/flux",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@pro-gram/flux",
|
|
3
|
+
"version": "1.6.0",
|
|
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": "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
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const fs = require('node:fs');
|
|
3
|
+
const fsp = fs.promises;
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const https = require('node:https');
|
|
6
|
+
const crypto = require('node:crypto');
|
|
7
|
+
const { pipeline } = require('node:stream/promises');
|
|
8
|
+
const { execFileSync } = require('node:child_process');
|
|
9
|
+
const dependencies = require('../dependencies.json');
|
|
10
|
+
const pkg = require('../package.json');
|
|
11
|
+
function installRoot() {
|
|
12
|
+
if (!process.env.LOCALAPPDATA) throw new Error('Windows LOCALAPPDATA is unavailable.');
|
|
13
|
+
return path.join(process.env.LOCALAPPDATA, 'Programs', 'DrumBuddy');
|
|
14
|
+
}
|
|
15
|
+
async function hash(file) { const sha = crypto.createHash('sha256'); await pipeline(fs.createReadStream(file), sha); return sha.digest('hex'); }
|
|
16
|
+
function response(url, redirects = 0) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
const parsed = new URL(url);
|
|
19
|
+
if (parsed.protocol !== 'https:' || redirects > 5) return reject(new Error('Invalid dependency download redirect.'));
|
|
20
|
+
const request = https.get(parsed, { headers: { 'User-Agent': 'DrumBuddy/' + pkg.version } }, res => {
|
|
21
|
+
if ([301, 302, 303, 307, 308].includes(res.statusCode)) { res.resume(); resolve(response(new URL(res.headers.location, parsed).href, redirects + 1)); }
|
|
22
|
+
else if (res.statusCode !== 200) { res.resume(); reject(new Error('Dependency download returned HTTP ' + res.statusCode)); }
|
|
23
|
+
else resolve(res);
|
|
24
|
+
});
|
|
25
|
+
request.setTimeout(60000, () => request.destroy(new Error('The dependency download timed out.'))); request.on('error', reject);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
async function cached(asset, cache) {
|
|
29
|
+
const accepted = [asset.sha256, asset.alternateSha256].filter(Boolean);
|
|
30
|
+
const file = path.join(cache, asset.file);
|
|
31
|
+
if (fs.existsSync(file) && accepted.includes(await hash(file))) return file;
|
|
32
|
+
console.log('Flux: downloading ' + asset.file + ' from its official source...');
|
|
33
|
+
const temp = file + '.' + crypto.randomUUID() + '.partial';
|
|
34
|
+
try {
|
|
35
|
+
await pipeline(await response(asset.url), fs.createWriteStream(temp, { flags: 'wx' }));
|
|
36
|
+
if (!accepted.includes(await hash(temp))) throw new Error('Integrity check failed for ' + asset.file + '. Nothing downloaded will be executed.');
|
|
37
|
+
await fsp.copyFile(temp, file); return file;
|
|
38
|
+
} finally { await fsp.unlink(temp).catch(() => {}); }
|
|
39
|
+
}
|
|
40
|
+
async function install() {
|
|
41
|
+
if (process.platform !== 'win32' || process.arch !== 'x64') throw new Error('Flux needs Windows 10/11 x64.');
|
|
42
|
+
const root = installRoot();
|
|
43
|
+
const cache = path.join(process.env.LOCALAPPDATA, 'DrumBuddy', 'DependencyCache');
|
|
44
|
+
await fsp.mkdir(cache, { recursive: true });
|
|
45
|
+
const installer = path.resolve(__dirname, '..', 'payload', 'DrumBuddy-Setup.exe');
|
|
46
|
+
if (await hash(installer) !== dependencies.installerSha256) throw new Error('The Flux installer failed its integrity check.');
|
|
47
|
+
if (!dependencies.bundledAssets) {
|
|
48
|
+
await cached(dependencies.ffmpeg, cache);
|
|
49
|
+
await cached(dependencies.panel, cache);
|
|
50
|
+
}
|
|
51
|
+
console.log('Flux: installing version ' + pkg.version + ' and the Desktop shortcut...');
|
|
52
|
+
execFileSync(installer, ['--update-app'], { windowsHide: true, stdio: 'inherit' });
|
|
53
|
+
await fsp.writeFile(path.join(root, 'npm-version.txt'), pkg.version + '\n');
|
|
54
|
+
const manifest = path.join(root, 'installed-files.txt');
|
|
55
|
+
const original = await fsp.readFile(manifest, 'utf8');
|
|
56
|
+
await fsp.writeFile(manifest, original.trimEnd() + '\nnpm-version.txt\n');
|
|
57
|
+
console.log('Flux is ready. Open its Desktop shortcut or run flux. Use Install Drivers for the official Zoom driver guide.');
|
|
58
|
+
}
|
|
59
|
+
module.exports = { install, installRoot, hash, cached };
|
|
60
|
+
if (require.main === module) install().catch(err => { console.error('Flux setup: ' + err.message + '\nClose Flux before updating. Retry with flux --setup.'); process.exitCode = 1; });
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
function needsUpdate(installed, required) {
|
|
3
|
+
const parse = value => /^(\d+)\.(\d+)\.(\d+)$/.exec(String(value || '').trim());
|
|
4
|
+
const current = parse(installed), target = parse(required);
|
|
5
|
+
if (!current || !target) return true;
|
|
6
|
+
for (let i = 1; i <= 3; i++) {
|
|
7
|
+
if (Number(current[i]) < Number(target[i])) return true;
|
|
8
|
+
if (Number(current[i]) > Number(target[i])) return false;
|
|
9
|
+
}
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
module.exports = { needsUpdate };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.IO;
|
|
3
|
+
using System.IO.Compression;
|
|
4
|
+
using System.Linq;
|
|
5
|
+
using System.Net;
|
|
6
|
+
using System.Security.Cryptography;
|
|
7
|
+
|
|
8
|
+
namespace DrumBuddySetup
|
|
9
|
+
{
|
|
10
|
+
internal static class AssetBootstrap
|
|
11
|
+
{
|
|
12
|
+
private const string FfmpegUrl="https://www.gyan.dev/ffmpeg/builds/packages/ffmpeg-9.0.2-essentials_build.zip";
|
|
13
|
+
private const string FfmpegHash="60F467265B1E312373DBCD92200C2618A74850F98D3D078E94296BB3FA2047BA";
|
|
14
|
+
private const string PanelUrl="https://zoomcorp.com/media/original_images/R16_list_0.png";
|
|
15
|
+
private static readonly string[] PanelHashes={"315A71E8942A445C903B2D1AEDB703B64AAB30F054E46199A2BAC447D3D03CB2","5564FA622F101DC27EA402C399C5B9B1E1E039B8771DAF40B185DAB9772ADF38"};
|
|
16
|
+
private static string Hash(string path) { using(var sha=SHA256.Create())using(var file=File.OpenRead(path))return BitConverter.ToString(sha.ComputeHash(file)).Replace("-",""); }
|
|
17
|
+
private static string Fetch(string url,string name,string[] expected)
|
|
18
|
+
{
|
|
19
|
+
string cache=Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"DrumBuddy","DependencyCache");Directory.CreateDirectory(cache);
|
|
20
|
+
string target=Path.Combine(cache,name);
|
|
21
|
+
if(File.Exists(target) && expected.Contains(Hash(target),StringComparer.OrdinalIgnoreCase))return target;
|
|
22
|
+
string temporary=target+"."+Guid.NewGuid().ToString("N")+".partial";
|
|
23
|
+
try {
|
|
24
|
+
using(var client=new WebClient()) { client.Headers[HttpRequestHeader.UserAgent]="DrumBuddy/1.6.0";client.DownloadFile(url,temporary); }
|
|
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
|
+
File.Copy(temporary,target,true);return target;
|
|
27
|
+
}finally { if(File.Exists(temporary))File.Delete(temporary); }
|
|
28
|
+
}
|
|
29
|
+
public static void Ensure(string stage,Action<double> progress)
|
|
30
|
+
{
|
|
31
|
+
string tools=Path.Combine(stage,"tools"),licenses=Path.Combine(stage,"licenses");Directory.CreateDirectory(tools);Directory.CreateDirectory(licenses);
|
|
32
|
+
if(!File.Exists(Path.Combine(tools,"ffmpeg.exe"))) {
|
|
33
|
+
string zip=Fetch(FfmpegUrl,"ffmpeg-9.0.2.zip",new[] {FfmpegHash});
|
|
34
|
+
using(var archive=ZipFile.OpenRead(zip)) {
|
|
35
|
+
var binaries=archive.Entries.Where(e=>e.FullName.EndsWith("/bin/ffmpeg.exe",StringComparison.OrdinalIgnoreCase)).ToArray();
|
|
36
|
+
if(binaries.Length!=1)throw new IOException("The FFmpeg archive does not contain the expected executable.");
|
|
37
|
+
string root=binaries[0].FullName.Split('/')[0];
|
|
38
|
+
binaries[0].ExtractToFile(Path.Combine(tools,"ffmpeg.exe"),false);
|
|
39
|
+
foreach(string name in new[] {"LICENSE","README.txt"}) {
|
|
40
|
+
var entry=archive.GetEntry(root+"/"+name);if(entry==null)throw new IOException("The FFmpeg archive is missing its license information.");
|
|
41
|
+
entry.ExtractToFile(Path.Combine(licenses,name=="LICENSE"?"FFmpeg-GPLv3.txt":"FFmpeg-build.txt"),true);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if(progress!=null)progress(.9);
|
|
46
|
+
if(!File.Exists(Path.Combine(stage,"r16-panel.png")))File.Copy(Fetch(PanelUrl,"r16-panel.png",PanelHashes),Path.Combine(stage,"r16-panel.png"),false);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|