liblsdj

package module
v0.0.0-...-5f435bd Latest Latest
Warning

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

Go to latest
Published: Mar 14, 2022 License: MIT Imports: 3 Imported by: 0

README

liblsdj

forked from: github.com/8lall0/liblsdj

Little Sound DJ is wonderful tool that transforms your old gameboy into a music making machine. It has a thriving community of users that pushes their old hardware to its limits, in pursuit of new musical endeavours. It can however be cumbersome to manage songs and sounds outside of the gameboy.

In this light liblsdj is being developed, a cross-platform and fast Go library for interacting with the LSDJ save format (.sav), song files (.lsdsng) and more. The end goal is to deliver liblsdj and afterwards a suite of tools for working with everything LSDJ.

This is a Go port of liblsdj.

System requirements

You need only a working Go environment installed.

Every architecture supported by Go should work fine.

Installation

not ready yet

Todo

  • Compress .lsdsng song
  • Decompress .lsdsng song
  • Read song from .lsdsng
  • Write song onto .lsdsng
  • Read from .sav
  • Write to .sav
  • Expose a decent api
  • Write a test suite

Author

Savino Pio Liguori, @twitter.

License

This project is licensed under the MIT License - see the LICENSE.md file for details

Documentation

Index

Constants

View Source
const (
	CommandNone        = 0x00
	CommandA           = 0x01
	CommandB           = 0x17
	CommandC           = 0x02
	CommandD           = 0x03
	CommandE           = 0x04
	CommandF           = 0x05
	CommandG           = 0x06
	CommandH           = 0x07
	CommandK           = 0x08
	CommandL           = 0x09
	CommandM           = 0x0a
	CommandO           = 0x0b
	CommandP           = 0x0c
	CommandR           = 0x0d
	CommandS           = 0x0e
	CommandT           = 0x0f
	CommandV           = 0x10
	CommandW           = 0x11
	CommandZ           = 0x12
	CommandArduinoboyN = 0x13
	CommandArduinoboyX = 0x14
	CommandArduinoboyQ = 0x15
	CommandArduinoboyY = 0x16
)
View Source
const (
	RunLengthEncodingByte = 0xc0
	SpecialActionByte     = 0xe0
	EndOfFileByte         = 0xff
	DefaultWaveByte       = 0xf0
	DefaultInstrumentByte = 0xf1
)
View Source
const (
	InstrumentNameLen    = 5
	InstrumentDefaultLen = 16

	NoTable                   = 0x20
	InstrumentUnlimitedLength = 0x40
	KitLengthAuto             = 0x0

	InstrPulse byte = iota
	InstrWave
	InstrKit
	InstrNoise

	PlVibFast PlVibSpeed = iota
	PlVibTick
	PlVibStep

	VibTriangle VibShape = iota
	VibSawtooth
	VibSquare

	VibUp VibDirection = iota
	VibDown
)
View Source
const (
	KitDistClip   KitDistortion = 0xD0
	KitDistShape  KitDistortion = 0xD1
	KitDistShape2 KitDistortion = 0xD2
	KitDistWrap   KitDistortion = 0xD3

	KitLoopOff KitLoopMode = iota
	KitLoopOn
	KitLoopAttack

	KitPspeedFast KitPspeed = iota
	KitPspeedSlow
	KitPspeedStep
)
View Source
const (
	NoActiveProject = 0xff
	SavProjectCnt   = 32
	HeaderStart     = SongDecompSize
	BlockCnt        = 191
	BlockSize       = 0x200
)
View Source
const (
	SongDecompSize = 0x8000
	RowCnt         = 256
	ChainCnt       = 128
	PhraseCnt      = 0xFF
	InstrCnt       = 64
	SynthCnt       = 16
	TableCnt       = 32
	WaveCnt        = 256
	GrooveCnt      = 32
	WordCnt        = 42
	BookmarkPosCnt = 16
	NoBookmark     = 0xFF
	CloneDeep      = 0
	CloneSlim      = 1

	InstrAllocTableSize  = 64
	TableAllocTableSize  = 32
	ChainAllocTableSize  = 16
	PhraseAllocTableSize = 32
)
View Source
const (
	SynthWaveformSawtooth = 0
	SynthWaveformSquare   = 1
	SynthWaveformTriangle = 2

	SynthFilterLowPass  = 0
	SynthFilterHighPass = 1
	SynthFilterBandPass = 2
	SynthFilterAllPass  = 3

	SynthDistortionClip = 0
	SynthDistortionWrap = 1
	SynthDistortionFold = 2

	SynthPhaseNormal  = 0
	SynthPhaseResync  = 1
	SynthPhaseResync2 = 2
)
View Source
const (
	WordLen     = 16
	WordNameLen = 4
)
View Source
const ChainLen = 16
View Source
const ChannelCnt = 4
View Source
const GrooveLen = 16
View Source
const PhraseLen = 16
View Source
const ProjectNameLen = 8
View Source
const TableLen = 16
View Source
const WaveLen = 16

Variables

View Source
var ChainLenFF = [TableLen]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
View Source
var ChainLenZero = [TableLen]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
View Source
var DefaultGroove = Groove{0x06, 0x06, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
View Source
var DefaultInstrumentCompression = [InstrumentDefaultLen]byte{0xA8, 0, 0, 0xFF, 0, 0, 3, 0, 0, 0xD0, 0, 0, 0, 0xF3, 0, 0}
View Source
var DefaultWave = [WaveLen]byte{0x8E, 0xCD, 0xCC, 0xBB, 0xAA, 0xA9, 0x99, 0x88, 0x87, 0x76, 0x66, 0x55, 0x54, 0x43, 0x32, 0x31}
View Source
var PhraseLenFF = [PhraseLen]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
View Source
var PhraseLenZero = [PhraseLen]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
View Source
var TableLengthZero = [TableLen]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
View Source
var WordNameDefault = [WordCnt][WordNameLen]byte{{'C', ' ', '2', ' '}, {'C', ' ', '2', ' '}, {'D', ' ', '2', ' '}, {'D', ' ', '2', ' '}, {'E', ' ', '2', ' '}, {'F', ' ', '2', ' '}, {'F', ' ', '2', ' '}, {'G', ' ', '2', ' '}, {'G', ' ', '2', ' '}, {'A', ' ', '2', ' '}, {'A', ' ', '2', ' '}, {'B', ' ', '2', ' '}, {'C', ' ', '3', ' '}, {'C', ' ', '3', ' '}, {'D', ' ', '3', ' '}, {'D', ' ', '3', ' '}, {'E', ' ', '3', ' '}, {'F', ' ', '3', ' '}, {'F', ' ', '3', ' '}, {'G', ' ', '3', ' '}, {'G', ' ', '3', ' '}, {'A', ' ', '3', ' '}, {'A', ' ', '3', ' '}, {'B', ' ', '3', ' '}, {'C', ' ', '4', ' '}, {'C', ' ', '4', ' '}, {'D', ' ', '4', ' '}, {'D', ' ', '4', ' '}, {'E', ' ', '4', ' '}, {'F', ' ', '4', ' '}, {'F', ' ', '4', ' '}, {'G', ' ', '4', ' '}, {'G', ' ', '4', ' '}, {'A', ' ', '4', ' '}, {'A', ' ', '4', ' '}, {'B', ' ', '4', ' '}, {'C', ' ', '5', ' '}, {'C', ' ', '5', ' '}, {'D', ' ', '5', ' '}, {'D', ' ', '5', ' '}, {'E', ' ', '5', ' '}, {'F', ' ', '5', ' '}}

Functions

func CheckRb

func CheckRb(r io.ReadSeeker, position int64) bool

func SavWrite

func SavWrite(s *Sav)

func WriteLsdsng

func WriteLsdsng(w io.WriteSeeker, p Project)

func WriteSong

func WriteSong(w io.WriteSeeker, s *Song)

Types

type Chain

type Chain struct {
	Phrases        [ChainLen]byte
	Transpositions [ChainLen]byte
}

func (*Chain) Clear

func (c *Chain) Clear()

type Channel

type Channel byte
const (
	Culse1T Channel = iota
	Pulse2T
	WaveT
	NoiseT
)

type Command

type Command struct {
	Command byte
	Value   byte
}

func (*Command) Clear

func (c *Command) Clear()

func (*Command) Get

func (c *Command) Get() []byte

func (*Command) Write

func (c *Command) Write(r io.ReadSeeker)

type Groove

type Groove [GrooveLen]byte

func (*Groove) Clear

func (g *Groove) Clear()

type HeaderT

type HeaderT struct {
	ProjectNames  [SavProjectCnt * 8]byte
	Versions      [SavProjectCnt * 1]byte
	Empty         [30]byte
	Init          [2]byte
	ActiveProject byte
}

type Instrument

type Instrument struct {
	Name           [InstrumentNameLen]byte
	InsType        byte
	EnvelopeVolume byte
	Panning        Panning
	Table          byte // 0x20 or higher = LSDJ_NO_TABLE
	Automate       byte
	Instrument     InstrumentT
}

func (*Instrument) ClearAsPulse

func (i *Instrument) ClearAsPulse()

func (*Instrument) Read

func (i *Instrument) Read(r io.ReadSeeker, version byte)

type InstrumentKit

type InstrumentKit struct {
	Kit1    byte
	Offset1 byte
	Length1 byte
	Loop1   KitLoopMode

	Kit2    byte
	Offset2 byte
	Length2 byte
	Loop2   KitLoopMode

	Pitch        byte
	HalfSpeed    byte
	Distortion   KitDistortion
	PlVibSpeed   PlVibSpeed
	VibShape     VibShape
	VibDirection VibDirection
}

func (*InstrumentKit) Clear

func (i *InstrumentKit) Clear()

func (*InstrumentKit) Read

func (i *InstrumentKit) Read(in *Instrument, r io.ReadSeeker, version byte)

func (*InstrumentKit) Write

func (i *InstrumentKit) Write(in *Instrument, w io.WriteSeeker, version byte)

type InstrumentNoise

type InstrumentNoise struct {
	Length   byte
	Shape    byte
	SCommand SCommand
}

func (*InstrumentNoise) Clear

func (i *InstrumentNoise) Clear()

func (*InstrumentNoise) Read

func (i *InstrumentNoise) Read(in *Instrument, r io.ReadSeeker, version byte)

func (*InstrumentNoise) Write

func (i *InstrumentNoise) Write(in *Instrument, w io.WriteSeeker, version byte)

type InstrumentPulse

type InstrumentPulse struct {
	PulseWidth PulseWave
	Length     byte // 0x40 and above = unlimited
	Sweep      byte

	PlVibSpeed   PlVibSpeed
	VibShape     VibShape
	VibDirection VibDirection

	Transpose  byte
	DrumMode   byte
	Pulse2tune byte
	FineTune   byte
}

func (*InstrumentPulse) Clear

func (i *InstrumentPulse) Clear()

func (*InstrumentPulse) Read

func (i *InstrumentPulse) Read(in *Instrument, r io.ReadSeeker, version byte)

func (*InstrumentPulse) Write

func (i *InstrumentPulse) Write(in *Instrument, w io.WriteSeeker, version byte)

type InstrumentT

type InstrumentT interface {
	Read(in *Instrument, r io.ReadSeeker, version byte)
	Write(in *Instrument, w io.WriteSeeker, version byte)
	Clear()
}

type InstrumentWave

type InstrumentWave struct {
	PlVibSpeed   PlVibSpeed
	VibShape     VibShape
	VibDirection VibDirection

	Transpose byte
	DrumMode  byte
	Synth     byte
	Playback  PlaybackMode
	Length    byte
	Repeat    byte
	Speed     byte
}

func (*InstrumentWave) Clear

func (i *InstrumentWave) Clear()

func (*InstrumentWave) Read

func (i *InstrumentWave) Read(in *Instrument, r io.ReadSeeker, version byte)

func (*InstrumentWave) Write

func (i *InstrumentWave) Write(in *Instrument, w io.WriteSeeker, version byte)

type KitDistortion

type KitDistortion byte

type KitLoopMode

type KitLoopMode byte

type KitPspeed

type KitPspeed byte

type Panning

type Panning byte
const (
	PanNone Panning = iota
	PanRight
	PanLeft
	PanLeftRight
)

type Phrase

type Phrase struct {
	Notes       [PhraseLen]byte
	Instruments [PhraseLen]byte
	Commands    [PhraseLen]Command
}

func (*Phrase) Clear

func (p *Phrase) Clear()

type PlVibSpeed

type PlVibSpeed byte

type PlaybackMode

type PlaybackMode byte
const (
	PlayOnce PlaybackMode = iota
	PlayLoop
	PlayPingPong
	PlayManual
)

type Project

type Project struct {
	Name    [ProjectNameLen]byte
	Version byte
	Song    *Song
}

func ReadLsdsng

func ReadLsdsng(r io.ReadSeeker) (p Project)

type PulseWave

type PulseWave byte
const (
	PulseWave125 PulseWave = iota
	PulseWave25
	PulseWave50
	PulseWave75
)

type Row

type Row struct {
	Pulse1 byte
	Pulse2 byte
	Wave   byte
	Noise  byte
}

func (*Row) Clear

func (ro *Row) Clear()

func (*Row) Read

func (ro *Row) Read(r io.ReadSeeker)

func (*Row) Write

func (ro *Row) Write(w io.WriteSeeker)

type SCommand

type SCommand byte
const (
	SCommandFree SCommand = iota
	SCommandStable
)

type Sav

type Sav struct {
	Projects     [SavProjectCnt]*Project
	Active       byte
	ActiveSong   *Song
	Reserved8120 [30]byte
}

func (*Sav) SetWorkingSong

func (s *Sav) SetWorkingSong(so *Song, activeProject byte)

type Song

type Song struct {
	FormatVersion byte
	Tempo         byte
	Transposition byte
	DrumMax       byte

	Rows        [RowCnt]Row
	Chains      [ChainCnt]*Chain
	Phrases     [PhraseCnt]*Phrase
	Instruments [InstrCnt]*Instrument
	Synths      [SynthCnt]Synth
	Waves       [WaveCnt]Wave
	Tables      [TableCnt]*Table
	Grooves     [GrooveCnt]Groove

	Words     [WordCnt]Word
	WordNames [WordCnt][WordNameLen]byte

	Bookmarks struct {
		Pulse1 [BookmarkPosCnt]byte
		Pulse2 [BookmarkPosCnt]byte
		Wave   [BookmarkPosCnt]byte
		Noise  [BookmarkPosCnt]byte
	}

	//TODO: bookmarks
	Meta struct {
		KeyDelay        byte
		KeyRepeat       byte
		Font            byte
		Sync            byte
		ColorSet        byte
		Clone           byte
		FileChangedFlag byte
		PowerSave       byte
		PreListen       byte

		TotalTime struct {
			Days    byte
			Hours   byte
			Minutes byte
		}
		WorkTime struct {
			Hours   byte
			Minutes byte
		}
	}
	Reserved1030 [96]byte
	Reserved1fba [70]byte
	Reserved2000 [32]byte
	Reserved3fbf byte
	Reserved3fb9 byte
	Reserved3fc6 [10]byte
	Reserved3fd1 [47]byte
	Reserved5fe0 [32]byte
	Reserved7ff2 [13]byte
}

func ReadSong

func ReadSong(r io.ReadSeeker, version byte) (s *Song, err error)

func (*Song) Clear

func (s *Song) Clear()

func (*Song) ReadBank0

func (s *Song) ReadBank0(r io.ReadSeeker)

func (*Song) ReadBank1

func (s *Song) ReadBank1(r io.ReadSeeker, version byte)

func (*Song) ReadBank2

func (s *Song) ReadBank2(r io.ReadSeeker)

func (*Song) ReadBank3

func (s *Song) ReadBank3(r io.ReadSeeker)

func (*Song) WriteBank0

func (s *Song) WriteBank0(w io.WriteSeeker)

func (*Song) WriteBank1

func (s *Song) WriteBank1(w io.WriteSeeker)

func (*Song) WriteBank2

func (s *Song) WriteBank2(w io.WriteSeeker)

func (*Song) WriteBank3

func (s *Song) WriteBank3(w io.WriteSeeker)

type Synth

type Synth struct {
	Waveform       byte
	Filter         byte
	ResonanceStart byte
	ResonanceEnd   byte
	Distortion     byte
	Phase          byte

	VolumeStart byte
	VolumeEnd   byte
	CutOffStart byte
	CutOffEnd   byte

	PhaseStart  byte
	PhaseEnd    byte
	VshiftStart byte
	VshiftEnd   byte

	LimitStart byte
	LimitEnd   byte

	Reserved [2]byte

	Overwritten byte // 0 if false, 1 if true
}

func (*Synth) Clear

func (s *Synth) Clear()

func (*Synth) ReadSoftSynthParams

func (s *Synth) ReadSoftSynthParams(r io.ReadSeeker)

func (*Synth) WriteSoftSynthParams

func (s *Synth) WriteSoftSynthParams(w io.WriteSeeker)

type Table

type Table struct {
	Volumes        [TableLen]byte
	Transpositions [TableLen]byte
	Commands1      [TableLen]Command
	Commands2      [TableLen]Command
}

func (*Table) Clear

func (t *Table) Clear()

func (*Table) GetCommand1

func (t *Table) GetCommand1() (out []byte)

func (*Table) GetCommand2

func (t *Table) GetCommand2() (out []byte)

type VibDirection

type VibDirection byte

type VibShape

type VibShape byte

type Wave

type Wave [WaveLen]byte

func (*Wave) Clear

func (w *Wave) Clear()

type Word

type Word struct {
	Allophones [WordLen]byte
	Lenghts    [WordLen]byte
}

func (*Word) Clear

func (w *Word) Clear()

func (*Word) Write

func (wo *Word) Write(w io.WriteSeeker)

Jump to

Keyboard shortcuts

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