Reputation: 85
I'm a musician attempting to write a music reading programme for guitarists. I want to time two consecutive sounds so that the first stops when the second begins. Each should last a predetermined duration (defined in this example as 72 in 60000/72). As a beginner coder I'm struggling and would really appreciate any help.
-- AUDIO 1 --
local aa = audio.loadStream(sounds/chord1.mp3)
audio.play(aa)
-- TIMER 1 --
local timeLimit = 1
local function timerDown()
timeLimit = timeLimit-1
if(timeLimit==0)then
end
end
timer.performWithDelay( 60000/72, timerDown, timeLimit )
-- TIMER 2 --
local timeLimit = 1
local function timerDown()
timeLimit = timeLimit-1
if(timeLimit==0)then
-- AUDIO 2 --
local aa = audio.loadStream(sounds/chord2.mp3])
audio.play(aa)
end
end
timer.performWithDelay( 60000/72, timerDown, timeLimit )
Upvotes: 3
Views: 1025
Reputation: 407
There are a few things to note here. Sorry for the wall of text!
Must be enclosed in quotes.
local aa = audio.loadStream(sounds/chord1.mp3)
becomes:
local aa = audio.loadStream('sounds/chord1.mp3')
Values which aren't explained anywhere should be avoided. They make code harder to understand and harder to maintain or modify.
timer.performWithDelay(60000/72, timerDown, timeLimit)
becomes:
-- Might be slight overkill but hopefully you get the idea!
local beatsToPlay = 10
local beatsPerMinute = 72
local millisPerMinute = 60 * 1000
local playTimeMinutes = beatsToPlay / beatsPerMinute
local playTimeMillis = playTimeMinutes * millisPerMinute
timer.performWithDelay(playTimeMillis, timerDown, timeLimit)
It is an invaluable skill when programming to be able to read and understand documentation. Corona's API is documented here.
audio.loadStream()
's docs tell you that it returns an audio handle which you can use to play sounds which is what you've got already. It also reminds you that you should dispose of the handle when you are done so you'll need to add that in.
timer.performWithDelay()
's docs tell you that it needs the delay time in milliseconds and a listener which is what will be activated at that time, so you will need to write a listener of some description. If you follow the link to listener or if you look at the examples further down the page then you'll see that a simple function will suffice.
audio.play()
is fine as it is but if you read the docs then it informs you of some more functionality which you could use to your advantage. Namely the options
parameter, which includes duration
and onComplete
. duration
is how long - in millis - to play the sound. onComplete
is a listener which will be triggered when the sound has finished playing.
local function playAndQueue(handle, playTime, queuedHandle, queuedPlayTime)
audio.play(handle, { duration = playTime })
timer.performWithDelay(playTime, function(event)
audio.dispose(handle)
audio.play(queuedHandle, { duration = queuedPlayTime })
end)
timer.performWithDelay(playTime + queuedPlayTime, function(event)
audio.dispose(queuedHandle)
end)
end
local audioHandle1 = audio.loadStream('sounds/chord1.mp3')
local audioHandle2 = audio.loadStream('sounds/chord2.mp3')
local beatsToPlay = 10
local beatsPerMinute = 72
local millisPerMinute = 60 * 1000
local playTimeMinutes = beatsToPlay / beatsPerMinute
local playTimeMillis = playTimeMinutes * millisPerMinute
playAndQueue(audioHandle1, playTimeMillis, audioHandle2, playTimeMillis)
onComplete
:local function playAndQueue(handle, playTime, queuedHandle, queuedPlayTime)
-- Before we can set the 1st audio playing we have to define what happens
-- when it is done (disposes self and starts the 2nd audio).
-- Before we can start the 2nd audio we have to define what happens when
-- it is done (disposes of the 2nd audio handle)
local queuedCallback = function(event)
audio.dispose(queuedHandle)
end
local callback = function(event)
audio.dispose(handle)
local queuedOpts = {
duration = queuedPlayTime,
onComplete = queuedCallback
}
audio.play(queuedHandle, queuedOpts)
end
local opts = {
duration = playTime,
onComplete = callback
}
audio.play(handle, opts)
end
local audioHandle1 = audio.loadStream('sounds/chord1.mp3')
local audioHandle2 = audio.loadStream('sounds/chord2.mp3')
local beatsToPlay = 10
local beatsPerMinute = 72
local millisPerMinute = 60 * 1000
local playTimeMinutes = beatsToPlay / beatsPerMinute
local playTimeMillis = playTimeMinutes * millisPerMinute
playAndQueue(audioHandle1, playTimeMillis, audioHandle2, playTimeMillis)
You might find that using onComplete
works out better than pure timers since you might end up disposing the audio handle just before is is done being used for playback (and causing errors). I haven't had any experience with Corona so I'm not sure how robust its timer or audio libraries are.
Upvotes: 2