audio.go 29 KB

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