105 lines
2.1 KiB
Go
105 lines
2.1 KiB
Go
package editor
|
|
|
|
import (
|
|
"errors"
|
|
"math/rand/v2"
|
|
|
|
"aego/asset"
|
|
"aego/core/ids"
|
|
"aego/data"
|
|
"aego/editor/core/context"
|
|
"aego/modules/audio"
|
|
)
|
|
|
|
var (
|
|
errNoOutput = errors.New("the audio output is not open")
|
|
errNoVariants = errors.New("the audio event has no clips")
|
|
)
|
|
|
|
// audition remembers which event started the preview clip.
|
|
type audition struct {
|
|
event ids.AssetID
|
|
clip ids.AssetID
|
|
}
|
|
|
|
func previewModule(ed *context.Editor) (*audio.Module, error) {
|
|
if ed.Engine == nil || ed.Loader == nil {
|
|
return nil, errNoOutput
|
|
}
|
|
if mod := audio.ModuleOf(ed.Engine); mod != nil {
|
|
return mod, nil
|
|
}
|
|
return nil, errNoOutput
|
|
}
|
|
|
|
func (p *plugin) playClip(ed *context.Editor, id ids.AssetID) error {
|
|
mod, err := previewModule(ed)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
p.aud = audition{}
|
|
return mod.Preview(ed.Loader, id, false)
|
|
}
|
|
|
|
func (p *plugin) playEvent(ed *context.Editor, id ids.AssetID) error {
|
|
mod, err := previewModule(ed)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if ed.Types == nil {
|
|
return errNoOutput
|
|
}
|
|
var src asset.DataSource = ed.Loader
|
|
ev, err := data.Get[audio.Event](data.NewLibrary(ed.Types.Schema(), src), id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var clips []ids.AssetID
|
|
for _, v := range ev.Variants {
|
|
if !v.ID.IsZero() {
|
|
clips = append(clips, v.ID)
|
|
}
|
|
}
|
|
if len(clips) == 0 {
|
|
return errNoVariants
|
|
}
|
|
clip := clips[rand.IntN(len(clips))]
|
|
if err := mod.Preview(ed.Loader, clip, ev.Loop); err != nil {
|
|
return err
|
|
}
|
|
p.aud = audition{event: id, clip: clip}
|
|
return nil
|
|
}
|
|
|
|
func (p *plugin) stopAudition(ed *context.Editor) {
|
|
if mod, err := previewModule(ed); err == nil {
|
|
mod.StopPreview()
|
|
}
|
|
p.aud = audition{}
|
|
}
|
|
|
|
func playingClip(ed *context.Editor) ids.AssetID {
|
|
mod, err := previewModule(ed)
|
|
if err != nil {
|
|
return ids.AssetID{}
|
|
}
|
|
if _, live := mod.PreviewPosition(); !live {
|
|
return ids.AssetID{}
|
|
}
|
|
return mod.PreviewClip()
|
|
}
|
|
|
|
func (p *plugin) clipPlaying(ed *context.Editor) ids.AssetID {
|
|
if !p.aud.event.IsZero() {
|
|
return ids.AssetID{}
|
|
}
|
|
return playingClip(ed)
|
|
}
|
|
|
|
func (p *plugin) eventPlaying(ed *context.Editor) ids.AssetID {
|
|
if c := playingClip(ed); !c.IsZero() && c == p.aud.clip {
|
|
return p.aud.event
|
|
}
|
|
return ids.AssetID{}
|
|
}
|