attempt to index out of range sample

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Ethan_Pixelate
Prole
Posts: 7
Joined: Fri Dec 06, 2019 11:26 pm

attempt to index out of range sample

Post by Ethan_Pixelate »

I am trying to make a function that slows down/speeds up a sound through SoundData, i cant just use Source:setPitch() because i will ultimately be overlaying this SoundData with others and have it exported to wav (Don't ask why, it's a really stupid project, or ask anyways cuz its also really funny).

The problem I'm having is that I keep getting an out of range error (note that im using the setSample and getSample with an extra number that respects what channel im operating on)

Code: Select all

local M = {}

M.Name = "Pitch Control"
M.Description = "Slows down, or speeds up a cut."

function M:Operate(Sound)
    local Speed = math.random(0.5,2)

    local SampleRate = Sound:getSampleRate()
    local Duration = Sound:getSampleCount()
    local Channels = Sound:getChannelCount()

    local NewDuration = math.floor(Duration*Speed)-1
    local NewSound = love.sound.newSoundData(
        NewDuration,
        SampleRate,
        Sound:getBitDepth(),
        Channels
    )
    for C=1,Channels,1 do
        for I=1,NewDuration,1 do
            local NormalizedI = I/NewDuration
            local SampleIndex = math.floor(NormalizedI*Duration)
            NewSound:setSample(I,C,Sound:getSample(SampleIndex,C))
        end
    end

    return NewSound
end

return M
this is the line causing the error in specific:

Code: Select all

NewSound:setSample(I,C,Sound:getSample(SampleIndex,C))
any help would be appreciated, thanks. :D
MrFariator
Party member
Posts: 282
Joined: Wed Oct 05, 2016 11:53 am

Re: attempt to index out of range sample

Post by MrFariator »

Going off a limb here, but as per wiki the sample positions start from 0 when using getSample/setSample. As such I think that erroring line should be along the lines of:

Code: Select all

NewSound:setSample(I-1,C,Sound:getSample(SampleIndex-1,C))
With the caveat that you'll have to be careful that the "SampleIndex-1" remains within [0,Duration-1], inclusive.

Because hyphotetically lets say the sample count of the original sound is 200, and the new sound will get 100 samples allotted to it. With your code you're eventually going to try touching either position 200 or 100, when the last valid position is at 199 or 99 respectively.
Ethan_Pixelate
Prole
Posts: 7
Joined: Fri Dec 06, 2019 11:26 pm

Re: attempt to index out of range sample

Post by Ethan_Pixelate »

I tried that, but I'm still getting the error, I'm also making sure that I cant go over the limit by having NewDuration be set to whatever *minus* 1, not sure if SampleIndex follows, but as evident by the fix not working, that doesn't seem to be the case either, was worth a shot though.
User avatar
pgimeno
Party member
Posts: 2825
Joined: Sun Oct 18, 2015 2:58 pm

Re: attempt to index out of range sample

Post by pgimeno »

I think the problem is with NewDuration. First of all, due to the implementation of math.random in LuaJIT, this line will either give a value of 0.5 or 1.5 (which one of both is random):

Code: Select all

local Speed = math.random(0.5,2)
I think you want this instead:

Code: Select all

local Speed = math.random()*1.5 + 0.5
Then there's this:

Code: Select all

local NewDuration = math.floor(Duration*Speed)-1
The -1 makes it one sample short. If you have N=3 samples, the sample indices will be 0, 1, 2, i.e. from 0 to N-1; but if you have N-1=2 samples, trying to access index 2 will fail. Remove the -1 and do as MrFariator said.

Edit: Hmm, thinking about it, this is also suspect:

Code: Select all

 local NormalizedI = I/NewDuration
You get a fractional number there, and you don't know how the function is going to round it. I suggest you change it to this:

Code: Select all

local NormalizedI = math.floor((I-1)/NewDuration)
then use the value raw:

Code: Select all

NewSound:setSample(I-1,C,Sound:getSample(SampleIndex,C))
Although at this point, it's easier to loop from 0 to NewDuration-1 than to subtract 1 from each usage of I.
Ethan_Pixelate
Prole
Posts: 7
Joined: Fri Dec 06, 2019 11:26 pm

Re: attempt to index out of range sample

Post by Ethan_Pixelate »

Alright, so I have applied the fixes up to the "local NewDuration = math.floor(Duration*Speed)-1", and the effect actually was successfully applied a couple of times, but then another error on the 3rd time it was used. The reason I didn't fix the rest is because I think I didn't make it clear enough why I was making NormalizedI a fractional number. The reason NormalizedI is a fractional number is because I'm trying to represent I as a percentage instead of an absolute integer position so that I can get a transformed position on Sound so that I can copy it to NewSound. In other words, nearest neighbor scaling for sound instead of textures, so rounding NormalizedI wouldn't really be a good thing because that would mean making it 0 or 1. Will try it anyways to see if it works though.
User avatar
pgimeno
Party member
Posts: 2825
Joined: Sun Oct 18, 2015 2:58 pm

Re: attempt to index out of range sample

Post by pgimeno »

Yeah I was pretty off with that comment, sorry. If you can provide a runnable example maybe we can help better.
Ethan_Pixelate
Prole
Posts: 7
Joined: Fri Dec 06, 2019 11:26 pm

Re: attempt to index out of range sample

Post by Ethan_Pixelate »

Yeah, I probably should have done that in the original post, here it is:
Attachments
TT5000.zip
(9.38 KiB) Downloaded 43 times
User avatar
pgimeno
Party member
Posts: 2825
Joined: Sun Oct 18, 2015 2:58 pm

Re: attempt to index out of range sample

Post by pgimeno »

Okay, the problem was using a 1-based index to access the samples. This works:

Code: Select all

local NormalizedI = (I-1)/NewDuration
But as I said, it's easier at this point to loop with a zero-based index instead of subtracting 1 twice:

Code: Select all

for I=0,NewDuration-1 do
The same problem is in RandomChopping. Looping from 0 to Duration-1 makes it start working in principle, but for me it crashes later because I-Start is negative when Start is > 0. I think you want I+Start there. Note that you don't use End, and even if you did, you have to watch out for End < Start. If you want to chop at random, you probably need to first pick a random length, then choose a start point between 0 and Duration - length, then copy `length` samples from there (not `Duration` samples, because in that case you'd go out of range again).
Ethan_Pixelate
Prole
Posts: 7
Joined: Fri Dec 06, 2019 11:26 pm

Re: attempt to index out of range sample

Post by Ethan_Pixelate »

So I tried what you said and it works!!

Thank you so much :D
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot], Gunroar:Cannon() and 72 guests