Random music playing radio

Started by MrNashington, Thu 27/06/2013 21:49:58

Previous topic - Next topic

MrNashington

Hey there!
I have been trying to figure out how to do this for a while now and a friend told me to ask the forums, which is kind of scary considering how ruthless some of the answers are in other threads heh.

Anyway, I am trying to create a random music playing radio. So whenever the radio is turned on in-game, it plays a random song and repeats on going through all the songs at random.

If anyone could help out it would be much appreciated.

Thanks alot, Charlie :)

Adeel

#1
Okay. Probably wrong advice.  :-[ I take back everything what I said (or written).

Quote from: Crimson Wizard on Thu 27/06/2013 23:05:51
How this will work if there are 100 songs?
Also, repeatedly_execute is been called 40 times per second. Meaning you will restart the music over every 1/40 second.

Yes,  I thought about that part too. Secondly, I were sure someone would correct me because I had read about repeatedly_execute is been called 40 times per second. Still, I thought it wouldn't hurt to give it a try 8-0

MrNashington, I apologize and hope you don't "e-strangle" me. :)

Crimson Wizard

#2
Omg omg omg, Adeel. I am at risk to give "ruthless answer" here. :)
How this will work if there are 100 songs?
Also, repeatedly_execute is been called 40 times per second. Meaning you will restart the music over every 1/40 second.

MrNashington, first thing you should know is that the new Audio system that AGS uses since v. 3.2 is not much compatible with random picking.
I will give two examples, first for new Audio system, second for old one.
To enable old system: go to Global Settings, find "Backwards Compatibility" group and set "Enforce new style audio system" to FALSE.
(You can actually use both systems in this case, which may be beneficial).

The examples I am about to show here play a random music every time (it will likely repeat some of them). I think it is something to start with.

Using new system:
Code: ags

#define MAX_TUNES 10
AudioClip *RadioTunes[MAX_TUNES];

function game_start()
{
   RadioTunes[0] = aTune1;
   RadioTunes[1] = aTune2;
   RadioTunes[2] = aTune3;
   .... etc ....
}

function PlayRadioTuneAtRandom()
{
   AudioClip *tune = RadioTunes[Random(MAX_TUNES - 1]];
   tune.Play();
}


Using old system, import your music in the "Audio/Music" node in your project tree, as you usually do, and make sure their ScriptName is "aMusicX" where X is number, starting from 1 (aMusic1, aMusic2, aMusic2 etc). Make your tunes have sequential numbers. Then, to play a random one of them do simply this:
Code: ags

#define FIRST_TUNE_ID 1  // change to real number (first tune id)
#define MAX_TUNES     10 // change to real number (total number of tunes)

function PlayRadioTuneAtRandom()
{
   PlayMusic(FIRST_TUNE_ID + Random(MAX_TUNES - 1));
}

Crimson Wizard

#3
Alright. Next problem.
How to make a list of non-repeating tunes?

Code: ags

int OrderList[MAX_TUNES]; // this will keep indexes of tunes in random order
bool TunePicked[MAX_TUNES]; // array which tells if the tune was already put into the random list

function Shuffle()
{
   // First, mark all tunes as unused
   int slot = 0;
   while (slot < MAX_TUNES)
   {
      OrderList[slot] = -1;
      TunePicked[slot] = false;
      slot++;
   }

   // Now fill in the random list
   slot = 0;
   while (slot < MAX_TUNES)
   {
      // get random tune id
      int tune_id = Random(MAX_TUNES - 1);
      // is it already used?
      if (TunePicked[tune_id])
      {
         // then iterate through the list to find nearest available tune, starting with the next index
         int find_tune = tune_id + 1;
         bool is_found = false;
         // seek until we find available tune or returned back to random index we got previously
         // (the latter should not normally happen) 
         while (!is_found && find_tune != tune_id)
         {
            // went over the end of list? get to the beginning
            if (find_tune >= MAX_TUNES)
               find_tune = 0;
            // did we find a free tune?
            if (!TunePicked[find_tune])
               is_found = true;
            else
               find_tune++; // try next
         }
         // remember the free id we found
         tune_id = find_tune;
      }

      // so, now we have a tune id!
      // mark it as used:
      TunePicked[tune_id] = true;
      // keep it in the list
      OrderList[slot] = tune_id;
      // move on!
      slot++;
   }

   // In the end we should have "OrderList" array filled with random tune indexes
}




//------------------------------------

How to use this list of random tune indexes.
Code: ags

int CurrentTune;

//--------------------------
// add this in the end of the previously mentioned "Shuffle" function:
CurrentTune = 0;
//--------------------------

// function that plays next random tune:
function PlayNextTuneFromRandomList()
{
   int tune_index = OrderList[CurrentTune];

   // new audio system:
   AudioClip *tune = RadioTunes[tune_index];
   tune.Play();
   // old audio system:
   PlayMusic(FIRST_TUNE_ID + tune_index);
  
   CurrentTune++; // this will make another tune playing next time
   if (CurrentTune >= MAX_TUNES)
   {
      // oops, tune list is over.
      CurrentTune = 0; // start from the beginning, or....
      Shuffle(); // re-shuffle tunes
      // the choice is yours!
   }
}




Sorry, but all this code is not tested in real game! Feel free to blame me if something goes wrong.

E: I really hope someone will test this and tell if its working. I am almost asleep as typing this.
Also.... I think it is NOT a Beginner's Technical Question, but rather an Advanced one. ;)

MrNashington

Thanks for the help. I am still unable to work it out though, it doesn't play any music. :/

Khris

Well, have you managed to get a specific track to play yet?

MrNashington

Quote from: Khris on Fri 28/06/2013 16:59:36
Well, have you managed to get a specific track to play yet?

Nope, it is just silent. :/

Khris

At least show us the code you used.
SOME INFO

MrNashington

Quote from: Khris on Fri 28/06/2013 17:08:18
At least show us the code you used.
SOME INFO

Code: AGS
// main global script file
#define FIRST_TUNE_ID 0  // change to real number (first tune id)
#define MAX_TUNES     3 // change to real number (total number of tunes)


Code: AGS
function Button10_OnClick(GUIControl *control, MouseButton button)
{
  PlayMusic(FIRST_TUNE_ID + Random(MAX_TUNES - 1));
}


Crimson Wizard

#9
MrNashington, I must apologize, I was mistaken about how to use old style audio system in the new AGS.

Previously I told you should put music in folder, but new AGS does not need that.
Instead, import your music in the "Audio/Music" node in your project tree, as you usually do, and make sure its ScriptName is "aMusicX" where X is number (aMusic0, aMusic1, aMusic2 etc).

MrNashington

Quote from: Crimson Wizard on Fri 28/06/2013 17:54:17
MrNashington, I must apologize, I was mistaken about how to use old style audio system in the new AGS.

Previously I told you should put music in folder, but new AGS does not need that.
Instead, import your music in the "Audio/Music" node in your project tree, as you usually do, and make sure its ScriptName is "aMusicX" where X is number (aMusic0, aMusic1, aMusic2 etc).

It works now! Thanks alot for the help, it is much appreciated :)

Crimson Wizard

#11
Ouch! One more mistake. You should enumerate them from 1, not from 0, because "0" means no music. If you make aMusic0, it will automatically play at room start (looks like a little bug to me).
I will test my own code now, 'cause I finally got some time.

MrNashington


Crimson Wizard

Wooohooo, it's working :D. Tried it out with 7 songs.
I am really happy now, because it was a while since I coded something cool in AGS.

FYI, here's an easy way to debug a result of Shuffle(). Put this in the very end of function:
Code: ags

#ifdef DEBUG
   String tunes_order = "";
   slot = 0;
   while (slot < MAX_TUNES)
   {
     tunes_order = tunes_order.Append(String.Format("%d, ", FIRST_TUNE_ID + OrderList[slot]));
     slot++;
   }
   Display("Order of the tunes: %s", tunes_order);
#endif

monkey0506

Just in case anyone's interested, this is sorta what the Playlist module is for.


SMF spam blocked by CleanTalk