/*************************************************************************** simplemusic.c - Simple music playing plugin for eboxy ------------------- begin : Sun Oct 13 2002 copyright : (C) 2002 by Paul Eggleton email : bluelightning@bluelightning.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "eboxyplugin.h" #include "pluginconstants.h" #include "string.h" #include "SDL.h" #include "SDL_mixer.h" /* Globals */ Mix_Music *music = NULL; char *musicfile = NULL; int autorepeat = 0; /* Prototypes */ char *sm_play(const char *sender, int numargs, const char *args[]); char *sm_pause(const char *sender, int numargs, const char *args[]); char *sm_stop(const char *sender, int numargs, const char *args[]); char *sm_getfile(const char *sender); int sm_setfile(const char *sender, const char *value); char *sm_getautorepeat(const char *sender); int sm_setautorepeat(const char *sender, const char *value); void sm_musicdone(void); int strtobool(const char *str); const char *booltostr(int n); /* Implementation */ int ebplugin_init(void) { int rc = 0; /* Audio parameters */ int audio_rate = 44100; Uint16 audio_format = AUDIO_S16; /* 16-bit stereo */ int audio_channels = 2; int audio_buffers = 4096; /* Initialise audio */ if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers)) { fprintf(stderr, "simplemusic: Unable to open audio!\n"); return 1; } /* Set version info for the plugin */ setPluginInfo("SimpleMusic", "0.2"); /* Find out what audio parameters we actually got (FIXME: should probably check this) */ Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels); /* Register an object to be used in scripts */ rc = registerObject("simplemusic"); if(rc) return rc; rc = registerMethodDL("simplemusic", "play", 0, "sm_play"); if(rc) return rc; rc = registerMethodDL("simplemusic", "pause", 0, "sm_pause"); if(rc) return rc; rc = registerMethodDL("simplemusic", "stop", 0, "sm_stop"); if(rc) return rc; rc = registerPropertyDL("simplemusic", "file", "sm_getfile", "sm_setfile"); if(rc) return rc; rc = registerPropertyDL("simplemusic", "autorepeat", "sm_getautorepeat", "sm_setautorepeat"); if(rc) return rc; /* Success */ return 0; } int ebplugin_message(int msgcode, void *msgdata) { return 0; /* return 0 here for future compatibility */ } void ebplugin_deinit(void) { /* Stop music (if playing) */ sm_stop("", 0, NULL); /* Free allocated memory */ if(musicfile) free(musicfile); /* Close audio device */ Mix_CloseAudio(); } char *sm_play(const char *sender, int numargs, const char *args[]) { if(!musicfile) { fprintf(stderr, "SimpleMusic: no file to play specified\n"); return NULL; } if(!music) { /* Actually loads up the music */ music = Mix_LoadMUS(musicfile); if(music) { /* This begins playing the music - the first argument is a pointer to Mix_Music structure, and the second is how many times you want it to loop (use -1 for infinite, and 0 to have it just play once) */ if(Mix_PlayMusic(music, 0) != 0) { /* Error occurred */ fprintf(stderr, "SimpleMusic: %s\n", Mix_GetError()); return NULL; } /* We want to know when our music has stopped playing so we can free it up and set 'music' back to NULL. SDL_Mixer provides us with a callback routine we can use to do exactly that */ Mix_HookMusicFinished(sm_musicdone); } else { /* Error occurred */ fprintf(stderr, "SimpleMusic: %s\n", Mix_GetError()); return NULL; } } else if(Mix_PausedMusic()) { Mix_ResumeMusic(); } else { Mix_RewindMusic(); Mix_PlayMusic(music, 0); } return NULL; } char *sm_pause(const char *sender, int numargs, const char *args[]) { if(music) { /* Pause the music */ if(Mix_PausedMusic()) Mix_ResumeMusic(); else Mix_PauseMusic(); } return NULL; } char *sm_stop(const char *sender, int numargs, const char *args[]) { if(music) { /* Stop the music from playing */ Mix_HaltMusic(); /* Unload the music from memory */ Mix_FreeMusic(music); music = NULL; } return NULL; } char *sm_getfile(const char *sender) { return strdup(musicfile); } int sm_setfile(const char *sender, const char *value) { sm_stop("", 0, NULL); if(musicfile) free(musicfile); musicfile = strdup(value); return 0; } char *sm_getautorepeat(const char *sender) { return strdup(booltostr(autorepeat)); } int sm_setautorepeat(const char *sender, const char *value) { autorepeat = strtobool(value); return 0; } /* This is the function that we told SDL_Mixer to call when the music was finished. */ void sm_musicdone(void) { if(autorepeat) sm_play("", 0, NULL); else { sm_stop("", 0, NULL); fireEvent("simplemusic", "OnFinish"); } } /* Convert a string value into a boolean */ int strtobool(const char *str) { if(strcasecmp(str, "true") == 0 || strcasecmp(str, "on") == 0 || strcasecmp(str, "yes") == 0 || atoi(str) != 0) return 1; else return 0; } /* Convert an integer to a string */ const char *booltostr(int n) { if(n) return "1"; else return "0"; }