audio.go 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  1. // Audio extension
  2. package al
  3. /*
  4. #cgo pkg-config: allegro_audio-5
  5. #cgo CFLAGS: -I/usr/local/include
  6. #cgo linux LDFLAGS: -lc_nonshared
  7. #include <stdlib.h>
  8. #include <allegro5/allegro.h>
  9. #include <allegro5/allegro_audio.h>
  10. #include "helpers.h"
  11. */
  12. import "C"
  13. import "runtime"
  14. import "unsafe"
  15. // User event type emitted when a stream fragment is ready to be
  16. // refilled with more audio data.
  17. const (
  18. EVENT_AUDIO_STREAM_FRAGMENT = C.ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT
  19. EVENT_AUDIO_STREAM_FINISHED = C.ALLEGRO_EVENT_AUDIO_STREAM_FINISHED
  20. EVENT_AUDIO_RECORDER_FRAGMENT = C.ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT
  21. )
  22. // Converts wrapper Event pointer to C Allegro audio recorder event
  23. func (self *Event) AUDIO_RECORDER_EVENT() *C.ALLEGRO_AUDIO_RECORDER_EVENT {
  24. return (*C.ALLEGRO_AUDIO_RECORDER_EVENT)(self.toPointer())
  25. }
  26. type AudioRecorderEvent C.ALLEGRO_AUDIO_RECORDER_EVENT
  27. type AudioDepth int
  28. // Converts an AudioDepth to an ALLEGRO_AUDIO_DEPTH
  29. func (self AudioDepth) toC() C.ALLEGRO_AUDIO_DEPTH {
  30. return C.ALLEGRO_AUDIO_DEPTH(self)
  31. }
  32. const (
  33. AUDIO_DEPTH_INT8 AudioDepth = C.ALLEGRO_AUDIO_DEPTH_INT8
  34. AUDIO_DEPTH_INT16 AudioDepth = C.ALLEGRO_AUDIO_DEPTH_INT16
  35. AUDIO_DEPTH_INT24 AudioDepth = C.ALLEGRO_AUDIO_DEPTH_INT24
  36. AUDIO_DEPTH_UINT8 AudioDepth = C.ALLEGRO_AUDIO_DEPTH_UINT8
  37. AUDIO_DEPTH_UINT16 AudioDepth = C.ALLEGRO_AUDIO_DEPTH_UINT16
  38. AUDIO_DEPTH_UINT24 AudioDepth = C.ALLEGRO_AUDIO_DEPTH_UINT24
  39. AUDIO_DEPTH_FLOAT32 AudioDepth = C.ALLEGRO_AUDIO_DEPTH_FLOAT32
  40. AUDIO_DEPTH_UNSIGNED AudioDepth = C.ALLEGRO_AUDIO_DEPTH_UNSIGNED
  41. )
  42. /*
  43. Speaker configuration (mono, stereo, 2.1, 3, etc). With regards to
  44. * behavior, most of this code makes no distinction between, say, 4.1 and
  45. * 5 speaker setups.. they both have 5 "channels". However, users would
  46. * like the distinction, and later when the higher-level stuff is added,
  47. * the differences will become more important. (v>>4)+(v&0xF) should yield
  48. * the total channel count.
  49. */
  50. type ChannelConf int
  51. // Converts a ChannelConf to a C.ALLEGRO_CHANNEL_CONF
  52. func (self ChannelConf) toC() C.ALLEGRO_CHANNEL_CONF {
  53. return (C.ALLEGRO_CHANNEL_CONF)(self)
  54. }
  55. const (
  56. CHANNEL_CONF_1 ChannelConf = C.ALLEGRO_CHANNEL_CONF_1
  57. CHANNEL_CONF_2 ChannelConf = C.ALLEGRO_CHANNEL_CONF_2
  58. CHANNEL_CONF_3 ChannelConf = C.ALLEGRO_CHANNEL_CONF_3
  59. CHANNEL_CONF_4 ChannelConf = C.ALLEGRO_CHANNEL_CONF_4
  60. CHANNEL_CONF_5_1 ChannelConf = C.ALLEGRO_CHANNEL_CONF_5_1
  61. CHANNEL_CONF_6_1 ChannelConf = C.ALLEGRO_CHANNEL_CONF_6_1
  62. CHANNEL_CONF_7_1 ChannelConf = C.ALLEGRO_CHANNEL_CONF_7_1
  63. MAX_CHANNELS ChannelConf = C.ALLEGRO_MAX_CHANNELS
  64. )
  65. type PlayMode int
  66. // Converts a PlayMode to a C.ALLEGRO_PLAYMODE
  67. func (self PlayMode) toC() C.ALLEGRO_PLAYMODE {
  68. return (C.ALLEGRO_PLAYMODE)(self)
  69. }
  70. const (
  71. PLAYMODE_ONCE PlayMode = C.ALLEGRO_PLAYMODE_ONCE
  72. PLAYMODE_LOOP PlayMode = C.ALLEGRO_PLAYMODE_LOOP
  73. PLAYMODE_BIDIR PlayMode = C.ALLEGRO_PLAYMODE_BIDIR
  74. )
  75. type MixerQuality int
  76. // Converts a MixerQuaklity to a C.ALLEGRO_MIXER_QUALITY
  77. func (self MixerQuality) toC() C.ALLEGRO_MIXER_QUALITY {
  78. return (C.ALLEGRO_MIXER_QUALITY)(self)
  79. }
  80. const (
  81. MIXER_QUALITY_POINT MixerQuality = C.ALLEGRO_MIXER_QUALITY_POINT
  82. MIXER_QUALITY_LINEAR MixerQuality = C.ALLEGRO_MIXER_QUALITY_LINEAR
  83. MIXER_QUALITY_CUBIC MixerQuality = C.ALLEGRO_MIXER_QUALITY_CUBIC
  84. )
  85. const AUDIO_PAN_NONE = -1000.0
  86. type AudioEventType int
  87. const (
  88. ALLEGRO_EVENT_AUDIO_ROUTE_CHANGE = C.ALLEGRO_EVENT_AUDIO_ROUTE_CHANGE
  89. EVENT_AUDIO_INTERRUPTION = C.ALLEGRO_EVENT_AUDIO_INTERRUPTION
  90. EVENT_AUDIO_END_INTERRUPTION = C.ALLEGRO_EVENT_AUDIO_END_INTERRUPTION
  91. )
  92. type Sample struct {
  93. handle *C.ALLEGRO_SAMPLE
  94. }
  95. type SampleId C.ALLEGRO_SAMPLE_ID
  96. func (self *SampleId) toC() *C.ALLEGRO_SAMPLE_ID {
  97. return (*C.ALLEGRO_SAMPLE_ID)(self)
  98. }
  99. type SampleInstance struct {
  100. handle *C.ALLEGRO_SAMPLE_INSTANCE
  101. }
  102. type AudioStream struct {
  103. handle *C.ALLEGRO_AUDIO_STREAM
  104. }
  105. type Mixer struct {
  106. handle *C.ALLEGRO_MIXER
  107. }
  108. type Voice struct {
  109. handle *C.ALLEGRO_VOICE
  110. }
  111. type AudioRecorder struct {
  112. handle *C.ALLEGRO_AUDIO_RECORDER
  113. }
  114. func (self *Sample) toC() *C.ALLEGRO_SAMPLE {
  115. return (*C.ALLEGRO_SAMPLE)(self.handle)
  116. }
  117. // Destroys the sample.
  118. func (self *Sample) Destroy() {
  119. if self.handle != nil {
  120. C.al_destroy_sample(self.toC())
  121. }
  122. self.handle = nil
  123. }
  124. // Sets up a finalizer for this Sample that calls Destroy() and return self
  125. func (self *Sample) SetDestroyFinalizer() *Sample {
  126. if self != nil {
  127. runtime.SetFinalizer(self, func(me *Sample) { me.Destroy() })
  128. }
  129. return self
  130. }
  131. func wrapSampleRaw(sample *C.ALLEGRO_SAMPLE) *Sample {
  132. if sample == nil {
  133. return nil
  134. }
  135. return &Sample{sample}
  136. }
  137. func wrapSample(sample *C.ALLEGRO_SAMPLE) *Sample {
  138. self := wrapSampleRaw(sample)
  139. if self != nil {
  140. runtime.SetFinalizer(self, func(me *Sample) { me.Destroy() })
  141. }
  142. return self
  143. }
  144. func createSample(data []byte, samples uint, freq uint, depth AudioDepth, chan_conf ChannelConf) *C.ALLEGRO_SAMPLE {
  145. // don't let allegro free the data, it's owned by Go.
  146. // XXX: copy data here in stead of using the go data???
  147. return C.al_create_sample(unsafe.Pointer(&data[0]), C.uint(samples),
  148. C.uint(freq), depth.toC(), chan_conf.toC(), b2cb(false))
  149. }
  150. // Creates a Sample with a Destroy finalizer set. BEWARE! data must be big enough fort he params
  151. // or this will crash spectacularly. Also, make sure that data doesn't get collected by the GC, or
  152. // trouble will arise.
  153. func CreateSample(data []byte, samples uint, freq uint, depth AudioDepth, chan_conf ChannelConf) *Sample {
  154. return wrapSample(createSample(data, samples, freq, depth, chan_conf))
  155. }
  156. // Returns the frequency of the sample
  157. func (self *Sample) Frequency() uint {
  158. return uint(C.al_get_sample_frequency(self.handle))
  159. }
  160. // Returns the length of the sample
  161. func (self *Sample) Length() uint {
  162. return uint(C.al_get_sample_length(self.handle))
  163. }
  164. // Returns the depth of the sample
  165. func (self *Sample) Depth() uint {
  166. return uint(C.al_get_sample_depth(self.handle))
  167. }
  168. // returns the amount of channels the sample has
  169. func (self *Sample) Channels() uint {
  170. return uint(C.al_get_sample_channels(self.handle))
  171. }
  172. // Returns the raw data pointer of the sample data.
  173. func (self *Sample) DataRaw() unsafe.Pointer {
  174. return (C.al_get_sample_data(self.handle))
  175. }
  176. // Returns the frequency of the sample instance
  177. func (self *SampleInstance) Frequency() uint {
  178. return uint(C.al_get_sample_instance_frequency(self.handle))
  179. }
  180. // Returns the length of the sample instance
  181. func (self *SampleInstance) Length() uint {
  182. return uint(C.al_get_sample_instance_length(self.handle))
  183. }
  184. // Returns the position of the sample instance
  185. func (self *SampleInstance) Position() uint {
  186. return uint(C.al_get_sample_instance_position(self.handle))
  187. }
  188. // Returns the of the sample instance
  189. func (self *SampleInstance) Speed() float32 {
  190. return float32(C.al_get_sample_instance_speed(self.handle))
  191. }
  192. // Returns the of the sample instance
  193. func (self *SampleInstance) Gain() float32 {
  194. return float32(C.al_get_sample_instance_gain(self.handle))
  195. }
  196. // Returns the of the sample instance
  197. func (self *SampleInstance) Pan() float32 {
  198. return float32(C.al_get_sample_instance_pan(self.handle))
  199. }
  200. // Returns the of the sample instance
  201. func (self *SampleInstance) Time() float32 {
  202. return float32(C.al_get_sample_instance_time(self.handle))
  203. }
  204. // Returns the depth of the sample instance
  205. func (self *SampleInstance) Depth() AudioDepth {
  206. return AudioDepth(C.al_get_sample_instance_depth(self.handle))
  207. }
  208. // Returns the channel configuration of the sample instance
  209. func (self *SampleInstance) Channels() ChannelConf {
  210. return ChannelConf(C.al_get_sample_instance_channels(self.handle))
  211. }
  212. // Returns the play mode of the sample instance
  213. func (self *SampleInstance) Playmode() PlayMode {
  214. return PlayMode(C.al_get_sample_instance_playmode(self.handle))
  215. }
  216. // Returns wheter or not the sample instance is playing
  217. func (self *SampleInstance) Playing() bool {
  218. return cb2b(C.al_get_sample_instance_playing(self.handle))
  219. }
  220. // Returns wheter or not the sample instance is attached
  221. func (self *SampleInstance) Attached() bool {
  222. return cb2b(C.al_get_sample_instance_attached(self.handle))
  223. }
  224. // Sets the position of the sample instance.
  225. func (self *SampleInstance) SetPosition(val uint) bool {
  226. return cb2b(C.al_set_sample_instance_position(self.handle, C.uint(val)))
  227. }
  228. // Sets the length of the sample instance.
  229. func (self *SampleInstance) SetLength(val uint) bool {
  230. return cb2b(C.al_set_sample_instance_length(self.handle, C.uint(val)))
  231. }
  232. // Sets the speed of the sample instance.
  233. func (self *SampleInstance) SetSpeed(val float32) bool {
  234. return cb2b(C.al_set_sample_instance_speed(self.handle, C.float(val)))
  235. }
  236. // Sets the gain of the sample instance.
  237. func (self *SampleInstance) SetGain(val float32) bool {
  238. return cb2b(C.al_set_sample_instance_gain(self.handle, C.float(val)))
  239. }
  240. // Sets the pan of the sample instance.
  241. func (self *SampleInstance) SetPan(val float32) bool {
  242. return cb2b(C.al_set_sample_instance_pan(self.handle, C.float(val)))
  243. }
  244. // Sets the play mode of the sample instance.
  245. func (self *SampleInstance) SetPlaymode(val PlayMode) bool {
  246. return cb2b(C.al_set_sample_instance_playmode(self.handle, val.toC()))
  247. }
  248. // Sets the play status of the sample instance.
  249. func (self *SampleInstance) SetPlaying(val bool) bool {
  250. return cb2b(C.al_set_sample_instance_playing(self.handle, b2cb(val)))
  251. }
  252. // Detaches the sample instance from it's player
  253. func (self *SampleInstance) Detach() bool {
  254. return cb2b(C.al_detach_sample_instance(self.handle))
  255. }
  256. // Sets the sample data to use for the sample instance
  257. func (self *SampleInstance) SetSample(val *Sample) bool {
  258. return cb2b(C.al_set_sample(self.handle, val.handle))
  259. }
  260. // Gets the RAW sample data that was linked to the sample instance
  261. func (self *SampleInstance) SampleRaw() *Sample {
  262. return wrapSampleRaw(C.al_get_sample(self.handle))
  263. }
  264. // Plays the sample instance
  265. func (self *SampleInstance) Play() bool {
  266. return cb2b(C.al_play_sample_instance(self.handle))
  267. }
  268. // Stops the sample instannce playback
  269. func (self *SampleInstance) Stop() bool {
  270. return cb2b(C.al_stop_sample_instance(self.handle))
  271. }
  272. func (self *AudioStream) toC() *C.ALLEGRO_AUDIO_STREAM {
  273. return (*C.ALLEGRO_AUDIO_STREAM)(self.handle)
  274. }
  275. // Destroys the audio stream.
  276. func (self *AudioStream) Destroy() {
  277. if self.handle != nil {
  278. C.al_destroy_audio_stream(self.toC())
  279. }
  280. self.handle = nil
  281. }
  282. // Sets up a finalizer for this AudioStream that calls Destroy() and return self
  283. func (self *AudioStream) SetDestroyFinalizer() *AudioStream {
  284. if self != nil {
  285. runtime.SetFinalizer(self, func(me *AudioStream) { me.Destroy() })
  286. }
  287. return self
  288. }
  289. func wrapAudioStreamRaw(data *C.ALLEGRO_AUDIO_STREAM) *AudioStream {
  290. if data == nil {
  291. return nil
  292. }
  293. return &AudioStream{data}
  294. }
  295. func wrapAudioStream(data *C.ALLEGRO_AUDIO_STREAM) *AudioStream {
  296. self := wrapAudioStreamRaw(data)
  297. return self.SetDestroyFinalizer()
  298. }
  299. // Creates an audio stream, with finalizer installed.
  300. func CreateAudioStream(bufc, samples, freq uint, depth AudioDepth, chan_conf ChannelConf) *AudioStream {
  301. return wrapAudioStream(C.al_create_audio_stream(C.size_t(bufc), C.uint(samples),
  302. C.uint(freq), depth.toC(), chan_conf.toC()))
  303. }
  304. // Creates an audio stream, with NO finalizer installed.
  305. func CreateAudioStreamRaw(bufc, samples, freq uint, depth AudioDepth, chan_conf ChannelConf) *AudioStream {
  306. return wrapAudioStreamRaw(C.al_create_audio_stream(C.size_t(bufc), C.uint(samples),
  307. C.uint(freq), depth.toC(), chan_conf.toC()))
  308. }
  309. // Drains all data from an audio stream
  310. func (self *AudioStream) Drain() {
  311. C.al_drain_audio_stream(self.handle)
  312. }
  313. // Returns the frequency of the audio stream
  314. func (self *AudioStream) Frequency() uint {
  315. return uint(C.al_get_audio_stream_frequency(self.handle))
  316. }
  317. // Returns the length of the audio stream
  318. func (self *AudioStream) Length() uint {
  319. return uint(C.al_get_audio_stream_length(self.handle))
  320. }
  321. // Returns the speed of the audio stream
  322. func (self *AudioStream) Speed() float32 {
  323. return float32(C.al_get_audio_stream_speed(self.handle))
  324. }
  325. // Returns the amount of fragments of the audio stream
  326. func (self *AudioStream) Fragments() float32 {
  327. return float32(C.al_get_audio_stream_fragments(self.handle))
  328. }
  329. // Returns the amount of available fragments of the audio stream
  330. func (self *AudioStream) AvailableFragments() float32 {
  331. return float32(C.al_get_available_audio_stream_fragments(self.handle))
  332. }
  333. // Returns the gain of the audio stream
  334. func (self *AudioStream) Gain() float32 {
  335. return float32(C.al_get_audio_stream_gain(self.handle))
  336. }
  337. // Returns the pan of the audio stream
  338. func (self *AudioStream) Pan() float32 {
  339. return float32(C.al_get_audio_stream_pan(self.handle))
  340. }
  341. // Returns the depth of the audio stream
  342. func (self *AudioStream) Depth() AudioDepth {
  343. return AudioDepth(C.al_get_audio_stream_depth(self.handle))
  344. }
  345. // Returns the channel configuration of the audio stream
  346. func (self *AudioStream) Channels() ChannelConf {
  347. return ChannelConf(C.al_get_audio_stream_channels(self.handle))
  348. }
  349. // Returns the play mode of the audio stream
  350. func (self *AudioStream) Playmode() PlayMode {
  351. return PlayMode(C.al_get_audio_stream_playmode(self.handle))
  352. }
  353. // Returns wheter or not the audio stream is playing
  354. func (self *AudioStream) Playing() bool {
  355. return cb2b(C.al_get_audio_stream_playing(self.handle))
  356. }
  357. // Returns wheter or not the audio stream is attached
  358. func (self *AudioStream) Attached() bool {
  359. return cb2b(C.al_get_audio_stream_attached(self.handle))
  360. }
  361. // Returns an unsafe pointer to the audio stream's fragment
  362. func (self *AudioStream) Fragment() unsafe.Pointer {
  363. return C.al_get_audio_stream_fragment(self.handle)
  364. }
  365. // Sets the speed of the audio stream.
  366. func (self *AudioStream) SetSpeed(val float32) bool {
  367. return cb2b(C.al_set_audio_stream_speed(self.handle, C.float(val)))
  368. }
  369. // Sets the gain of the audio stream.
  370. func (self *AudioStream) SetGain(val float32) bool {
  371. return cb2b(C.al_set_audio_stream_gain(self.handle, C.float(val)))
  372. }
  373. // Sets the pan of the audio stream.
  374. func (self *AudioStream) SetPan(val float32) bool {
  375. return cb2b(C.al_set_audio_stream_pan(self.handle, C.float(val)))
  376. }
  377. // Sets the play mode of the audio stream.
  378. func (self *AudioStream) SetPlaymode(val PlayMode) bool {
  379. return cb2b(C.al_set_audio_stream_playmode(self.handle, val.toC()))
  380. }
  381. // Sets the play status of the audio stream.
  382. func (self *AudioStream) SetPlaying(val bool) bool {
  383. return cb2b(C.al_set_audio_stream_playing(self.handle, b2cb(val)))
  384. }
  385. // Detaches the audio stream from it's player
  386. func (self *AudioStream) Detach() bool {
  387. return cb2b(C.al_detach_sample_instance(self.handle))
  388. }
  389. // Sets an unsafe pointer as the the audio stream's fragment
  390. func (self *AudioStream) SetFragment(ptr unsafe.Pointer) bool {
  391. return cb2b(C.al_set_audio_stream_fragment(self.handle, ptr))
  392. }
  393. // Rewinds the audio stream
  394. func (self *AudioStream) Rewind() bool {
  395. return cb2b(C.al_rewind_audio_stream(self.handle))
  396. }
  397. // Seeks to a position in the audio stream, expressed in seconds.
  398. func (self *AudioStream) SeekSeconds(secs float64) bool {
  399. return cb2b(C.al_seek_audio_stream_secs(self.handle, C.double(secs)))
  400. }
  401. // Gets the position in the audio stream, expressed in seconds.
  402. func (self *AudioStream) PositionSeconds() (secs float64) {
  403. return float64(C.al_get_audio_stream_position_secs(self.handle))
  404. }
  405. // Gets the length of the audio stream, expressed in seconds.
  406. func (self *AudioStream) LengthSeconds() (secs float64) {
  407. return float64(C.al_get_audio_stream_length_secs(self.handle))
  408. }
  409. // Sets up a loop in the audio stream, expressed in seconds.
  410. func (self *AudioStream) LoopSeconds(start, end float64) bool {
  411. return cb2b(C.al_set_audio_stream_loop_secs(self.handle, C.double(start), C.double(end)))
  412. }
  413. // Returns the event source to use to listen to events on the audio stream.
  414. func (self *AudioStream) Eventsource() *EventSource {
  415. return wrapEventSourceRaw(C.al_get_audio_stream_event_source(self.handle))
  416. }
  417. // Converts a mixer to it's underlying C pointer
  418. func (self *Mixer) toC() *C.ALLEGRO_MIXER {
  419. return (*C.ALLEGRO_MIXER)(self.handle)
  420. }
  421. // Destroys the mixer.
  422. func (self *Mixer) Destroy() {
  423. if self.handle != nil {
  424. C.al_destroy_mixer(self.toC())
  425. }
  426. self.handle = nil
  427. }
  428. // Sets up a finalizer for this Mixer that calls Destroy() and return self
  429. func (self *Mixer) SetDestroyFinalizer() *Mixer {
  430. if self != nil {
  431. runtime.SetFinalizer(self, func(me *Mixer) { me.Destroy() })
  432. }
  433. return self
  434. }
  435. // Wraps a C mixer into a go mixer
  436. func wrapMixerRaw(data *C.ALLEGRO_MIXER) *Mixer {
  437. if data == nil {
  438. return nil
  439. }
  440. return &Mixer{data}
  441. }
  442. // Wraps a C mixer into a go mixer and sets up a finalizer that calls Destroy()
  443. func wrapMixer(data *C.ALLEGRO_MIXER) *Mixer {
  444. self := wrapMixerRaw(data)
  445. return self.SetDestroyFinalizer()
  446. }
  447. func createMixer(freq uint, depth AudioDepth, chan_conf ChannelConf) *C.ALLEGRO_MIXER {
  448. return C.al_create_mixer(C.uint(freq), depth.toC(), chan_conf.toC())
  449. }
  450. // Creates a new mixer with no finaliser attached to it.
  451. func CreateMixerRaw(freq uint, depth AudioDepth, chan_conf ChannelConf) *Mixer {
  452. return wrapMixerRaw(createMixer(freq, depth, chan_conf))
  453. }
  454. // Creates a new mixer with a finaliser that will call Destroy attached to it.
  455. func CreateMixer(freq uint, depth AudioDepth, chan_conf ChannelConf) *Mixer {
  456. return wrapMixer(createMixer(freq, depth, chan_conf))
  457. }
  458. // Attaches a sample instance to the given mixer.
  459. func (mixer *Mixer) AttachSampleInstance(stream *SampleInstance) bool {
  460. return cb2b(C.al_attach_sample_instance_to_mixer(stream.handle, mixer.handle))
  461. }
  462. // Attaches the sample instance to the given mixer.
  463. func (stream *SampleInstance) Attach(mixer *Mixer) bool {
  464. return cb2b(C.al_attach_sample_instance_to_mixer(stream.handle, mixer.handle))
  465. }
  466. // Attaches an audio stream to the given mixer.
  467. func (mixer *Mixer) AttachAudioStream(stream *AudioStream) bool {
  468. return cb2b(C.al_attach_audio_stream_to_mixer(stream.handle, mixer.handle))
  469. }
  470. // Attaches the audio stream to the given mixer.
  471. func (stream *AudioStream) Attach(mixer *Mixer) bool {
  472. return cb2b(C.al_attach_audio_stream_to_mixer(stream.handle, mixer.handle))
  473. }
  474. // Attaches a mixer to the given mixer.
  475. func (mixer *Mixer) AttachMixer(stream *Mixer) bool {
  476. return cb2b(C.al_attach_mixer_to_mixer(stream.handle, mixer.handle))
  477. }
  478. // Attaches the given mixer to the latter mixer.
  479. func (stream *Mixer) Attach(mixer *Mixer) bool {
  480. return cb2b(C.al_attach_mixer_to_mixer(stream.handle, mixer.handle))
  481. }
  482. /*
  483. TODO:
  484. ALLEGRO_KCM_AUDIO_FUNC(bool, al_set_mixer_postprocess_callback, (
  485. ALLEGRO_MIXER *mixer,
  486. void (*cb)(void *buf, unsigned int samples, void *data),
  487. void *data));
  488. */
  489. // Returns the frequency of the mixer
  490. func (self *Mixer) Frequency() uint {
  491. return uint(C.al_get_mixer_frequency(self.handle))
  492. }
  493. // Returns the gain of the mixer
  494. func (self *Mixer) Gain() float32 {
  495. return float32(C.al_get_mixer_gain(self.handle))
  496. }
  497. // Returns the depth of the mixer
  498. func (self *Mixer) Depth() AudioDepth {
  499. return AudioDepth(C.al_get_mixer_depth(self.handle))
  500. }
  501. // Returns the channel configuration of the mixer
  502. func (self *Mixer) Channels() ChannelConf {
  503. return ChannelConf(C.al_get_mixer_channels(self.handle))
  504. }
  505. // Returns the quality of the mixer
  506. func (self *Mixer) Quality() MixerQuality {
  507. return MixerQuality(C.al_get_mixer_quality(self.handle))
  508. }
  509. // Returns wheter or not the mixer is playing
  510. func (self *Mixer) Playing() bool {
  511. return cb2b(C.al_get_mixer_playing(self.handle))
  512. }
  513. // Returns wheter or not the mixer is attached
  514. func (self *Mixer) Attached() bool {
  515. return cb2b(C.al_get_mixer_attached(self.handle))
  516. }
  517. // Sets the frequency of the mixer.
  518. func (self *Mixer) SetFrequency(val uint) bool {
  519. return cb2b(C.al_set_mixer_frequency(self.handle, C.uint(val)))
  520. }
  521. // Sets the quality of the mixer.
  522. func (self *Mixer) SetQuality(val MixerQuality) bool {
  523. return cb2b(C.al_set_mixer_quality(self.handle, val.toC()))
  524. }
  525. // Sets the gain of the mixer.
  526. func (self *Mixer) SetGain(val float32) bool {
  527. return cb2b(C.al_set_mixer_gain(self.handle, C.float(val)))
  528. }
  529. // Sets the play status of the mixer.
  530. func (self *Mixer) SetPlaying(val bool) bool {
  531. return cb2b(C.al_set_mixer_playing(self.handle, b2cb(val)))
  532. }
  533. // Detaches the mixer from it's player
  534. func (self *Mixer) Detach() bool {
  535. return cb2b(C.al_detach_mixer(self.handle))
  536. }
  537. // Converts a voice to it's underlying C pointer
  538. func (self *Voice) toC() *C.ALLEGRO_VOICE {
  539. return (*C.ALLEGRO_VOICE)(self.handle)
  540. }
  541. // Destroys the voice.
  542. func (self *Voice) Destroy() {
  543. if self.handle != nil {
  544. C.al_destroy_voice(self.toC())
  545. }
  546. self.handle = nil
  547. }
  548. // Wraps a C voice into a go mixer
  549. func wrapVoiceRaw(data *C.ALLEGRO_VOICE) *Voice {
  550. if data == nil {
  551. return nil
  552. }
  553. return &Voice{data}
  554. }
  555. // Sets up a finalizer for this Voice Wraps a C voice that calls Destroy()
  556. func (self *Voice) SetDestroyFinalizer() *Voice {
  557. if self != nil {
  558. runtime.SetFinalizer(self, func(me *Voice) { me.Destroy() })
  559. }
  560. return self
  561. }
  562. // Wraps a C voice into a go mixer and sets up a finalizer that calls Destroy()
  563. func wrapVoice(data *C.ALLEGRO_VOICE) *Voice {
  564. self := wrapVoiceRaw(data)
  565. return self.SetDestroyFinalizer()
  566. }
  567. // creates a C voice
  568. func createVoice(freq uint, depth AudioDepth, chan_conf ChannelConf) *C.ALLEGRO_VOICE {
  569. return C.al_create_voice(C.uint(freq), depth.toC(), chan_conf.toC())
  570. }
  571. // Creates a voice
  572. func CreateVoiceRaw(freq uint, depth AudioDepth, chan_conf ChannelConf) *Voice {
  573. return wrapVoiceRaw(createVoice(freq, depth, chan_conf))
  574. }
  575. // Creates a voice and setsup a finalizer on it that calls Destroy
  576. func CreateVoice(freq uint, depth AudioDepth, chan_conf ChannelConf) *Voice {
  577. return wrapVoice(createVoice(freq, depth, chan_conf))
  578. }
  579. // Attaches a sample instance to the given voice.
  580. func (voice *Voice) AttachSampleInstance(stream *SampleInstance) bool {
  581. return cb2b(C.al_attach_sample_instance_to_voice(stream.handle, voice.handle))
  582. }
  583. // Attaches the sample instance to the given voice.
  584. func (stream *SampleInstance) AttachToVoice(voice *Voice) bool {
  585. return cb2b(C.al_attach_sample_instance_to_voice(stream.handle, voice.handle))
  586. }
  587. // Attaches an audio stream to the given voice.
  588. func (voice *Voice) AttachAudioStream(stream *AudioStream) bool {
  589. return cb2b(C.al_attach_audio_stream_to_voice(stream.handle, voice.handle))
  590. }
  591. // Attaches the audio stream to the given voice.
  592. func (stream *AudioStream) AttachToVoice(voice *Voice) bool {
  593. return cb2b(C.al_attach_audio_stream_to_voice(stream.handle, voice.handle))
  594. }
  595. // Attaches the given mixer to the voice.
  596. func (mixer *Mixer) AttachToVoice(voice *Voice) bool {
  597. return cb2b(C.al_attach_mixer_to_voice(mixer.handle, voice.handle))
  598. }
  599. // Attaches the given voice to the mixer.
  600. func (voice *Voice) AttachMixer(mixer *Mixer) bool {
  601. return cb2b(C.al_attach_mixer_to_voice(mixer.handle, voice.handle))
  602. }
  603. // Detaches the voice.
  604. func (voice *Voice) Detach() {
  605. C.al_detach_voice(voice.handle)
  606. }
  607. // Returns the frequency of the voice
  608. func (self *Voice) Frequency() uint {
  609. return uint(C.al_get_voice_frequency(self.handle))
  610. }
  611. // Returns the position of the voice
  612. func (self *Voice) Position() uint {
  613. return uint(C.al_get_voice_position(self.handle))
  614. }
  615. // Returns the depth of the voice
  616. func (self *Voice) Depth() AudioDepth {
  617. return AudioDepth(C.al_get_voice_depth(self.handle))
  618. }
  619. // Returns the channel configuration of the voice
  620. func (self *Voice) Channels() ChannelConf {
  621. return ChannelConf(C.al_get_voice_channels(self.handle))
  622. }
  623. // Returns wheter or not the voice is playing
  624. func (self *Voice) Playing() bool {
  625. return cb2b(C.al_get_voice_playing(self.handle))
  626. }
  627. // Sets the position of the voice.
  628. func (self *Voice) SetPosition(val uint) bool {
  629. return cb2b(C.al_set_voice_position(self.handle, C.uint(val)))
  630. }
  631. // Sets the play status of the voice.
  632. func (self *Voice) SetPlaying(val bool) bool {
  633. return cb2b(C.al_set_voice_playing(self.handle, b2cb(val)))
  634. }
  635. // Installs the audio extension
  636. func InstallAudio() bool {
  637. return cb2b(C.al_install_audio())
  638. }
  639. // Uninstalls the audio extension
  640. func UninstallAudio() {
  641. C.al_uninstall_audio()
  642. }
  643. // Returns true if the audio extension is installed
  644. func IsAudioInstalled() bool {
  645. return cb2b(C.al_is_audio_installed())
  646. }
  647. // Returns the version of the audio extension
  648. func AudioVersion() uint32 {
  649. return uint32(C.al_get_allegro_audio_version())
  650. }
  651. // Gets the amount of available channels in a channel configguration
  652. func (self ChannelConf) ChannelCount() uint {
  653. return uint(C.al_get_channel_count(self.toC()))
  654. }
  655. // Gets the size of (foe calculating the size of allocating a sample)
  656. func (self AudioDepth) Size() uint {
  657. return uint(C.al_get_audio_depth_size(self.toC()))
  658. }
  659. // Reserves the given amount of samples and attaches them to the default mixer
  660. func ReserveSamples(samples int) bool {
  661. return cb2b(C.al_reserve_samples(C.int(samples)))
  662. }
  663. var defaultMixer *Mixer = nil
  664. // Returns a pointer to the default mixer. Has no dispose finaliser set.
  665. func DefaultMixer() *Mixer {
  666. return wrapMixerRaw(C.al_get_default_mixer())
  667. }
  668. // Sets the mixer as the default mixer.
  669. func (mixer *Mixer) SetDefault() {
  670. // this is purely to prevent the GC from collecting this mixer.
  671. defaultMixer = mixer
  672. C.al_set_default_mixer(mixer.handle)
  673. }
  674. // Restores the default mixer
  675. func RestoreDefaultMixer() {
  676. // GC reclaim is OK now.
  677. defaultMixer = nil
  678. C.al_restore_default_mixer()
  679. }
  680. // Plays a sample on the default mixer if enough samples have been reserved.
  681. // id returns a sample if that can be used to track the sample.
  682. func (self *Sample) Play(gain, pan, speed float32, loop PlayMode) (ok bool, id SampleId) {
  683. ok = cb2b(C.al_play_sample(self.handle, C.float(gain), C.float(pan), C.float(speed), loop.toC(), (&id).toC()))
  684. return ok, id
  685. }
  686. // Stops playing a sample that was started with sample.Play()
  687. func (self *SampleId) Stop() {
  688. C.al_stop_sample(self.toC())
  689. }
  690. // Stops playing all samples on the default mixer
  691. func StopSamples() {
  692. C.al_stop_samples()
  693. }
  694. /*
  695. Todo:
  696. ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_sample_loader, (const char *ext,
  697. ALLEGRO_SAMPLE *(*loader)(const char *filename)));
  698. ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_sample_saver, (const char *ext,
  699. bool (*saver)(const char *filename, ALLEGRO_SAMPLE *spl)));
  700. ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_audio_stream_loader, (const char *ext,
  701. ALLEGRO_AUDIO_STREAM *(*stream_loader)(const char *filename,
  702. size_t buffer_count, unsigned int samples)));
  703. ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_sample_loader_f, (const char *ext,
  704. ALLEGRO_SAMPLE *(*loader)(ALLEGRO_FILE *fp)));
  705. ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_sample_saver_f, (const char *ext,
  706. bool (*saver)(ALLEGRO_FILE *fp, ALLEGRO_SAMPLE *spl)));
  707. ALLEGRO_KCM_AUDIO_FUNC(bool, al_register_audio_stream_loader_f, (const char *ext,
  708. ALLEGRO_AUDIO_STREAM *(*stream_loader)(ALLEGRO_FILE *fp,
  709. size_t buffer_count, unsigned int samples)));
  710. */
  711. // Loads a C sample from a filename
  712. func loadSample(filename string) *C.ALLEGRO_SAMPLE {
  713. cstr := cstr(filename)
  714. defer cstrFree(cstr)
  715. return C.al_load_sample(cstr)
  716. }
  717. // Loads a sample from a filename and sets up no finalizer
  718. func LoadSampleRaw(filename string) *Sample {
  719. return wrapSampleRaw(loadSample(filename))
  720. }
  721. // Loads a sample from a filename and sets up a finalizer
  722. func LoadSample(filename string) *Sample {
  723. return LoadSampleRaw(filename).SetDestroyFinalizer()
  724. }
  725. // Saves a sample to a given filename
  726. func (self *Sample) Save(filename string) bool {
  727. cstr := cstr(filename)
  728. defer cstrFree(cstr)
  729. return cb2b(C.al_save_sample(cstr, self.handle))
  730. }
  731. // Loads a C audio stream sample from a filename
  732. func loadAudioStream(filename string, buffer_count, samples uint) *C.ALLEGRO_AUDIO_STREAM {
  733. cstr := cstr(filename)
  734. defer cstrFree(cstr)
  735. return C.al_load_audio_stream(cstr, C.size_t(buffer_count), C.uint(samples))
  736. }
  737. // Loads a sample from a filename and sets up no finalizer
  738. func LoadAudioStreamRaw(filename string, buffer_count, samples uint) *AudioStream {
  739. return wrapAudioStreamRaw(loadAudioStream(filename, buffer_count, samples))
  740. }
  741. // Loads a sample from a filename and sets up a finalizer
  742. func LoadAudioStream(filename string, buffer_count, samples uint) *AudioStream {
  743. return LoadAudioStreamRaw(filename, buffer_count, samples).SetDestroyFinalizer()
  744. }
  745. // Allegro's own file for cross platform and physfs reasons.
  746. type File struct {
  747. handle *C.ALLEGRO_FILE
  748. }
  749. // Closes the Allegro file
  750. func (self *File) Close() {
  751. if self.handle != nil {
  752. C.al_fclose(self.handle)
  753. }
  754. self.handle = nil
  755. }
  756. // Wraps an ALLEGRO_FILE into a File
  757. func wrapFileRaw(file *C.ALLEGRO_FILE) *File {
  758. if file == nil {
  759. return nil
  760. }
  761. return &File{file}
  762. }
  763. // Opens an Allegro File
  764. func openFile(filename, mode string) *C.ALLEGRO_FILE {
  765. cfilename := cstr(filename)
  766. defer cstrFree(cfilename)
  767. cmode := cstr(mode)
  768. defer cstrFree(cmode)
  769. return C.al_fopen(cfilename, cmode)
  770. }
  771. // Sets up a finalizer for this File that calls Close()
  772. func (self *File) SetCloseFinalizer() *File {
  773. if self != nil {
  774. runtime.SetFinalizer(self, func(me *File) { me.Close() })
  775. }
  776. return self
  777. }
  778. // Wraps a file and sets up a finalizer that calls Destroy()
  779. func wrapFile(data *C.ALLEGRO_FILE) *File {
  780. self := wrapFileRaw(data)
  781. return self.SetCloseFinalizer()
  782. }
  783. // Opens a file with no finalizer set
  784. func OpenFileRaw(filename, mode string) *File {
  785. self := openFile(filename, mode)
  786. return wrapFileRaw(self)
  787. }
  788. // Opens a file with a Close finalizer set
  789. func OpenFile(filename, mode string) *File {
  790. self := OpenFileRaw(filename, mode)
  791. return self.SetCloseFinalizer()
  792. }
  793. // Loads a Sample from a File. Filetype is a file extension that identifies the file type
  794. // like (.wav, .ogg, etc))
  795. func (self *File) loadSample(filetype string) *C.ALLEGRO_SAMPLE {
  796. cfiletype := cstr(filetype)
  797. defer cstrFree(cfiletype)
  798. return C.al_load_sample_f(self.handle, cfiletype)
  799. }
  800. // Saves a Sample to a File. Filetype is a file extension that identifies the file type
  801. func (self *File) SaveSample(filetype string, sample *Sample) bool {
  802. cfiletype := cstr(filetype)
  803. defer cstrFree(cfiletype)
  804. return cb2b(C.al_save_sample_f(self.handle, cfiletype, sample.handle))
  805. }
  806. // Loads an ALLEGRO_AUDIO_STREAM from a file. Filetype is a file extension
  807. // that identifies the file type (.ogg, etc)
  808. func (self *File) loadAudioStream(filetype string, buffer_count,
  809. samples uint) *C.ALLEGRO_AUDIO_STREAM {
  810. cfiletype := cstr(filetype)
  811. defer cstrFree(cfiletype)
  812. return C.al_load_audio_stream_f(self.handle, cfiletype,
  813. C.size_t(buffer_count), C.uint(samples))
  814. }
  815. // Loads a Sample from a File. Filetype is a file extension that identifies the file type
  816. // like (.wav, .ogg, etc))
  817. func (self *File) LoadSampleRaw(filetype string) *Sample {
  818. return wrapSampleRaw(loadSample(filetype))
  819. }
  820. // Loads a Sample from a File. Filetype is a file extension that identifies the file type
  821. // like (.wav, .ogg, etc)). Sets up a finalizer.
  822. func (self *File) LoadSample(filetype string) *Sample {
  823. return LoadSampleRaw(filetype).SetDestroyFinalizer()
  824. }
  825. // Loads an AudioStream from a file. Filetype is a file extension
  826. // that identifies the file type (.ogg, etc)
  827. func (self *File) LoadAudioStreamRaw(filetype string, buffer_count,
  828. samples uint) *AudioStream {
  829. return wrapAudioStreamRaw(loadAudioStream(filetype, buffer_count, samples))
  830. }
  831. // Loads an AudioStream from a file. Filetype is a file extension
  832. // that identifies the file type (.ogg, etc). Sets up a finalizer.
  833. func (self *File) LoadAudioStream(filetype string, buffer_count,
  834. samples uint) *AudioStream {
  835. return LoadAudioStreamRaw(filetype, buffer_count, samples).SetDestroyFinalizer()
  836. }
  837. // Returns the event source of the audio subsystem
  838. func AudioEventSource() *EventSource {
  839. return wrapEventSourceRaw(C.al_get_audio_event_source())
  840. }
  841. // Converts a recorder to it's underlying C pointer
  842. func (self *AudioRecorder) toC() *C.ALLEGRO_AUDIO_RECORDER {
  843. return (*C.ALLEGRO_AUDIO_RECORDER)(self.handle)
  844. }
  845. // Destroys the recorder.
  846. func (self *AudioRecorder) Destroy() {
  847. if self.handle != nil {
  848. C.al_destroy_audio_recorder(self.toC())
  849. }
  850. self.handle = nil
  851. }
  852. // Wraps a C recorder into a go mixer
  853. func wrapAudioRecorderRaw(data *C.ALLEGRO_AUDIO_RECORDER) *AudioRecorder {
  854. if data == nil {
  855. return nil
  856. }
  857. return &AudioRecorder{data}
  858. }
  859. // Sets up a finalizer for this AudioRecorder Wraps a C recorder that calls Destroy()
  860. func (self *AudioRecorder) SetDestroyFinalizer() *AudioRecorder {
  861. if self != nil {
  862. runtime.SetFinalizer(self, func(me *AudioRecorder) { me.Destroy() })
  863. }
  864. return self
  865. }
  866. // Wraps a C recorder into a go recorder and sets up a finalizer that calls Destroy()
  867. func wrapAudioRecorder(data *C.ALLEGRO_AUDIO_RECORDER) *AudioRecorder {
  868. self := wrapAudioRecorderRaw(data)
  869. return self.SetDestroyFinalizer()
  870. }
  871. // Creates a C recorder
  872. func createAudioRecorder(fragment_count, samples, freq uint,
  873. depth AudioDepth, chan_conf ChannelConf) *C.ALLEGRO_AUDIO_RECORDER {
  874. return C.al_create_audio_recorder(C.size_t(fragment_count), C.uint(samples),
  875. C.uint(freq), depth.toC(), chan_conf.toC())
  876. }
  877. // Creates an Audio Recorder and sets no finalizer
  878. func CreateAudioRecorderRaw(fragment_count, samples, freq uint,
  879. depth AudioDepth, chan_conf ChannelConf) *AudioRecorder {
  880. return wrapAudioRecorderRaw(createAudioRecorder(fragment_count, samples, freq, depth, chan_conf))
  881. }
  882. // Creates an Audio Recorder and sets a finalizer
  883. func CreateAudioRecorder(fragment_count, samples, freq uint,
  884. depth AudioDepth, chan_conf ChannelConf) *AudioRecorder {
  885. return CreateAudioRecorderRaw(fragment_count, samples,
  886. freq, depth, chan_conf).SetDestroyFinalizer()
  887. }
  888. // Starts recording on the audio recorder.
  889. func (self *AudioRecorder) Start() bool {
  890. return cb2b(C.al_start_audio_recorder(self.handle))
  891. }
  892. // Stops recording on the audio recorder.
  893. func (self *AudioRecorder) Stop() {
  894. C.al_stop_audio_recorder(self.handle)
  895. }
  896. // Gets the audio recorder's event source
  897. func (self *AudioRecorder) EventSource() *EventSource {
  898. return wrapEventSourceRaw(C.al_get_audio_recorder_event_source(self.handle))
  899. }
  900. // Converts to AudioRecorderEvent
  901. func wrapAudioRecorderEvent(event *C.ALLEGRO_AUDIO_RECORDER_EVENT) *AudioRecorderEvent {
  902. return (*AudioRecorderEvent)(event)
  903. }
  904. // Converts an event into an allegro recorder event
  905. func (self *Event) AudioRecorderEvent() *AudioRecorderEvent {
  906. return wrapAudioRecorderEvent(C.al_get_audio_recorder_event(self.toC()))
  907. }
  908. // Gets an unsafe pointer to the recorder event's buffer
  909. func (self *AudioRecorderEvent) BufferPointer() unsafe.Pointer {
  910. return self.buffer
  911. }
  912. // Gets the amount of samples for this recorder event
  913. func (self *AudioRecorderEvent) Samples() uint {
  914. return uint(self.samples)
  915. }
  916. // Gets the recorder's buffer copied into a byte slice
  917. func (self *AudioRecorderEvent) Buffer() []byte {
  918. return C.GoBytes(self.buffer, C.int(self.samples))
  919. }