Scream Tracker 3 module: Go parsing library

Scream Tracker 3 module is a tracker music file format that, as all tracker music, bundles both sound samples and instructions on which notes to play. It originates from a Scream Tracker 3 music editor (1994) by Future Crew, derived from original Scream Tracker 2 (.stm) module format.

Instrument descriptions in S3M format allow to use either digital samples or setup and control AdLib (OPL2) synth.

Music is organized in so called patterns. "Pattern" is a generally a 64-row long table, which instructs which notes to play on which time measure. "Patterns" are played one-by-one in a sequence determined by orders, which is essentially an array of pattern IDs

  • this way it's possible to reuse certain patterns more than once for repetitive musical phrases.

File extension

s3m

KS implementation details

License: CC0-1.0

References

This page hosts a formal specification of Scream Tracker 3 module using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

Go source code to parse Scream Tracker 3 module

s3m.go

// Code generated by kaitai-struct-compiler from a .ksy source file. DO NOT EDIT.

import (
	"github.com/kaitai-io/kaitai_struct_go_runtime/kaitai"
	"bytes"
	"io"
)


/**
 * Scream Tracker 3 module is a tracker music file format that, as all
 * tracker music, bundles both sound samples and instructions on which
 * notes to play. It originates from a Scream Tracker 3 music editor
 * (1994) by Future Crew, derived from original Scream Tracker 2 (.stm)
 * module format.
 * 
 * Instrument descriptions in S3M format allow to use either digital
 * samples or setup and control AdLib (OPL2) synth.
 * 
 * Music is organized in so called `patterns`. "Pattern" is a generally
 * a 64-row long table, which instructs which notes to play on which
 * time measure. "Patterns" are played one-by-one in a sequence
 * determined by `orders`, which is essentially an array of pattern IDs
 * - this way it's possible to reuse certain patterns more than once
 * for repetitive musical phrases.
 * @see <a href="http://hackipedia.org/browse.cgi/File%20formats/Music%20tracker/S3M%2c%20ScreamTracker%203/Scream%20Tracker%203.20%20by%20Future%20Crew.txt">Source</a>
 */
type S3m struct {
	SongName []byte
	Magic1 []byte
	FileType uint8
	Reserved1 []byte
	NumOrders uint16
	NumInstruments uint16
	NumPatterns uint16
	Flags uint16
	Version uint16
	SamplesFormat uint16
	Magic2 []byte
	GlobalVolume uint8
	InitialSpeed uint8
	InitialTempo uint8
	IsStereo bool
	MasterVolume uint64
	UltraClickRemoval uint8
	HasCustomPan uint8
	Reserved2 []byte
	OfsSpecial uint16
	Channels []*S3m_Channel
	Orders []byte
	Instruments []*S3m_InstrumentPtr
	Patterns []*S3m_PatternPtr
	ChannelPans []*S3m_ChannelPan
	_io *kaitai.Stream
	_root *S3m
	_parent kaitai.Struct
}
func NewS3m() *S3m {
	return &S3m{
	}
}

func (this S3m) IO_() *kaitai.Stream {
	return this._io
}

func (this *S3m) Read(io *kaitai.Stream, parent kaitai.Struct, root *S3m) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp1, err := this._io.ReadBytes(int(28))
	if err != nil {
		return err
	}
	tmp1 = kaitai.BytesTerminate(tmp1, 0, false)
	this.SongName = tmp1
	tmp2, err := this._io.ReadBytes(int(1))
	if err != nil {
		return err
	}
	tmp2 = tmp2
	this.Magic1 = tmp2
	if !(bytes.Equal(this.Magic1, []uint8{26})) {
		return kaitai.NewValidationNotEqualError([]uint8{26}, this.Magic1, this._io, "/seq/1")
	}
	tmp3, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.FileType = tmp3
	tmp4, err := this._io.ReadBytes(int(2))
	if err != nil {
		return err
	}
	tmp4 = tmp4
	this.Reserved1 = tmp4
	tmp5, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.NumOrders = uint16(tmp5)
	tmp6, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.NumInstruments = uint16(tmp6)
	tmp7, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.NumPatterns = uint16(tmp7)
	tmp8, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.Flags = uint16(tmp8)
	tmp9, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.Version = uint16(tmp9)
	tmp10, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.SamplesFormat = uint16(tmp10)
	tmp11, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp11 = tmp11
	this.Magic2 = tmp11
	if !(bytes.Equal(this.Magic2, []uint8{83, 67, 82, 77})) {
		return kaitai.NewValidationNotEqualError([]uint8{83, 67, 82, 77}, this.Magic2, this._io, "/seq/10")
	}
	tmp12, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.GlobalVolume = tmp12
	tmp13, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.InitialSpeed = tmp13
	tmp14, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.InitialTempo = tmp14
	tmp15, err := this._io.ReadBitsIntBe(1)
	if err != nil {
		return err
	}
	this.IsStereo = tmp15 != 0
	tmp16, err := this._io.ReadBitsIntBe(7)
	if err != nil {
		return err
	}
	this.MasterVolume = tmp16
	this._io.AlignToByte()
	tmp17, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.UltraClickRemoval = tmp17
	tmp18, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.HasCustomPan = tmp18
	tmp19, err := this._io.ReadBytes(int(8))
	if err != nil {
		return err
	}
	tmp19 = tmp19
	this.Reserved2 = tmp19
	tmp20, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.OfsSpecial = uint16(tmp20)
	for i := 0; i < int(32); i++ {
		_ = i
		tmp21 := NewS3m_Channel()
		err = tmp21.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Channels = append(this.Channels, tmp21)
	}
	tmp22, err := this._io.ReadBytes(int(this.NumOrders))
	if err != nil {
		return err
	}
	tmp22 = tmp22
	this.Orders = tmp22
	for i := 0; i < int(this.NumInstruments); i++ {
		_ = i
		tmp23 := NewS3m_InstrumentPtr()
		err = tmp23.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Instruments = append(this.Instruments, tmp23)
	}
	for i := 0; i < int(this.NumPatterns); i++ {
		_ = i
		tmp24 := NewS3m_PatternPtr()
		err = tmp24.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Patterns = append(this.Patterns, tmp24)
	}
	if (this.HasCustomPan == 252) {
		for i := 0; i < int(32); i++ {
			_ = i
			tmp25 := NewS3m_ChannelPan()
			err = tmp25.Read(this._io, this, this._root)
			if err != nil {
				return err
			}
			this.ChannelPans = append(this.ChannelPans, tmp25)
		}
	}
	return err
}

/**
 * Number of orders in a song
 */

/**
 * Number of instruments in a song
 */

/**
 * Number of patterns in a song
 */

/**
 * Scream Tracker version that was used to save this file
 */

/**
 * 1 = signed samples, 2 = unsigned samples
 */

/**
 * Offset of special data, not used by Scream Tracker directly.
 */
type S3m_Channel struct {
	IsDisabled bool
	ChType uint64
	_io *kaitai.Stream
	_root *S3m
	_parent *S3m
}
func NewS3m_Channel() *S3m_Channel {
	return &S3m_Channel{
	}
}

func (this S3m_Channel) IO_() *kaitai.Stream {
	return this._io
}

func (this *S3m_Channel) Read(io *kaitai.Stream, parent *S3m, root *S3m) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp26, err := this._io.ReadBitsIntBe(1)
	if err != nil {
		return err
	}
	this.IsDisabled = tmp26 != 0
	tmp27, err := this._io.ReadBitsIntBe(7)
	if err != nil {
		return err
	}
	this.ChType = tmp27
	return err
}

/**
 * Channel type (0..7 = left sample channels, 8..15 = right sample channels, 16..31 = AdLib synth channels)
 */
type S3m_ChannelPan struct {
	Reserved1 uint64
	HasCustomPan bool
	Reserved2 bool
	Pan uint64
	_io *kaitai.Stream
	_root *S3m
	_parent *S3m
}
func NewS3m_ChannelPan() *S3m_ChannelPan {
	return &S3m_ChannelPan{
	}
}

func (this S3m_ChannelPan) IO_() *kaitai.Stream {
	return this._io
}

func (this *S3m_ChannelPan) Read(io *kaitai.Stream, parent *S3m, root *S3m) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp28, err := this._io.ReadBitsIntBe(2)
	if err != nil {
		return err
	}
	this.Reserved1 = tmp28
	tmp29, err := this._io.ReadBitsIntBe(1)
	if err != nil {
		return err
	}
	this.HasCustomPan = tmp29 != 0
	tmp30, err := this._io.ReadBitsIntBe(1)
	if err != nil {
		return err
	}
	this.Reserved2 = tmp30 != 0
	tmp31, err := this._io.ReadBitsIntBe(4)
	if err != nil {
		return err
	}
	this.Pan = tmp31
	return err
}

/**
 * If true, then use a custom pan setting provided in the `pan`
 * field. If false, the channel would use the default setting
 * (0x7 for mono, 0x3 or 0xc for stereo).
 */

type S3m_Instrument_InstTypes int
const (
	S3m_Instrument_InstTypes__Sample S3m_Instrument_InstTypes = 1
	S3m_Instrument_InstTypes__Melodic S3m_Instrument_InstTypes = 2
	S3m_Instrument_InstTypes__BassDrum S3m_Instrument_InstTypes = 3
	S3m_Instrument_InstTypes__SnareDrum S3m_Instrument_InstTypes = 4
	S3m_Instrument_InstTypes__Tom S3m_Instrument_InstTypes = 5
	S3m_Instrument_InstTypes__Cymbal S3m_Instrument_InstTypes = 6
	S3m_Instrument_InstTypes__Hihat S3m_Instrument_InstTypes = 7
)
var values_S3m_Instrument_InstTypes = map[S3m_Instrument_InstTypes]struct{}{1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {}}
func (v S3m_Instrument_InstTypes) isDefined() bool {
	_, ok := values_S3m_Instrument_InstTypes[v]
	return ok
}
type S3m_Instrument struct {
	Type S3m_Instrument_InstTypes
	Filename []byte
	Body kaitai.Struct
	TuningHz uint32
	Reserved2 []byte
	SampleName []byte
	Magic []byte
	_io *kaitai.Stream
	_root *S3m
	_parent *S3m_InstrumentPtr
}
func NewS3m_Instrument() *S3m_Instrument {
	return &S3m_Instrument{
	}
}

func (this S3m_Instrument) IO_() *kaitai.Stream {
	return this._io
}

func (this *S3m_Instrument) Read(io *kaitai.Stream, parent *S3m_InstrumentPtr, root *S3m) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp32, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Type = S3m_Instrument_InstTypes(tmp32)
	tmp33, err := this._io.ReadBytes(int(12))
	if err != nil {
		return err
	}
	tmp33 = kaitai.BytesTerminate(tmp33, 0, false)
	this.Filename = tmp33
	switch (this.Type) {
	case S3m_Instrument_InstTypes__Sample:
		tmp34 := NewS3m_Instrument_Sampled()
		err = tmp34.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp34
	default:
		tmp35 := NewS3m_Instrument_Adlib()
		err = tmp35.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Body = tmp35
	}
	tmp36, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.TuningHz = uint32(tmp36)
	tmp37, err := this._io.ReadBytes(int(12))
	if err != nil {
		return err
	}
	tmp37 = tmp37
	this.Reserved2 = tmp37
	tmp38, err := this._io.ReadBytes(int(28))
	if err != nil {
		return err
	}
	tmp38 = kaitai.BytesTerminate(tmp38, 0, false)
	this.SampleName = tmp38
	tmp39, err := this._io.ReadBytes(int(4))
	if err != nil {
		return err
	}
	tmp39 = tmp39
	this.Magic = tmp39
	if !(bytes.Equal(this.Magic, []uint8{83, 67, 82, 83})) {
		return kaitai.NewValidationNotEqualError([]uint8{83, 67, 82, 83}, this.Magic, this._io, "/types/instrument/seq/6")
	}
	return err
}
type S3m_Instrument_Adlib struct {
	Reserved1 []byte
	_unnamed1 []byte
	_io *kaitai.Stream
	_root *S3m
	_parent *S3m_Instrument
}
func NewS3m_Instrument_Adlib() *S3m_Instrument_Adlib {
	return &S3m_Instrument_Adlib{
	}
}

func (this S3m_Instrument_Adlib) IO_() *kaitai.Stream {
	return this._io
}

func (this *S3m_Instrument_Adlib) Read(io *kaitai.Stream, parent *S3m_Instrument, root *S3m) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp40, err := this._io.ReadBytes(int(3))
	if err != nil {
		return err
	}
	tmp40 = tmp40
	this.Reserved1 = tmp40
	if !(bytes.Equal(this.Reserved1, []uint8{0, 0, 0})) {
		return kaitai.NewValidationNotEqualError([]uint8{0, 0, 0}, this.Reserved1, this._io, "/types/instrument/types/adlib/seq/0")
	}
	tmp41, err := this._io.ReadBytes(int(16))
	if err != nil {
		return err
	}
	tmp41 = tmp41
	this._unnamed1 = tmp41
	return err
}
type S3m_Instrument_Sampled struct {
	ParaptrSample *S3m_SwappedU3
	LenSample uint32
	LoopBegin uint32
	LoopEnd uint32
	DefaultVolume uint8
	Reserved1 uint8
	IsPacked uint8
	Flags uint8
	_io *kaitai.Stream
	_root *S3m
	_parent *S3m_Instrument
	_f_sample bool
	sample []byte
}
func NewS3m_Instrument_Sampled() *S3m_Instrument_Sampled {
	return &S3m_Instrument_Sampled{
	}
}

func (this S3m_Instrument_Sampled) IO_() *kaitai.Stream {
	return this._io
}

func (this *S3m_Instrument_Sampled) Read(io *kaitai.Stream, parent *S3m_Instrument, root *S3m) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp42 := NewS3m_SwappedU3()
	err = tmp42.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.ParaptrSample = tmp42
	tmp43, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.LenSample = uint32(tmp43)
	tmp44, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.LoopBegin = uint32(tmp44)
	tmp45, err := this._io.ReadU4le()
	if err != nil {
		return err
	}
	this.LoopEnd = uint32(tmp45)
	tmp46, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.DefaultVolume = tmp46
	tmp47, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Reserved1 = tmp47
	tmp48, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.IsPacked = tmp48
	tmp49, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Flags = tmp49
	return err
}
func (this *S3m_Instrument_Sampled) Sample() (v []byte, err error) {
	if (this._f_sample) {
		return this.sample, nil
	}
	this._f_sample = true
	_pos, err := this._io.Pos()
	if err != nil {
		return nil, err
	}
	tmp50, err := this.ParaptrSample.Value()
	if err != nil {
		return nil, err
	}
	_, err = this._io.Seek(int64(tmp50 * 16), io.SeekStart)
	if err != nil {
		return nil, err
	}
	tmp51, err := this._io.ReadBytes(int(this.LenSample))
	if err != nil {
		return nil, err
	}
	tmp51 = tmp51
	this.sample = tmp51
	_, err = this._io.Seek(_pos, io.SeekStart)
	if err != nil {
		return nil, err
	}
	return this.sample, nil
}

/**
 * Default volume
 */

/**
 * 0 = unpacked, 1 = DP30ADPCM packing
 */
type S3m_InstrumentPtr struct {
	Paraptr uint16
	_io *kaitai.Stream
	_root *S3m
	_parent *S3m
	_f_body bool
	body *S3m_Instrument
}
func NewS3m_InstrumentPtr() *S3m_InstrumentPtr {
	return &S3m_InstrumentPtr{
	}
}

func (this S3m_InstrumentPtr) IO_() *kaitai.Stream {
	return this._io
}

func (this *S3m_InstrumentPtr) Read(io *kaitai.Stream, parent *S3m, root *S3m) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp52, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.Paraptr = uint16(tmp52)
	return err
}
func (this *S3m_InstrumentPtr) Body() (v *S3m_Instrument, err error) {
	if (this._f_body) {
		return this.body, nil
	}
	this._f_body = true
	_pos, err := this._io.Pos()
	if err != nil {
		return nil, err
	}
	_, err = this._io.Seek(int64(this.Paraptr * 16), io.SeekStart)
	if err != nil {
		return nil, err
	}
	tmp53 := NewS3m_Instrument()
	err = tmp53.Read(this._io, this, this._root)
	if err != nil {
		return nil, err
	}
	this.body = tmp53
	_, err = this._io.Seek(_pos, io.SeekStart)
	if err != nil {
		return nil, err
	}
	return this.body, nil
}
type S3m_Pattern struct {
	Size uint16
	Body *S3m_PatternCells
	_io *kaitai.Stream
	_root *S3m
	_parent *S3m_PatternPtr
	_raw_Body []byte
}
func NewS3m_Pattern() *S3m_Pattern {
	return &S3m_Pattern{
	}
}

func (this S3m_Pattern) IO_() *kaitai.Stream {
	return this._io
}

func (this *S3m_Pattern) Read(io *kaitai.Stream, parent *S3m_PatternPtr, root *S3m) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp54, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.Size = uint16(tmp54)
	tmp55, err := this._io.ReadBytes(int(this.Size - 2))
	if err != nil {
		return err
	}
	tmp55 = tmp55
	this._raw_Body = tmp55
	_io__raw_Body := kaitai.NewStream(bytes.NewReader(this._raw_Body))
	tmp56 := NewS3m_PatternCells()
	err = tmp56.Read(_io__raw_Body, this, this._root)
	if err != nil {
		return err
	}
	this.Body = tmp56
	return err
}
type S3m_PatternCell struct {
	HasFx bool
	HasVolume bool
	HasNoteAndInstrument bool
	ChannelNum uint64
	Note uint8
	Instrument uint8
	Volume uint8
	FxType uint8
	FxValue uint8
	_io *kaitai.Stream
	_root *S3m
	_parent *S3m_PatternCells
}
func NewS3m_PatternCell() *S3m_PatternCell {
	return &S3m_PatternCell{
	}
}

func (this S3m_PatternCell) IO_() *kaitai.Stream {
	return this._io
}

func (this *S3m_PatternCell) Read(io *kaitai.Stream, parent *S3m_PatternCells, root *S3m) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp57, err := this._io.ReadBitsIntBe(1)
	if err != nil {
		return err
	}
	this.HasFx = tmp57 != 0
	tmp58, err := this._io.ReadBitsIntBe(1)
	if err != nil {
		return err
	}
	this.HasVolume = tmp58 != 0
	tmp59, err := this._io.ReadBitsIntBe(1)
	if err != nil {
		return err
	}
	this.HasNoteAndInstrument = tmp59 != 0
	tmp60, err := this._io.ReadBitsIntBe(5)
	if err != nil {
		return err
	}
	this.ChannelNum = tmp60
	this._io.AlignToByte()
	if (this.HasNoteAndInstrument) {
		tmp61, err := this._io.ReadU1()
		if err != nil {
			return err
		}
		this.Note = tmp61
	}
	if (this.HasNoteAndInstrument) {
		tmp62, err := this._io.ReadU1()
		if err != nil {
			return err
		}
		this.Instrument = tmp62
	}
	if (this.HasVolume) {
		tmp63, err := this._io.ReadU1()
		if err != nil {
			return err
		}
		this.Volume = tmp63
	}
	if (this.HasFx) {
		tmp64, err := this._io.ReadU1()
		if err != nil {
			return err
		}
		this.FxType = tmp64
	}
	if (this.HasFx) {
		tmp65, err := this._io.ReadU1()
		if err != nil {
			return err
		}
		this.FxValue = tmp65
	}
	return err
}
type S3m_PatternCells struct {
	Cells []*S3m_PatternCell
	_io *kaitai.Stream
	_root *S3m
	_parent *S3m_Pattern
}
func NewS3m_PatternCells() *S3m_PatternCells {
	return &S3m_PatternCells{
	}
}

func (this S3m_PatternCells) IO_() *kaitai.Stream {
	return this._io
}

func (this *S3m_PatternCells) Read(io *kaitai.Stream, parent *S3m_Pattern, root *S3m) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	for i := 0;; i++ {
		tmp66, err := this._io.EOF()
		if err != nil {
			return err
		}
		if tmp66 {
			break
		}
		tmp67 := NewS3m_PatternCell()
		err = tmp67.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Cells = append(this.Cells, tmp67)
	}
	return err
}
type S3m_PatternPtr struct {
	Paraptr uint16
	_io *kaitai.Stream
	_root *S3m
	_parent *S3m
	_f_body bool
	body *S3m_Pattern
}
func NewS3m_PatternPtr() *S3m_PatternPtr {
	return &S3m_PatternPtr{
	}
}

func (this S3m_PatternPtr) IO_() *kaitai.Stream {
	return this._io
}

func (this *S3m_PatternPtr) Read(io *kaitai.Stream, parent *S3m, root *S3m) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp68, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.Paraptr = uint16(tmp68)
	return err
}
func (this *S3m_PatternPtr) Body() (v *S3m_Pattern, err error) {
	if (this._f_body) {
		return this.body, nil
	}
	this._f_body = true
	_pos, err := this._io.Pos()
	if err != nil {
		return nil, err
	}
	_, err = this._io.Seek(int64(this.Paraptr * 16), io.SeekStart)
	if err != nil {
		return nil, err
	}
	tmp69 := NewS3m_Pattern()
	err = tmp69.Read(this._io, this, this._root)
	if err != nil {
		return nil, err
	}
	this.body = tmp69
	_, err = this._io.Seek(_pos, io.SeekStart)
	if err != nil {
		return nil, err
	}
	return this.body, nil
}

/**
 * Custom 3-byte integer, stored in mixed endian manner.
 */
type S3m_SwappedU3 struct {
	Hi uint8
	Lo uint16
	_io *kaitai.Stream
	_root *S3m
	_parent *S3m_Instrument_Sampled
	_f_value bool
	value int
}
func NewS3m_SwappedU3() *S3m_SwappedU3 {
	return &S3m_SwappedU3{
	}
}

func (this S3m_SwappedU3) IO_() *kaitai.Stream {
	return this._io
}

func (this *S3m_SwappedU3) Read(io *kaitai.Stream, parent *S3m_Instrument_Sampled, root *S3m) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp70, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Hi = tmp70
	tmp71, err := this._io.ReadU2le()
	if err != nil {
		return err
	}
	this.Lo = uint16(tmp71)
	return err
}
func (this *S3m_SwappedU3) Value() (v int, err error) {
	if (this._f_value) {
		return this.value, nil
	}
	this._f_value = true
	this.value = int(this.Lo | this.Hi << 16)
	return this.value, nil
}