misc/libopenalbridge/commands.c
changeset 3514 59dbd31e9953
parent 3513 f589230fa21b
child 3529 0e968ba12a84
equal deleted inserted replaced
3513:f589230fa21b 3514:59dbd31e9953
       
     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         the_sounds[index].stats++;
       
    97     }
       
    98 }
       
    99 
       
   100 void openal_toggleloop (uint32_t index) {
       
   101     ALint loop;
       
   102 
       
   103     if (openal_ready() == AL_TRUE && index < cache_size) {
       
   104         alGetSourcei (Sources[the_sounds[index].source_index], AL_LOOPING, &loop);
       
   105         alSourcei (Sources[the_sounds[index].source_index], AL_LOOPING, !((uint8_t) loop) & 0x00000001);
       
   106     }
       
   107 }
       
   108 
       
   109 
       
   110 void openal_setvolume (uint32_t index, float gain) {
       
   111     if (openal_ready() == AL_TRUE && index < cache_size)
       
   112         alSourcef (Sources[the_sounds[index].source_index], AL_GAIN, gain);
       
   113 }
       
   114 
       
   115 
       
   116 void openal_setglobalvolume (float gain) {
       
   117     if (openal_ready() == AL_TRUE)
       
   118         alListenerf (AL_GAIN, gain);
       
   119 }
       
   120 
       
   121 void openal_togglemute () {
       
   122     ALfloat gain;
       
   123 
       
   124     if (openal_ready() == AL_TRUE) {
       
   125         alGetListenerf (AL_GAIN, &gain);
       
   126         if (gain > 0) {
       
   127             old_gain = gain;
       
   128             gain = 0;
       
   129         } else
       
   130             gain = old_gain;
       
   131 
       
   132         alListenerf (AL_GAIN, gain);
       
   133     }
       
   134 }
       
   135 
       
   136 // Fade in or out by calling a helper thread
       
   137 void openal_fade (uint32_t index, uint16_t quantity, al_fade_t direction) {
       
   138 #ifndef _WIN32
       
   139     pthread_t thread;
       
   140 #else
       
   141     HANDLE Thread;
       
   142 #endif
       
   143     fade_t *fade;
       
   144 
       
   145     if (openal_ready() == AL_TRUE && index < cache_size) {
       
   146         fade = (fade_t*) Malloc(sizeof(fade_t));
       
   147         fade->index = index;
       
   148         fade->quantity = quantity;
       
   149         fade->type = direction;
       
   150 
       
   151 #ifndef _WIN32
       
   152         pthread_create(&thread, NULL, (void *)helper_fade, (void *)fade);
       
   153         pthread_detach(thread);
       
   154 #else
       
   155         Thread = (HANDLE) _beginthread((void *)helper_fade, 0, (void *)fade);
       
   156 #endif
       
   157     }
       
   158 }
       
   159 
       
   160 void openal_setposition (uint32_t index, float x, float y, float z) {
       
   161     if (openal_ready() == AL_TRUE && index < cache_size)
       
   162         alSource3f(Sources[the_sounds[index].source_index], AL_POSITION, x, y, z);;
       
   163 }
       
   164 
       
   165 void helper_fade(void *tmp) {
       
   166     ALfloat gain;
       
   167     ALfloat target_gain;
       
   168     fade_t *fade;
       
   169     uint32_t index;
       
   170     uint16_t quantity;
       
   171     al_fade_t type;
       
   172 
       
   173     fade = tmp;
       
   174     index = fade->index;
       
   175     quantity = fade->quantity;
       
   176     type = fade->type;
       
   177     free (fade);
       
   178 
       
   179     if (type == AL_FADE_IN) {
       
   180 #ifdef DEBUG
       
   181         fprintf(stderr,"(Bridge Info) - Fade-in in progress [index %d quantity %d]", index, quantity);
       
   182 #endif
       
   183 
       
   184         // save the volume desired after the fade
       
   185         alGetSourcef(Sources[the_sounds[index].source_index], AL_GAIN, &target_gain);
       
   186         if (target_gain > 1.0f || target_gain <= 0.0f)
       
   187             target_gain = 1.0f;
       
   188 
       
   189         for (gain = 0.0f ; gain <= target_gain; gain += (float) quantity/10000) {
       
   190 #ifdef TRACE
       
   191             fprintf(stderr,"(Bridge Debug) - Fade-in set gain to %f\n", gain);
       
   192 #endif
       
   193             alSourcef(Sources[the_sounds[index].source_index], AL_GAIN, gain);
       
   194             usleep(10000);
       
   195         }
       
   196     } else {
       
   197         alGetSourcef(Sources[the_sounds[index].source_index], AL_GAIN, &target_gain);
       
   198 
       
   199         for (gain = target_gain; gain >= 0.00f; gain -= (float) quantity/10000) {
       
   200 #ifdef TRACE
       
   201             fprintf(stderr,"(Bridge Debug) - Fade-out set gain to %f\n", gain);
       
   202 #endif
       
   203             alSourcef(Sources[the_sounds[index].source_index], AL_GAIN, gain);
       
   204             usleep(10000);
       
   205         }
       
   206 
       
   207         if (AL_NO_ERROR != alGetError())
       
   208             fprintf(stderr,"(Bridge Warning) - Failed to set fade-out effect\n");
       
   209 
       
   210         // stop that sound and reset its volume
       
   211         alSourceStop (Sources[the_sounds[index].source_index]);
       
   212         alSourcef (Sources[the_sounds[index].source_index], AL_GAIN, target_gain);
       
   213     }
       
   214 
       
   215     if (AL_NO_ERROR != alGetError())
       
   216         fprintf(stderr,"(Bridge Warning) - Failed to set fade effect\n");
       
   217 
       
   218 #ifndef _WIN32
       
   219     pthread_exit(NULL);
       
   220 #else
       
   221     _endthread();
       
   222 #endif
       
   223 }
       
   224