audio.lua 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. -- love.audio
  2. --------------------------------------------------------------------------------
  3. --------------------------------------------------------------------------------
  4. ------------------------------------OBJECTS-------------------------------------
  5. --------------------------------------------------------------------------------
  6. --------------------------------------------------------------------------------
  7. -- RecordingDevice (love.audio.getRecordingDevices)
  8. love.test.audio.RecordingDevice = function(test)
  9. -- skip recording device on runners, they cant emulate it
  10. if GITHUB_RUNNER then
  11. return test:skipTest('cant emulate recording devices in CI')
  12. end
  13. -- check devices first
  14. local devices = love.audio.getRecordingDevices()
  15. if #devices == 0 then
  16. return test:skipTest('cant test this works: no recording devices found')
  17. end
  18. -- check object created and basics
  19. local device = devices[1]
  20. test:assertObject(device)
  21. test:assertMatch({1, 2}, device:getChannelCount(), 'check channel count is 1 or 2')
  22. test:assertNotEquals(nil, device:getName(), 'check has name')
  23. -- check initial data is empty as we haven't recorded anything yet
  24. test:assertNotNil(device:getBitDepth())
  25. test:assertEquals(nil, device:getData(), 'check initial data empty')
  26. test:assertEquals(0, device:getSampleCount(), 'check initial sample empty')
  27. test:assertNotNil(device:getSampleRate())
  28. test:assertFalse(device:isRecording(), 'check not recording')
  29. -- start recording for a short time
  30. local startrecording = device:start(32000, 4000, 16, 1)
  31. test:waitFrames(10)
  32. test:assertTrue(startrecording, 'check recording started')
  33. test:assertTrue(device:isRecording(), 'check now recording')
  34. test:assertEquals(4000, device:getSampleRate(), 'check sample rate set')
  35. test:assertEquals(16, device:getBitDepth(), 'check bit depth set')
  36. test:assertEquals(1, device:getChannelCount(), 'check channel count set')
  37. local recording = device:stop()
  38. test:waitFrames(10)
  39. -- after recording
  40. test:assertFalse(device:isRecording(), 'check not recording')
  41. test:assertEquals(nil, device:getData(), 'using stop should clear buffer')
  42. test:assertObject(recording)
  43. end
  44. -- Source (love.audio.newSource)
  45. love.test.audio.Source = function(test)
  46. -- create stereo source
  47. local stereo = love.audio.newSource('resources/click.ogg', 'static')
  48. test:assertObject(stereo)
  49. -- check stereo props
  50. test:assertEquals(2, stereo:getChannelCount(), 'check stereo src')
  51. test:assertRange(stereo:getDuration("seconds"), 0, 0.1, 'check stereo seconds')
  52. test:assertNotNil(stereo:getFreeBufferCount())
  53. test:assertEquals('static', stereo:getType(), 'check stereo type')
  54. -- check cloning a stereo
  55. local clone = stereo:clone()
  56. test:assertEquals(2, clone:getChannelCount(), 'check clone stereo src')
  57. test:assertRange(clone:getDuration("seconds"), 0, 0.1, 'check clone stereo seconds')
  58. test:assertNotNil(clone:getFreeBufferCount())
  59. test:assertEquals('static', clone:getType(), 'check cloned stereo type')
  60. -- mess with stereo playing
  61. test:assertFalse(stereo:isPlaying(), 'check not playing')
  62. stereo:setLooping(true)
  63. stereo:play()
  64. test:assertTrue(stereo:isPlaying(), 'check now playing')
  65. test:assertTrue(stereo:isLooping(), 'check now playing')
  66. stereo:pause()
  67. stereo:seek(0.01, 'seconds')
  68. test:assertEquals(0.01, stereo:tell('seconds'), 'check seek/tell')
  69. stereo:stop()
  70. test:assertFalse(stereo:isPlaying(), 'check stopped playing')
  71. -- check volume limits
  72. stereo:setVolumeLimits(0.1, 0.5)
  73. local min, max = stereo:getVolumeLimits()
  74. test:assertRange(min, 0.1, 0.2, 'check min limit')
  75. test:assertRange(max, 0.5, 0.6, 'check max limit')
  76. -- check setting volume
  77. stereo:setVolume(1)
  78. test:assertEquals(1, stereo:getVolume(), 'check set volume')
  79. stereo:setVolume(0)
  80. test:assertEquals(0, stereo:getVolume(), 'check set volume')
  81. -- change some get/set props that can apply to stereo
  82. stereo:setPitch(2)
  83. test:assertEquals(2, stereo:getPitch(), 'check pitch change')
  84. -- create mono source
  85. local mono = love.audio.newSource('resources/clickmono.ogg', 'stream')
  86. test:assertObject(mono)
  87. test:assertEquals(1, mono:getChannelCount(), 'check mono src')
  88. test:assertEquals(2927, mono:getDuration("samples"), 'check mono seconds')
  89. test:assertEquals('stream', mono:getType(), 'check mono type')
  90. -- air absorption
  91. test:assertEquals(0, mono:getAirAbsorption(), 'get air absorption')
  92. mono:setAirAbsorption(1)
  93. test:assertEquals(1, mono:getAirAbsorption(), 'set air absorption')
  94. -- cone
  95. mono:setCone(0, 90*(math.pi/180), 1)
  96. local ia, oa, ov = mono:getCone()
  97. test:assertEquals(0, ia, 'check cone ia')
  98. test:assertEquals(math.floor(9000*(math.pi/180)), math.floor(oa*100), 'check cone oa')
  99. test:assertEquals(1, ov, 'check cone ov')
  100. -- direction
  101. mono:setDirection(3, 1, -1)
  102. local x, y, z = mono:getDirection()
  103. test:assertEquals(3, x, 'check direction x')
  104. test:assertEquals(1, y, 'check direction y')
  105. test:assertEquals(-1, z, 'check direction z')
  106. -- relative
  107. mono:setRelative(true)
  108. test:assertTrue(mono:isRelative(), 'check set relative')
  109. -- position
  110. mono:setPosition(1, 2, 3)
  111. x, y, z = mono:getPosition()
  112. test:assertEquals(x, 1, 'check pos x')
  113. test:assertEquals(y, 2, 'check pos y')
  114. test:assertEquals(z, 3, 'check pos z')
  115. -- velocity
  116. mono:setVelocity(1, 3, 4)
  117. x, y, z = mono:getVelocity()
  118. test:assertEquals(x, 1, 'check velocity x')
  119. test:assertEquals(y, 3, 'check velocity x')
  120. test:assertEquals(z, 4, 'check velocity x')
  121. -- rolloff
  122. mono:setRolloff(1)
  123. test:assertEquals(1, mono:getRolloff(), 'check rolloff set')
  124. -- create queue source
  125. local queue = love.audio.newQueueableSource(44100, 16, 1, 3)
  126. local sdata = love.sound.newSoundData(1024, 44100, 16, 1)
  127. test:assertObject(queue)
  128. local run = queue:queue(sdata)
  129. test:assertTrue(run, 'check queued sound')
  130. queue:stop()
  131. -- check making a filer
  132. local setfilter = stereo:setFilter({
  133. type = 'lowpass',
  134. volume = 0.5,
  135. highgain = 0.3
  136. })
  137. test:assertTrue(setfilter, 'check filter applied')
  138. local filter = stereo:getFilter()
  139. test:assertEquals('lowpass', filter.type, 'check filter type')
  140. test:assertEquals(0.5, filter.volume, 'check filter volume')
  141. test:assertRange(filter.highgain, 0.3, 0.4, 'check filter highgain')
  142. test:assertEquals(nil, filter.lowgain, 'check filter lowgain')
  143. -- add an effect
  144. local effsource = love.audio.newSource('resources/click.ogg', 'static')
  145. love.audio.setEffect('testeffect', {
  146. type = 'flanger',
  147. volume = 0.75
  148. })
  149. local seteffect, err = effsource:setEffect('testeffect', {
  150. type = 'highpass',
  151. volume = 0.3,
  152. lowgain = 0.1
  153. })
  154. -- both these fail on 12 using stereo or mono, no err
  155. test:assertTrue(seteffect, 'check effect was applied')
  156. local filtersettings = effsource:getEffect('effectthatdoesntexist', {})
  157. test:assertNotNil(filtersettings)
  158. love.audio.stop(stereo)
  159. love.audio.stop(mono)
  160. love.audio.stop(effsource)
  161. end
  162. --------------------------------------------------------------------------------
  163. --------------------------------------------------------------------------------
  164. ------------------------------------METHODS-------------------------------------
  165. --------------------------------------------------------------------------------
  166. --------------------------------------------------------------------------------
  167. -- love.audio.getActiveEffects
  168. love.test.audio.getActiveEffects = function(test)
  169. -- check we get a value
  170. test:assertNotNil(love.audio.getActiveEffects())
  171. -- check setting an effect active
  172. love.audio.setEffect('testeffect', {
  173. type = 'chorus',
  174. volume = 0.75
  175. })
  176. test:assertEquals(1, #love.audio.getActiveEffects(), 'check 1 effect running')
  177. test:assertEquals('testeffect', love.audio.getActiveEffects()[1], 'check effect details')
  178. end
  179. -- love.audio.getActiveSourceCount
  180. love.test.audio.getActiveSourceCount = function(test)
  181. -- check we get a value
  182. test:assertNotNil(love.audio.getActiveSourceCount())
  183. -- check source isn't active by default
  184. local testsource = love.audio.newSource('resources/click.ogg', 'static')
  185. love.audio.stop(testsource)
  186. test:assertEquals(0, love.audio.getActiveSourceCount(), 'check not active')
  187. -- check playing a source marks it as active
  188. love.audio.play(testsource)
  189. test:assertEquals(1, love.audio.getActiveSourceCount(), 'check now active')
  190. love.audio.pause()
  191. end
  192. -- love.audio.getDistanceModel
  193. love.test.audio.getDistanceModel = function(test)
  194. -- check we get a value
  195. test:assertNotNil(love.audio.getDistanceModel())
  196. -- check default value from documentation
  197. test:assertEquals('inverseclamped', love.audio.getDistanceModel(), 'check default value')
  198. -- check get correct value after setting
  199. love.audio.setDistanceModel('inverse')
  200. test:assertEquals('inverse', love.audio.getDistanceModel(), 'check setting model')
  201. end
  202. -- love.audio.getDopplerScale
  203. love.test.audio.getDopplerScale = function(test)
  204. -- check default value
  205. test:assertEquals(1, love.audio.getDopplerScale(), 'check default 1')
  206. -- check correct value after setting to 0
  207. love.audio.setDopplerScale(0)
  208. test:assertEquals(0, love.audio.getDopplerScale(), 'check setting to 0')
  209. love.audio.setDopplerScale(1)
  210. end
  211. -- love.audio.getEffect
  212. love.test.audio.getEffect = function(test)
  213. -- check getting a non-existent effect
  214. test:assertEquals(nil, love.audio.getEffect('madeupname'), 'check wrong name')
  215. -- check getting a valid effect
  216. love.audio.setEffect('testeffect', {
  217. type = 'chorus',
  218. volume = 0.75
  219. })
  220. test:assertNotNil(love.audio.getEffect('testeffect'))
  221. -- check effect values match creation values
  222. test:assertEquals('chorus', love.audio.getEffect('testeffect').type, 'check effect type')
  223. test:assertEquals(0.75, love.audio.getEffect('testeffect').volume, 'check effect volume')
  224. end
  225. -- love.audio.getMaxSceneEffects
  226. -- @NOTE feel like this is platform specific number so best we can do is a nil?
  227. love.test.audio.getMaxSceneEffects = function(test)
  228. test:assertNotNil(love.audio.getMaxSceneEffects())
  229. end
  230. -- love.audio.getMaxSourceEffects
  231. -- @NOTE feel like this is platform specific number so best we can do is a nil?
  232. love.test.audio.getMaxSourceEffects = function(test)
  233. test:assertNotNil(love.audio.getMaxSourceEffects())
  234. end
  235. -- love.audio.getOrientation
  236. -- @NOTE is there an expected default listener pos?
  237. love.test.audio.getOrientation = function(test)
  238. -- checking getting values matches what was set
  239. love.audio.setOrientation(1, 2, 3, 4, 5, 6)
  240. local fx, fy, fz, ux, uy, uz = love.audio.getOrientation()
  241. test:assertEquals(1, fx, 'check fx orientation')
  242. test:assertEquals(2, fy, 'check fy orientation')
  243. test:assertEquals(3, fz, 'check fz orientation')
  244. test:assertEquals(4, ux, 'check ux orientation')
  245. test:assertEquals(5, uy, 'check uy orientation')
  246. test:assertEquals(6, uz, 'check uz orientation')
  247. end
  248. -- love.audio.getPlaybackDevice
  249. love.test.audio.getPlaybackDevice = function(test)
  250. test:assertNotNil(love.audio.getPlaybackDevice)
  251. test:assertNotNil(love.audio.getPlaybackDevice())
  252. end
  253. -- love.audio.getPlaybackDevices
  254. love.test.audio.getPlaybackDevices = function(test)
  255. test:assertNotNil(love.audio.getPlaybackDevices)
  256. test:assertGreaterEqual(0, #love.audio.getPlaybackDevices(), 'check table')
  257. end
  258. -- love.audio.getPosition
  259. -- @NOTE is there an expected default listener pos?
  260. love.test.audio.getPosition = function(test)
  261. -- check getting values matches what was set
  262. love.audio.setPosition(1, 2, 3)
  263. local x, y, z = love.audio.getPosition()
  264. test:assertEquals(1, x, 'check x position')
  265. test:assertEquals(2, y, 'check y position')
  266. test:assertEquals(3, z, 'check z position')
  267. end
  268. -- love.audio.getRecordingDevices
  269. -- @NOTE hardware dependent so best can do is not nil check
  270. love.test.audio.getRecordingDevices = function(test)
  271. test:assertNotNil(love.audio.getRecordingDevices())
  272. end
  273. -- love.audio.getVelocity
  274. love.test.audio.getVelocity = function(test)
  275. -- check getting values matches what was set
  276. love.audio.setVelocity(1, 2, 3)
  277. local x, y, z = love.audio.getVelocity()
  278. test:assertEquals(1, x, 'check x velocity')
  279. test:assertEquals(2, y, 'check y velocity')
  280. test:assertEquals(3, z, 'check z velocity')
  281. end
  282. -- love.audio.getVolume
  283. love.test.audio.getVolume = function(test)
  284. -- check getting values matches what was set
  285. love.audio.setVolume(0.5)
  286. test:assertEquals(0.5, love.audio.getVolume(), 'check matches set')
  287. end
  288. -- love.audio.isEffectsSupported
  289. love.test.audio.isEffectsSupported = function(test)
  290. test:assertNotNil(love.audio.isEffectsSupported())
  291. end
  292. -- love.audio.newQueueableSource
  293. -- @NOTE this is just basic nil checking, objs have their own test method
  294. love.test.audio.newQueueableSource = function(test)
  295. test:assertObject(love.audio.newQueueableSource(32, 8, 1, 8))
  296. end
  297. -- love.audio.newSource
  298. -- @NOTE this is just basic nil checking, objs have their own test method
  299. love.test.audio.newSource = function(test)
  300. test:assertObject(love.audio.newSource('resources/click.ogg', 'static'))
  301. test:assertObject(love.audio.newSource('resources/click.ogg', 'stream'))
  302. end
  303. -- love.audio.pause
  304. love.test.audio.pause = function(test)
  305. -- check nothing paused (as should be nothing playing)
  306. local nopauses = love.audio.pause()
  307. test:assertEquals(0, #nopauses, 'check nothing paused')
  308. -- check 1 source paused after playing/pausing 1
  309. local source = love.audio.newSource('resources/click.ogg', 'static')
  310. love.audio.play(source)
  311. local onepause = love.audio.pause()
  312. test:assertEquals(1, #onepause, 'check 1 paused')
  313. love.audio.stop(source)
  314. end
  315. -- love.audio.play
  316. love.test.audio.play = function(test)
  317. -- check playing source is detected
  318. local source = love.audio.newSource('resources/click.ogg', 'static')
  319. love.audio.play(source)
  320. test:assertTrue(source:isPlaying(), 'check something playing')
  321. love.audio.stop()
  322. end
  323. -- love.audio.setDistanceModel
  324. love.test.audio.setDistanceModel = function(test)
  325. -- check setting each of the distance models is accepted and val returned
  326. local distancemodel = {
  327. 'none', 'inverse', 'inverseclamped', 'linear', 'linearclamped',
  328. 'exponent', 'exponentclamped'
  329. }
  330. for d=1,#distancemodel do
  331. love.audio.setDistanceModel(distancemodel[d])
  332. test:assertEquals(distancemodel[d], love.audio.getDistanceModel(),
  333. 'check model set to ' .. distancemodel[d])
  334. end
  335. end
  336. -- love.audio.setDopplerScale
  337. love.test.audio.setDopplerScale = function(test)
  338. -- check setting value is returned properly
  339. love.audio.setDopplerScale(0)
  340. test:assertEquals(0, love.audio.getDopplerScale(), 'check set to 0')
  341. love.audio.setDopplerScale(1)
  342. test:assertEquals(1, love.audio.getDopplerScale(), 'check set to 1')
  343. end
  344. -- love.audio.setEffect
  345. love.test.audio.setEffect = function(test)
  346. -- check effect is set correctly
  347. local effect = love.audio.setEffect('testeffect', {
  348. type = 'chorus',
  349. volume = 0.75
  350. })
  351. test:assertTrue(effect, 'check effect created')
  352. -- check values set match
  353. local settings = love.audio.getEffect('testeffect')
  354. test:assertEquals('chorus', settings.type, 'check effect type')
  355. test:assertEquals(0.75, settings.volume, 'check effect volume')
  356. end
  357. -- love.audio.setMixWithSystem
  358. love.test.audio.setMixWithSystem = function(test)
  359. test:assertNotNil(love.audio.setMixWithSystem(true))
  360. end
  361. -- love.audio.setOrientation
  362. love.test.audio.setOrientation = function(test)
  363. -- check setting orientation vals are returned
  364. love.audio.setOrientation(1, 2, 3, 4, 5, 6)
  365. local fx, fy, fz, ux, uy, uz = love.audio.getOrientation()
  366. test:assertEquals(1, fx, 'check fx orientation')
  367. test:assertEquals(2, fy, 'check fy orientation')
  368. test:assertEquals(3, fz, 'check fz orientation')
  369. test:assertEquals(4, ux, 'check ux orientation')
  370. test:assertEquals(5, uy, 'check uy orientation')
  371. test:assertEquals(6, uz, 'check uz orientation')
  372. end
  373. -- love.audio.setPlaybackDevice
  374. love.test.audio.setPlaybackDevice = function(test)
  375. -- check method
  376. test:assertNotNil(love.audio.setPlaybackDevice)
  377. -- check blank string name
  378. test:assertTrue(love.audio.setPlaybackDevice(''), 'check blank device is fine')
  379. -- check invalid name
  380. test:assertFalse(love.audio.setPlaybackDevice('loveFM'), 'check invalid device fails')
  381. -- check setting already set
  382. test:assertTrue(love.audio.setPlaybackDevice(love.audio.getPlaybackDevice()), 'check existing device is fine')
  383. -- if other devices to play with lets set a different one
  384. local devices = love.audio.getPlaybackDevices()
  385. if #devices > 1 then
  386. local another = ''
  387. local current = love.audio.getPlaybackDevice()
  388. for a=1,#devices do
  389. if devices[a] ~= current then
  390. another = devices[a]
  391. break
  392. end
  393. end
  394. if another ~= '' then
  395. -- check setting new device
  396. local success4, msg4 = love.audio.setPlaybackDevice(another)
  397. test:assertTrue(success4, 'check setting different device')
  398. -- check resetting to default
  399. local success5, msg5 = love.audio.setPlaybackDevice()
  400. test:assertTrue(success5, 'check resetting')
  401. test:assertEquals(current, love.audio.getPlaybackDevice())
  402. end
  403. end
  404. end
  405. -- love.audio.setPosition
  406. love.test.audio.setPosition = function(test)
  407. -- check setting position vals are returned
  408. love.audio.setPosition(1, 2, 3)
  409. local x, y, z = love.audio.getPosition()
  410. test:assertEquals(1, x, 'check x position')
  411. test:assertEquals(2, y, 'check y position')
  412. test:assertEquals(3, z, 'check z position')
  413. end
  414. -- love.audio.setVelocity
  415. love.test.audio.setVelocity = function(test)
  416. -- check setting velocity vals are returned
  417. love.audio.setVelocity(1, 2, 3)
  418. local x, y, z = love.audio.getVelocity()
  419. test:assertEquals(1, x, 'check x velocity')
  420. test:assertEquals(2, y, 'check y velocity')
  421. test:assertEquals(3, z, 'check z velocity')
  422. end
  423. -- love.audio.setVolume
  424. love.test.audio.setVolume = function(test)
  425. -- check setting volume works
  426. love.audio.setVolume(0.5)
  427. test:assertEquals(0.5, love.audio.getVolume(), 'check set to 0.5')
  428. end
  429. -- love.audio.stop
  430. love.test.audio.stop = function(test)
  431. -- check source is playing first
  432. local source = love.audio.newSource('resources/click.ogg', 'static')
  433. love.audio.play(source)
  434. test:assertTrue(source:isPlaying(), 'check is playing')
  435. -- check source is then stopped
  436. love.audio.stop()
  437. test:assertFalse(source:isPlaying(), 'check stopped playing')
  438. end