📄 music_cmd.c
字号:
/* SDL_mixer: An audio mixer library based on the SDL library Copyright (C) 1997-2004 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@libsdl.org*/#include "SDL_config.h"/* This file supports an external command for playing music */#if defined(unix) || defined(__MACOSX__) /* This is a UNIX-specific hack */#include <sys/types.h>#include <sys/wait.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <signal.h>#include <ctype.h>#include "SDL_mixer.h"#include "music_cmd.h"/* Unimplemented */void MusicCMD_SetVolume(int volume){ Mix_SetError("No way to modify external player volume");}/* Load a music stream from the given file */MusicCMD *MusicCMD_LoadSong(const char *cmd, const char *file){ MusicCMD *music; /* Allocate and fill the music structure */ music = (MusicCMD *)malloc(sizeof *music); if ( music == NULL ) { Mix_SetError("Out of memory"); return(NULL); } strncpy(music->file, file, (sizeof music->file)-1); music->file[(sizeof music->file)-1] = '\0'; strncpy(music->cmd, cmd, (sizeof music->cmd)-1); music->cmd[(sizeof music->cmd)-1] = '\0'; music->pid = 0; /* We're done */ return(music);}/* Parse a command line buffer into arguments */static int ParseCommandLine(char *cmdline, char **argv){ char *bufp; int argc; argc = 0; for ( bufp = cmdline; *bufp; ) { /* Skip leading whitespace */ while ( isspace(*bufp) ) { ++bufp; } /* Skip over argument */ if ( *bufp == '"' ) { ++bufp; if ( *bufp ) { if ( argv ) { argv[argc] = bufp; } ++argc; } /* Skip over word */ while ( *bufp && (*bufp != '"') ) { ++bufp; } } else { if ( *bufp ) { if ( argv ) { argv[argc] = bufp; } ++argc; } /* Skip over word */ while ( *bufp && ! isspace(*bufp) ) { ++bufp; } } if ( *bufp ) { if ( argv ) { *bufp = '\0'; } ++bufp; } } if ( argv ) { argv[argc] = NULL; } return(argc);}static char **parse_args(char *command, char *last_arg){ int argc; char **argv; /* Parse the command line */ argc = ParseCommandLine(command, NULL); if ( last_arg ) { ++argc; } argv = (char **)malloc((argc+1)*(sizeof *argv)); if ( argv == NULL ) { return(NULL); } argc = ParseCommandLine(command, argv); /* Add last command line argument */ if ( last_arg ) { argv[argc++] = last_arg; } argv[argc] = NULL; /* We're ready! */ return(argv);}/* Start playback of a given music stream */void MusicCMD_Start(MusicCMD *music){ music->pid = fork(); switch(music->pid) { /* Failed fork() system call */ case -1: Mix_SetError("fork() failed"); return; /* Child process - executes here */ case 0: { char command[PATH_MAX]; char **argv; /* Execute the command */ strcpy(command, music->cmd); argv = parse_args(command, music->file); if ( argv != NULL ) { execvp(argv[0], argv); } /* exec() failed */ perror(argv[0]); _exit(-1); } break; /* Parent process - executes here */ default: break; } return;}/* Stop playback of a stream previously started with MusicCMD_Start() */void MusicCMD_Stop(MusicCMD *music){ int status; if ( music->pid > 0 ) { while ( kill(music->pid, 0) == 0 ) { kill(music->pid, SIGTERM); sleep(1); waitpid(music->pid, &status, WNOHANG); } music->pid = 0; }}/* Pause playback of a given music stream */void MusicCMD_Pause(MusicCMD *music){ if ( music->pid > 0 ) { kill(music->pid, SIGSTOP); }}/* Resume playback of a given music stream */void MusicCMD_Resume(MusicCMD *music){ if ( music->pid > 0 ) { kill(music->pid, SIGCONT); }}/* Close the given music stream */void MusicCMD_FreeSong(MusicCMD *music){ free(music);}/* Return non-zero if a stream is currently playing */int MusicCMD_Active(MusicCMD *music){ int status; int active; active = 0; if ( music->pid > 0 ) { waitpid(music->pid, &status, WNOHANG); if ( kill(music->pid, 0) == 0 ) { active = 1; } } return(active);}#endif /* unix */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -