ForeverZer0 44 Report post Posted April 30, 2012 (edited) MCI Audio Module Version: 1.2 Author: ForeverZer0 Introduction This script acts a either a drop-in replacement or enhancement to the built-in Audio module. It contains a plethora of functions that the default player lacks, such as seek, pause, record, fade in/out, and many more. It works by totally bypassing the built-in audio library, and directly accessing Window's "winmm" library using Ruby's Win32API. This library is home to the Media Control Interface, or MCI, which provides functions for manipulating audio and video. This allows for much more control over sound, and the ability for RPG Maker to play additional audio formats, since all that is needed is to distribute the appropriate codecs along with your game in order to use them. Features Full seek functions, accurate to the millisecond Ability to read file lengths Ability to pause and resume a playing file Functions for transitioning from one volume to another over a given number of frames, to both lower and higher volumes Can create as many mixers as needed, which allows to play multiple sounds simultaneously, which gives the ability to play more than one BGM or BGS at a time Record function to capture input from the user (.wav format only) Ability to set volume to left and right speaker independently Mute functions Can set the speed of playback Ability to set treble and bass (Not all devices support this) Searches RTP files and uses them automatically if file is not local Easy access for additional calls to the Media Control Interface No porting external libraries with your game, all functioning is done within the script and the operating system Can use any audio format you wish, so long as the appropriate codec is installed on the host computer Compatibility with RMXP, RMVX, and RMVXA Screenshots This is a small audio player scene I made for the XP version. Its incomplete, and for demo puroposes only. Demo RMXP Demo 1.2 Script Pastebin Link Auto-Restore Plugin Instructions Simply set the code in the configuration to what version of RPG Maker you are using. See script for detailed instructions on scrip calls available to you, and demo for examples of a few. On some systems, audio can continue to play after the RGSS player has closed. To prevent this, add the following line to the botton of "Main", after all the code: Audio.mci_eval('close all') Compatibility Not tested on Linux running under Wine. I don't have a VM installed at the present time, so if anyone tests this, let me know. High chance of incompatibility with programs that encrypt audio files Due to vast differences in how the format is handled, some of this player's features do not work with MIDI, most notably volume control, which also effects fading. I have created alternate controls to control MIDI volume, but they can only work with the sacrifice of many other functions, and the volume applies to ALL playing MIDIs, not just the one the volume is applied to. I decided this was not worth it, so I omitted volume control of MIDI by default, but if you are willing to make these sacrifices, there is a setting to enable it. If you your game relies heavily on MIDI, but you still would like to use this script, there are conversion programs available, which I can assist you with if need be. Author's Notes If you are looking for a good codec pack, I recommend K-Lite Codec Pack. This is a single package that will cover pretty much every standard audio format available, and even a few exotics (especially with the Mega-Pack). Changing pitch will be different. MCI does not have a function for this, so I am changing the speed as a generic substitute. Changing the speed does change the pitch, but it true sound pitch alters the sampling rate as well, which this player does not. You have a couple alternatives if you absolutely need the pitch change: Edit the files using an external editor and import it Use the default system to play such sounds using the alias names For more information about using MCI commands, please see the full documentation at MSDN Edited July 8, 2012 by ForeverZer0 Share this post Link to post Share on other sites
Polraudio 122 Report post Posted April 30, 2012 OMFG!. This is exactly the sort of thing i was looking for . Thank you very much for making this . Mind if i strip your audio player apart to make my own for use in my project? Will give credit of course. Share this post Link to post Share on other sites
ForeverZer0 44 Report post Posted April 30, 2012 No, I don't mind at all, it was something I threw together for the demo. It was coded kinda quick and sloppy, so I just didn't want to release it as a full script, nor spend a bunch of time working on at the moment. It started out as debug tool when writing the other parts, and I just cleaned it up a bit for demo purposes. It was actually your post that kinda spawned the idea for this. I think I even suggested using MCI for control, and afterwards I got to thinking that it actually wouldn't be to difficult to implement a wrapper for it in Ruby, so I wrote it. I'm glad that you can find use for it, although the lack of MIDI support does kinda suck. MIDI is a horrible format to work with programmatically, it is a complete different animal from every other format... I hope you can still manage with what there is, though. Share this post Link to post Share on other sites
Polraudio 122 Report post Posted April 30, 2012 It will be put some good use. I have a juke box that's been missing something like this. Share this post Link to post Share on other sites
Moonpearl 32 Report post Posted April 30, 2012 I have a technical question: with your script, are the MIDI files still played with RMXP's synth, or with the host system's synth? Share this post Link to post Share on other sites
ForeverZer0 44 Report post Posted April 30, 2012 The host system , RPG Maker is fully bypassed. Aside from the aliases to the RGSS module, this script will run and play music using just Ruby. For this reason, it's important that you either distribute or link user of your game to the appropriate codecs, since there is no guaranteed their system knows how to handle it. Share this post Link to post Share on other sites
Moonpearl 32 Report post Posted April 30, 2012 Sweet! I was looking for a way to have RGSS play MIDI files using my system's device, because I have a SoundFont mapped to it so that the music sounds better. With your script, it works just fine! All of the RTP's original music suddenly sounds way better. Guess I'll have to write a tutorial on how to map a SoundFont to the system device right away. Share this post Link to post Share on other sites
ciccio92 0 Report post Posted April 30, 2012 Nice script, really interesting! I think I'm gonna use in my project, I always looked for something like that. Share this post Link to post Share on other sites
Moonpearl 32 Report post Posted April 30, 2012 I have a bug to report. When I start your demo, BGM does not play in the title and map scenes. It plays only when called from the jukebox (then keeps on playing correctly even after leaving the menu). Any ideas why this happens? Share this post Link to post Share on other sites
gerkrt 0 Report post Posted July 8, 2012 Hi im having a problem. I want to create a script that makes that the music isnt restarted after combat. For that for now im trying to store the map song position and then play it again and seek it to the saved position. But that donts works. For some reason i can seek a file that i just created a line above. But i created a event in map that seeks it and works fine. The start argument also donts seems to work.´ As a example i post the test script. I was adapting other scritp to here. For now i was testing a scape routine. Like this it dont sounds when entering again the map. class Scene_Map alias fmodex_old_map_call_battle call_battle def call_battle p "vasm", Audio['bgm'].position $game_temp.map_bgm_pos = Audio['bgm'].position fmodex_old_map_call_battle end end class Game_Temp attr_accessor :map_bgm_pos attr_accessor :from_battle alias :fmodex_old_temp_initialize :initialize unless $@ def initialize fmodex_old_temp_initialize @map_bgm_pos = 0 @from_battle = false end end class Scene_Battle #-------------------------------------------------------------------------- # * Frame Update (party command phase: escape) #-------------------------------------------------------------------------- def update_phase2_escape # Calculate enemy agility average enemies_agi = 0 enemies_number = 0 for enemy in $game_troop.enemies if enemy.exist? enemies_agi += enemy.agi enemies_number += 1 end end if enemies_number > 0 enemies_agi /= enemies_number end # Calculate actor agility average actors_agi = 0 actors_number = 0 for actor in $game_party.actors if actor.exist? actors_agi += actor.agi actors_number += 1 end end if actors_number > 0 actors_agi /= actors_number end # Determine if escape is successful success = rand(100) < 50 * actors_agi / enemies_agi # If escape is successful if success # Play escape SE p "escape mode" $game_system.se_play($data_system.escape_se) $game_temp.from_battle = false Audio.bgm_play($game_temp.map_bgm.name, 100, 100, $game_temp.map_bgm_pos) # Battle ends battle_end(1) # If escape is failure else # Clear all party member actions $game_party.clear_actions # Start main phase start_phase4 end end end Share this post Link to post Share on other sites
ForeverZer0 44 Report post Posted July 8, 2012 I updated the script and demo. Added the following: - Fixed incorrect filepaths that mixed forward and backward slashes - Fixed a bug that would cause full paths to files not to play sometimes - Added an enumerator for iterating Audio mixers ("Audio.each_mixer") - Added methods to Game_System for memorizing/restoring audio I also created a small plugin that will automatically memorize/restore BGM and BGS before and after battle. It is not part of the main script. If you would like to use it, either get it separately with the link above in the main post, or copy-paste from the demo. Share this post Link to post Share on other sites
gerkrt 0 Report post Posted July 10, 2012 Thanks thats what i just needed. Share this post Link to post Share on other sites