Skip to content

Commit

Permalink
Rewrote the DeviceInfo struct so that it uses pure Go types and is no…
Browse files Browse the repository at this point in the history
… longer directly passable to Miniaudio. This is to avoide subtle errors where Miniaudio updates, an internal struct field type changes, and suddenly your app is crashing for no good reason because the Malgo version of the Info struct is still using the old types, some field offsets are all wrong ETC. Before this, Malgo could crash on 32-bit Windows. Now CGO resolves struct field offsets and we just convert between C and Go.

DeviceInfo now uses anonymous structs just like Miniaudio. The advantage of this is that everything is in one place and looks nicer in docs, and we can remove a bunch of types that are only ever used in device info and clutter up the docs.

Added the DeviceInfo.toCRepr() and deviceInfoFromCRepr method and function which convert between C and Go representations of DeviceInfo.

All fields with type uint32 are now type int, meaning you usually need less type conversions. Many Go functions just use int by default and converting between everything is annoying.

Name is now type string instead of type [256]char and we use C.GoString to properly convert it into a Go string. We could probably convert it to a string instead using string(info.Name[:firstZeroByte]), but whatever. Fixes gen2brain#28.

Added the Formats field which is a slice of FormatType. This replaces the old Formats and FormatCount fields and does a better job than both of them combined, which is basically what it is.

Breaking change because the types of nearly all if not all fields has changed. Nothing else has changed.
  • Loading branch information
Keithcat1 committed Sep 15, 2021
1 parent 2184b47 commit 679c633
Showing 1 changed file with 29 additions and 26 deletions.
55 changes: 29 additions & 26 deletions device_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,42 +20,45 @@ func (d DeviceID) String() string {
}
return hex.EncodeToString(d[:displayLen])
}

func (d *DeviceID) Pointer() unsafe.Pointer {
return C.CBytes(d[:])
}

func (d *DeviceID) cptr() *C.ma_device_id {
return (*C.ma_device_id)(unsafe.Pointer(d))
}

// DeviceInfo type.
type DeviceInfo struct {
ID DeviceID
name [256]byte
IsDefault uint32
FormatCount uint32
Formats [6]uint32
MinChannels uint32
MaxChannels uint32
MinSampleRate uint32
MaxSampleRate uint32

_ uint32
_ [64]byte
_ [4]byte
Name string
IsDefault bool
// the formats supported by the device
Formats []FormatType
MinChannels int
MaxChannels int
MinSampleRate int
MaxSampleRate int
}
// String returns string.
func deviceInfoFromCRepr(cInfo C.ma_device_info) DeviceInfo {
info := DeviceInfo {
ID : *(*DeviceID)(unsafe.Pointer(&cInfo.id)),
Name: goString(&cInfo.name[0]),
IsDefault: intToBool(cInfo.isDefault),
Formats: func() []FormatType {

// Name returns the name of the device.
func (d *DeviceInfo) Name() string {
return string(d.name[:])
var formats = make([]FormatType, int(cInfo.formatCount))
for pos, i := range cInfo.formats[:int(cInfo.formatCount)] {
formats[pos] = FormatType(i)
}
return formats
}(),
MinChannels: int(cInfo.minChannels),
MaxChannels: int(cInfo.maxChannels),
MinSampleRate: int(cInfo.minSampleRate),
MaxSampleRate: int(cInfo.maxSampleRate),
}
return info
}

// String returns string.
func (d *DeviceInfo) String() string {
return fmt.Sprintf("{ID: [%v], Name: %s}", d.ID, d.Name())
}

func deviceInfoFromPointer(ptr unsafe.Pointer) DeviceInfo {
return *(*DeviceInfo)(ptr)
}
return fmt.Sprintf("{ID: [%v], Name: %s}", d.ID, d.Name)
}

0 comments on commit 679c633

Please sign in to comment.