Page 1 of 1

Understanding the basics of require and threads

Posted: Sun Jun 25, 2023 12:06 am
by randomnovice
Hi folks,

Complete coding novice here and I think I'm missing something basic about the way that either require or threads work.

I'm trying to make use of Zorg's excellent "advanced sound library" (asl) found here.

I've checked that the asl.lua and asl-thread.lua are both run correctly by inserting a basic print("Did this") command in each and yes, they run.

But when I try to call the function Source:setTimeStretch(2.0) I get the following error:

Code: Select all

Error: main.lua:201: attempt to call method 'setTimeStretch' (a nil value)
stack traceback:
	[love "boot.lua"]:345: in function 'setTimeStretch'
	main.lua:201: in function <main.lua:181>
	main.lua:152: in function 'update'
	main.lua:39: in function <main.lua:12>
	[C]: in function 'xpcall'
	[love "boot.lua"]:361: in function <[love "boot.lua"]:348>
	[C]: in function 'xpcall'
The way I have tried to call it is in these few lines:

Code: Select all

tSPEECH[gSPEECH_PLAYING] = love.audio.newSource("cache/line"..gSPEECH_PLAYING..".mp3", "static")
tSPEECH[gSPEECH_PLAYING]:setTimeStretch(2.0)
tSPEECH[gSPEECH_PLAYING]:play()
I've attached the file but it's likely to be on a very basic level that I've got something wrong as I have no idea what I'm doing, so anyone who is feeling helpful it might be easier to suggest one of the possible common ways I might have made a mistake rather than sifting through heaps of code.

Re: Understanding the basics of require and threads

Posted: Sun Jun 25, 2023 7:38 am
by zorg
Hi.

Please read the "Usage:" part of the readme on the github page you linked; the library does not monkeypatch love.audio.newSource so creating a regular Source object like that won't magically make it have a setTimeStretch method. :3

Re: Understanding the basics of require and threads

Posted: Sun Jun 25, 2023 10:37 am
by randomnovice
Thank you. I did/have read but I didn't quite understand. Novice here.

I noticed that there was another way of including it

Code: Select all

local new = require 'asl'
Could you/anyone give any pointers on how to create an audio source that I can apply timestretch to?

I looked for a function akin to love.audio.newAdvancedSource but couldn't see anything.

Re: Understanding the basics of require and threads

Posted: Sun Jun 25, 2023 10:58 am
by zorg
randomnovice wrote: Sun Jun 25, 2023 10:37 am I noticed that there was another way of including it

Code: Select all

local new = require 'asl'
That is the first way; you just require the library into that variable; since the library only resturns a constructor that makes the modified Source objects, you can just do this instead of what you were trying to do:

Code: Select all

-- top of your file or something
local newASource = require 'asl'

-- ...

tSPEECH[gSPEECH_PLAYING] = newASource("cache/line"..gSPEECH_PLAYING..".mp3", "static")
tSPEECH[gSPEECH_PLAYING]:setTimeStretch(2.0)
tSPEECH[gSPEECH_PLAYING]:play()
Alternatively, if you do want to put it into löve's own table:

Code: Select all

-- top of your file or something
love.audio.newAdvancedSource = require 'asl'

-- ...

tSPEECH[gSPEECH_PLAYING] = love.audio.newAdvancedSource("cache/line"..gSPEECH_PLAYING..".mp3", "static")
tSPEECH[gSPEECH_PLAYING]:setTimeStretch(2.0)
tSPEECH[gSPEECH_PLAYING]:play()
I would suggest you read up more about lua and how require works though, that might be helpful!

Re: Understanding the basics of require and threads

Posted: Sun Jun 25, 2023 1:10 pm
by randomnovice
Thank you, that solved it!

Yes, in my brain I had thought of require like including a library of functions, but it seems in this case it's more like methods.

Yup, plenty of reading to do but thank you I've got something that works now... ish.

Unfortunately I've run into a problem where the timestretch seems to make the sound loop, as if playing it twice as fast you get two instances etc. But it's a NEW problem to think about, which is nice :)

Re: Understanding the basics of require and threads

Posted: Sat Jul 01, 2023 8:06 pm
by randomnovice
I've sat with that problem for a week and tried various ideas, but I'm still stuck :(

It seems to me that applying the timestretch method sometimes (but not always) makes the audio source skip over it's "end of file" so that it loops back to the beginning. The more that the audio is sped up, the more likely this is to happen.

I've made absolutely sure that isLooping is false (it is).
I've listened to the downloaded mp3 sources and there is no looping on the original source files.

And the only code that plays the (next) source in my file is this, which fires within love.update():

Code: Select all

if safetest(tSETTINGS.Speech, "Yes") and tSPEECH~=nil and gSPEECH_LINE<gettablesize(tSPEECH) and (gSPEECH_LINE==0 or not tSPEECH[gSPEECH_LINE]:isPlaying()) then
   gSPEECH_LINE = gSPEECH_LINE + 1
   tSPEECH[gSPEECH_LINE]:play()
end
There's no way that this can play the same sound again (that I can fathom).

I'm afraid the library (link above) is far beyond my knowledge of audio manipulation. Could it somehow make sources miss their "end of file"?

I tried experimenting with converting the .mp3 into sounddata so that I could queue the sources but that's no good either, as the advanced sound library can't apply the timestretch to sounddata (I don't think).

Big picture of what I am trying to do:
- Use text-to-speech online to download mp3 files of text
- Play these mp3 files one after another at a custom faster speed (default is too slow)