Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ADD finishcallback, range and offset #67

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions src/playdate/bindings/sound.nim
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import utils
type FilePlayerPtr = pointer
type AudioSamplePtr = pointer
type SamplePlayerPtr = pointer
type SoundSourcePtr = pointer

type PDSndCallbackProcRaw {.importc: "sndCallbackProc", header: "pd_api.h".} = proc(soundSource: SoundSourcePtr, userData: pointer): void {.cdecl.}


type PlaydateSoundFileplayer {.importc: "const struct playdate_sound_fileplayer",
header: "pd_api.h", bycopy.} = object
Expand Down Expand Up @@ -81,13 +85,15 @@ type PlaydateSoundSampleplayer {.importc: "const struct playdate_sound_samplepla
getRate {.importc: "getRate".}: proc (player: SamplePlayerPtr): cfloat {.cdecl, raises: [].}
# setOffset* {.importc: "setOffset".}: proc (player: SamplePlayerPtr; offset: cfloat) {.
# cdecl.}
# setPlayRange* {.importc: "setPlayRange".}: proc (player: ptr SamplePlayer;
# start: cint; `end`: cint) {.cdecl.}
# setFinishCallback* {.importc: "setFinishCallback".}: proc (
# player: ptr SamplePlayer; callback: SndCallbackProc) {.cdecl.}
setPlayRange* {.importc: "setPlayRange".}: proc (player: SamplePlayerPtr;
start: cint; `end`: cint) {.cdecl, raises: [].}
setFinishCallback* {.importc: "setFinishCallback".}: proc (
player: SamplePlayerPtr; callback: PDSndCallbackProcRaw, userData: pointer = nil) {.cdecl, raises: [].}
# setLoopCallback* {.importc: "setLoopCallback".}: proc (player: ptr SamplePlayer;
# callback: SndCallbackProc) {.cdecl.}
# getOffset* {.importc: "getOffset".}: proc (player: ptr SamplePlayer): cfloat {.cdecl.}
getOffset* {.importc: "getOffset".}: proc (player: SamplePlayerPtr): cfloat {.cdecl , raises: [].}
setOffset {.importc: "setOffset".}: proc (player: SamplePlayerPtr; offset: cfloat) {.
cdecl, raises: [].}
setPaused {.importc: "setPaused".}: proc (player: SamplePlayerPtr; flag: cint) {.
cdecl, raises: [].}
# type PlaydateSoundSampleplayer* = ptr PlaydateSoundSampleplayerRaw
Expand Down
43 changes: 43 additions & 0 deletions src/playdate/sound.nim
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{.push raises: [].}

import std/importutils
import tables
import bindings/sound
import bindings/api
import system
Expand All @@ -16,9 +17,17 @@ type
resource: AudioSamplePtr
AudioSample* = ref AudioSampleObj

PDSoundCallbackFunction* = proc(userData: pointer) {.raises: [].}

var
## Finish callbacks for sound sources (FilePlayer, SamplePlayer)
soundCallbackMap: Table[SoundSourcePtr, PDSoundCallbackFunction] = initTable[SoundSourcePtr, PDSoundCallbackFunction]()


proc `=destroy`(this: var AudioSampleObj) =
privateAccess(PlaydateSound)
privateAccess(PlaydateSoundSample)
soundCallbackMap.del(this.resource)
playdate.sound.sample.freeSample(this.resource)

proc newAudioSample*(this: ptr PlaydateSound, bytes: int32): AudioSample =
Expand Down Expand Up @@ -178,6 +187,16 @@ proc setVolume*(this: SamplePlayer, left: float32, right: float32) =
privateAccess(PlaydateSoundSampleplayer)
playdate.sound.sampleplayer.setVolume(this.resource, left.cfloat, right.cfloat)

proc `offset=`*(this: SamplePlayer, offset: float32) =
privateAccess(PlaydateSound)
privateAccess(PlaydateSoundSampleplayer)
playdate.sound.sampleplayer.setOffset(this.resource, offset.cfloat)

proc offset*(this: SamplePlayer): float32 =
privateAccess(PlaydateSound)
privateAccess(PlaydateSoundSamplePlayer)
return playdate.sound.sampleplayer.getOffset(this.resource).float32

proc play*(this: SamplePlayer, repeat: int, rate: float32) =
privateAccess(PlaydateSound)
privateAccess(PlaydateSoundSampleplayer)
Expand Down Expand Up @@ -208,6 +227,30 @@ proc rate*(this: SamplePlayer): float32 =
privateAccess(PlaydateSoundSampleplayer)
return playdate.sound.sampleplayer.getRate(this.resource).float32

proc privateFinishCallback(soundSource: SoundSourcePtr, userData: pointer) {.cdecl, raises: [].} =
try:
soundCallbackMap[soundSource](userData)
except:
echo "No finish callback for sound source pointer " & repr(soundSource)

proc setFinishCallback*(this: SamplePlayer, callback: PDSoundCallbackFunction) =
privateAccess(PlaydateSound)
privateAccess(PlaydateSoundSampleplayer)
try:
if callback == nil:
soundCallbackMap.del(this.resource)
playdate.sound.sampleplayer.setFinishCallback(this.resource, nil, nil)
else:
soundCallbackMap[this.resource] = callback
playdate.sound.sampleplayer.setFinishCallback(this.resource, privateFinishCallback, nil)
except:
echo "Error setting finish callback"

proc setPlayRange*(this: SamplePlayer, start: int32, `end`: int32) =
privateAccess(PlaydateSound)
privateAccess(PlaydateSoundSampleplayer)
playdate.sound.sampleplayer.setPlayRange(this.resource, start.cint, `end`.cint)

# PlaydateSound
var headphoneChanged: proc(headphone: bool, microphone: bool) = nil

Expand Down