love2d / love

LÖVE is an awesome 2D game framework for Lua.
https://love2d.org
Other
5.03k stars 399 forks source link

QueueableSource:tell() returns only currently played sounndata chunk position. #1546

Closed slime73 closed 4 years ago

slime73 commented 4 years ago

Original report by Snusmumriken (Bitbucket: MainTomato, GitHub: MainTomato).


Minimal example:

local decoder = love.sound.newDecoder('allstar.mp3', 44100 * 5)
local sr, bd, cc = decoder:getSampleRate(), decoder:getBitDepth(), decoder:getChannelCount()
local source = love.audio.newQueueableSource(sr, bd, cc, 8)

function love.draw()
  while source:getFreeBufferCount() > 0 do
    local data = decoder:decode()
    if not data then return end
      source:queue(data)
      source:play()
  end
  local f = "Time: %.5f tell: %.3f"
  love.graphics.print(  f:format(os.clock(), source:tell()) )
end

slime73 commented 4 years ago

Original comment by Gabe Stilez (Bitbucket: z0r8, ).


Yes, that’s how QSources function; if you want to keep track of the actual position, then store that yourself in a variable. (Though you can only do that up to the precision of Decoder:decode’s chunk sizes… or that combined with what you get back through QSource:tell, even though that’s not /as/ accurate as you might want it to be… hard to tell what your exact goal would be.

You’d already need to do this if you would be using a SoundData (statically loading the source sound in) instead of a Decoder, since for realtime buffering, you’d need to keep track of the small chunks' offsets through time anyway; a Decoder would just mitigate that in terms of giving you chunks it reads in… preferrably from disk, although currently even that’s not a thing as far as i remember the discussions about it.

Alternatively, if you don’t need samplepoint accurate tracking, then you don’t technically need to use QSources either, so again, depends on actual use-case, but this is not a bug.

slime73 commented 4 years ago

Original comment by Snusmumriken (Bitbucket: MainTomato, GitHub: MainTomato).


The problem is that I just need accurate tracking for sound analysis (fft and beat detection), so I need a chunk position to analysis. I know “how to solve“, but it’s hard and not so correct.

slime73 commented 4 years ago

Original comment by Gabe Stilez (Bitbucket: z0r8, ).


Yeah, as i said, you need to track the playback pointer yourself because even if Qsource:tell worked how you want it to, it wouldn’t be accurate at all; Source:tell isn’t accurate enough with a regular Source object either.

The most accurate tracking you will get is if you use a small SoundData buffer and a large one where you copy chunks from (not using a Decoder at all, since the decode method can’t really be given how many samplepoints to return), and you pass that into whatever FFT / beat detector lib you use… that said, the one lua one i know of is horridly slow; i should know, i tested it.

Still, this should be in the forums as a question, and not in the bug tracker, because again, it is not a bug. If you do open a thread about it, i can share with you some projects of mine where i am accurately tracking audio data for visualization.

raidho36 commented 4 years ago

This is intended behavior. You would have to do manual book-keeping either way (i.e. if it returned total playback time instead then you'd have to calculate in-buffer position manually). Since Qsource can't seek to anywhere beyond what's currently buffered, the sensible thing to return was in-buffer position so that it can be used for seeking.

zorggn commented 4 years ago

(Just to note, since my github account is missing from the pasted z0r8 posts, it's @zorggn here.)