Hello everyone!
I am having trouble using the internal audio/midi engine in Scratch where I have a loop going on 4 of the same note and becoming out of sync once the loop completes.
Here is a link to a graphic of my script so far: http://www.watermans.org/scratch2.png
In this project, I have around 50 sprites with the exact same script you see in the image, the only difference being different variations of notes being played (not all equaling 2 beats).
I've tried (briefly) to utilize a sync variable, but to no avail. I haven't seen too many solutions in my searches online so far, but perhaps someone on here could assist. Thanks so much!
Offline
What do you mean, they're out of sync?
Offline
For example, this one sprite is performing 4 pitches at .5 beats each. The second sprite that would play simultaneously is performing 4 different pitches at .5 beats each, but after a few repetitions, they become out of sync despite their sharing a common bpm of 133.
Offline
I have a feeling this is due to Scratch's threading. It can't really run two scripts at once, so it does one, then the other, but it alternates quickly enough that you rarely notice it. I'm not sure there's anything to do for it.
You can try adding a [wait (0) seconds] block at the front of the play scripts; it might keep them in sync, but i really don't know. It's tough to beat.
Offline
Yeah I'm definitely sensing the difficulty here. I did come across one project here where the creator demonstrated his syncing ability using a J.S. Bach Invention (13 if I'm not mistaken). Wouldn't really work with my project due to the robust number of sprites, but it was what i found:
http://scratch.mit.edu/projects/diegofguillen/2515723
I'll try your wait theory next...Thanks!
Offline
I’ve had the same problem with tracks getting out of sync and ended up using a broadcast to sync the start of each measure. You might need just one script that sends out “play 4 notes” broadcast messages. Then (maybe) each receive script, in each sprite, could use your local on/off variables to determine if the notes should actually be played.
Offline
Well that is a possibility. One problem is that, because each sprite is playing a different set of pitches and rhythms. Perhaps I can use the broadcast blocks by creating my loops for each sprite based on the longest musical phrase I'll be inputting?
Boy that sounds confusing...
Offline
NHAE wrote:
Well that is a possibility. One problem is that, because each sprite is playing a different set of pitches and rhythms. Perhaps I can use the broadcast blocks by creating my loops for each sprite based on the longest musical phrase I'll be inputting?
Boy that sounds confusing...
Do you want to upload a sub-set of your project? Maybe just four or five of the clickable-note-playing sprites?
Offline
http://scratch.mit.edu/projects/DigimathFixit/3026534
Please see if this does any better. I used a variable called measure where I meant beat.
Also shaved some time of each beat because Scratch does not mind dropping messages and the scripts have to be idle when the message is sent.
I also removed some of your logic because I just wanted to show the beat technique.
ALso, I only did the first 5 scripts.
And Flash instruments don't sound the same as offline and I think the BPM is also off.
Slight update. I replaced your item 6 with a longer melody (and my changes) and also synchronized the start of item 5 and 6 so they will be together (using another variable).
You'll need to download for this to work right.
Last edited by Digimath (2013-01-08 17:06:07)
Offline
This seems to work rather well via flash, Digimath! I just downloaded and am currently having trouble getting any of the sounds to produce (except for sprite1, where the "if sprite1 clicked" block was detached).
I'll have to look at the script a bit closer tomorrow to really attempt to understand what is going on. After such a long day filled with meetings, my brain is somewhat mush. Thanks so much for all your help.
Offline
NHAE wrote:
This seems to work rather well via flash, Digimath! I just downloaded and am currently having trouble getting any of the sounds to produce (except for sprite1, where the "if sprite1 clicked" block was detached). [...]
Is there a chance that you were trying to use it offline without first clicking the green flag? It would have worked online without having to do that because the website does it for you and your version didn’t need the GF clicked to work offline, but that new little script in the Stage, that would get started with a click of the GF, is what sends out the beat broadcasts and nothing will play without it.
Offline
I think I figured it out. I made a variable and called it sync. Then I put this script in the stage. (I don't think it matters where you put it, but it seems most logical.)
when [space v] key pressed forever set [sync v] to (0) wait <[133] / [60]> secs set [sync v] to (1)After that I replace your script (that is placed after sprite is clicked)
wait (0.01) secswith
wait until <(sync) = [1]>So now you have a variable that is a handle for all sprite when click to wait until they are in sync with the bps from a forever loop when space is pressed. I guess you could replace space with green flag so that the user can't start without pressing green flag or whatever you want. Hope this helps you.
Offline
Digimath, that was indeed it. In my haze, I neglected to see the green flag block to activate the project itself. Your script seems to work great, though I haven't tested it with phrases longer or shorter than 2 beats. In the end, there will be a great deal of variation in each phrase (some 2 beats, some 1/2 a beat, some 4, 5, and even 10 beats, etc.).
chimoo5, I like this idea a lot! I tried it this morning and the simplicity of it is superb. This could be the solution I'm looking for (and one I came somewhat close to yesterday!). So far, the only concern I have is that, unlike Digimath's script, when you click each button, it does not begin right away. I did try it with a "when spriteX clicked" block instead of a green flag block, but to no avail. It also seemed as though the phrases were a little less locked in.
Thanks everyone for all of your hard work! I really want to get this project working as best as it can and you are all so extremely helpful!
Offline
No problem I looked over your script (with new script) and saw what you mean. I have a couple suggestion if I may. One is I realized you have more than of when Sprite clicked blocks (in the sprite) maybe you like it organized different, but I felt at times Scratch has trouble doing both at the same time. Not sure if it is true, but it got me thinking to simplifying your code a bit. Ridding of the variable no/off. Trying this:
when [Sprite1] clicked if <(costume #) = [1]> set instrument to [1 v] switch to costume [button2 v] wait until < (sync) = [1] > repeat until <<touching [mouse-pointer v] ?> and <mouse down?>> set tempo to (133) bpm play note (96 v) for (0.5) beats end else switch to costume [button1 v]
when [Sprite3] clicked if <(costume #) = [1]> set instrument to [1 v] switch to costume [button2 v] wait until < (sync) = [1] > repeat until <<touching [mouse-pointer v] ?> and <mouse down?>> set tempo to (133) bpm play note (84 v) for (0.1) beats play note (88 v) for (0.4) beats play note (90 v) for (0.5) beats play note (88 v) for (1) beats end else switch to costume [button1 v]Side note if you do try this sprite1 has the costume name: [button and button1] unlike the others (I change the code to be the same as the other while changing the costume name themselves.) This code also fixes the second problem the button not being pushed down when clicked right away. So all that's necessary is the instrument tempo and notes in the repeat until. I think is best used with previous code using green flag rather than space.
Offline
By the way if you care about the latency from when the button is clicked to when sound is produce I experimented with changing wait 133/60 to 133/120. I'm not fully sure of the repercussion I tried it 180 and 240 and seems to not be as significant or sometimes buggy. Also to reduce redundancy of calculating it I would set up a variable (bps or beat) to contain the value of it.
when gf clicked set [beat v] to ([133] / [120]) forever set [sync v] to [0] wait (beat) secs set [sync v] to [1] endI checked with an if statement to see it beat contains an "exact" (more than a few decimal places like 133/120 value) or a shorten approximation and it is an "exact" even though beat shows it contains only 1.1.
Offline
So I am trying to figure out what you mean. I think I understand but I haven't used sound much but I will explain what I understand.
I looked at your sprites and saw the following.
Sprite1 = 0.5 beats
Sprite2 = 1 beats
Sprite3 = 2 beats
Sprite4 = 2 beats
Sprite5 = 2 beats
I realize my bps didn't line up properly since Sprite1 would play 4 times more than Sprite5. So that means when Sprite5 is clicked it should chime in when Sprite1 should finishes its fourth beat. If that is the case then I changed the stage script with:
when gf clicked forever set [0.5 v] to (0) rest for (0.5) beats set [0.5 v] to (1) when gf clicked forever set [1 v] to (0) rest for (1) beats set [1 v] to (1) when gf clicked forever set [2 v] to (0) rest for (2) beats set [2 v] to (1)and then replace in the script of the Sprite
wait until <(the appropriate beat vaule) = (1)>I know I am using the green flag more than once but I haven't put much thought into it until I know this is correct. I re-uploaded it check to see if this is what you what. If not you can clarify it.
Offline
I had an idea to use broadcast and that made it so that only one green flag exists. I tried this:
when gf clicked broadcast[0.5 v] broadcast [1 v] broadcast [2 v]and then example for 1 beat
when I receive [1 v] forever set[1 v] to (0) rest for (1) beats set [1 v] to (1)So now its is re-uploaded with newest codes. http://scratch.mit.edu/projects/chimoo5/3030259
Offline
That's pretty close to the idea that Digimath. I've uploaded my latest adjustments from last night to this project for you to check out. I used digimath's idea of broadcasting the beat from the stage, but I'm still having trouble getting any note over 1 beat (quarter note) to sound in full without repeating its attack. Meaning, if I had a phrase that was 4 beats, where 3 of those beats were to be held by one note, that one 3-beat note would continue to repeat itself for 3 beats. I may have solved the issue if you look at sprite14, but it's not quite right...
http://www.watermans.org/inctest.sb
Offline