-
spacether,
have you experienced problems with the start method having some delay before starting a sound?
if so, how do you compensate?
-
Yes, I have, initially, the delay varies, but usually is ~200 - 300 milliseconds. Since my position method comes entirely from the timer, initially, my position is incremented ~ 100 times a second, so ~ 20 or 30 times before the song object reports a position. When the song.position changes, a watcher measures the difference between the timer and the song.position, and stores the values in an array and then averages the array values to come up with a song vs timer offset. This offset is then added on to the timer time to give the accurate time. Initially the offset is zero, but once the song.position reports values the offset is corrected, making a jump forward in the position, usually only ~ 130 milliseconds, and after that, the timer is accurate to within +- 30 milliseconds of the song.position.
Here is some code to get people started:
PHP Code:
// the offset is set to gettimer when play is pressed,
// and when play is pressed, an 1 millisecond interval
// is started, calling the Start function
var offset = 0;
function Avg_Obj(type, path, array_length) {
this.txtbox = type; this.pospath = path; this.value = "";
this.arr=new Array(array_length); this.arr_avg=0;
this.GetValue = function() {
return((this.txtbox == "song") ? eval(this.pospath) : getTimer()- eval(this.pospath));
};
this.Update = function(property, oldval, newval) {
if (this.txtbox == "songvstimer") oldval = _root.TimerPos.GetValue();
if (this.txtbox == "song")_root.SongvsTimerPos.value=newval;
if (newval != oldval) {
this.arr.pop();
this.arr.unshift((newval - oldval));
var a=0, avg=0;
for(a=0; a<this.arr.length; a++){ if(this.arr[a]==undefined) break; avg += this.arr[a];};
this.arr_avg = (avg/(a*1+1));
_root[this.txtbox].text = this.arr.toString() +" \r "+ Math.floor(this.arr_avg) +" "+Math.floor(1000/this.arr_avg) +" per sec";
}
return newval;
};
this.watch("value", this.Update);
}
SongPos = new Avg_Obj("song", "_root.mp3player.song.position", 20);
TimerPos = new Avg_Obj("mytimer", "_root.offset", 20);
SongvsTimerPos = new Avg_Obj("songvstimer", "", 20);
function Start() {
SongPos.value = SongPos.GetValue();
TimerPos.value = TimerPos.GetValue();
}
Last edited by spacether; 01-17-2005 at 10:01 PM.
-
thanks for sharing your technique.
do you have an online example application that I can add to the Flash audio example sticky thread?
-
-
One Solution
HI,
I've been searching the web for a solution and found this:
http://www.active-web.cc/html/resear...ync/f6sync.txt
you can get an sample file here
http://www.active-web.cc/html/research
it works perfectly, no onSoundComplete sync problems anymore,
s
I think...I dreamed...in pixels last night...
-
Senior Member
This is what I am looking for, but I don´t really understand it.
My onSoundComplete- code looks like this. There´s one for every track.
---
//track one:guitar//
var sound_ids:Array;
function playNextSound()
{
trace("!!"+sound_ids);
if(sound_ids.length)
{
mySound.attachSound(sound_ids[0]);
mySound.start();
}
sound_ids.shift();
}
var mySound:Sound = new Sound(this);
mySound.onSoundComplete = playNextSound;
----
and then the different loops are put together like this.
----
//track one/guitarr//
on (release)
{
sound_ids = new Array();
if(myGuit!=undefined) sound_ids.push('rg1_'+myGuit);
if(myGuit1!=undefined) sound_ids.push('rg1_'+myGuit1);
if(myGuit2!=undefined) sound_ids.push('rg1_'+myGuit2);
if(myGuit3!=undefined) sound_ids.push('rg1_'+myGuit3);
play._visible = false;
stop._visible = true;
playNextSound();
}
---
I understand that I add short silence in the start of every loopsound and then set the offset for the next sound. How much of silence do I add and what do I put the offset to?
Mattias Gordon
illustrator/ animator
-
onsoundcomplete
Hi,
I found out that in the gamepackage of andré michelle, there's a ready to use class for sample syncing with onsoundcomplete. I haven't figured it out yet myself, but it seems it's not the ideal solution because you need a good and fast system to run it on.
try to download the sample files from the url above and check the code there. there is also a empty sound in the library, use that one. you need to place the soundstart method in the onsoundcomplete of the empty noise.
something like this:
sync.attachsound(emptysound)
sync.onsoundcomplete = function()
{
sync.start(0,1)
//calaculate offset
nextsound.start(offset,1)
}
sync.start(0,1)
here is the url for andré michelle's gamepackage and soundpackage http://board.gamepackage.org/
grtz
s
I think...I dreamed...in pixels last night...
-
Senior Member
Yes, I checked it out but don´t really know how to do start.
Now I put loops after each other. Loops that "the user" had chosen.
How do I include the sync-sound into that so the loops play without a delay?
I am little lost, unfortunately. Can you give me a starter...
Mattias Gordon
illustrator/ animator
-
Senior Member
Something like this:
//sync-sound//
createEmptyMovieClip("sync_mc",100);
sync = new Sound(sync_mc);
sync.attachSound("sync");
sync.setVolume(0);
sync.onSoundComplete=function(){
sync.start(0,1);//44100*SPEED/(BPM*2/5)-44100*23.2*3/1000);
tmr-=2048/44100;
if (tmr>0){
return;
}
tmr+=SPEED/(BPM*2/5);
offset=SPEED/(BPM*2/5)-tmr;
}
//track one:guitar//
var sound_ids:Array;
function playNextSound()
{
trace("!!"+sound_ids);
if(sound_ids.length)
{
mySound.attachSound(sound_ids[0]);
mySound.start(offset,1);
}
sound_ids.shift();
}
var mySound:Sound = new Sound(this);
mySound.onSoundComplete = playNextSound;
//track two:bass//
var sound_idi:Array;
function playNextSoundi()
{
trace("!!"+sound_idi);
if(sound_idi.length)
{
mySoundi.attachSound(sound_idi[0]);
mySoundi.start(offset,1);
}
sound_idi.shift();
}
var mySoundi:Sound = new Sound(this);
mySoundi.onSoundComplete = playNextSoundi;
//track three:drums//
var sound_ida:Array;
function playNextSounda()
{
trace("!!"+sound_ida);
if(sound_ida.length)
{
mySounda.attachSound(sound_ida[0]);
mySounda.start(offset,1);
}
sound_ida.shift();
}
var mySounda:Sound = new Sound(this);
mySounda.onSoundComplete = playNextSounda;
----
Do you think if I am on the right track,or?
Mattias Gordon
illustrator/ animator
-
Hi,
it should be more something like this:
var sound_ids:Array=[snd1, snd2,...];
var nextsound = 0
//sync-sound//
createEmptyMovieClip("sync_mc",100);
sync = new Sound(sync_mc);
sync.attachSound("sync");
sync.setVolume(0);
sync.onSoundComplete=function()
{
sync.start(0,1);//44100*SPEED/(BPM*2/5)-44100*23.2*3/1000);
tmr-=2048/44100;
tmr+=SPEED/(BPM*2/5);
offset=SPEED/(BPM*2/5)-tmr;
if (tmr>0)
{
return;
} // here the code decised wether to play a next sound or not
mySound.attachSound(sound_ids[nextsound]);
mySound.start(offset,1);
nextsound++
}
http://trashcan.andre-michelle.com/fla_unsorted/
there you can download a little flash file, user_cut.fla. it's the same principle.
keep in mind that you only use one onsoundcomplete to trigger the sounds, everything should stay in that function...
it seems the best way to keep tracks in sync, is playing them all at ones and play with the volume.... ( seems a bit old school )
take a look at http://basementmx.andre-michelle.com/
i hope , in the future, this problem will be solved forever.
I think...I dreamed...in pixels last night...
-
Senior Member
Thanks,
I give it a try.
One things though.
SPEED and BPM must be variables or? Where are they defined?
Mattias Gordon
illustrator/ animator
-
just define them where you created you're soundarray
something like bpm = 125, speed = 7
I think...I dreamed...in pixels last night...
-
Senior Member
How do I know which speed and bpm is the right? My game is based on loops that are same length. can I get the iformation from the sounds themselves?
Mattias Gordon
illustrator/ animator
-
sorry, BPM = beats per minute of the loop. normally you can extract that information from youre sound files. speed is more the tempo of the overall song,
that you need to find out yourself...
I think...I dreamed...in pixels last night...
-
I am so sorry
I'm quite sorry for necro'ing this 11 month old thread, but I truly believe it is the only thread publicly archived that shows how to get a correct position in a song at any time through action script.
I have a program, that has an array of "beats". This array is 1000 - 1400 indecis long, and is in milliseconds. The construction of this array is on startup, and is given a location of a datafile by the FLASHVARS.
Debugging shows this array go correctly.
I then have a script that, when playing,
Code:
//delay = 0;
temptime = audio.position-delay;
for (n=0; n<beatarray.length; n++) {
if (temptime>=beatarray[n]) {
lastworking = n;
//delay = (beatarray[n] - temptime)/3;
} else {
n = beatarray.length;
//break
}
}
if (lasttimeswas<lastworking) {
//delay++;
bgflashing = true;
White._alpha = 100;
audiotext.text = temptime+newline+beatarray[lastworking];
}
It flashes on the "newest" beat, and will therefore work if you go back in time!
This is important, because if someone drags the slider backward, the script should compensate.
Now heres the thing. it runs OMFG AMAZING in flash.
Not on the internet, for me, or any of my friends, at least 5 beats in the flashes are just WAYYYY off.
wtf.
So, I'm blaming audio.position.
So I saw this script.
And I tried to implement:
Code:
White.onPress = function() {
//An Advanced Timer
var offset = 0;
function Avg_Obj(type, path, array_length) {
this.txtbox = type;
this.pospath = path;
this.value = "";
this.arr = new Array(array_length);
this.arr_avg = 0;
this.GetValue = function() {
return ((this.txtbox == "song") ? eval(this.pospath) : getTimer()-eval(this.pospath));
};
this.Update = function(property, oldval, newval) {
if (this.txtbox == "songvstimer") {
oldval = _root.TimerPos.GetValue();
}
if (this.txtbox == "song") {
_root.SongvsTimerPos.value = newval;
}
if (newval != oldval) {
this.arr.pop();
this.arr.unshift((newval-oldval));
var a = 0, avg = 0;
for (a=0; a<this.arr.length; a++) {
if (this.arr[a] == undefined) {
break;
}
avg += this.arr[a];
}
this.arr_avg = (avg/(a*1+1));
_root[this.txtbox].text = this.arr.toString()+" \r "+Math.floor(this.arr_avg)+" "+Math.floor(1000/this.arr_avg)+" per sec";
}
return newval;
};
this.watch("value", this.Update);
}
audio.start();
SongPos = new Avg_Obj("song", "audio.position", 20);
TimerPos = new Avg_Obj("mytimer", "getTimer()", 20);
SongvsTimerPos = new Avg_Obj("songvstimer", "", 20);
function Start() {
// the offset is set to gettimer when play is pressed,
// and when play is pressed, an 1 millisecond interval
// is started, calling the Start function
/*
*/
SongPos.value = SongPos.GetValue();
TimerPos.value = TimerPos.GetValue();
SongvsTimer.value = SongvsTimerPos.Update()
}
Start();
gotoAndPlay(4);
};
And then changed temptime to:
Code:
temptime = SongvsTimerPos.Update()-delay;
No dice. any advice?
edit: once again, the "on press" function of white works fine, thats on frame 2, it goes to frame 4 which loops indefinately (frame 5 gotoandplay's frame 4)..
and on frame 4 I need to access the "position" of the song. I get strange results on browsers, and need to make this position more exact.
edit: perhaps I should post this in actionscript?
Last edited by taifunbrowser; 12-02-2006 at 12:28 PM.
maximum width 300 no more maximum hieght 40 no more not interchangable
-
Hi,
maybe you should use a tool like flashamp to analize your song first. it will give you an output that you can use in flash to keep animations in sync with the sound your playing...
grtz
s
I think...I dreamed...in pixels last night...
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|