| 1 | /*************************************************************************** |
| 2 | * Copyright (C) 2005 by Michal Turek - Woq * |
| 3 | * WOQ (zavinac) seznam.cz * |
| 4 | * * |
| 5 | * Program ukazuje nahrani zvuku ve formatu .AU pomoci knihovny * |
| 6 | * SDL_sound, jeho dekodovani a nasledne prehravani * |
| 7 | * (opet pro jednoduchost smycka). Zde je pouzit .AU, ale naprosto * |
| 8 | * stejnym zpusobem lze pouzivat zvukove soubory jakychkoli jinych * |
| 9 | * formatu (.MP3, .OGG atd.), staci jen zmenit jmeno souboru. * |
| 10 | * * |
| 11 | * This program is free software; you can redistribute it and/or modify * |
| 12 | * it under the terms of the GNU General Public License as published by * |
| 13 | * the Free Software Foundation; either version 2 of the License, or * |
| 14 | * (at your option) any later version. * |
| 15 | * * |
| 16 | * This program is distributed in the hope that it will be useful, * |
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
| 19 | * GNU General Public License for more details. * |
| 20 | * * |
| 21 | * You should have received a copy of the GNU General Public License * |
| 22 | * along with this program; if not, write to the * |
| 23 | * Free Software Foundation, Inc., * |
| 24 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * |
| 25 | ***************************************************************************/ |
| 26 | |
| 27 | #include <stdio.h> |
| 28 | #include <SDL/SDL.h> |
| 29 | #include <SDL/SDL_sound.h>// Nezapomenout prilinkovat -lSDL_sound |
| 30 | |
| 31 | |
| 32 | /* |
| 33 | * Symbolicke konstanty |
| 34 | */ |
| 35 | |
| 36 | #define SDL_SUBSYSTEMS SDL_INIT_AUDIO |
| 37 | |
| 38 | /* |
| 39 | * Funkcni prototypy |
| 40 | */ |
| 41 | |
| 42 | void AudioCallback(void *unused, Uint8 *stream, int len); |
| 43 | int Init(); // Inicializace |
| 44 | void Destroy(); // Deinicializace |
| 45 | int ProcessEvent(); // Osetruje udalosti |
| 46 | int main(int argc, char *argv[]); // Vstup do programu |
| 47 | |
| 48 | |
| 49 | /* |
| 50 | * Globalni promenne |
| 51 | */ |
| 52 | |
| 53 | |
| 54 | Sound_Sample *g_sample; // Zvuk |
| 55 | Uint32 g_pos; // Pozice pri prehravani |
| 56 | |
| 57 | |
| 58 | /* |
| 59 | * Audio callback funkce, posila data do streamu |
| 60 | */ |
| 61 | |
| 62 | void AudioCallback(void *unused, Uint8 *stream, int len) |
| 63 | { |
| 64 | // Ukazatel na cast, kde se ma zacit prehravat |
| 65 | Uint8 *wave_ptr = (Uint8 *)g_sample->buffer + g_pos; |
| 66 | |
| 67 | // Delka zvuku do konce |
| 68 | int wave_left = g_sample->buffer_size - g_pos; |
| 69 | |
| 70 | // Zbyvajici delka je mensi nez pozadovana |
| 71 | // Cyklus, protoze cely zvuk muze byt kratsi |
| 72 | while(wave_left <= len) |
| 73 | { |
| 74 | // Posle data na zvukovou kartu |
| 75 | SDL_MixAudio(stream, wave_ptr, wave_left, SDL_MIX_MAXVOLUME); |
| 76 | |
| 77 | // Posune se o prave zapsana data |
| 78 | stream += wave_left; |
| 79 | len -= wave_left; |
| 80 | |
| 81 | // Od zacatku zvuku |
| 82 | wave_ptr = (Uint8 *)g_sample->buffer; |
| 83 | wave_left = g_sample->buffer_size; |
| 84 | g_pos = 0; |
| 85 | } |
| 86 | |
| 87 | // Je jistota, ze zbyvajici cast zvuku je delsi nez pozadovana |
| 88 | SDL_MixAudio(stream, wave_ptr, len, SDL_MIX_MAXVOLUME); |
| 89 | g_pos += len; |
| 90 | } |
| 91 | |
| 92 | |
| 93 | /* |
| 94 | * Inicializacni funkce |
| 95 | */ |
| 96 | |
| 97 | int Init() |
| 98 | { |
| 99 | // Inicializace SDL |
| 100 | if(SDL_Init(SDL_SUBSYSTEMS) == -1) |
| 101 | { |
| 102 | fprintf(stderr, "Unable to initialize SDL: %s\n", |
| 103 | SDL_GetError()); |
| 104 | return 0; |
| 105 | } |
| 106 | |
| 107 | // Inicializace SDL_sound |
| 108 | if(Sound_Init() == 0) |
| 109 | { |
| 110 | fprintf(stderr, "Unable to initialize SDL_sound: %s\n", |
| 111 | Sound_GetError()); |
| 112 | return 0; |
| 113 | } |
| 114 | |
| 115 | // Vypise verzi SDL_sound |
| 116 | Sound_Version compiled; |
| 117 | Sound_Version linked; |
| 118 | SOUND_VERSION(&compiled); |
| 119 | Sound_GetLinkedVersion(&linked); |
| 120 | |
| 121 | printf("\nVersion of compiled SDL_sound: %d.%d.%d\n", |
| 122 | compiled.major, compiled.minor, compiled.patch); |
| 123 | printf("Version of linked SDL_sound: %d.%d.%d\n\n", |
| 124 | linked.major, linked.minor, linked.patch); |
| 125 | |
| 126 | // Vypise dostupne audio formaty |
| 127 | const Sound_DecoderInfo **dec_info = Sound_AvailableDecoders(); |
| 128 | |
| 129 | printf("Supported sound formats:\n"); |
| 130 | int i; |
| 131 | for(i = 0; dec_info[i] != NULL; i++) |
| 132 | { |
| 133 | printf("%s\t- %s\n", |
| 134 | *dec_info[i]->extensions, dec_info[i]->description); |
| 135 | } |
| 136 | printf("\n"); |
| 137 | |
| 138 | // Nastaveni audia |
| 139 | SDL_AudioSpec desired, obtained; |
| 140 | desired.freq = 22050;// 16-bit. stereo na 22 kHz |
| 141 | desired.format = AUDIO_S16; |
| 142 | desired.channels = 2; |
| 143 | desired.samples = 512;// Vhodne pro hry |
| 144 | desired.callback = AudioCallback; |
| 145 | desired.userdata = NULL; |
| 146 | |
| 147 | // Otevre audio zarizeni |
| 148 | if(SDL_OpenAudio(&desired, &obtained) == -1) |
| 149 | { |
| 150 | fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError()); |
| 151 | return 0; |
| 152 | } |
| 153 | |
| 154 | // Loading audia a dekodovani (vse najednou) |
| 155 | Sound_AudioInfo info; |
| 156 | info.channels = obtained.channels; |
| 157 | info.format = obtained.format; |
| 158 | info.rate = obtained.freq; |
| 159 | |
| 160 | g_sample = Sound_NewSampleFromFile("bd.wav", &info, 512); |
| 161 | if(g_sample == NULL) |
| 162 | { |
| 163 | fprintf(stderr, "Unable to load sound: %s\n", Sound_GetError()); |
| 164 | return 0; |
| 165 | } |
| 166 | |
| 167 | // Dekoduje cely zvuk najednou |
| 168 | Sound_DecodeAll(g_sample); |
| 169 | if(g_sample->flags & SOUND_SAMPLEFLAG_ERROR) |
| 170 | { |
| 171 | fprintf(stderr, "Unable to decode sound: %s\n", |
| 172 | Sound_GetError()); |
| 173 | return 0; |
| 174 | } |
| 175 | |
| 176 | // Zacne prehravat |
| 177 | SDL_PauseAudio(0); |
| 178 | |
| 179 | return 1; |
| 180 | } |
| 181 | |
| 182 | |
| 183 | /* |
| 184 | * Deinicializacni funkce |
| 185 | */ |
| 186 | |
| 187 | void Destroy() |
| 188 | { |
| 189 | Sound_FreeSample(g_sample); // Uvolni zvuk |
| 190 | Sound_Quit(); // Ukonci SDL_sound |
| 191 | SDL_CloseAudio(); // Zavre audio zarizeni |
| 192 | SDL_Quit(); // Deinicializuje SDL |
| 193 | } |
| 194 | |
| 195 | |
| 196 | /* |
| 197 | * Osetreni udalosti |
| 198 | */ |
| 199 | |
| 200 | int ProcessEvent() |
| 201 | { |
| 202 | SDL_Event event; |
| 203 | |
| 204 | while(SDL_WaitEvent(&event)) |
| 205 | { |
| 206 | switch(event.type) |
| 207 | { |
| 208 | case SDL_KEYDOWN: |
| 209 | switch(event.key.keysym.sym) |
| 210 | { |
| 211 | case SDLK_ESCAPE: |
| 212 | return 0; |
| 213 | break; |
| 214 | |
| 215 | default: |
| 216 | break; |
| 217 | } |
| 218 | break; |
| 219 | |
| 220 | case SDL_QUIT: |
| 221 | return 0; |
| 222 | break; |
| 223 | |
| 224 | default: |
| 225 | break; |
| 226 | } |
| 227 | } |
| 228 | |
| 229 | return 1; |
| 230 | } |
| 231 | |
| 232 | |
| 233 | /* |
| 234 | * Vstup do programu |
| 235 | */ |
| 236 | |
| 237 | int main(int argc, char *argv[]) |
| 238 | { |
| 239 | printf("\nPress ESC key to quit.\n"); |
| 240 | |
| 241 | // Inicializace |
| 242 | if(!Init()) |
| 243 | { |
| 244 | Destroy(); |
| 245 | return 1; |
| 246 | } |
| 247 | |
| 248 | // Hlavni smycka programu |
| 249 | int done = 0; |
| 250 | while(!done) |
| 251 | { |
| 252 | done = !ProcessEvent(); |
| 253 | } |
| 254 | |
| 255 | // Deinicializace a konec |
| 256 | Destroy(); |
| 257 | return 0; |
| 258 | } |
| 259 | |