misc/libopenalbridge/commands.c
changeset 9431 0f5961910e27
parent 9357 a501f5ec7b34
parent 9429 7a97a554ac80
child 9433 f0a8ac191839
equal deleted inserted replaced
9357:a501f5ec7b34 9431:0f5961910e27
     1 /*
       
     2  *  commands.c
       
     3  *  Hedgewars
       
     4  *
       
     5  *  Created by Vittorio on 13/06/10.
       
     6  *  Copyright 2010 __MyCompanyName__. All rights reserved.
       
     7  *
       
     8  */
       
     9 
       
    10 #include "commands.h"
       
    11 #include "wrappers.h"
       
    12 
       
    13 ALfloat old_gain;
       
    14 extern ALuint *Sources;
       
    15 extern ALuint cache_size, cache_index, sources_number;
       
    16 extern ALboolean instances_number;
       
    17 extern al_sound_t *the_sounds;
       
    18 
       
    19 void openal_pausesound (uint32_t index) {
       
    20     if (openal_ready() == AL_TRUE && index < cache_size)
       
    21         alSourcePause(Sources[the_sounds[index].source_index]);
       
    22 }
       
    23 
       
    24 
       
    25 void openal_stopsound (uint32_t index) {
       
    26     if (openal_ready() == AL_TRUE && index < cache_size)
       
    27         alSourceStop(Sources[the_sounds[index].source_index]);
       
    28 }
       
    29 
       
    30 
       
    31 void openal_playsound (unsigned int index) {
       
    32     ALboolean needsSource = AL_TRUE;
       
    33     ALfloat SourcePosition[] = { 0.0, 0.0, 0.0 };
       
    34     ALfloat SourceVelocity[] = { 0.0, 0.0, 0.0 };
       
    35     ALint state;
       
    36     int i, j;
       
    37 
       
    38     if (openal_ready() == AL_TRUE && index < cache_size) {
       
    39         // check if sound has already a source
       
    40         if (the_sounds[index].source_index != -1) {
       
    41             // it has a source, check it's not playing
       
    42             alGetSourcei(Sources[the_sounds[index].source_index], AL_SOURCE_STATE, &state);
       
    43             if (state != AL_PLAYING && state != AL_PAUSED) {
       
    44                 // it is not being played, so we can use it safely
       
    45 	            needsSource = AL_FALSE;
       
    46             }
       
    47             // else it is being played, so we have to allocate a new source for this buffer
       
    48         }
       
    49 
       
    50         if (needsSource) {
       
    51 #ifdef DEBUG
       
    52             fprintf(stderr,"(Bridge Debug) - looking for a source for sound %d\n", index);
       
    53 #endif
       
    54             for (i = 0; i < sources_number; i++) {
       
    55                 // let's iterate on Sources until we find a source that is not playing
       
    56                 alGetSourcei(Sources[i], AL_SOURCE_STATE, &state);
       
    57                 if (state != AL_PLAYING && state != AL_PAUSED) {
       
    58                     // let's iterate on the_sounds until we find the sound using that source
       
    59                     for (j = 0; j < cache_size; j++) {
       
    60                         if (the_sounds[j].source_index == i) {
       
    61                             the_sounds[j].source_index = -1;
       
    62                             break;
       
    63                         }
       
    64                     }
       
    65                     // here we know that no-one is using that source so we can use it
       
    66                     break;
       
    67                 }
       
    68             }
       
    69 
       
    70             if (i == sources_number) {
       
    71                 // this means all sources are busy
       
    72             }
       
    73 
       
    74             // set source properties that it will use when it's in playback
       
    75             alSourcei (Sources[i], AL_BUFFER,   the_sounds[index].buffer);
       
    76             alSourcef (Sources[i], AL_PITCH,    1.0f);
       
    77             alSourcef (Sources[i], AL_GAIN,     1.0f);
       
    78             alSourcefv(Sources[i], AL_POSITION, SourcePosition);
       
    79             alSourcefv(Sources[i], AL_VELOCITY, SourceVelocity);
       
    80             alSourcei (Sources[i], AL_LOOPING,  0);
       
    81 
       
    82             if (AL_NO_ERROR != alGetError()) {
       
    83                 fprintf(stderr,"(Bridge ERROR) - failed to set Source properties\n");
       
    84                 return;
       
    85             }
       
    86             the_sounds[index].source_index = i;
       
    87         }
       
    88 
       
    89         alSourcePlay(Sources[the_sounds[index].source_index]);
       
    90 
       
    91         if (AL_NO_ERROR != alGetError()) {
       
    92             fprintf(stderr,"(Bridge Warning) - failed to play sound %d\n", index);
       
    93             return;
       
    94         }
       
    95     }
       
    96 }
       
    97 
       
    98 void openal_toggleloop (uint32_t index) {
       
    99     ALint loop;
       
   100 
       
   101     if (openal_ready() == AL_TRUE && index < cache_size) {
       
   102         alGetSourcei (Sources[the_sounds[index].source_index], AL_LOOPING, &loop);
       
   103         alSourcei (Sources[the_sounds[index].source_index], AL_LOOPING, !((uint8_t) loop) & 0x00000001);
       
   104     }
       
   105 }
       
   106 
       
   107 
       
   108 void openal_setvolume (uint32_t index, float gain) {
       
   109     if (openal_ready() == AL_TRUE && index < cache_size)
       
   110         alSourcef (Sources[the_sounds[index].source_index], AL_GAIN, gain);
       
   111 }
       
   112 
       
   113 
       
   114 void openal_setglobalvolume (float gain) {
       
   115     if (openal_ready() == AL_TRUE)
       
   116         alListenerf (AL_GAIN, gain);
       
   117 }
       
   118 
       
   119 void openal_togglemute () {
       
   120     ALfloat gain;
       
   121 
       
   122     if (openal_ready() == AL_TRUE) {
       
   123         alGetListenerf (AL_GAIN, &gain);
       
   124         if (gain > 0) {
       
   125             old_gain = gain;
       
   126             gain = 0;
       
   127         } else
       
   128             gain = old_gain;
       
   129 
       
   130         alListenerf (AL_GAIN, gain);
       
   131     }
       
   132 }
       
   133 
       
   134 // Fade in or out by calling a helper thread
       
   135 void openal_fade (uint32_t index, uint16_t quantity, al_fade_t direction) {
       
   136 #ifndef _WIN32
       
   137     pthread_t thread;
       
   138 #else
       
   139     HANDLE Thread;
       
   140 #endif
       
   141     fade_t *fade;
       
   142 
       
   143     if (openal_ready() == AL_TRUE && index < cache_size) {
       
   144         fade = (fade_t*) Malloc(sizeof(fade_t));
       
   145         fade->index = index;
       
   146         fade->quantity = quantity;
       
   147         fade->type = direction;
       
   148 
       
   149 #ifndef _WIN32
       
   150         pthread_create(&thread, NULL, (void *)helper_fade, (void *)fade);
       
   151         pthread_detach(thread);
       
   152 #else
       
   153         Thread = (HANDLE) _beginthread((void *)helper_fade, 0, (void *)fade);
       
   154 #endif
       
   155     }
       
   156 }
       
   157 
       
   158 void openal_setposition (uint32_t index, float x, float y, float z) {
       
   159     if (openal_ready() == AL_TRUE && index < cache_size)
       
   160         alSource3f(Sources[the_sounds[index].source_index], AL_POSITION, x, y, z);;
       
   161 }
       
   162 
       
   163 void helper_fade(void *tmp) {
       
   164     ALfloat gain;
       
   165     ALfloat target_gain;
       
   166     fade_t *fade;
       
   167     uint32_t index;
       
   168     uint16_t quantity;
       
   169     al_fade_t type;
       
   170 
       
   171     fade = tmp;
       
   172     index = fade->index;
       
   173     quantity = fade->quantity;
       
   174     type = fade->type;
       
   175     free (fade);
       
   176 
       
   177     if (type == AL_FADE_IN) {
       
   178 #ifdef DEBUG
       
   179         fprintf(stderr,"(Bridge Info) - Fade-in in progress [index %d quantity %d]", index, quantity);
       
   180 #endif
       
   181 
       
   182         // save the volume desired after the fade
       
   183         alGetSourcef(Sources[the_sounds[index].source_index], AL_GAIN, &target_gain);
       
   184         if (target_gain > 1.0f || target_gain <= 0.0f)
       
   185             target_gain = 1.0f;
       
   186 
       
   187         for (gain = 0.0f ; gain <= target_gain; gain += (float) quantity/10000) {
       
   188 #ifdef TRACE
       
   189             fprintf(stderr,"(Bridge Debug) - Fade-in set gain to %f\n", gain);
       
   190 #endif
       
   191             alSourcef(Sources[the_sounds[index].source_index], AL_GAIN, gain);
       
   192             usleep(10000);
       
   193         }
       
   194     } else {
       
   195         alGetSourcef(Sources[the_sounds[index].source_index], AL_GAIN, &target_gain);
       
   196 
       
   197         for (gain = target_gain; gain >= 0.00f; gain -= (float) quantity/10000) {
       
   198 #ifdef TRACE
       
   199             fprintf(stderr,"(Bridge Debug) - Fade-out set gain to %f\n", gain);
       
   200 #endif
       
   201             alSourcef(Sources[the_sounds[index].source_index], AL_GAIN, gain);
       
   202             usleep(10000);
       
   203         }
       
   204 
       
   205         if (AL_NO_ERROR != alGetError())
       
   206             fprintf(stderr,"(Bridge Warning) - Failed to set fade-out effect\n");
       
   207 
       
   208         // stop that sound and reset its volume
       
   209         alSourceStop (Sources[the_sounds[index].source_index]);
       
   210         alSourcef (Sources[the_sounds[index].source_index], AL_GAIN, target_gain);
       
   211     }
       
   212 
       
   213     if (AL_NO_ERROR != alGetError())
       
   214         fprintf(stderr,"(Bridge Warning) - Failed to set fade effect\n");
       
   215 
       
   216 #ifndef _WIN32
       
   217     pthread_exit(NULL);
       
   218 #else
       
   219     _endthread();
       
   220 #endif
       
   221 }
       
   222