/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2012 I-maginer This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ----------------------------------------------------------------------------- */ struct PlugSound = [ SND_inst : PInstance, SND_player : AudioPlayer, SND_fLastPos : F, SND_lEvents : [[F S] r1], SND_bStopped : I, SND_bPlaying : I ]mkPlugSound;; fun getSoundPosEvents(inst, etime, sndstr)= let audioPlayerGetCurrentTime sndstr.SND_player -> pos in let if (sndstr.SND_fLastPos <=. pos) then pos else audioPlayerGetLength sndstr.SND_player -> cpos in ( if (pos == sndstr.SND_fLastPos) then nil else ( let sizelist sndstr.SND_lEvents -> size in let 0 -> i in while i < size do ( let nth_list sndstr.SND_lEvents i -> [epos evt] in if sndstr.SND_fLastPos == nil then if (cpos >=. epos) then SendPluginEvent inst evt nil nil else nil else if (cpos >=. epos && sndstr.SND_fLastPos <. epos) then SendPluginEvent inst evt nil nil else nil; set i = i + 1; ); ); set sndstr.SND_fLastPos = if (cpos != pos) then 0.0 else pos; ); 0;; fun deleteOb(inst, sndstr)= if (sndstr.SND_player == nil) then nil else ( audioPlayerDelete sndstr.SND_player; set sndstr.SND_player = nil; ); setPluginInstanceCbScenePreRender inst nil; 0;; fun cbUpdateSound(inst, viewstr, etime, sndstr)= if (sndstr.SND_player == nil) then nil else ( audioPlayerUpdate sndstr.SND_player; if (!sndstr.SND_bPlaying) then nil else getSoundPosEvents inst etime sndstr; ); 0;; fun cbEndSound(snd, sndstr)= set sndstr.SND_bPlaying = 0; set sndstr.SND_fLastPos = 0.0; if (sndstr.SND_bStopped) then nil else SendPluginEvent sndstr.SND_inst "Ended" nil nil; 0;; fun playSound(inst, from, action, param, rep, sndstr)= set sndstr.SND_bStopped = 0; set sndstr.SND_bPlaying = 1; audioPlayerPlay sndstr.SND_player; SendPluginEvent sndstr.SND_inst "Playing" nil nil; 0;; fun pauseSound(inst, from, action, param, rep, sndstr)= audioPlayerPause sndstr.SND_player; set sndstr.SND_bPlaying = 0; SendPluginEvent sndstr.SND_inst "Paused" nil nil; 0;; fun stopSound(inst, from, action, param, rep, sndstr)= set sndstr.SND_bStopped = 1; set sndstr.SND_bPlaying = 0; audioPlayerStop sndstr.SND_player; SendPluginEvent sndstr.SND_inst "Stopped" nil nil; 0;; fun setSoundVolume(inst, from, action, param, rep, sndstr) = if (atoi param) == nil then nil else audioPlayerSetVolume sndstr.SND_player (atoi param); 0;; fun cbSetPitch(inst, from, action, param, rep, sndstr) = if (atof param) == nil then nil else audioPlayerSetPitch sndstr.SND_player (atof param); 0;; fun cbSeek(inst, from, action, param, rep, sndstr) = if (atof param) == nil then nil else audioPlayerSeek sndstr.SND_player (atof param); 0;; fun cbEnableEffect(inst, from, action, param, rep, sndstr) = audioPlayerEnableEffect sndstr.SND_player; 0;; fun cbDisableEffect(inst, from, action, param, rep, sndstr) = audioPlayerDisableEffect sndstr.SND_player; 0;; fun cbChangeSound(inst, from, action, param, rep, sndstr) = set sndstr.SND_fLastPos = 0.0; if (param == nil) then nil else audioPlayerOpenSound sndstr.SND_player param; 0;; fun sortSoundPos(p1, p2)= let p1 -> [f1 _] in let p2 -> [f2 _] in f1 <=. f2;; fun newOb(inst)= let (getPluginInstanceParam inst "source") -> objname in let atof (getPluginInstanceParam inst "attenuation") -> attenuation in let if attenuation == nil then 1.0 else attenuation -> attenuation in let (getPluginInstanceParam inst "path") -> sndpath in let atoi (getPluginInstanceParam inst "isurl") -> isurl in let (getPluginInstanceParam inst "url") -> url in let atoi (getPluginInstanceParam inst "enable") -> playstart in let atoi (getPluginInstanceParam inst "loop") -> isloop in let atoi (getPluginInstanceParam inst "volume") -> ivolume in let if ivolume == nil then 100 else ivolume -> ivolume in let atof (getPluginInstanceParam inst "pitch") -> pitch in let if pitch == nil then 1.0 else pitch -> pitch in let atoi (getPluginInstanceParam inst "enableeffect") -> enableeffect in let atoi (getPluginInstanceParam inst "innerangle") -> innerangle in let if innerangle == nil then 360 else innerangle -> innerangle in let atoi (getPluginInstanceParam inst "outerangle") -> outerangle in let if outerangle == nil then 360 else outerangle -> outerangle in let atoi (getPluginInstanceParam inst "outervol") -> outervol in let if outervol == nil then 0 else outervol -> outervol in let V3DgetObjectByName c3dXsession objname -> object in let if !isurl then sndpath else url -> path in let mkPlugSound [inst nil nil nil 1 0] -> sndstr in ( PluginRegisterAction inst "Play" mkfun6 @playSound sndstr; PluginRegisterAction inst "Pause" mkfun6 @pauseSound sndstr; PluginRegisterAction inst "Stop" mkfun6 @stopSound sndstr; PluginRegisterAction inst "Set Volume" mkfun6 @setSoundVolume sndstr; PluginRegisterAction inst "Set Pitch" mkfun6 @cbSetPitch sndstr; PluginRegisterAction inst "Seek" mkfun6 @cbSeek sndstr; PluginRegisterAction inst "Enable Effect" mkfun6 @cbEnableEffect sndstr; PluginRegisterAction inst "Disable Effect" mkfun6 @cbDisableEffect sndstr; PluginRegisterAction inst "Change Sound" mkfun6 @cbChangeSound sndstr; set sndstr.SND_player = audioPlayerCreate3d (getPluginInstanceName inst) isloop enableeffect ivolume pitch (mknode @cbEndSound sndstr) object attenuation [innerangle outerangle outervol]; let getPluginInstanceUserEvents inst -> levent in let sizelist levent -> size in let 0 -> i in while i < size do ( let nth_list levent i -> evt in let atof (hd hd (strextr evt)) -> pos in ( set sndstr.SND_lEvents = lcat sndstr.SND_lEvents [pos evt]::nil; ); set i = i + 1; ); set sndstr.SND_lEvents = sortlist sndstr.SND_lEvents @sortSoundPos; setPluginInstanceCbScenePreRender inst mkfun4 @cbUpdateSound sndstr; audioPlayerOpenSound sndstr.SND_player path; if !playstart then nil else playSound inst nil nil nil nil sndstr; setPluginInstanceCbDel inst mkfun2 @deleteOb sndstr; ); 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;