/*************************************************************************** * Copyright (C) 2005 by Michal Turek - Woq * * WOQ (zavinac) seznam.cz * * * * Program prehrava v nekonecne smycce zvuk nahrany z .wav souboru. * * Pomoci mezerniku je mozne prehravani pozastavit a +/- meni hlasitost. * * * * 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. * ***************************************************************************/ #include <stdio.h> #include <SDL.h> /* * Symbolicke konstanty */ #define SDL_SUBSYSTEMS SDL_INIT_VIDEO|SDL_INIT_AUDIO #define WIN_WIDTH 320 #define WIN_HEIGHT 240 #define WIN_BPP 0 #define WIN_TITLE "SDL a audio" /* * Funkcni prototypy */ void AudioCallback(void *unused, Uint8 *stream, int len); bool Init(); // Inicializace void Destroy(); // Deinicializace bool ProcessEvent(); // Osetruje udalosti int main(int argc, char *argv[]); // Vstup do programu /* * Globalni promenne */ Uint8 g_win_flags = SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE; SDL_Surface *g_screen; // Surface okna Uint8 *g_sound_data; // Ukazatel na data zvuku Uint32 g_sound_len; // Delka dat int g_sound_pos; // Pozice pri prehravani bool g_sound_paused = false; // Flag pozastaveni int g_sound_volume = SDL_MIX_MAXVOLUME / 2; // Hlasitost /* * Audio callback funkce, posila data do streamu */ void AudioCallback(void *unused, Uint8 *stream, int len) { // Ukazatel na cast, kde se ma zacit prehravat Uint8 *wave_ptr = g_sound_data + g_sound_pos; // Delka zvuku do konce int wave_left = g_sound_len - g_sound_pos; // Zbyvajici delka je mensi nez pozadovana // Cyklus, protoze cely zvuk muze byt kratsi while(wave_left <= len) { // Posle data na zvukovou kartu SDL_MixAudio(stream, wave_ptr, wave_left, g_sound_volume); // Posune se o prave zapsana data stream += wave_left; len -= wave_left; // Od zacatku zvuku wave_ptr = g_sound_data; wave_left = g_sound_len; g_sound_pos = 0; } // Je jistota, ze zbyvajici cast zvuku je delsi nez pozadovana SDL_MixAudio(stream, wave_ptr, len, g_sound_volume); g_sound_pos += len; } /* * Inicializacni funkce */ bool Init() { // Inicializace SDL if(SDL_Init(SDL_SUBSYSTEMS) == -1) { fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); return false; } // Nastaveni ikony SDL_Surface *icon = SDL_LoadBMP("./icon.bmp"); if(icon != NULL) { SDL_WM_SetIcon(icon, NULL); SDL_FreeSurface(icon); } // Vytvori okno s definovanymi vlastnostmi g_screen = SDL_SetVideoMode(WIN_WIDTH, WIN_HEIGHT, WIN_BPP, g_win_flags); if(g_screen == NULL) { fprintf(stderr, "Unable to set %dx%d video: %s\n", WIN_WIDTH, WIN_HEIGHT, SDL_GetError()); return false; } // Titulek okna SDL_WM_SetCaption(WIN_TITLE, NULL); // Nahraje zvuk SDL_AudioSpec sound_spec;// Format zvuku if(SDL_LoadWAV("test.wav", &sound_spec, &g_sound_data, &g_sound_len) == NULL) { fprintf(stderr, "Unable to load test.wav: %s\n", SDL_GetError()); return false; } // Nastavi callback funkci sound_spec.callback = AudioCallback; // Otevre audio if(SDL_OpenAudio(&sound_spec, NULL) < 0) { fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError()); return false; } // Vypise jmeno audio driveru char name[32]; printf("Audio driver: %s\n", SDL_AudioDriverName(name, 32)); // Zacne prehravat SDL_PauseAudio(0); return true; } /* * Deinicializacni funkce */ void Destroy() { // Zavre audio a uvolni data wavu SDL_CloseAudio(); SDL_FreeWAV(g_sound_data); SDL_Quit(); } /* * Osetreni udalosti */ bool ProcessEvent() { SDL_Event event; while(SDL_WaitEvent(&event)) { switch(event.type) { case SDL_KEYDOWN: switch(event.key.keysym.sym) { // Pozastaveni zvuku case SDLK_SPACE: g_sound_paused = !g_sound_paused; if(g_sound_paused) SDL_PauseAudio(1); else SDL_PauseAudio(0); break; // Hlasitost case SDLK_KP_PLUS: if(g_sound_volume < SDL_MIX_MAXVOLUME-10) g_sound_volume += 10; break; case SDLK_KP_MINUS: if(g_sound_volume > 10) g_sound_volume -= 10; break; case SDLK_ESCAPE: return false; break; default: break; } break; case SDL_QUIT: return false; break; default: break; } } return true; } /* * Vstup do programu */ int main(int argc, char *argv[]) { printf(WIN_TITLE); printf("\nPress ESC key to quit.\n"); // Inicializace if(!Init()) { Destroy(); return 1; } // Hlavni smycka programu bool done = false; while(!done) { done = !ProcessEvent(); } // Deinicializace a konec Destroy(); return 0; }