Arpeggiator

Home Forums General Programming Arpeggiator

Viewing 17 posts - 1 through 17 (of 17 total)
  • Author
    Posts
  • #119460
    Tedjuh
    Participant
      • Topics: 9
      • Replies: 97
      • Total: 106
      • ★★

      For my panel I need up to 512 blocks to be painted. They should be named block1,block2, block2,etc. because they need to be able to vary in size. In the init file I create the block1. Block1=(). In the paint file I do block1:setBounds() and to draw the rectangle I do: block1:drawRect(). I see the block. So far, so good.

      But how to generate 512 of them when iterating? When I do: string.format(“block%s:setBounds()”,i), the block returns nil. Same with g:drawRect(string.format(“block%s”,i),1)). Tried the toFloat.. but to no avail. Tried a table, again nil. Is there someone that can tell me what I’m missing here?

      #119461
      samoht
      Participant
        • Topics: 1
        • Replies: 54
        • Total: 55
        a={}
        for i=1 , 512 do a = "block"..i.."=()"
        end

        a[9] –> block9=()

        #119462
        samoht
        Participant
          • Topics: 1
          • Replies: 54
          • Total: 55
          a={}
          for i=1 , 512 do a = "block"..i.."=()"
          end
          
          for k,v in ipairs(a) do print (v) end
          #119466
          samoht
          Participant
            • Topics: 1
            • Replies: 54
            • Total: 55

            Behind the “a” that follows the word “for” , there have to be rectangular brackets surrounding i.
            I am unable to show these in code in WordPress

            #119468
            Tedjuh
            Participant
              • Topics: 9
              • Replies: 97
              • Total: 106
              • ★★

              Thank you for the input but you are creating a table as far as I can tell. But in the paint script I can’t do something like a[9]:setBounds(). It will return nil.

              But first let me try to create 512 rectangles like: block1 = Rectangle(). Something is wrong with my syntax or way of thinking how to do it.

              For i = 1,512 do string.format(“block%d = Rectangle()”,i) end
              Returns nil, probably because it’s a string.
              But block..i.. = Rectangle() gives an error telling me there can’t be concatenation before =.

              Bit at a loss here, is it possible at all to do it with a for loop?

              #119469
              Possemo
              Participant
                • Topics: 14
                • Replies: 638
                • Total: 652
                • ★★★

                I don’t see exactly what you want to do. Why do you want to add =Rectangle() to the variable? Couldn’t you do something like i=Rectangle() and i being Block1 to Block512?

                Edit: no of course that won’t work either… Maybe if we now exactly what you want to do then it would be easier to make some suggestions. E.g. when you draw some graphics, do you use the uiCustomComponent? Probably. You would need to set coordinates for the rectangle otherwise they will all draw over themselves. Or do you use a dedicated uiCustomComponent for each rectangle? Probably not, that would make the panel too complex.

                • This reply was modified 3 years, 8 months ago by Possemo.
                #119477
                Tedjuh
                Participant
                  • Topics: 9
                  • Replies: 97
                  • Total: 106
                  • ★★

                  Warning, very long post:

                  To get an idea of what I’m working at, see attached picture 1. The GUI is still work in progress.
                  — On top: comboBox that controls the number of steps (1-32). (Working)
                  — At the bottom: Vertical bars to set the velocity (0-127) for each selected note. (Partially working)
                  — To the left: A slider to be able to scroll: (Working)
                  — In the middle: PianoBar (Black and white blocks) from C-1 to G9 (127 notes) (Now on middle octave)
                  — To the Right: NoteBar (White and grey Rows) to set the position of the note in steps (1-32)

                  Everything except the comboBox and Slider are separate uiCustomComponents. Later to be made as one big uiCustomComponent. But for starters..

                  What’s working for now:
                  Sysex, generated with mouse events. Synthesizer accepts it and plays it the right way.
                  — The Sysex is also used to paint the blocks. The paint script iterates over the Sysex to define the note (0-127), which position (1,32), the width (1,32) and last but not least the velocity (1,127) to be painted.
                  — By double-clicking on the piano bar, the note bar gets emptied.
                  — When I click on a row, a red block gets painted on mouseDown.
                  — Blocks are deleted when double-clicking at them.
                  — No overlapping of blocks possible if the Sysex is correct.
                  — When I mouse over a block, you are able to drag it to become wider or smaller.

                  But when I dragged one of the blocks, they all became wider or smaller. I figured that it had something to do with not naming different blocks. In the Juce Graphics Class I can call a Rectangle like:
                  void Graphics::drawRect (Rectangle< int >rectangle,int lineThickness = 1 ) const

                  So I figured, create different named blocks. Tried that with the following codes:
                  In the init file the block gets created:

                  
                  block1 = Rectangle()
                  

                  In the paint script I do:
                  (x,y,w,h and l are all set)

                  
                  if arp1:getByte(1) > 0 and arp1:getByte(1) < 128 then
                  g:setColour(Colour(0xFFFF0000))
                  block1:setBounds(x,y,w[width],h)			
                  g:drawRect(block1,l)
                  end
                  

                  Read something about square brackets not being shown on this forum. At some mouse events there’s some calculation done that gives a value that is being read from a table with x[1] and w[width]. x = position of the block in height, w is the width of the block.

                  I am able to set different colors, widths, heights and so on for the blocks when I add more blocks to the init file and call them in the paint script with block1, block2, etc. (See picture 2.) I can even paint blocks on different notes. (Disabled for now). That is all working.. it’s just the naming convention for the graphics class that’s bugging me.

                  According to the Sysex implementation I can select 16 different notes with 32 positions each. So, a max of 16×32 = 512 “possible” blocks. Now I don’t mind some coding but.. that would mean a hell lot of code. Just to create 512 Rectangles, let alone do the same for the code above for 512 different rectangles. So, first I want to be able to create 512 blocks/ rectangles, to be able to call them separate from each other in the paint script. But I can’t even seem to do that..

                  For instance if I want to number different modulators I do:
                  for i = 1,512
                  panel:getModulatorByName(string.format(“block%s”,i)):getComponent()
                  end

                  It’s working because the modulatorName is a string. But I’m not adding a modulator, right?

                  for i = 1,512 do string.format(“block%s:Rectangle()”,i) end (Doesn’t work, string)

                  for i = 1,512 do block..i..= Rectangle() end (Doesn’t work, gives error no “..” allowed before “=”)

                  Creating a table..

                  bRectangle = {}
                  for i = 1,512 do
                  bRectangle = “block[“..i..”] = Rectangle()”
                  end

                  Doesn’t work either because I can’t call:
                  bRectangle[1]:setBounds() or
                  g:drawRect(bRectangle[1],1)
                  in the paint script. Both return nil.

                  Anyone? 🙁

                  Attachments:
                  You must be logged in to view attached files.
                  #119483
                  dnaldoog
                  Participant
                    • Topics: 4
                    • Replies: 480
                    • Total: 484
                    • ★★

                    He Tedjuh,

                    Does

                    
                    for i=1,512 do
                    _G["block"..i]=Rectangle()
                    end
                    

                    work?


                    Note: When posting iterators you can’t use [i] because it is interpreted as BBCode for italic formatting, therefore the unclosed [i]text[/i] is deleted, so you need to substitute something like [j]

                    #119490
                    dnaldoog
                    Participant
                      • Topics: 4
                      • Replies: 480
                      • Total: 484
                      • ★★

                      This code seems to work!

                      
                      paintc = function(--[[ CtrlrComponent --]] comp --[[ CtrlrComponent --]], g)
                          local x, y, w, h = 20, 30, comp:getWidth(), comp:getHeight()
                          backdrop = 0xff99ccff
                          g:fillAll(Colour(backdrop))
                          g:setColour(Colour(0xff000000))
                          for i = 1, 512 do
                              _G["block" .. i] = Rectangle()
                          end
                      
                          g:setColour(Colour(0xff000000))
                      
                          block502:setBounds(x + 20, y + 20, (w / 2) + 20, (h / 2) + 20)
                          g:setColour(Colour(0xffffff00))
                          g:fillRect(block502)
                      
                          block500:setBounds(x, y, w / 2, h / 2)
                          g:setColour(Colour(0xff000000))
                          g:drawRect(block500, 2.5)
                      
                          block501:setBounds(x + 10, y + 10, (w / 2) + 10, (h / 2) + 10)
                          g:setColour(Colour(0xff000000))
                          g:drawRect(block501, 2.5)
                      
                      end
                      

                      example of fillRect and drawRect generated from lua loop

                      Attachments:
                      You must be logged in to view attached files.
                      #119492
                      Tedjuh
                      Participant
                        • Topics: 9
                        • Replies: 97
                        • Total: 106
                        • ★★

                        I’m going to try the code you gave Dnaldoog. Looks promising. I swear I found the _G[] thing in some old forum posts from human fly but I got the wrong syntax doing _G[block ..i.. ], without the ” “. So close, argh.

                        Just one question. Is it possible to do the same to the g:setBounds() or g:fillRect() ? Like _G[“block” ..i]:setBounds() ?

                        I could try this myself. Was just wondering :). But thank you already. Like so many times before.

                        #119493
                        dnaldoog
                        Participant
                          • Topics: 4
                          • Replies: 480
                          • Total: 484
                          • ★★

                          Hi Tedjuh!

                          _G["block" ..i]:setBounds() would work as long as you have already declared an object `_G[“block” ..i]:Rectangle(). so I guess they could be included in the same loop:

                          
                          paintc = function(--[[ CtrlrComponent --]] comp --[[ CtrlrComponent --]], g)
                              local x, y, w, h = 20, 30, comp:getWidth(), comp:getHeight()
                              backdrop = 0xff99ccff
                              g:fillAll(Colour(backdrop))
                              g:setColour(Colour(0xff000000))
                              for i = 1, 512 do
                          _G["block" .. i] = Rectangle()
                          _G["block"..i]:setBounds(x,y,w,h)
                              end
                          
                              g:setColour(Colour(0xff000000))
                          
                             -- block502:setBounds(x + 20, y + 20, (w / 2) + 20, (h / 2) + 20)
                              g:setColour(Colour(0xffffff00))
                              g:fillRect(block502)
                          
                             -- block500:setBounds(x, y, w / 2, h / 2)
                              g:setColour(Colour(0xff000000))
                              g:drawRect(block500, 2.5)
                          
                             -- block501:setBounds(x + 10, y + 10, (w / 2) + 10, (h / 2) + 10)
                              g:setColour(Colour(0xff000000))
                              g:drawRect(block501, 2.5)
                          
                          end
                          

                          You could then dynamically change the x,y positioning within the loop

                          Regards,

                          John

                          #119498
                          Possemo
                          Participant
                            • Topics: 14
                            • Replies: 638
                            • Total: 652
                            • ★★★

                            Why not generate the renctangles on the fly according to the mouse position? You have to query the mouse position anyway, don’t you? Instead of selecting a predefined rectangle when a mouse x and y is within a specific range, just draw the rectangle. You will have to calculate x and y – well I don’t know but I guess there must be an elegant way to do this. Hmm, ok when I look at your pictures you probably want to be able to shift the rectangles when you move to higher or lower note range… and you will have to be able to clear them when you click an already drawn rectangle again.. quite some coding work. Well yes, maybe it is easier to predefine all rectangles. It will be interesting to see if this works.

                            #119500
                            Tedjuh
                            Participant
                              • Topics: 9
                              • Replies: 97
                              • Total: 106
                              • ★★

                              Why not generate the renctangles on the fly according to the mouse position?

                              Because there is no viewport class imported to ctrlr (There is one in juce though.), I need to do some trickery to create the sense of a viewport.

                              So when I scroll up or down, all coordinates for the black and white lines are read from a table. Later, the Sysex is being read and paints the rectangles. Because the Sysex are 16 different MemoryBlocks, one for each note, I’m even able to do the repaint per note instead of repainting the whole component.

                              Elegant? Maybe not. There is indeed a lot of calculation going on in the background. Lots of if else then statements on the mouse events. Lots of getByte and setByte. Lots of repaint. But it is almost working as intended.

                              With the Rectangle class being up to date or a viewport class, it could have been more elegant but unfortunately that isn’t the case. No Biggie but it means a lot more code than needed, yes.

                              Gonna give your code a try now, Dnaldoog. You’ll hear from me soon.

                              #119502
                              dnaldoog
                              Participant
                                • Topics: 4
                                • Replies: 480
                                • Total: 484
                                • ★★

                                Hi Tedjuh,

                                I got to thinking that Possemo’s suggestion of on the fly mouse creation was excellent.

                                You can avoid those cumbersome loops and probably super complex code.

                                Here is a panel that creates a `fillRect’ on the grid where the mouse was clicked. Instead of generating vertical and horizontal lines, you could have a mock png image in a different layer as backdrop.

                                You would then have to move the image according to your scrolling modulator or alternatively redraw the graphics lines in the component and offset the mouseclick y coordinate. It’s probably not too difficult finding the new coordinates that way although I haven’t got that far yet.

                                Here is the code. ※ Variables mpX and mpY are mouseUp coordinates. (see below)

                                
                                paintMe2 = function(--[[ CtrlrComponent --]] comp --[[ CtrlrComponent --]], g)
                                    g:setColour(Colour(0xff000000))
                                    local height = comp:getHeight()
                                    local width = comp:getWidth()
                                    local x, y = 0, 0
                                    local wDiv = width / 32
                                    local hDiv = height / 16
                                    --************************************
                                    --draw surrounding area
                                    g:drawVerticalLine(width - 1, 0, height)
                                    g:drawVerticalLine(0, 0, height)
                                    g:drawHorizontalLine(0, 0, width)
                                    g:drawHorizontalLine(height - 1, 0, width)
                                    -- end draw surrounding area
                                    --************************************
                                    local verticalCoords = {0}
                                    local horizontalCoords = {0}
                                
                                    for i = 1, 32 do
                                        g:drawVerticalLine(wDiv * i, 0, height)
                                        table.insert(verticalCoords, (wDiv * i))
                                    end -- loop 32 horizontal
                                
                                    for i = 1, 16 do
                                        g:drawHorizontalLine(hDiv * i, 0, width)
                                        table.insert(horizontalCoords, (hDiv * i))
                                    end -- loop 32 horizontal
                                
                                    for j = 1, #verticalCoords do
                                        if verticalCoords[j] > mpX then
                                            x = verticalCoords[j - 1]
                                            break
                                        end
                                    end
                                
                                    for j = 1, #horizontalCoords do
                                        if horizontalCoords[j] > mpY  then
                                            y = horizontalCoords[j - 1]
                                            break
                                        end
                                    end
                                
                                    local rec = Rectangle(x, y, wDiv, hDiv)
                                    g:setColour(Colour(0xff0000ff))
                                    g:fillRect(rec)
                                end -- function
                                

                                Other functions:

                                
                                mouseUp = function(--[[ CtrlrComponent --]] comp, --[[ MouseEvent --]] event)
                                repaint_component()
                                end
                                
                                mouseMove = function(--[[ CtrlrComponent --]] comp, --[[ MouseEvent --]] event)
                                	mpX = event.x
                                	mpY = event.y
                                end
                                
                                repaint_component = function(--[[ CtrlrModulator --]] mod, --[[ number --]] value, --[[ number --]] source)
                                panel:getComponent("c"):repaint()
                                end
                                

                                This code must be lean, because when doing debug prints of the tables to console(), it doesn’t slow down the program much!

                                • This reply was modified 3 years, 8 months ago by dnaldoog. Reason: fixed missing [i]
                                Attachments:
                                You must be logged in to view attached files.
                                #119508
                                Tedjuh
                                Participant
                                  • Topics: 9
                                  • Replies: 97
                                  • Total: 106
                                  • ★★

                                  Appreciate the work you put into this Dnaldoog. Funny thing is, I already wrote most of the code like you did but “with” the scrolling part. I never got the IMG to work so I did it all with painting.

                                  The thing I’m not doing (yet) is creating rectangles on the fly because I wanted to avoid the inserting and deleting values in tables.

                                  It’s hard to explain the way I do it now and I promise to send you a mail later with the panel. But I discovered a major f*ck up. I discovered ctrlr overwrote my old save while I thought it was saving to a new version.

                                  Actually it is. Even I’m opening arpbuild4.. when I save it, it says it’s saving to arpbuild3. Great.. give me some time to rewrite some code and I’ll send you the new version later.

                                  #119513
                                  Tedjuh
                                  Participant
                                    • Topics: 9
                                    • Replies: 97
                                    • Total: 106
                                    • ★★

                                    Ok, after giving Possemo and dnaldoog’s advice some thoughts. I think it’s a better idea to separate the Sysex and the building of the rectangles in the arpeggiator. It should mean some rewriting of the code but that is not a big deal. Dnaldoog gave me a headstart.

                                    In other words, thank you for the advice.

                                    #119519
                                    Tedjuh
                                    Participant
                                      • Topics: 9
                                      • Replies: 97
                                      • Total: 106
                                      • ★★

                                      Getting there. See animated gif.

                                      Lots of things to finetune. Also need to get the velocity bar at the bottom to work. Make it switch velocities on mousedown according to the note that is selected. But getting there.

                                      Thank you all.

                                      Attachments:
                                      You must be logged in to view attached files.
                                    Viewing 17 posts - 1 through 17 (of 17 total)
                                    • The forum ‘Programming’ is closed to new topics and replies.
                                    There is currently 0 users and 65 guests online
                                    No users are currently active
                                    Forum Statistics
                                    Threads: 2,495, Posts: 17,374, Members: 77,605
                                    Most users ever online was 12 on January 22, 2019 3:47 pm
                                    Ctrlr