Is it possible to play two or more BGS files at the same time with plugins?

  • Yes

    Votes: 7 100.0%
  • No

    Votes: 0 0.0%

  • Total voters
    7

Diretooth

Lv. 25 Werewolf
Veteran
Joined
Mar 10, 2013
Messages
1,231
Reaction score
445
First Language
English
Primarily Uses
RMMV
I was wondering if it was possible with plugins if one could have two or more BGS files playing at the same time. Let's say you want the sound effect of a waterfall playing at the same time as a campfire, with some finagling, you can have one play in BGM and the other as BGS. But then what do you do when you have a certain song playing because the heroine has proclaimed their love, or the hero's decided to reveal why he's hunting the big bad?
I've looked in the Master Plugin list and didn't find anything that could accomplish two BGS files playing at the same time, and if there is something, it probably has a not-very-easily-searched name or I'm just dumb.

TL;DR, or just a synopsis, I'm looking for a plugin that allows for two BGS files to play at the same time. I first want to know if it is possible, so I don't bog people down with an impossible task.
Second, if it is possible, all I need is the ability to play two BGS files at the same time, no fancy bells and whistles like a fade-in fade-out or the ability to play it in reverse. Just playing the sound, and being able to turn it off.
Third, if possible, I'd like it to be able to be for commercial use, if I have to send a free copy of the game, then I'll gladly do it, as well as including a special thanks to the person who made it beyond just a name in the credits.

(That moment when the TL;DR is just as long as the initial description.)
 

Naveed

Veteran
Veteran
Joined
Nov 2, 2013
Messages
314
Reaction score
148
First Language
English
Primarily Uses
RMMV
Open the rpg_managers.js file and go to line 1070. You'll find the following function:

Code:
AudioManager.playBgs = function(bgs, pos) {
    if (this.isCurrentBgs(bgs)) {
        this.updateBgsParameters(bgs);
    } else {
        this.stopBgs();
        if (bgs.name) {
            this._bgsBuffer = this.createBuffer('bgs', bgs.name);
            this.updateBgsParameters(bgs);
            this._bgsBuffer.play(true, pos || 0);
        }
    }
    this.updateCurrentBgs(bgs, pos);
};

Line 1074 is this.stopBgs();
Comment out this line by typing // before it.

It should look like this:

Code:
AudioManager.playBgs = function(bgs, pos) {
    if (this.isCurrentBgs(bgs)) {
        this.updateBgsParameters(bgs);
    } else {
       // this.stopBgs();
        if (bgs.name) {
            this._bgsBuffer = this.createBuffer('bgs', bgs.name);
            this.updateBgsParameters(bgs);
            this._bgsBuffer.play(true, pos || 0);
        }
    }
    this.updateCurrentBgs(bgs, pos);
};


That'll prevent the previous BGS from stopping whenever a new BGS starts playing, so you'll be able to play multiple BGS at the same time.
 

Diretooth

Lv. 25 Werewolf
Veteran
Joined
Mar 10, 2013
Messages
1,231
Reaction score
445
First Language
English
Primarily Uses
RMMV
While it does indeed allow for multiple BGS tracks to play, it completely prevents the 'Fadeout BGM' function from working. However, I can simply update the BGS file so that it plays at different volumes and pitches without a new BGS instance starting. (So I'm not hearing Waves1 at Pitch 50 Volume 100, while also having Waves1 at Pitch 150 Volume 50. So I can simply lower the volume to simulate the BGS ending.
This can work for now, though I'd like to keep the topic open so that if anyone has other suggestions, or makes a plugin, that they can bring it here.
Thanks, Naveed, this was helpful.
 

Marianojoey

Veteran
Veteran
Joined
Jun 5, 2017
Messages
48
Reaction score
23
First Language
Spanish
Primarily Uses
RMMV
I'm not an expert at programming, and I definitely can't program in Java (but I can follow code, at least) so perhaps I'm speaking something that's wrong... but, the solution propposed, even if it'd allow for 2 BGS to play at that particular moment would make the first one unstoppable, since "Current" would be the second one (the first would be sounding in the background... permanently.

Would it be possible to assign a variable to each BGS you want to play and then (with the propposed change in effect), you change which one of all the ones you are playing is the "Current" one (perhaps using a script... sorry, I'm a noob at this, so I don't know how to use them yet), and change the the settings for that particular BGS (like pitch, volume or even stopping it). At the end of the scene or if changing location, you just go changing the respective variable and selecting to stop BGS, so no sound in the background would affect your game. :)

Anyway, sorry if I'm saying something wrong, and please excuse any grammatical mistakes I could had, but English isn't my main language. :)
 

Marianojoey

Veteran
Veteran
Joined
Jun 5, 2017
Messages
48
Reaction score
23
First Language
Spanish
Primarily Uses
RMMV
Alternatively, you could play around with the sound/music files. You could create a music file that has a channel added with the sound of the waterfall, and in that scene (or the map, if it's what you need), while the BGM is playing (with the added waterfall), you just use the other sound as BGS. :)

Also, you could not have music playing in the scene, and use the BGS for the waterfall as BGM (just put the file in the BGM folder and select it like any other music file). :D

In any of this two cases, you don't need a plugin, so it's a viable pluginless way to do it, and you don't need to play around with the master code either. ;)

If I have any other ideas, I'll come back to share them. :)
 

Diretooth

Lv. 25 Werewolf
Veteran
Joined
Mar 10, 2013
Messages
1,231
Reaction score
445
First Language
English
Primarily Uses
RMMV
@Marianojoey What I'm wanting would be extremely difficult to do with two loopable tracks, one non-loop track, and a track meant for sound effects. Editing and making multiple 'simultaneous' files like 'Heartbeat + spooky mansion' would exponentially increase the file size of the game, which you want to have as small a file size as possible for your game. The smaller the size, the shorter the download time. While at present, the current method suggested will make past tracks continue essentially forever, it does allow me to effectively 'mute' them.
 

LadyBaskerville

Hell-poodle
Veteran
Joined
Sep 12, 2016
Messages
645
Reaction score
530
First Language
German
Primarily Uses
RMMV
I've made a plugin for a second BGS track:
Code:
/*
* @plugindesc Play a second BGS
*
* Plugin Commands:
*
* Play2ndBGS name valume pitch pan
* E.g. Play2ndBGS Wind 90 100 0
*
* Fadeout2ndBGS duration
* E.g. Fadeout2ndBGS 3
*
*/

_Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
    _Game_Interpreter_pluginCommand.call(this, command, args);
  
   if (command == 'Play2ndBGS') {
       var bgsName = args[0];
       var bgsVolume = Number(args[1]) || 90;
       var bgsPitch = Number(args[2]) || 100;
       var bgsPan = Number(args[3]) || 0;
       var bgs = {name:bgsName,volume:bgsVolume,pitch:bgsPitch,pan:bgsPan};
       AudioManager.playBgs2(bgs);
   }
  
   if (command == 'Fadeout2ndBGS') {
       var duration = Number(args[0]) || 1;
       AudioManager.fadeOutBgs2(duration);
   }
};



AudioManager.playBgs2 = function(bgs, pos) {
    if (this.isCurrentBgs2(bgs)) {
        this.updateBgs2Parameters(bgs);
    } else {
        this.stopBgs2();
        if (bgs.name) {
            this._bgs2Buffer = this.createBuffer('bgs', bgs.name);
            this.updateBgs2Parameters(bgs);
            this._bgs2Buffer.play(true, pos || 0);
        }
    }
    this.updateCurrentBgs2(bgs, pos);
};

AudioManager.replayBgs2 = function(bgs) {
    if (this.isCurrentBgs2(bgs)) {
        this.updateBgs2Parameters(bgs);
    } else {
        this.playBgs2(bgs, bgs.pos);
        if (this._bgs2Buffer) {
            this._bgs2Buffer.fadeIn(this._replayFadeTime);
        }
    }
};

AudioManager.isCurrentBgs2 = function(bgs) {
    return (this._currentBgs2 && this._bgs2Buffer &&
            this._currentBgs2.name === bgs.name);
};

AudioManager.updateBgs2Parameters = function(bgs) {
    this.updateBufferParameters(this._bgs2Buffer, this._bgsVolume, bgs);
};

AudioManager.updateCurrentBgs2 = function(bgs, pos) {
    this._currentBgs2 = {
        name: bgs.name,
        volume: bgs.volume,
        pitch: bgs.pitch,
        pan: bgs.pan,
        pos: pos
    };
};

AudioManager.stopBgs2 = function() {
    if (this._bgs2Buffer) {
        this._bgs2Buffer.stop();
        this._bgs2Buffer = null;
        this._currentBgs2 = null;
    }
};

AudioManager.fadeOutBgs2 = function(duration) {
    if (this._bgs2Buffer && this._currentBgs2) {
        this._bgs2Buffer.fadeOut(duration);
        this._currentBgs2 = null;
    }
};

AudioManager.fadeInBgs2 = function(duration) {
    if (this._bgs2Buffer && this._currentBgs2) {
        this._bgs2Buffer.fadeIn(duration);
    }
};

AudioManager.saveBgs2 = function() {
    if (this._currentBgs2) {
        var bgs = this._currentBgs2;
        return {
            name: bgs.name,
            volume: bgs.volume,
            pitch: bgs.pitch,
            pan: bgs.pan,
            pos: this._bgs2Buffer ? this._bgs2Buffer.seek() : 0
        };
    } else {
        return this.makeEmptyAudioObject();
    }
};

_AudioManager_stopAll = AudioManager.stopAll;
AudioManager.stopAll = function() {
    _AudioManager_stopAll.call(this);
    this.stopBgs2();
};


_BattleManager_saveBgmAndBgs = BattleManager.saveBgmAndBgs;
BattleManager.saveBgmAndBgs = function() {
   _BattleManager_saveBgmAndBgs.call(this);
    this._mapBgs2 = AudioManager.saveBgs2();
};

_BattleManager_playBattleBgm = BattleManager.playBattleBgm;
BattleManager.playBattleBgm = function() {
    _BattleManager_playBattleBgm.call(this);
   AudioManager.stopBgs2();
};


_BattleManager_replayBgmAndBgs = BattleManager.replayBgmAndBgs;
BattleManager.replayBgmAndBgs = function() {
    _BattleManager_replayBgmAndBgs.call(this);
    if (this._mapBgs2) {
        AudioManager.replayBgs2(this._mapBgs2);
    }
};

_Game_System_initialize = Game_System.prototype.initialize;
Game_System.prototype.initialize = function() {
    _Game_System_initialize.call(this);
    this._bgs2OnSave = null;
};

_Game_System_onBeforeSave = Game_System.prototype.onBeforeSave;
Game_System.prototype.onBeforeSave = function() {
    _Game_System_onBeforeSave.call(this);
    this._bgs2OnSave = AudioManager.saveBgs2();
};

_Game_System_onAfterLoad = Game_System.prototype.onAfterLoad;
Game_System.prototype.onAfterLoad = function() {
    _Game_System_onAfterLoad.call(this);
    AudioManager.playBgs2(this._bgs2OnSave);
};

Scene_Base.prototype.fadeOutAll = function() {
    var time = this.slowFadeSpeed() / 60;
    AudioManager.fadeOutBgm(time);
    AudioManager.fadeOutBgs(time);
   AudioManager.fadeOutBgs2(time);
    AudioManager.fadeOutMe(time);
    this.startFadeOut(this.slowFadeSpeed());
};

_Scene_Title_playTitleMusic = Scene_Title.prototype.playTitleMusic;
Scene_Title.prototype.playTitleMusic = function() {
    _Scene_Title_playTitleMusic.call(this);
    AudioManager.stopBgs2();
};

_Scene_Map_stopAudioOnBattleStart = Scene_Map.prototype.stopAudioOnBattleStart;
Scene_Map.prototype.stopAudioOnBattleStart = function() {
    _Scene_Map_stopAudioOnBattleStart.call(this);
    AudioManager.stopBgs2();
};

_Scene_Gameover_playGameoverMusic = Scene_Gameover.prototype.playGameoverMusic;
Scene_Gameover.prototype.playGameoverMusic = function() {
    _Scene_Gameover_playGameoverMusic.call(this);
    AudioManager.stopBgs2();
};

You can do whatever you want with it.

I'm not quite happy with it, though. It only allows you to set a secondary BGS track that plays in addition to BGM and main BGS with plugin commands; I would prefer to have a -theoretically- indefinite amount of tracks playing at the same time. Maybe I can work it out later.
 

someoneinthebox

Mom said I am special.
Member
Joined
Mar 21, 2018
Messages
4
Reaction score
0
First Language
English
Primarily Uses
RMMV
By the way, if anyone interested, there is a way to play a few BGS in the same time with a little changing rpg_managers.js without any plugins. It works for me but has one minus - you must stop BGSes if location changes and start BGSes in new location by checking conditions for them (if you have it). The solution is in BGS array.

Firstly you must create an array in AudioManager:

Code:
AudioManager._bgsBuffers     = [];

Then as @Naveed said you must comment stop BGS in playBgs function and (!) push new buffer into array:

Code:
AudioManager.playBgs = function(bgs, pos) {
    if (this.isCurrentBgs(bgs)) {
        this.updateBgsParameters(bgs);
    } else {
       // this.stopBgs();
        if (bgs.name) {
            this._bgsBuffer = this.createBuffer('bgs', bgs.name);
            this._bgsBuffers.push(this._bgsBuffer);
            this.updateBgsParameters(bgs);
            this._bgsBuffer.play(true, pos || 0);
        }
    }
    this.updateCurrentBgs(bgs, pos);
};

Then you must modufy stopBgs function:

Code:
AudioManager.stopBgs = function() {
   if(this._bgsBuffers.length > 0)
   {
       for(var bgs = 0; bgs < this._bgsBuffers.length; bgs++)
       {
           this._bgsBuffers[bgs].stop();
       }
   }
   this._bgsBuffers = [];
    if (this._bgsBuffer) {
        //this._bgsBuffer.stop();
        this._bgsBuffer = null;
        this._currentBgs = null;
    }  
};

And finally fadeOutBgs function:

Code:
AudioManager.fadeOutBgs = function(duration) {
    if (this._bgsBuffer && this._currentBgs)
   {
       if(this._bgsBuffers.length > 0)
       {
           for(var bgs = 0; bgs < this._bgsBuffers.length; bgs++)
           {
               this._bgsBuffers[bgs].fadeOut(duration);
           }
           this._bgsBuffers = [];
       }
       else
       {
           this._bgsBuffer.fadeOut(duration);
       }
        this._currentBgs = null;
    }
};
 

Latest Threads

Latest Posts

Latest Profile Posts

too... many... ideas... can't... edit them down :dizzy:
Don't you love your work?
It's been half a month and I didn't give signs of life, not even in my website.

I've been studying about my project and I discovered something that I definitely think it will be better.

On the other hand, I still have to learn how to use it properly so I need time.
This catgirl name is Elyune.
Her hobby is cooking and eating sweets. She's also an alchemist.

Cat_girl.jpg
catgirl-1.jpg
Raptor Revolt Demo 4_10_2021 3_12_09 PM.png

Latest custom tileset work for RAPTOR REVOLT in this beach scene set in the acheroraptor capital in Ridge City, Hell Creek.

Forum statistics

Threads
110,287
Messages
1,051,985
Members
143,311
Latest member
Zerho
Top