tracker

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 23, 2023 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package tracker contains the data model for the Sointu tracker GUI.

Index

Constants

This section is empty.

Variables

View Source
var ErrInvalidRows = errors.New("rows per beat and rows per pattern must be greater than 1")
View Source
var GmDlsEntries = []GmDlsEntry{}/* 495 elements not displayed */

GmDlsEntries is a list of all samples in the gm.dls file. Do not modify during runtime.

View Source
var GmDlsEntryMap = make(map[vm.SampleOffset]int)

GmDlsEntryMap is a reverse map, to find the index of the GmDlsEntry in the GmDlsEntries list based on the sample offset. Do not modify during runtime.

View Source
var InstrumentPresets instrumentPresets

Functions

This section is empty.

Types

type GmDlsEntry

type GmDlsEntry struct {
	Start              int    // sample start offset in words
	LoopStart          int    // loop start offset in words
	LoopLength         int    // loop length in words
	SuggestedTranspose int    // suggested transpose in semitones, so that all samples play at same pitch
	Name               string // sample name
}

GmDlsEntry is a single sample entry from the gm.dls file

type MIDINoteEvent added in v0.3.0

type MIDINoteEvent struct {
	Frame   int
	On      bool
	Channel int
	Note    byte
}

MIDINoteEvent is a MIDI event triggering or releasing a note. In processing, the Frame is relative to the start of the current buffer. In a Recording, the Frame is relative to the start of the recording.

type Model

type Model struct {
	PlayerMessages <-chan PlayerMessage
	// contains filtered or unexported fields
}

Model implements the mutable state for the tracker program GUI.

Go does not have immutable slices, so there's no efficient way to guarantee accidental mutations in the song. But at least the value members are protected. It is owned by the GUI thread (goroutine), while the player is owned by by the audioprocessing thread. They communicate using the two channels

func NewModel

func NewModel(modelMessages chan<- interface{}, playerMessages <-chan PlayerMessage, recoveryFilePath string) *Model

func (*Model) AddInstrument

func (m *Model) AddInstrument(after bool)

func (*Model) AddOrderRow

func (m *Model) AddOrderRow(after bool)

func (*Model) AddTrack

func (m *Model) AddTrack(after bool)

func (*Model) AddUnit

func (m *Model) AddUnit(after bool)

func (*Model) AdjustPatternNumber added in v0.2.0

func (m *Model) AdjustPatternNumber(delta int, swap bool)

func (*Model) AdjustSelectionPitch

func (m *Model) AdjustSelectionPitch(delta int)

func (*Model) CanAddInstrument

func (m *Model) CanAddInstrument() bool

func (*Model) CanAddTrack

func (m *Model) CanAddTrack() bool

func (*Model) CanDeleteInstrument

func (m *Model) CanDeleteInstrument() bool

func (*Model) CanDeleteTrack

func (m *Model) CanDeleteTrack() bool

func (*Model) CanDeleteUnit

func (m *Model) CanDeleteUnit() bool

func (*Model) CanRedo

func (m *Model) CanRedo() bool

func (*Model) CanUndo

func (m *Model) CanUndo() bool

func (*Model) ChangedSinceSave

func (m *Model) ChangedSinceSave() bool

func (*Model) ClearUndoHistory

func (m *Model) ClearUndoHistory()

func (*Model) Cursor

func (m *Model) Cursor() ScorePoint

func (*Model) DeleteInstrument

func (m *Model) DeleteInstrument(forward bool)

func (*Model) DeleteOrderRow

func (m *Model) DeleteOrderRow(forward bool)

func (*Model) DeletePatternSelection

func (m *Model) DeletePatternSelection()

func (*Model) DeleteSelection

func (m *Model) DeleteSelection()

func (*Model) DeleteTrack

func (m *Model) DeleteTrack(forward bool)

func (*Model) DeleteUnits added in v0.2.0

func (m *Model) DeleteUnits(forward bool, a, b int) []sointu.Unit

func (*Model) FilePath

func (m *Model) FilePath() string

func (*Model) InstrEnlarged added in v0.2.0

func (m *Model) InstrEnlarged() bool

func (*Model) InstrIndex

func (m *Model) InstrIndex() int

func (*Model) Instrument

func (m *Model) Instrument() sointu.Instrument

func (*Model) IsPatternUnique

func (m *Model) IsPatternUnique(track, pattern int) bool

func (*Model) LowNibble

func (m *Model) LowNibble() bool

func (*Model) MarshalRecovery added in v0.3.0

func (m *Model) MarshalRecovery() []byte

func (*Model) MaxInstrumentVoices

func (m *Model) MaxInstrumentVoices() int

func (*Model) MaxTrackVoices

func (m *Model) MaxTrackVoices() int

func (*Model) Note

func (m *Model) Note() byte

func (*Model) NoteOff added in v0.2.0

func (m *Model) NoteOff(id NoteID)

func (*Model) NoteOn added in v0.2.0

func (m *Model) NoteOn(id NoteID)

func (*Model) NoteTracking

func (m *Model) NoteTracking() bool

func (*Model) NumParams

func (m *Model) NumParams() int

func (*Model) Octave

func (m *Model) Octave() int

Returns the current octave for jamming and inputting nodes

func (*Model) Panic added in v0.2.0

func (m *Model) Panic() bool

func (*Model) Param

func (m *Model) Param(index int) (Parameter, error)

func (*Model) ParamIndex

func (m *Model) ParamIndex() int

func (*Model) PasteUnits added in v0.2.0

func (m *Model) PasteUnits(units []sointu.Unit)

func (*Model) PlayFromPosition added in v0.2.0

func (m *Model) PlayFromPosition(sr ScoreRow)

func (*Model) PlayPosition added in v0.2.0

func (m *Model) PlayPosition() ScoreRow

func (*Model) Playing added in v0.2.0

func (m *Model) Playing() bool

func (*Model) ProcessPlayerMessage added in v0.2.0

func (m *Model) ProcessPlayerMessage(msg PlayerMessage)

func (*Model) Recording added in v0.2.0

func (m *Model) Recording() bool

func (*Model) Redo

func (m *Model) Redo()

func (*Model) RemoveUnusedData added in v0.2.0

func (m *Model) RemoveUnusedData()

func (*Model) ResetParam

func (m *Model) ResetParam()

func (*Model) ResetSong

func (m *Model) ResetSong()

func (*Model) SaveRecovery added in v0.3.0

func (m *Model) SaveRecovery() error

func (*Model) SelectionCorner

func (m *Model) SelectionCorner() ScorePoint

func (*Model) SetBPM

func (m *Model) SetBPM(value int)

func (*Model) SetChangedSinceSave

func (m *Model) SetChangedSinceSave(value bool)

func (*Model) SetCurrentPattern

func (m *Model) SetCurrentPattern(pat int)

func (*Model) SetCursor

func (m *Model) SetCursor(value ScorePoint)

func (*Model) SetFilePath

func (m *Model) SetFilePath(value string)

func (*Model) SetInstrEnlarged added in v0.2.0

func (m *Model) SetInstrEnlarged(val bool)

func (*Model) SetInstrIndex

func (m *Model) SetInstrIndex(value int)

func (*Model) SetInstrument

func (m *Model) SetInstrument(instrument sointu.Instrument) bool

func (*Model) SetInstrumentComment added in v0.2.0

func (m *Model) SetInstrumentComment(comment string)

func (*Model) SetInstrumentName

func (m *Model) SetInstrumentName(name string)

func (*Model) SetInstrumentVoices

func (m *Model) SetInstrumentVoices(value int)

func (*Model) SetLowNibble

func (m *Model) SetLowNibble(value bool)

func (*Model) SetNote

func (m *Model) SetNote(iv byte)

SetCurrentNote sets the (note) value in current pattern under cursor to iv

func (*Model) SetNoteTracking

func (m *Model) SetNoteTracking(value bool)

func (*Model) SetOctave

func (m *Model) SetOctave(value int) bool

Sets the current octave for jamming and inputting nodes and returns true if it changed. The value is clamped to 0..9

func (*Model) SetPanic added in v0.2.0

func (m *Model) SetPanic(val bool)

func (*Model) SetParam

func (m *Model) SetParam(value int)

func (*Model) SetParamIndex

func (m *Model) SetParamIndex(value int)

func (*Model) SetPlaying added in v0.2.0

func (m *Model) SetPlaying(val bool)

func (*Model) SetRecording added in v0.2.0

func (m *Model) SetRecording(val bool)

func (*Model) SetRowsPerBeat

func (m *Model) SetRowsPerBeat(value int)

func (*Model) SetRowsPerPattern

func (m *Model) SetRowsPerPattern(value int)

func (*Model) SetSelectionCorner

func (m *Model) SetSelectionCorner(value ScorePoint)

func (*Model) SetSong

func (m *Model) SetSong(song sointu.Song)

func (*Model) SetSongLength

func (m *Model) SetSongLength(value int)

func (*Model) SetTrackVoices

func (m *Model) SetTrackVoices(value int)

func (*Model) SetUnitIndex

func (m *Model) SetUnitIndex(value int)

func (*Model) SetUnitType

func (m *Model) SetUnitType(t string)

func (*Model) Song

func (m *Model) Song() sointu.Song

func (*Model) SwapInstruments

func (m *Model) SwapInstruments(i, j int)

func (*Model) SwapTracks added in v0.2.0

func (m *Model) SwapTracks(i, j int)

func (*Model) SwapUnits

func (m *Model) SwapUnits(i, j int)

func (*Model) Track

func (m *Model) Track() sointu.Track

func (*Model) Undo

func (m *Model) Undo()

func (*Model) Unit

func (m *Model) Unit() sointu.Unit

func (*Model) UnitIndex

func (m *Model) UnitIndex() int

func (*Model) UnmarshalRecovery added in v0.3.0

func (m *Model) UnmarshalRecovery(bytes []byte)

type ModelBPMChangedMessage added in v0.3.0

type ModelBPMChangedMessage struct {
	// contains filtered or unexported fields
}

Model implements the mutable state for the tracker program GUI.

Go does not have immutable slices, so there's no efficient way to guarantee accidental mutations in the song. But at least the value members are protected. It is owned by the GUI thread (goroutine), while the player is owned by by the audioprocessing thread. They communicate using the two channels

type ModelNoteOffMessage added in v0.2.0

type ModelNoteOffMessage struct {
	NoteID
}

Model implements the mutable state for the tracker program GUI.

Go does not have immutable slices, so there's no efficient way to guarantee accidental mutations in the song. But at least the value members are protected. It is owned by the GUI thread (goroutine), while the player is owned by by the audioprocessing thread. They communicate using the two channels

type ModelNoteOnMessage added in v0.2.0

type ModelNoteOnMessage struct {
	NoteID
}

Model implements the mutable state for the tracker program GUI.

Go does not have immutable slices, so there's no efficient way to guarantee accidental mutations in the song. But at least the value members are protected. It is owned by the GUI thread (goroutine), while the player is owned by by the audioprocessing thread. They communicate using the two channels

type ModelPanicMessage added in v0.2.0

type ModelPanicMessage struct {
	// contains filtered or unexported fields
}

Model implements the mutable state for the tracker program GUI.

Go does not have immutable slices, so there's no efficient way to guarantee accidental mutations in the song. But at least the value members are protected. It is owned by the GUI thread (goroutine), while the player is owned by by the audioprocessing thread. They communicate using the two channels

type ModelPlayFromPositionMessage added in v0.2.0

type ModelPlayFromPositionMessage struct {
	ScoreRow
}

Model implements the mutable state for the tracker program GUI.

Go does not have immutable slices, so there's no efficient way to guarantee accidental mutations in the song. But at least the value members are protected. It is owned by the GUI thread (goroutine), while the player is owned by by the audioprocessing thread. They communicate using the two channels

type ModelPlayingChangedMessage added in v0.2.0

type ModelPlayingChangedMessage struct {
	// contains filtered or unexported fields
}

Model implements the mutable state for the tracker program GUI.

Go does not have immutable slices, so there's no efficient way to guarantee accidental mutations in the song. But at least the value members are protected. It is owned by the GUI thread (goroutine), while the player is owned by by the audioprocessing thread. They communicate using the two channels

type ModelRecordingMessage added in v0.2.0

type ModelRecordingMessage struct {
	// contains filtered or unexported fields
}

Model implements the mutable state for the tracker program GUI.

Go does not have immutable slices, so there's no efficient way to guarantee accidental mutations in the song. But at least the value members are protected. It is owned by the GUI thread (goroutine), while the player is owned by by the audioprocessing thread. They communicate using the two channels

type ModelRowsPerBeatChangedMessage added in v0.3.0

type ModelRowsPerBeatChangedMessage struct {
	// contains filtered or unexported fields
}

Model implements the mutable state for the tracker program GUI.

Go does not have immutable slices, so there's no efficient way to guarantee accidental mutations in the song. But at least the value members are protected. It is owned by the GUI thread (goroutine), while the player is owned by by the audioprocessing thread. They communicate using the two channels

type NoteID added in v0.2.0

type NoteID struct {
	IsInstr bool
	Instr   int
	Track   int
	Note    byte
}

Describes a note triggered either a track or an instrument If Go had union or Either types, this would be it, but in absence those, this uses a boolean to define if the instrument is defined or the track

func NoteIDInstr added in v0.2.0

func NoteIDInstr(instr int, note byte) NoteID

func NoteIDTrack added in v0.2.0

func NoteIDTrack(track int, note byte) NoteID

type Parameter

type Parameter struct {
	Type      ParameterType
	Name      string
	Hint      string
	Value     int
	Min       int
	Max       int
	LargeStep int
}

type ParameterType

type ParameterType int
const (
	IntegerParameter ParameterType = iota
	BoolParameter
	IDParameter
)

type Player

type Player struct {
	// contains filtered or unexported fields
}

Player is the audio player for the tracker, run in a separate thread. It is controlled by messages from the model and MIDI messages via the context, typically from the VSTI host. The player sends messages to the model via the playerMessages channel. The model sends messages to the player via the modelMessages channel.

func NewPlayer

func NewPlayer(synther sointu.Synther, playerMessages chan<- PlayerMessage, modelMessages <-chan interface{}) *Player

NewPlayer creates a new player. The playerMessages channel is used to send messages to the model. The modelMessages channel is used to receive messages from the model. The synther is used to create new synths.

func (*Player) Process added in v0.2.0

func (p *Player) Process(buffer sointu.AudioBuffer, context PlayerProcessContext)

Process renders audio to the given buffer, trying to fill it completely. If the buffer is not filled, the synth is destroyed and an error is sent to the model. context tells the player which MIDI events happen during the current buffer. It is used to trigger and release notes during processing. The context is also used to get the current BPM from the host.

type PlayerCrashMessage added in v0.2.0

type PlayerCrashMessage struct {
	// contains filtered or unexported fields
}

PlayerCrashMessage is sent to the model when the player crashes.

type PlayerMessage added in v0.2.0

type PlayerMessage struct {
	Panic         bool
	AverageVolume Volume
	PeakVolume    Volume
	SongRow       ScoreRow
	VoiceLevels   [vm.MAX_VOICES]float32
	Inner         interface{}
}

PlayerMessage is a message sent from the player to the model. The Inner field can contain any message. Panic, AverageVolume, PeakVolume, SongRow and VoiceStates transmitted frequently, with every message, so they are treated specially, to avoid boxing. All the rest messages can be boxed to Inner interface{}

type PlayerProcessContext added in v0.2.0

type PlayerProcessContext interface {
	NextEvent() (event MIDINoteEvent, ok bool)
	BPM() (bpm float64, ok bool)
}

PlayerProcessContext is the context given to the player when processing audio. It is used to get MIDI events and the current BPM.

type PlayerVolumeErrorMessage added in v0.2.0

type PlayerVolumeErrorMessage struct {
	// contains filtered or unexported fields
}

PlayerVolumeErrorMessage is sent to the model there is an error in the volume analyzer. The error is not fatal.

type Recording added in v0.3.0

type Recording struct {
	BPM         float64 // vsts allow bpms as floats so for accurate reconstruction, keep it as float for recording
	Events      []MIDINoteEvent
	TotalFrames int
}

func (*Recording) Song added in v0.3.0

func (recording *Recording) Song(patch sointu.Patch, rowsPerBeat, rowsPerPattern int) (sointu.Song, error)

type ScorePoint added in v0.3.0

type ScorePoint struct {
	Track int
	ScoreRow
}

ScorePoint identifies a row and a track in a song score.

func (ScorePoint) AddPatterns added in v0.3.0

func (r ScorePoint) AddPatterns(patterns int) ScorePoint

func (ScorePoint) AddRows added in v0.3.0

func (r ScorePoint) AddRows(rows int) ScorePoint

func (ScorePoint) Clamp added in v0.3.0

func (p ScorePoint) Clamp(score sointu.Score) ScorePoint

func (ScorePoint) Wrap added in v0.3.0

func (p ScorePoint) Wrap(score sointu.Score) ScorePoint

type ScoreRect added in v0.3.0

type ScoreRect struct {
	Corner1 ScorePoint
	Corner2 ScorePoint
}

ScoreRect identifies a rectangular area in a song score.

func (*ScoreRect) Contains added in v0.3.0

func (r *ScoreRect) Contains(p ScorePoint) bool

type ScoreRow added in v0.3.0

type ScoreRow struct {
	Pattern int
	Row     int
}

ScoreRow identifies a row of the song score.

func (ScoreRow) AddPatterns added in v0.3.0

func (r ScoreRow) AddPatterns(patterns int) ScoreRow

func (ScoreRow) AddRows added in v0.3.0

func (r ScoreRow) AddRows(rows int) ScoreRow

func (ScoreRow) Clamp added in v0.3.0

func (r ScoreRow) Clamp(score sointu.Score) ScoreRow

func (ScoreRow) Wrap added in v0.3.0

func (r ScoreRow) Wrap(score sointu.Score) ScoreRow

type Volume

type Volume [2]float64

type VolumeAnalyzer added in v0.3.0

type VolumeAnalyzer struct {
	Level   Volume  // current volume level of left and right channels
	Attack  float64 // attack time constant in seconds
	Release float64 // release time constant in seconds
	Min     float64 // minimum volume in decibels
	Max     float64 // maximum volume in decibels
}

VolumeAnalyzer measures the volume in an AudioBuffer, in decibels relative to full scale (0 dB = signal level of +-1)

func (*VolumeAnalyzer) Update added in v0.3.0

func (v *VolumeAnalyzer) Update(buffer sointu.AudioBuffer) (err error)

Update updates the Level field, by analyzing the given buffer.

Internally, it first converts the signal to decibels (0 dB = +-1). Then, the average volume level is computed by smoothing the decibel values with a exponentially decaying average, with a time constant Attack (in seconds) if the decibel value is greater than current level and time constant Decay (in seconds) if the decibel value is less than current level.

Typical time constants for average level detection would be 0.3 seconds for both attack and release. For peak level detection, attack could be 1.5e-3 and release 1.5 (seconds)

MinVolume and MaxVolume are hard limits in decibels to prevent negative infinities for volumes

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL