How to create a cue point with [groove~]? 7 Hours I've lost on this today!


    jamie bell's icon
    jamie bell's icon
    jamie bell
    Jan 27 2016 | 2:00 am
    I am designing and building a hardware and software DJ system and would really appreciate some help with the [groove~] object, please? I have looked at the reference & tutorials and trawled my way through the forums and web but can't find the answer to my problem :(
    I decided to use [groove~] because it plays more formats and seems to process audio in a much cleaner way to other objects (i.e. less glitching and artefacts). Audio within a digital file can begin at any time and in order for a DJ to be able to mix their music a cue point needs to specified from which the file will begin play from. The tutorials and reference say that if a float./int value is sent to the left inlet then this will cause [groove~] to play from the value sent. I am using float values to give a high degree of accuracy that is required. The [groove~] tutorial/reference also have an example patch that has the start/end loop points taken from [info~] that I have also used within my patch.
    My problem is that [groove~] always begins playback at 0, even when a float. value is sent to the left inlet. Whatever value I send is automatically perceived as a 0 and starts from the beginning. I have sent the float value to the middle inlet of [groove~] with the right inlet receiving the total sample length via the [info~]. Is there any solution to this?
    I would love to post the basics of the patch for you to see but don't know how to make a txt file from Max 7. If anyone could give a quick explanation, that would also be very much appreciated, thanks :)

    • brendan mccloskey's icon
      brendan mccloskey's icon
      brendan mccloskey
      Jan 27 2016 | 11:10 am
      Hi you don't say if you are using groove~ to perform loops. If groove~ doesn't receive a "loop 1" message, it will always play to the end of the file (from a cue/start point at the middle inlet). If you specify a loop length (using middle and right inlets) it will play that loop duration ONLY IF "loop 1" is sent - if looping is off, it will play from the "loop" start, to the end of the file regardless of the loop end point. You probably already know this. If you want to send cue points to the LEFT inlet you must use a message. It's been years since I used groove~, but AFAIK if you sent a changing float to the left inlet groove always starts a 0. Go figure!
      There is a trick however, if you want to specify segment length WITHOUT looping, using trapezoid~ to envelope the output of groove~. If you set 'loop' points - or duration - with looping disabled groove~ still sends a sync signal out the right outlet. Cool. See attached.
      Max Patcher
      In Max, select New From Clipboard.
      Show Text
    • jamie bell's icon
      jamie bell's icon
      jamie bell
      Jan 27 2016 | 3:17 pm
      Thanks for the info and patch Brendan, very much appreciated :)
      I've worked through your example, with some success but still can't manage to get [groove~] to begin playback from a cue point within my patch!?! I can, however, hear the trapezoid effect the volume as it ramps up
      I'm using whole song files - the test file is a 17Mb .mp3 - and using cue point values taken from the 'loop sync out' outlet of [groove~]. You are right in saying that I don't want to loop the songs, I will be using different buffers for capturing/playing loops. I think the problem relates to either, using large file sizes or because I'm send the floating point values of 'loop sync out' to the left inlet? I'm edging my bets that the answer may require a conversion of the 'loop sync out' values to a time format?
      I am quite happy to use another object but [groove~] seems to be the only one that provides an accurate position of the playback position (I am new to this and only know a fraction of the objects available). I tried [sfplay~] using a [clocker] to get the time values but because it always starts the count from 0 it caused errors whenever a file began playback after the start of the file.
      I think i have managed to send a .txt file of my patch so that you can see what is happening/I am doing. I am using Max 7.0.6
      Many thanks
    • jamie bell's icon
      jamie bell's icon
      jamie bell
      Jan 27 2016 | 3:21 pm
      Sorry , but it didn't like me sending a .rtf file so here is an image of my patch, hopefully?
    • jamie bell's icon
      jamie bell's icon
      jamie bell
      Jan 27 2016 | 3:32 pm
      Here's a screenshot showing the project with a file loaded, so that you can see what is going on in terms of values, etc.
    • pdelges's icon
      pdelges's icon
      Jan 27 2016 | 3:44 pm
      groove~'s sync outputs a float between 0 and 1, but the loop points and playback positions are in ms. You can multiply the sync position with the buffer length before storing the cue point.
    • jamie bell's icon
      jamie bell's icon
      jamie bell
      Jan 27 2016 | 4:45 pm
      Thank you Duncan and Patrick for your help, I'm 90% there now!!! I've now managed to create a cue point, through integrating Duncan's patch and using Patrick's advice for multiplying the 'loop sync output' by the the buffer length. The last problem I have is that [trapeziod~] (I believe is the object responsible) is creating an attack envelope on the volume, so the sound gradually fades in over a duration of 2-3secs (approx.). Is there a way to cause [trapezoid~] to ramp up quicker from the cue point at all, please?
      Many thanks again :)
    • jamie bell's icon
      jamie bell's icon
      jamie bell
      Jan 29 2016 | 12:15 am
      I've managed to solve the problem of the volume fading in upon playback from a cue point. I appreciate that many people of different levels use these forums, so I'll explain what I did.
      Brendan McCloskey's patch worked fine due to the way in which [groove~] works. However, as Patrick Delges pointed out, "groove~'s sync outputs a float value between 0 and 1" and to get a time value (ms) "multiply the sync position with the buffer length". This means that larger file sizes will have a larger 'loop sync out: time' ratio values and this is what causes [trapezoid~] to ramp up over a longer duration. I attached a [snapshot~] to the output of [trapezoid~] and saw that this was the case; I noted that when [trapezoid~] output a value of 1 the correct volume was produced.
      To solve the problem, a [sig~] value of 1 was required whenever [trapezoid~] produced a value less than 1. As can be seen in the pic, below, the small patch I added is a switching mechanism for the [sig~] and [gate~], connected to the [trapezoid~], to ensure only one of the objects was sending a signal value of 1 to [*~], at any time. The reason for this is that if [*~] receives two signals, in the right- inlet, it will produce unwanted values used for the volume.
      Hope this helps?