/* sdlPlay-1f one-file (-1f) audio player (SDL 1.2 mixer) Copyright (C) 2016 MiNTed Games All Rights Reserved 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. 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 General Public License for more details. You should have received a copy of the GNU 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. */ /* one-file compile g++ `sdl-config --cflags` -Wall -DLINUX -O3 -DVERSION=\"1.0.2\" `sdl-config --libs` -lSDL_mixer -o sdlPlay-1f sdlPlay-1f.cpp ; \ g++ `sdl-config --cflags` -Wall -DLINUX -O3 -DVERSION=\"1.0.2\" -DPRG_SIZE=`ls -l sdlPlay-1f|cut -d \ -f 5` -DSRC_SIZE=`ls -l sdlPlay-1f.cpp|cut -d \ -f 5` `sdl-config --libs` -lSDL_mixer -o sdlPlay-1f sdlPlay-1f.cpp ; \ cat sdlPlay-1f.cpp >> sdlPlay-1f */ #include #include #include #include #include "SDL/SDL.h" #include "SDL/SDL_mixer.h" #ifdef LINUX #include #include #include #include #endif /* one-file source appendage */ #define NO_SIZE 12345 //#define SRC_TYPE ".zip" // if its a ZIP appendage #define SRC_TYPE ".cpp" // if its a TEXT appendage #ifndef PRG_SIZE //#define PRG_SIZE 18808 // last checked binary size was ... #define PRG_SIZE NO_SIZE // .. this should be close to actual #endif #ifndef SRC_SIZE // size of 1 text file or 1 zip file //#define SRC_SIZE 14701 // last checked source size was ... #define SRC_SIZE NO_SIZE // .. affects binary size if too small #endif const long offset_1f = PRG_SIZE; // this has never been accurate (EXT4) const long sizeOf_1f = SRC_SIZE; // we use this (-sizeOf_1f) as offset typedef struct sdlPlayEngineVariables { signed char debug; SDL_Event event; signed char done; SDL_RWops *sdlrw; float musicVolume; float ssx; float ssy; Mix_Music *music; int cursor_x, cursor_y; signed char eventTimer; signed char totalTime; signed char startTime; signed char stopTime; int timeTaken; // In seconds signed char timePlayed; signed char seconds; signed char minutes; signed char hours; signed char paused; signed char useAudio; int next; int current; int playlist; char playList[50][1024]; int loop; int loopCount; int repeat; int repeatCount; signed char info; signed char showFormat; // This really only applies to Linux users. char userHomeDirectory[1024]; char keyState[350]; signed char section; }; sdlPlayEngineVariables sdlPlay; void sdlPlayInit() { sdlPlay.debug = 0; if (sdlPlay.debug) printf("info: initializing engine\n"); sdlPlay.musicVolume = 100; sdlPlay.useAudio = 2; sdlPlay.ssx = 0; sdlPlay.ssy = 0; for (int i = 0 ; i < 350 ; i++) sdlPlay.keyState[i] = 0; sdlPlay.eventTimer = 0; sdlPlay.totalTime = 0; sdlPlay.startTime = 0; sdlPlay.stopTime = 0; sdlPlay.timeTaken = 0; sdlPlay.seconds = 0; sdlPlay.minutes = 0; sdlPlay.paused = 0; sdlPlay.next = 0; sdlPlay.current = 0; sdlPlay.playlist = 0; sdlPlay.loop = 0; sdlPlay.loopCount = 0; sdlPlay.repeat = 1; sdlPlay.repeatCount = 0; sdlPlay.info = 0; sdlPlay.showFormat = 0; sdlPlay.section = 0; } void initVars() { // set timer sdlPlay.startTime = time(NULL); srand(time(NULL)); // for randomise playlist // These are good values for sound and music if (sdlPlay.useAudio) { Mix_Volume(-1, 25); Mix_VolumeMusic((int)sdlPlay.musicVolume); } } void initSystem() { /* Initialize the SDL library */ if (SDL_Init(SDL_INIT_AUDIO) < 0) { printf("Couldn't initialize SDL: %s\n", SDL_GetError()); exit(1); } if (sdlPlay.useAudio) { if (Mix_OpenAudio(22050, AUDIO_S16, sdlPlay.useAudio, 1024) < 0) { printf("Error: Couldn't set 22050 Hz 16-bit audio - Reason: %s\n", Mix_GetError()); exit(1); } if (sdlPlay.info || sdlPlay.debug) { printf("info: audio 22050 Hz 16-bit"); if (sdlPlay.useAudio == 1) printf(" mono\n"); else printf(" stereo\n"); } }else{ if (sdlPlay.info || sdlPlay.debug) printf("info: audio disabled\n"); } } void loadMusic(char *filename) { if (Mix_PlayingMusic()) { if (sdlPlay.debug) printf("info: stop playing audio\n"); Mix_HaltMusic(); } if (sdlPlay.music != NULL) { if (sdlPlay.debug) printf("info: freeing sdlPlay.music\n"); Mix_FreeMusic(sdlPlay.music); } if (sdlPlay.info || sdlPlay.debug) printf("info: loading: %s\n",filename); sdlPlay.music = Mix_LoadMUS(filename); } int playSound() { if (sdlPlay.info || sdlPlay.debug) printf("info: playing sound: %s\n",sdlPlay.playList[sdlPlay.current]); // Mix_PlayChannel(-1, sdlPlay.music, 0); Mix_PlayMusic(sdlPlay.music, 0); return(1); } int playMusic() { if (sdlPlay.info || sdlPlay.debug) printf("info: playing music: %s\n",sdlPlay.playList[sdlPlay.current]); Mix_PlayMusic(sdlPlay.music, 0); return(1); } int playMod() { if (sdlPlay.info || sdlPlay.debug) printf("info: playing module: %s\n",sdlPlay.playList[sdlPlay.current]); Mix_PlayMusic(sdlPlay.music, 0); return(1); } int getAudioFile() { if (sdlPlay.next == sdlPlay.playlist) exit(0); loadMusic(sdlPlay.playList[sdlPlay.next]); if (sdlPlay.music == NULL) { if (sdlPlay.debug) printf("info: failed loading: %s\n",sdlPlay.playList[sdlPlay.next]); return(9); } sdlPlay.current = sdlPlay.next; if (Mix_GetMusicType(sdlPlay.music) == MUS_WAV) return(7); if (Mix_GetMusicType(sdlPlay.music) == MUS_MOD) return(6); return(5); } int isPlaying() { // Give the audio (and possibly the X server) time to work... SDL_Delay(1); if (Mix_PlayingMusic()) return(1); return(2); } int playLoop() { if (sdlPlay.music == NULL) { if (sdlPlay.debug) printf("info: failed playing: %s\n",sdlPlay.playList[sdlPlay.current]); return(9); } if (sdlPlay.loop > 0) if (sdlPlay.loopCount < sdlPlay.loop) { sdlPlay.loopCount++; if (Mix_GetMusicType(sdlPlay.music) == MUS_WAV) return(7); if (Mix_GetMusicType(sdlPlay.music) == MUS_MOD) return(6); return(5); } sdlPlay.loopCount = 0; return(9); } void freeSound() { if (sdlPlay.music != NULL) { if (sdlPlay.debug) printf("info: freeing sdlPlay.music\n"); Mix_FreeMusic(sdlPlay.music); } } void cleanUp() { if (sdlPlay.info || sdlPlay.debug) printf("info: Cleaning Up...\n"); freeSound(); if (sdlPlay.useAudio) { if (sdlPlay.debug) printf("info: Closing Audio\n"); Mix_CloseAudio(); } SDL_Quit(); if (sdlPlay.info || sdlPlay.debug) printf("info: ...Done Cleaning Up\nThank You for using sdlPlay\n"); } void version_1f() { printf("sdlPlay (one-file) %s\n", VERSION); } void output_1f(char *file_1f) { FILE *source_1f; char out_1f[1]; if (offset_1f == NO_SIZE || sizeOf_1f == NO_SIZE) { version_1f(); printf("error: no source file or zip\n"); exit(32); }else{ source_1f = fopen(file_1f, "rb"); if (source_1f == NULL) { version_1f(); printf("error: cant open '%s'\n", file_1f); exit(32); } // fseek(source_1f, offset_1f + 223, SEEK_SET); // off by ? (223) fseek(source_1f, -sizeOf_1f, SEEK_END); while(true) { if (!fread(out_1f, 1, 1, source_1f)) { fclose(source_1f); break; }else putchar((int) out_1f[0]); } } } int main(int argc, char *argv[]) { int total, argDone, j, section, sndFormats; bool hasMik, hasWav, hasAif, hasVoc, hasMid, hasOgg, hasFla, hasMp3; if ( (argc > 1) && ( (strcmp("--version", argv[1]) == 0) || (strcmp("-v", argv[1]) == 0) ) ) { version_1f(); exit(0); } if (sdlPlay.debug) printf("info: %s\n", argv[0]); if ( (argc == 1) || ( (argc > 1) && (strcmp("--help", argv[1]) == 0) ) ) { version_1f(); printf("Copyright 2016 MiNTed Games\n\n"); printf("Play sound files, tracker modules, audio files, using SDL v1.2.\n\n"); printf("usage: sdlPlay-1f [_option_] []\n"); if (argc > 1) { printf("\t--source one file source (to save 'sdlPlay-1f --src > sdlPlay-1f.cpp')\n"); printf("\t--src-size size of source appended (in bytes)\n"); printf("\t--src-type type of source appended (TXT/ZIP)\n"); printf("\t--noaudio dont play anything (use with verbose)\n"); printf("\t--mono Mono sound output (best for headphones)\n"); printf("\t--loop Loop audio times\n"); printf("\t--repeat repeat playlist times\n"); printf("\t--format Display file information(no shows all formats)\n"); printf("\t--help This help information\n"); printf("\t-v|--version Version information\n"); printf("\t-V|--verbose Verbose output\n"); printf("\t--debug Extra verbose output\n"); printf("\nspecial thanks to: www.parallelrealities.co.uk\n"); } printf("\n"); exit(0); } if ( (argc > 1) && ( (strcmp("--source", argv[1]) == 0) || (strcmp("--src", argv[1]) == 0) ) ) { output_1f(argv[0]); exit(31); } if ( (argc > 1 ) && (strcmp("--src-type", argv[1]) == 0) ) { printf(SRC_TYPE); exit(31); } if ( (argc > 1 ) && (strcmp("--src-size", argv[1]) == 0) ) { printf("%d", SRC_SIZE); exit(31); } sdlPlayInit(); // Must do this first! j = 0; for (int i = 1 ; i < argc ; i++) { argDone = 0; if ( (strcmp(argv[i], "-V") == 0) || (strcmp(argv[i], "--verbose") == 0) ) { sdlPlay.info = 1; argDone = 1; } if (strcmp(argv[i], "--debug") == 0) { sdlPlay.debug = 1; argDone = 1; } if ( (strcmp(argv[i], "--format") == 0) || (strcmp(argv[i], "--formats") == 0) ) { sdlPlay.showFormat = 1; argDone = 1; } if (strcmp(argv[i], "--noaudio") == 0) { sdlPlay.useAudio = 0; argDone = 1; } if (strcmp(argv[i], "--mono") == 0) { sdlPlay.useAudio = 1; argDone = 1; } if (strcmp(argv[i], "--loop") == 0) { i++; if (i == argc) { printf("error: --loop needs a number"); exit(1); } sdlPlay.loop = atoi(argv[i]); argDone = 1; } if (strcmp(argv[i], "--repeat") == 0) { i++; if (i == argc) { printf("error: --repeat needs a number"); exit(1); } sdlPlay.repeat = atoi(argv[i]); argDone = 1; } if (argDone == 0) { strcpy(sdlPlay.playList[j], argv[i]); j++; } } sdlPlay.playlist = j; if (sdlPlay.showFormat && sdlPlay.playlist == 0) { version_1f(); sdlPlay.useAudio = 2; initSystem(); sndFormats = 0; hasWav = false; hasAif = false; total = Mix_GetNumChunkDecoders(); printf("[%d] supported chunks:", total); for (int i = 0; i < total; i++) { if (strcmp(Mix_GetChunkDecoder(i),"WAVE") == 0) { hasWav = true; ++sndFormats; ++sndFormats; ++sndFormats;} if (strcmp(Mix_GetChunkDecoder(i),"AIFF") == 0) { hasAif = true; ++sndFormats; } if (strcmp(Mix_GetChunkDecoder(i),"VOC") == 0) { hasVoc = true; ++sndFormats; } printf(" %s", Mix_GetChunkDecoder(i)); } printf("\n"); hasMik = false; hasMid = false; hasOgg = false; hasFla = false; hasMp3 = false; total = Mix_GetNumMusicDecoders(); printf("[%d] supported music:", total); for (int i = 0; i < total; i++) { if (strcmp(Mix_GetMusicDecoder(i),"MIKMOD") == 0) hasMik = true; if (strcmp(Mix_GetMusicDecoder(i),"TIMIDITY") == 0) hasMid = true; if (strcmp(Mix_GetMusicDecoder(i),"OGG") == 0) { hasOgg = true; ++sndFormats; } if (strcmp(Mix_GetMusicDecoder(i),"FLAC") == 0) { hasFla = true; ++sndFormats; } if (strcmp(Mix_GetMusicDecoder(i),"MP3") == 0) { hasMp3 = true; ++sndFormats; } printf(" %s", Mix_GetMusicDecoder(i)); } printf("\n"); if (hasMik) { printf("[17] MikMod formats:"); if(sdlPlay.info) { printf("\n"); printf("\t.699 669 and Extended-669 (by Tran/Renaissance)\n"); printf("\t.AMF DMP Advanced Module Format (by Otto Chrons)\n"); printf("\t.DSM DSIK internal module format\n"); printf("\t.FAR Farandole Composer (by Daniel Potter)\n"); printf("\t.GDM General DigiMusic (by Edward Schlunder)\n"); printf("\t.IT Impulse Tracker (by Jeffrey Lim)\n"); printf("\t.IMF Imago Orpheus (by Lutz Roeder)\n"); printf("\t.MED Amiga MED modules (by Teijo Kinnunen)\n"); printf("\t.M15 Soundtracker 15-instrument\n"); printf("\t.MOD Standard 31-instrument Module loader\n"); printf("\t.MTM Multi-Tracker Module (by Renaissance)\n"); printf("\t.OKT Amiga Oktalyzer\n"); printf("\t.STM ScreamTracker 2 (by Future Crew)\n"); printf("\t.STX STMIK 0.2 (by Future Crew)\n"); printf("\t.S3M ScreamTracker 3 (by Future Crew)\n"); printf("\t.ULT UltraTracker (by MAS)\n"); printf("\t.UNI MikMod and APlayer internal module format\n"); printf("\t.XM FastTracker 2 (by Triton)\n"); }else{ printf(" 669 AMF DSM FAR GDM IT IMF MED M15 MOD MTM OKT STM STX S3M ULT UNI XM\n"); } } printf("[%d] sound formats:", sndFormats); if(sdlPlay.info) { printf("\n"); if (hasWav) printf("\t.RAW Raw audio sample\n"); if (hasWav) printf("\t.AU Sun audio sample\n"); if (hasWav) printf("\t.WAV Microsoft RIFF sound wave\n"); if (hasAif) printf("\t.AIF Apple Audio Interchange File Format (AIFF)\n"); if (hasVoc) printf("\t.VOC Creative Labs Voice sample\n"); if (hasOgg) printf("\t.OGG Vorbis OOG compressed audio sample\n"); if (hasFla) printf("\t.FLA Free Loss-less Audio Compression format (FLAC)\n"); if (hasMp3) printf("\t.MP3 MPEG Layer 3 compressed audio sample\n"); }else{ if (hasWav) printf(" RAW AU WAV"); if (hasAif) printf(" AIF"); if (hasOgg) printf(" OGG"); if (hasFla) printf(" FLA"); if (hasMp3) printf(" MP3"); printf("\n"); } if (hasMid) printf("[1] supported MIDI: "); if (sdlPlay.info) printf("\n\t"); if (hasMid) printf(".MID General MIDI file format\n"); Mix_CloseAudio(); SDL_Quit(); if (sdlPlay.debug) printf("info: audio closed\n"); exit(0); } atexit(cleanUp); initSystem(); // Opens video mode and sound initVars(); section = 0; while (true) { // non-blocking (but high CPU usage) // should be event driven, but this is faster switch(section) { case 0: section = getAudioFile(); break; case 1: section = isPlaying(); break; case 2: section = playLoop(); break; case 5: section = playMusic(); break; case 6: section = playMod(); break; case 7: section = playSound(); break; case 9: sdlPlay.next++; section = 0; break; } } return(0); }