Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Playing multiple sound files simultaneously.

in Questions Posts: 38

I hope I'm asking this question in the right place, but here goes.

I'm working on a program that simulates an accordion. Yes, you heard right, a 21-button accordion. I have created music files by sampling the sounds produced on my accordion. They are short, 2-sec files, that I have created and uploaded to Dropbox for use in my program. The idea is that by pressing a button the music file that corresponds with that button will play. @Ignatz described a method of playing a music or sound file while pressing a button, and going silent once released. That advice greatly helped.

On an accordion I can play multiple notes simultaneously. My question is: Can I select multiple sound files and play them simultaneously if I press multiple buttons? My goal is to produce a blended sound similar to pressing multiple buttons on an accordion. I'm guessing it's not possible but by asking the exports I can save myself some frustration.

I have searched this site but cannot find an answer. Any help is greatly appreciated.

«1

Comments

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty The quickest way would be to set up 2 buttons and listen if it plays your 2 sound files and if it sounds correct.

  • Posts: 707

    You can play multiple versions of the same sound simultaneously

    -- Use this function to perform your initial setup
    function setup()
    end
    
    -- This function gets called once every frame
    function draw()
        -- This sets a dark background color 
        background(40, 40, 50)
    end
    
    function touched(t)
    
        if t.state==MOVING then
            sound("Game Sounds One:Female Cheer 1")
        end
    end
    
  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty As @West shows, you can play multiple sound files, but will playing multiple sound files together blend correctly to give you the final sound you want. You’ll have to take the sound files you have and play some together to see if the resulting sound is what you want.

  • Posts: 38

    Thanks. Can't wait to give this a shot.
    I really appreciate this.

  • edited April 7 Posts: 38

    @West, @dave1707:
    We're getting close. I've modified the proposed solution to include what is to happen once touch has ended.

    The first example works with multiple sound files but can't be looped while pressing. Also I'm unable to stop sounds upon release.

    The blended sounds play well together (at leased as well as an accordion sounds LOL!)

    The second example works but with only one music file at a time. Plus music plays as long as I am touching screen and stops once touch has ENDED. That solution was described by @Ignatz to another member's question.

    --[[
    -- Plays both sounds listed opon touch (desired).
    -- Also desired, the ability to loop as long as I am touching the screen.
    -- But once touch has ENDED I want the both sounds to stop.
    function touched(t)
        if t.state==BEGAN then  -- plays both files
            -- two of my sampled 2-sec sounds
            sound("Dropbox:BC1PushC2")
            sound("Dropbox:TC1PullD5")
        elseif t.state==ENDED then  -- stop playing
            --music.stop() -- has no effect
            --sound.stop() -- or generates an error
        end
    end
    --]]
    
    --[[
    -- This works for only one file.
    function touched(t)
        if t.state==BEGAN then 
            music("Dropbox:TC1PullD5",true) -- my sampled 2-sec music file.
        elseif t.state==ENDED then
            music.stop()
        end
    end
    --]]
    

    I really hopes this helps. And, again, I appreciate the help.

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty Here’s something I set up with just 2 keys. Pressing each one plays a sound, and releasing each one stops the sound. You’ll have to try these with your sound files. You can set up as many keys as you want.

    function setup()
        keys={}
        table.insert(keys,key(100,100,"Game Sounds One:Wind 2"))
        table.insert(keys,key(200,100,"Game Sounds One:Crowd Boo"))
    end
    
    function draw()
        background(40, 40, 50)
        for a,b in pairs(keys) do
            b:draw()
        end
    end
    
    function touched(t)
        for a,b in pairs(keys) do
            b:touched(t)
        end
    end
    
    key=class()
    
    function key:init(x,y,s)
        self.x=x
        self.y=y
        self.w=50
        self.h=100
        self.k=nil 
        self.s=s  
        self.id=nil 
    end
    
    function key:draw()
        fill(255)
        rect(self.x,self.y,50,100)
    end
    
    function key:touched(t)
        if t.x>self.x and t.x<self.x+self.w and t.y>self.y and t.y<self.y+self.h then
            self.id=t.id
            if t.state==BEGAN then
                self.k=sound(self.s,1,1,1,true)
            end
            if t.state==ENDED then
                self.k:stop()
            end
        elseif t.state==ENDED and t.id==self.id then
            self.k:stop()
        end
    end
    
  • Posts: 38

    Thank you very much @dave1707. Your example works great as is. It works great with my sampled sounds substituted in and it, most importantly, works great in my project. Any multiple key presses on my accordion that sound well together sounds nice in my program.

    There are two more issues I need to chase down but I before I ask those questions of you I want to try and tackle them myself. One is related to the the above problem while the other relates to the fact that I am dealing with thirty buttons in this program. Each button can produce two tones. One for expanding or pulling the other for compressing or pushing on the accordion. That's a lot of variable definitions to keep track of. I'm glad I didn't buy a piano-style accordion.

    Once I solve that problem I may be able to get my setup() function to be less that 850 lines long. I'm using tables to hold my button objects once creaded so I think I need to use tables to hold the variables used to create them. Similar to your example above.

    Thanks again for your help. I really appreciate it.

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty Glad to hear its a good start for what you need. Also glad that you are trying to figure things out for yourself rather than just asking for an answer. The more you try to figure out youself, the more you’ll learn and won’t rely on others for help. But if you do run into problems, don’t hesitate to ask. That’s the whole purpose of this forum.

  • Posts: 38

    Thank you, @dave1707.

  • Posts: 38

    @dave1707, this is how things stand right now.

    I've modified the example you have generously provided by adding extra keys. I've also added the ability to simulate what would happen when the iPad is tilted. So now there are four keys in one direction and four keys in the other direction.

    When the right side of the iPad is tilted up the red set of keys are available. When the left side is tilted up the green set are available. Gravity.x +/- is used to govern which keys are displayed. I use color to keep track of what's going on.

    You can press and release or press and hold any combination all you want and the blended sound is pleasing. The problem I'm dealing with is when I press AND hold a key WHILE tilting from left to right or from right to left the sound gets locked in and will not stop. Like pushing and pulling on an accordion's bellows while holding a button changes the sound produced, I want to be able to accomplish this through tilting the iPad.

    My goal is that when I press AND hold a red key, for instance, while in one iPad orientation the corresponding green key should replace that sound as the iPad is tilted into the new orientation. When the key is released the sound stops.

    I've added a text statement to label each key's touch.id and it seems clear that I'm loosing the original touch.id as I am tilting the iPad. Somehow I need to keep track of the original id so I can release the original sound when Gravity.x's sense changes.

    I hope this make sense and you can provide additional guidance.
    (Side note: Is it correct to enclose the code that follows with ~~~ before and after to preserve formatting?)
    Thank you very much.


    supportedOrientations(PORTRAIT) displayMode(FULLSCREEN) function setup() -- key locs X1 = (WIDTH/5) X2 = (WIDTH/5)*2 X3 = (WIDTH/5)*3 X4 = (WIDTH/5)*4 Y = 200 -- added extra keys (all sounds are 2sec in length) keysPush={} table.insert(keysPush,key(X1,Y,"Dropbox:TC1PushG3")) table.insert(keysPush,key(X2,Y,"Dropbox:TC1PushC4")) table.insert(keysPush,key(X3,Y,"Dropbox:TC1PushE4")) table.insert(keysPush,key(X4,Y,"Dropbox:TC1PushG4")) keysPull={} table.insert(keysPull,key(X1,Y,"Dropbox:TC1PullB3")) table.insert(keysPull,key(X2,Y,"Dropbox:TC1PullD4")) table.insert(keysPull,key(X3,Y,"Dropbox:TC1PullF4")) table.insert(keysPull,key(X4,Y,"Dropbox:TC1PullA4")) end function draw() background(40, 40, 50) fill(255, 255, 255, 255) fontSize(25) textMode(CENTER) fontSize(50) -- display keys based on iPad orientation if Gravity.x > 0 then text(string.format("Gravity.x = %.f: Push",Gravity.x), WIDTH/2,HEIGHT/2-25) for a,b in pairs(keysPush) do fill(0, 255, 0, 255) b:draw() end elseif Gravity.x < -0 then text(string.format("Gravity.x = %.f: Pull",Gravity.x), WIDTH/2,HEIGHT/2-25) for a,b in pairs(keysPull) do fill(255, 0, 0, 255) b:draw() end end end function touched(t) if Gravity.x > 0 then for a,b in pairs(keysPush) do b:touched(t) end elseif Gravity.x < 0 then for a,b in pairs(keysPull) do b:touched(t) end end end key=class() function key:init(x,y,s) self.x=x self.y=y self.rad= 35 self.k=nil -- this will hold address of sound()? self.s=s -- sound to be played self.id=0 end function key:draw() ellipseMode(RADIUS) strokeWidth(5) ellipse(self.x,self.y,self.rad) stroke(255, 255, 255, 255) textMode(CENTER) fontSize(15) fill(255, 255, 255, 255) -- sound and touch id text(self.s,self.x,self.y-self.rad-25) text(self.id,self.x,self.y-self.rad-50) end function key:touched(t) if t.state==BEGAN then if vec2(t.x,t.y):dist(vec2(self.x,self.y)) <= self.rad then self.id=t.id self.k=sound(self.s,1,1,1,true) end elseif t.state==ENDED and t.id==self.id then self.k:stop() end end
  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty Since you like to solve you’re own problems, I’ll give you a suggestion. When you tilt the iPad, don't lock out the keys totally. If a red key is held down when you tilt the iPad, set the corresponding green key value to play. You can prevent the pressing of the red keys, but still allow the checking for ending the touch of a red key. Instead of checking Gravity in the touched function, try checking it in the key:touched function for BEGAN. That way you can still check for ENDED.

  • Posts: 38

    Thanks, @dave1707. I'll work on this and see what I come up with. I appreciate it.

  • Posts: 38

    @dave1707 , I'm still struggling with this problem but I feel I'm getting closer to my goal.

    The way it stands now is that when I press and hold a key in one orientation the correct sound plays. As I tilt the iPad to the new orientation the original sound continues to play BUT at least it stops playing when I release the key. So the sound is not getting locked in as before. This is a step closer.

    The sound that plays in one orientation needs to be replaced by a new sound as the iPad's orientation changes (i.e. at the point when gravity.x changes from positive to negative or vise versa). This all has to happen while the key is pressed and held. If that can happen AND cease to play once key is released I think WE would have it solved.

    When you write: "If a red key is held down when you tilt the iPad, set the corresponding green key value to play." I'm not clear how to accomplish this AND not have it play at the wrong time.

    One change I've made was to combine my two tables into one. That way, when I moved the testing of gravity.x from touched to key:touched (your suggestion), I could get away with accessing only a single table in the touched for loop and not have both sounds play. That was very beneficial.

    I hope this is clear and once again, thank you for your continued guidance.

    supportedOrientations(PORTRAIT)
    displayMode(FULLSCREEN)
    
    function setup()    
    
        -- key locs
        X1 = (WIDTH/5)
        X2 = (WIDTH/5)*2
        X3 = (WIDTH/5)*3
        X4 = (WIDTH/5)*4  
        Y = 200
    
    --[[
    Added extra keys
    "keysPush" and "keysPull" table have been combined into one table.
    --]]
        keysPushPull={}
        table.insert(keysPushPull,key(X1,Y,
            "Dropbox:TC1PushE4","Dropbox:TC1PullF4"))
        table.insert(keysPushPull,key(X2,Y,
            "Dropbox:TC1PushG4","Dropbox:TC1PullA4")) 
        table.insert(keysPushPull,key(X3,Y,
            "Dropbox:TC1PushC5","Dropbox:TC1PullB4"))                                            
        table.insert(keysPushPull,key(X4,Y,
            "Dropbox:TC1PushE5","Dropbox:TC1PullD5")) 
    
    end
    
    
    
    function draw()
        background(89, 89, 89, 255)
        fill(255, 255, 255, 255)
        fontSize(25)
        textMode(CENTER)   
        fontSize(40)
    
    -- display keys based on iPad orientation.
        if Gravity.x > 0 then
            text(string.format("Gravity.x = %.f: Push",Gravity.x),
                WIDTH/2,HEIGHT/2-25)
            for a,b in pairs(keysPushPull) do 
                fill(0, 255, 0, 255)        
                b:draw() 
            end
        elseif Gravity.x < 0 then
            text(string.format("Gravity.x = %.f: Pull",Gravity.x),
                WIDTH/2,HEIGHT/2-25)
            for a,b in pairs(keysPushPull) do
                fill(255, 0, 0, 255)      
                b:draw() 
            end
        end              
    end
    
    
    function touched(t)
        for a,b in pairs(keysPushPull) do
            b:touched(t)
        end
    end
    
    
    
    key=class()
    
    function key:init(x,y,sPush,sPull)
        self.x      = x
        self.y      = y
        self.sPush  = sPush
        self.sPull  = sPull
    
        self.id     =  0 
        self.rad    = 35    
        self.k      =  0   -- sound 
    end
    
    
    function key:draw()
        ellipseMode(RADIUS)
        strokeWidth(5)    
        ellipse(self.x,self.y,self.rad)
        stroke(255, 255, 255, 255)
        textMode(CENTER)
        fontSize(15)
        fill(255, 255, 255, 255)
        -- label each key with sound name and touch id 
        if Gravity.x > 0 then
            text(self.sPush, self.x,self.y-self.rad-25)
            text(self.id,    self.x,self.y-self.rad-50) 
        elseif Gravity.x < 0 then
            text(self.sPull, self.x,self.y-self.rad-25)
            text(self.id,    self.x,self.y-self.rad-50)
        end        
    end
    
    
    function key:touched(t)
        if t.state==BEGAN then
            if vec2(t.x,t.y):dist(vec2(self.x,self.y)) <= self.rad then 
                if Gravity.x > 0 then
                    self.id=t.id
                    self.k=sound(self.sPush,1,1,1,true)
                elseif Gravity.x < 0 then
                    self.id=t.id                
                    self.k=sound(self.sPull,1,1,1,true)
                end            
            end           
        elseif  t.state==ENDED and t.id==self.id then
            self.k:stop()
        end    
    end
    
    
  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty When you’re pressing a key and you get a sound, and then you change orientation, is the same sound supposed to switch to the other key or is the other key supposed to play a different sound.

  • Posts: 707

    @Scotty

    Your logic and code is fine for the above, but the issue is that the touched function when the screen is touched for the first time (or released). Tilting the screen does not visit the touched function.

    To explore - try changing

    if t.state==BEGAN then
    

    to

    if t.state==BEGAN or t.state==MOVING then
    

    This will give you what you are after, but only if you are moving your finger on the button (the touch movement will trigger the touched function).

    What you probably want to explore is using the touched function to create a table of currently active touches and cycle through them on on the main draw cycle. I'll let you have a go at this (unless Dave or others can suggest a better approach) but let me know if you want further pointers - I've done similar with a touch tracker and the code should somewhere on this forum

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty Here’s what I was thinking. The red key can be pushed when Gravity is negative and the green key pushed when Gravity is positive. The sound for any key stops when that key is released no matter what the value of Gravity. I don’t have access to your sound files, so I’m using the same Codea sound for both keys. I don’t know if you want both key sounds to play at the same time or not.

    function setup()
        rectMode(CENTER)
        k1=key(100,100,-1,color(255,0,0),"Game Sounds One:Wind 2")
        k2=key(WIDTH-100,100,1,color(0,255,0),"Game Sounds One:Wind 2")
    end
    
    function draw()
        background(40, 40, 50)
        k1:draw()
        k2:draw()
    end
    
    function touched(t)
        k1:touched(t)
        k2:touched(t)
    end
    
    key=class()
    
    function key:init(x,y,g,col,s)
        self.x=x
        self.y=y
        self.w=50
        self.h=50
        self.g=g    -- -1=key valid for gravity negative  1=key valid for gravity positive
        self.id=0   -- touch id
        self.c=col  -- key color
        self.s=s    -- sound to play for this key
        self.k=nil  -- sound thats playing
    end
    
    function key:draw()
        fill(self.c)
        rect(self.x,self.y,self.w,self.h)
    end
    
    function key:touched(t)
        if t.x>self.x-self.w/2 and t.x<self.x+self.w/2 and
                t.y>self.y-self.h/2 and t.y<self.y+self.h/2 then
            if t.state==BEGAN then
                if Gravity.x<0 and self.g==-1 then    -- gravity negative and key negative
                    self.id=t.id
                    self.k=sound(self.s,1,1,1,true)
                elseif Gravity.x>0 and self.g==1 then    -- gravity positive and key positive
                    self.id=t.id
                    self.k=sound(self.s,1,1,1,true)
                end
            end
        end
        if t.state==ENDED and t.id==self.id then
            self.id=nil
            self.k:stop()        
        end
    end
    
  • edited May 5 Posts: 38

    @dave1707, forgive me but I have yet to figure out how to share Dropbox sound files. I'm willing to share -- just not smart enough to share. LOL!

    In your example it appears you have TWO buttons, a red and a green. Make that be ONE button that can produce two different sounds, a high/low sound, and two different colors, red/green, depending on the iPad orientation. So, to keep this example as simple as possible: one button, two sounds and two colors.

    In my example, I have four buttons. If a one-button can work I should be able to get multiple buttons to work. My goal is 29 buttons, like an accordion.

    Thanks again for your help.

  • Posts: 38

    @West thanks for your suggestion. I've tried adding MOVING to the if condition but that just keep adding more sounds but not stopping them once the button is released.

    As for your other suggestion, keeping track of active touches that is worth exploring.

    Also I'm trying to figure out how to share Dropbox sound files, once I do that it should make my example make more sense.

    Thank you very much.

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty I guess I don’t know how an accordion actually works. So the buttons on the different sides of the accordion play different notes and depending on pulling or pushing the accordion, each button will play one of two notes assigned to it. If that’s the case, then as long as a button is pressed, it will switch between the two notes as the iPad is tilted until the button is released. If that’s the case, then I can modify my above code to handle that.

  • dave1707dave1707 Mod
    edited May 5 Posts: 6,828

    @Scotty Here’s what I think you were saying. One button, two sounds, two colors depending on which way the iPad is tilted. If this is what you want, I can probably make the code smaller because I did a quick chop job just to make it work this way.

    function setup()
        rectMode(CENTER)
        k1=key(WIDTH/2,200,"Game Sounds One:Wind 2","Game Sounds One:Crowd Boo")
    end
    
    function draw()
        background(40, 40, 50)
        k1:draw()
    end
    
    function touched(t)
        k1:touched(t)
    end
    
    key=class()
    
    function key:init(x,y,s1,s2)
        self.x=x
        self.y=y
        self.w=50
        self.h=50
        self.g=g
        self.id=0   -- touch id
        self.s1=s1    -- sound 1 to play for this key
        self.s2=s2    -- sound 2 to play for this key
        self.k=nil  -- sound thats playing
    end
    
    function key:draw()
        if Gravity.x<0 then
            fill(255,0,0)
            if self.k~=nil and self.g==1 then
                self.k:stop()
                self.k=sound(self.s1,1,1,1,true)
            end
            self.g=-1
        else
            fill(0,255,0)
            if self.k~=nil and self.g==-1 then
                self.k:stop()
                self.k=sound(self.s2,1,1,1,true)
            end
            self.g=1
        end
        rect(self.x,self.y,self.w,self.h)
    end
    
    function key:touched(t)
        if t.x>self.x-self.w/2 and t.x<self.x+self.w/2 and
                t.y>self.y-self.h/2 and t.y<self.y+self.h/2 then
            if t.state==BEGAN then
                self.id=t.id
                if self.g<0 then
                    self.k=sound(self.s1,1,1,1,true)
                else
                    self.k=sound(self.s2,1,1,1,true)
                end
            end
        end
        if t.state==ENDED and t.id==self.id then
            self.id=nil
            self.k:stop()  
            self.k=nil      
        end
    end
    
  • Posts: 38

    @dave1707, your description of my problem looks to be spot on. I ran your modified example and that seems to work as advertised.

    I control the color in draw( ) so it stands to reason I should control the sound there as well. I will modify my program and see how it works and report back. Hopefully I can figure out how to share Dropbox sound files then I can share the results.

    By the way, accordions work just like a harmonica. Draw breath in produces one sound, blowing out produces a different sound on the same hole.

    You can't imagine how much I appreciate your help. I also will thank @West for his contribution. I've learned a great deal in this exercise.

    ...Scott

  • dave1707dave1707 Mod
    edited May 5 Posts: 6,828

    @Scotty As for sharing Dropbox files, there’s a Public folder in Dropbox. Any file you put in that folder gets it own link that can be shared with anyone, even non Dropbox users. Once you go into the Public folder, there’s a file there that explains how to do it. As for the accordion, I thought that the keys on one side was for pushing, and the other side for pulling. Now I know.

  • Posts: 815
    @dave1707 - I thought the Dropbox public folder was no longer public. I think you can provide links from any Dropbox folder but need email addresses to give better access (listing/read/write).
  • dave1707dave1707 Mod
    Posts: 6,828

    @Bri_G The Public folder seems to work. I moved a file there and then selected create a link. I then copied the link and was able to paste it in a test discussion. From the test discussion I selected the link which took me to the file.

  • Posts: 38

    @dave1707 and @Bri_G, thanks for the Dropbox tip. I had not seen the public folder. I'll see if I can go public with my sound files.

    If I can I'll share the whole project. It's fairly large because the accordion I'm simulating has 21 treble buttons and 8 bass buttons for a total of 58 sounds. I'm happy to share given how much guidance I received.

    By the way, I could have spent 10 bucks and bought an accordion app from Apple's App Store but I'm too frugal (cheap). But it would not have come with all the knowledge I've gained from this exercise.

    Thanks again.

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty The whole fun of it is learning to do it yourself. For me, the fun is figuring out how to help others with their code.

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty Creating 58 Dropbox links and pasting them in a discussion might be a lot of trouble. I know I wouldn’t copy them into a folder so the Codea project could read them. A lot of times, I won’t even copy 1 file for an example project. Maybe you could ask how many users are interested before you do all that work.

  • Posts: 38

    Good point, @dave1707. If I had to link, copy and paste one file at a time, believe me, it wouldn't get done.

    I appreciate people like you who take the time to tackle a crazy project like mine.

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty I don’t know how you created your sound files, but maybe similar files, just for your example, could be created mathematically. Set up a 58 count for loop and create 58 sound files based on some frequency calculation.

  • Posts: 38

    Thanks for the advice @dave1707, but believe it or not, I sampled all the sounds my accordion produces using an app called Hokusai. Then, after editing, I uploaded them into Dropbox. It didn't take as long as you would imagine. After a quick re-sync I was in business.

    Given the amount of effort that would be required to provide all the sound files I may just have to do as you suggest and create mathematically generated sounds. Knowing that every note in a musical scale is a specific frequency it may not be that big a deal.

    By the way, I tending to believe @Bri_G when he says that Dropbox's Public folder is no longer public. I'm seeing in their doco that as of September 2017 it's no longer available for general use. Looks like they are asking for specific email addresses, as per Bri_G. If I can ask, when had you tried your quick Dropbox test? I'm wondering if things changed after your test.

    More things to ponder, more things to learn.

    Thanks again.

  • dave1707dave1707 Mod
    edited May 9 Posts: 6,828

    @Scotty I tried the Dropbox test a few days ago but I’ll try it here. I moved an image to the public folder, tapped the three dots on the right of the file, selected ‘share‘ from the list. It brought up an email type screen and in the lower right of the page was ‘create a link‘. I tapped that and it said a link was created and showed some options. One was copy link. I selected ‘copy link‘ and then pasted it below. It’s one of the Dropbox sample images of a parakeet. See if selecting the link below show a parakeet. I think I listed the correct steps.

    Removed link and image from my public folder
    
  • Posts: 38

    Wow, Parakeet playing chess. That's the image I see also. @dave1707, I'll give it another shot. If it works I'll upload the 8 sampled sounds for the 4-key test program. Knowing that you do not like to copy in more than a couple files I'll understand if don't want.

    By the way, my 29-key program works quite well. One slight problem is that every so often a key will get "hung up" and stays locked in. It requires a restart of the program. I'm wondering how random those touch id's are and maybe that's causing the hang up.

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty It might be possible to get duplicate id's. I’ll have to run one of my other programs that does multiple id's and see if a duplicate shows up. If not, I’ll load my above example and see if I get a stuck key with that. If I do, I can give you a fix for it.

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty Duplicate id's are happening. I wrote a quick test and after tapping the screen 40 times, only 2 id’s were being used. I was also able to tap the screen 100 times before a third id popped up.

  • Posts: 38

    @dave1707 I was starting to suspect as much. Thanks.

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty Even though I’m getting duplicate ID’s with my test program, I don’t know if I can get a duplicate ID while one is being used. I don’t know how the ID’s are calculated, but it doesn’t seem to be a random number. I’ll have to try writing another test and see if I can get the same ID while it’s being used by another touch.

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty I haven’t been able to get a duplicate ID of an ID that’s in use. I get plenty of duplicate ID numbers, but as long as they’re not being used then it doesn’t matter. As for the stuck key, then something isn’t working the way it should. I’ll see if I can make it happen in the code I gave you above.

  • Posts: 38

    @dave1707 Thanks. I can get the "struck key" to happen while running the 29-key version. I'll try trapping the ID numbers in a table and look at them when it happens.

  • dave1707dave1707 Mod
    edited May 10 Posts: 6,828

    @Scotty I was able to get a stuck key with my single key program above. To do it, tap the button then slide your finger off the button and while still touching the screen, touch the button with another finger. Then lift your finger off the button, then lift the other finger. The sound will still be playing even though nothing is touching the screen. I changed the above code to this and I think the only thing that changed was in the key:touched function.

    function setup()
        rectMode(CENTER)
        k1=key(100,200,"Game Sounds One:Wind 2","Game Sounds One:Crowd Boo")
    end
    
    function draw()
        background(40, 40, 50)
        k1:draw()
    end
    
    function touched(t)
        k1:touched(t)
    end
    
    key=class()
    
    function key:init(x,y,s1,s2)
        self.x=x
        self.y=y
        self.w=50
        self.h=50
        self.g=g
        self.id=0   -- touch id
        self.s1=s1    -- sound 1 to play for this key
        self.s2=s2    -- sound 2 to play for this key
        self.k=nil  -- sound thats playing
    end
    
    function key:draw()
        if Gravity.x<0 then
            fill(255,0,0)
            if self.k~=nil and self.g==1 then
                self.k:stop()
                self.k=sound(self.s1,1,1,1,true)
            end
            self.g=-1
        else
            fill(0,255,0)
            if self.k~=nil and self.g==-1 then
                self.k:stop()
                self.k=sound(self.s2,1,1,1,true)
            end
            self.g=1
        end
        rect(self.x,self.y,self.w,self.h)
    end
    
    function key:touched(t)
        if t.x>self.x-self.w/2 and t.x<self.x+self.w/2 and
                t.y>self.y-self.h/2 and t.y<self.y+self.h/2 then
            if t.state==BEGAN then
                self.id=t.id
                if self.g<0 then
                    self.k=sound(self.s1,1,1,1,true)
                else
                    self.k=sound(self.s2,1,1,1,true)
                end
            end
        elseif t.state==MOVING and t.id==self.id then
            self.id=0
            self.k:stop()  
            self.k=nil      
        end
        if t.state==ENDED and t.id==self.id then
            self.id=0
            self.k:stop()  
            self.k=nil      
        end
    end
    
  • Posts: 38

    @dave1707 Thanks for this suggestion. However, I can still produce the problem by simply enlarging the size of the key -- large enough to easily get two fat fingers on at the same time. @West had also suggested adding MOVING to key:touched, but the same problem happens.

    In my accordion program, with many keys, I set the key size somewhat small and still get stuck keys. I've added code to insert the id numbers into a table but I don't see any duplicates.

    Hopefully this is not a "your iPad it too old" problem.

    Still Stymied.

    Thanks.

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty I doubt that it’s a too old iPad problem. I haven’t tried this yet, but I wonder if checking if a key is already being pressed and ignore any other touches for that key.

  • Posts: 38

    @dave1707 As @West mentioned above, "Tilting the screen does not visit the touched function.", that may be why I'm not seeing the duplicates in my idTable.

    I'm storing them simply to figure out what's going on. Perhaps, as @West mentioned above, I should store the "active" touches and not use an id that is currently "active". That may be what he is referring to.

    The way it stands right now is I can play a complete tune without a lockup and sometimes the second note locks up.

    Thanks.

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty In the draw key:draw() function, after self.k:stop(), maybe you should check the self.id and make sure it’s not 0 before setting self.k=sound. You need to check everywhere that self.k is getting set with a sound to make sure that it’s valid to set it.

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty This is what I consider to be the fun part of writing code. Something isn’t working the way you want, and you have to figure out why. The more programs you write and the more problems you have to figure out, the more you learn. Each problem makes you a better programmer because you start to learn the pitfalls of writing code. And no matter how much you learn, you’ll always run into problems that you have to figure out. You’ll start writing more complex programs and it won’t seem that hard. They may not work exactly how you want them in the beginning, but they will eventually as you work out the problems.

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty Here’s another version to try. I made the key big so multiple fingers will fit for the test. I made self.id a table to keep track of multiple fingers touching or releasing from the same key.

    function setup()
        rectMode(CENTER)
        k1=key(100,200,"Game Sounds One:Wind 2","Game Sounds One:Crowd Boo")
    end
    
    function draw()
        background(40, 40, 50)
        k1:draw()
    end
    
    function touched(t)
        k1:touched(t)
    end
    
    key=class()
    
    function key:init(x,y,s1,s2)
        self.x=x
        self.y=y
        self.w=200
        self.h=200
        self.g=g
        self.id={}  -- touch id
        self.s1=s1    -- sound 1 to play for this key
        self.s2=s2    -- sound 2 to play for this key
        self.k=nil  -- sound thats playing
    end
    
    function key:draw()
        if Gravity.x<0 then
            fill(255,0,0)
            if self.k~=nil and self.g==1 then
                self.k:stop()
                self.k=sound(self.s1,1,1,1,true)
            end
            self.g=-1
        else
            fill(0,255,0)
            if self.k~=nil and self.g==-1 then
                self.k:stop()
                self.k=sound(self.s2,1,1,1,true)
            end
            self.g=1
        end
        rect(self.x,self.y,self.w,self.h)
    end
    
    function key:touched(t)
        if t.x>self.x-self.w/2 and t.x<self.x+self.w/2 and
                t.y>self.y-self.h/2 and t.y<self.y+self.h/2 then
            if t.state==BEGAN or t.state==MOVING then
                table.insert(self.id,t.id)
                if self.g<0 then
                    if self.k==nil then
                        self.k=sound(self.s1,1,1,1,true)
                    end
                else
                    if self.k==nil then
                        self.k=sound(self.s2,1,1,1,true)
                    end
                end
            end
        elseif t.state==MOVING then
            for z=#self.id,1,-1 do
                if self.id[z]==t.id then
                    table.remove(self.id,z)
                end
            end 
            if #self.id==0 and self.k~=nil then
                self.k:stop()  
                self.k=nil 
            end
        end
        if t.state==ENDED then
            for z=#self.id,1,-1 do
                if self.id[z]==t.id then
                    table.remove(self.id,z)
                end
            end 
            if #self.id==0 and self.k~=nil then
                self.k:stop()  
                self.k=nil 
            end
        end
    end
    
  • Posts: 38

    @dave1707 This looks like a slick solution. I've modified my program and can now whale on the keys with only very infrequent lock-ups. Far fewer than before. However, my testing has come to an abrupt halt.

    I added a few more sounds to the program but can not hear them. I tried re-syncing Dropbox and now cannot hear any of the sounds. Not a single one of the 58 sounds. I hope it's just pilot error and not something Dropbox decided change that effects the functionality.

    I've learned a great deal on this project and appreciate all your help. That's a very creative use of tables. I'm starting to believe that there is nothing tables cannot do.

    I've also learned that the last 10 percent of a project's development takes 90 percent of the effort.

    If I can get a program-generated collection of sounds, rather than my sampled sounds, I'll send it your way.

    Thanks again.

  • Posts: 38

    @dave1707 It was Pilot-error with Dropbox. My OCD tendencies made me put all my sound files in a separate folder just to be neat. Unfortunately, Codea could not find them. Life is good again.

    ...Scott

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty Can you hear any sounds at all or just the ones you download from Dropbox. If it’s just the Dropbox sounds, can you download one of them to some other program and hear it. As for tables, they simplify a program a lot and are something that should be learned how to use. You say that you can still lockup a sound. I’ll have to add more keys to the above code and see if I can lock it up.

  • dave1707dave1707 Mod
    Posts: 6,828

    @Scotty I changed my code above to show 6 keys and the only way so far that I can get a stuck key is to touch the screen with 4 fingers which starts the sound but also allows me to slide the screen left or right to show other screens. Moving the current screen just a little affects the touch and locks the sound when I remove my fingers. Touching the screen with multiple fingers and sliding them is a built in option to do different things.

  • Posts: 38

    @dave1707 As far as Dropbox is concerned, I moved all the sounds back to the Codea folder and now all the sounds work just fine. Thanks for looking into that.

    And for the locked keys issue, using four fingers and getting sloppy is probably the problem. I'll play with the program and note what I'm doing when the lockup happens. I have two rows of keys. Ten in the key of F and 11 in the key of C so I have plenty to work with.

    Thanks again.

Sign In or Register to comment.