mirror of
https://github.com/vsariola/sointu.git
synced 2025-07-18 21:14:31 -04:00
feat(tracker): add menu item to export .wav
Also refactor the common functions for .wav export into base package so that both sointu-play and tracker can use same functions.
This commit is contained in:
@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"gioui.org/app"
|
||||
"gopkg.in/yaml.v3"
|
||||
@ -82,3 +83,33 @@ func (t *Tracker) saveSong(filename string) bool {
|
||||
t.SetChangedSinceSave(false)
|
||||
return true
|
||||
}
|
||||
|
||||
func (t *Tracker) exportWav(pcm16 bool) {
|
||||
filename, err := dialog.File().Filter(".wav file", "wav").Title("Export .wav").Save()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var extension = filepath.Ext(filename)
|
||||
if extension == "" {
|
||||
filename = filename + ".wav"
|
||||
}
|
||||
synth, err := t.synthService.Compile(t.Song().Patch)
|
||||
if err != nil {
|
||||
t.Alert.Update(fmt.Sprintf("Error compiling the patch during export: %v", err), Error, time.Second*3)
|
||||
return
|
||||
}
|
||||
for i := 0; i < 32; i++ {
|
||||
synth.Release(i)
|
||||
}
|
||||
data, _, err := sointu.Play(synth, t.Song()) // render the song to calculate its length
|
||||
if err != nil {
|
||||
t.Alert.Update(fmt.Sprintf("Error rendering the song during export: %v", err), Error, time.Second*3)
|
||||
return
|
||||
}
|
||||
buffer, err := sointu.Wav(data, pcm16)
|
||||
if err != nil {
|
||||
t.Alert.Update(fmt.Sprintf("Error converting to .wav: %v", err), Error, time.Second*3)
|
||||
return
|
||||
}
|
||||
ioutil.WriteFile(filename, buffer, 0644)
|
||||
}
|
||||
|
@ -39,6 +39,22 @@ func (t *Tracker) Layout(gtx layout.Context) {
|
||||
for t.ConfirmSongDialog.BtnCancel.Clicked() {
|
||||
t.ConfirmSongDialog.Visible = false
|
||||
}
|
||||
dstyle = ConfirmDialog(t.Theme, t.WaveTypeDialog, "Export .wav in int16 or float32 sample format?")
|
||||
dstyle.ShowAlt = true
|
||||
dstyle.OkStyle.Text = "Int16"
|
||||
dstyle.AltStyle.Text = "Float32"
|
||||
dstyle.Layout(gtx)
|
||||
for t.WaveTypeDialog.BtnOk.Clicked() {
|
||||
t.exportWav(true)
|
||||
t.WaveTypeDialog.Visible = false
|
||||
}
|
||||
for t.WaveTypeDialog.BtnAlt.Clicked() {
|
||||
t.exportWav(false)
|
||||
t.WaveTypeDialog.Visible = false
|
||||
}
|
||||
for t.WaveTypeDialog.BtnCancel.Clicked() {
|
||||
t.WaveTypeDialog.Visible = false
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tracker) confirmedSongAction() {
|
||||
|
@ -61,6 +61,8 @@ func (t *Tracker) layoutMenuBar(gtx C) D {
|
||||
case 3:
|
||||
t.SaveSongAsFile()
|
||||
case 4:
|
||||
t.WaveTypeDialog.Visible = true
|
||||
case 5:
|
||||
t.TryQuit()
|
||||
}
|
||||
clickedItem, hasClicked = t.Menus[0].Clicked()
|
||||
@ -93,6 +95,7 @@ func (t *Tracker) layoutMenuBar(gtx C) D {
|
||||
MenuItem{IconBytes: icons.FileFolder, Text: "Open Song", ShortcutText: shortcutKey + "O"},
|
||||
MenuItem{IconBytes: icons.ContentSave, Text: "Save Song", ShortcutText: shortcutKey + "S"},
|
||||
MenuItem{IconBytes: icons.ContentSave, Text: "Save Song As..."},
|
||||
MenuItem{IconBytes: icons.ImageAudiotrack, Text: "Export Wav..."},
|
||||
MenuItem{IconBytes: icons.ActionExitToApp, Text: "Quit"},
|
||||
)),
|
||||
layout.Rigid(t.layoutMenu("Edit", &t.MenuBar[1], &t.Menus[1], unit.Dp(160),
|
||||
|
@ -70,6 +70,7 @@ type Tracker struct {
|
||||
PatternOrderScrollBar *ScrollBar
|
||||
ConfirmInstrDelete *Dialog
|
||||
ConfirmSongDialog *Dialog
|
||||
WaveTypeDialog *Dialog
|
||||
ConfirmSongActionType int
|
||||
window *app.Window
|
||||
|
||||
@ -82,6 +83,7 @@ type Tracker struct {
|
||||
errorChannel chan error
|
||||
quitted bool
|
||||
audioContext sointu.AudioContext
|
||||
synthService sointu.SynthService
|
||||
|
||||
*tracker.Model
|
||||
}
|
||||
@ -165,8 +167,10 @@ func New(audioContext sointu.AudioContext, synthService sointu.SynthService, syn
|
||||
PatternOrderScrollBar: &ScrollBar{Axis: layout.Vertical},
|
||||
ConfirmInstrDelete: new(Dialog),
|
||||
ConfirmSongDialog: new(Dialog),
|
||||
WaveTypeDialog: new(Dialog),
|
||||
errorChannel: make(chan error, 32),
|
||||
window: window,
|
||||
synthService: synthService,
|
||||
}
|
||||
t.Model = tracker.NewModel()
|
||||
vuBufferObserver := make(chan []float32)
|
||||
|
Reference in New Issue
Block a user