comparison ALmixer.c @ 20:9365e714fc4b

Added SeekChannel, SeekSource. Fixed a return value bug in RewindSource.
author Eric Wing <ewing@anscamobile.com>
date Mon, 08 Nov 2010 22:19:47 -0800
parents 038baa026db3
children 46e82b415520
comparison
equal deleted inserted replaced
19:a8d96c934e77 20:9365e714fc4b
2328 static ALint Internal_RewindSource(ALuint source) 2328 static ALint Internal_RewindSource(ALuint source)
2329 { 2329 {
2330 ALint channel; 2330 ALint channel;
2331 if(0 == source) 2331 if(0 == source)
2332 { 2332 {
2333 return Internal_RewindChannel(-1) + 1; 2333 return Internal_RewindChannel(-1);
2334 } 2334 }
2335 2335
2336 channel = Internal_GetChannel(source); 2336 channel = Internal_GetChannel(source);
2337 if(-1 == channel) 2337 if(-1 == channel)
2338 { 2338 {
2339 ALmixer_SetError("Cannot rewind source: %s", ALmixer_GetError()); 2339 ALmixer_SetError("Cannot rewind source: %s", ALmixer_GetError());
2340 return 0; 2340 return 0;
2341 } 2341 }
2342 return Internal_RewindChannel(channel) + 1; 2342 return Internal_RewindChannel(channel);
2343 } 2343 }
2344 2344
2345 2345
2346 2346
2347 2347
3218 3218
3219 return AL_TRUE; 3219 return AL_TRUE;
3220 } 3220 }
3221 3221
3222 3222
3223 static ALint Internal_SeekChannel(ALint channel, ALuint msec)
3224 {
3225 ALint retval = 0;
3226 ALenum error;
3227 ALint state;
3228 ALint running_count = 0;
3229
3230 if(0 == msec)
3231 {
3232 return Internal_RewindChannel(channel);
3233 }
3234
3235 if(channel >= Number_of_Channels_global)
3236 {
3237 ALmixer_SetError("Cannot seek channel %d because it exceeds maximum number of channels (%d)\n", channel, Number_of_Channels_global);
3238 return -1;
3239 }
3240
3241 if((error = alGetError()) != AL_NO_ERROR)
3242 {
3243 fprintf(stderr, "24Testing error: %s\n",
3244 alGetString(error));
3245 }
3246 /* Clear error */
3247 alGetError();
3248
3249 /* If the user specified a specific channel */
3250 if(channel >= 0)
3251 {
3252 /* only need to process channel if in use */
3253 if(ALmixer_Channel_List[channel].channel_in_use)
3254 {
3255
3256 /* What should I do? Do I just rewind the channel
3257 * or also rewind the data? Since the data is
3258 * shared, let's make it the user's responsibility
3259 * to rewind the data.
3260 */
3261 if(ALmixer_Channel_List[channel].almixer_data->decoded_all)
3262 {
3263 /* convert milliseconds to seconds */
3264 ALfloat sec_offset = msec / 1000.0f;
3265
3266 alGetSourcei(
3267 ALmixer_Channel_List[channel].alsource,
3268 AL_SOURCE_STATE, &state
3269 );
3270 if((error = alGetError()) != AL_NO_ERROR)
3271 {
3272 fprintf(stderr, "25Testing error: %s\n",
3273 alGetString(error));
3274 }
3275 /* OpenAL seek */
3276 alSourcef(ALmixer_Channel_List[channel].alsource, AL_SEC_OFFSET, sec_offset);
3277 if((error = alGetError()) != AL_NO_ERROR)
3278 {
3279 ALmixer_SetError("%s",
3280 alGetString(error) );
3281 retval = -1;
3282 }
3283 /* Need to resume playback if it was originally playing */
3284 if(AL_PLAYING == state)
3285 {
3286 alSourcePlay(ALmixer_Channel_List[channel].alsource);
3287 if((error = alGetError()) != AL_NO_ERROR)
3288 {
3289 ALmixer_SetError("%s",
3290 alGetString(error) );
3291 retval = -1;
3292 }
3293 }
3294 else if(AL_PAUSED == state)
3295 {
3296 /* HACK: The problem is that when paused, after
3297 * the Rewind, I can't get it off the INITIAL
3298 * state without restarting
3299 */
3300 alSourcePlay(ALmixer_Channel_List[channel].alsource);
3301 if((error = alGetError()) != AL_NO_ERROR)
3302 {
3303 fprintf(stderr, "25Testing error: %s\n",
3304 alGetString(error));
3305 }
3306 alSourcePause(ALmixer_Channel_List[channel].alsource);
3307 if((error = alGetError()) != AL_NO_ERROR)
3308 {
3309 ALmixer_SetError("%s",
3310 alGetString(error) );
3311 retval = -1;
3312 }
3313 }
3314 }
3315 else
3316 {
3317 /* Streamed data is different. Rewinding the channel
3318 * does no good. Rewinding the data will have an
3319 * effect, but it will be lagged based on how
3320 * much data is queued. Recommend users call Halt
3321 * before rewind if they want immediate results.
3322 */
3323 retval = Internal_SeekData(ALmixer_Channel_List[channel].almixer_data, msec);
3324 }
3325 }
3326 }
3327 /* The user wants to rewind all channels */
3328 else
3329 {
3330 ALint i;
3331 ALfloat sec_offset = msec / 1000.0f;
3332
3333 for(i=0; i<Number_of_Channels_global; i++)
3334 {
3335 /* only need to process channel if in use */
3336 if(ALmixer_Channel_List[i].channel_in_use)
3337 {
3338 /* What should I do? Do I just rewind the channel
3339 * or also rewind the data? Since the data is
3340 * shared, let's make it the user's responsibility
3341 * to rewind the data.
3342 */
3343 if(ALmixer_Channel_List[i].almixer_data->decoded_all)
3344 {
3345 alGetSourcei(
3346 ALmixer_Channel_List[i].alsource,
3347 AL_SOURCE_STATE, &state
3348 );
3349 if((error = alGetError()) != AL_NO_ERROR)
3350 {
3351 fprintf(stderr, "26Testing error: %s\n",
3352 alGetString(error));
3353 }
3354
3355 alSourcef(ALmixer_Channel_List[channel].alsource, AL_SEC_OFFSET, sec_offset);
3356 if((error = alGetError()) != AL_NO_ERROR)
3357 {
3358 ALmixer_SetError("%s",
3359 alGetString(error) );
3360 retval = -1;
3361 }
3362 /* Need to resume playback if it was originally playing */
3363 if(AL_PLAYING == state)
3364 {
3365 alSourcePlay(ALmixer_Channel_List[i].alsource);
3366 if((error = alGetError()) != AL_NO_ERROR)
3367 {
3368 ALmixer_SetError("%s",
3369 alGetString(error) );
3370 retval = -1;
3371 }
3372 }
3373 else if(AL_PAUSED == state)
3374 {
3375 /* HACK: The problem is that when paused, after
3376 * the Rewind, I can't get it off the INITIAL
3377 * state without restarting
3378 */
3379 alSourcePlay(ALmixer_Channel_List[i].alsource);
3380 if((error = alGetError()) != AL_NO_ERROR)
3381 {
3382 fprintf(stderr, "27Testing error: %s\n",
3383 alGetString(error));
3384 }
3385 alSourcePause(ALmixer_Channel_List[i].alsource);
3386 if((error = alGetError()) != AL_NO_ERROR)
3387 {
3388 ALmixer_SetError("%s",
3389 alGetString(error) );
3390 retval = -1;
3391 }
3392 }
3393 }
3394 else
3395 {
3396 /* Streamed data is different. Rewinding the channel
3397 * does no good. Rewinding the data will have an
3398 * effect, but it will be lagged based on how
3399 * much data is queued. Recommend users call Halt
3400 * before rewind if they want immediate results.
3401 */
3402 running_count += Internal_SeekData(ALmixer_Channel_List[i].almixer_data, msec);
3403 }
3404 }
3405 }
3406 }
3407 if(-1 == retval)
3408 {
3409 return -1;
3410 }
3411 else
3412 {
3413 return running_count;
3414 }
3415
3416 }
3417
3418 static ALint Internal_SeekSource(ALuint source, ALuint msec)
3419 {
3420 ALint channel;
3421 if(0 == source)
3422 {
3423 return Internal_SeekChannel(-1, msec);
3424 }
3425
3426 channel = Internal_GetChannel(source);
3427 if(-1 == channel)
3428 {
3429 ALmixer_SetError("Cannot seek source: %s", ALmixer_GetError());
3430 return 0;
3431 }
3432 return Internal_SeekChannel(channel, msec);
3433 }
3434
3435
3223 3436
3224 static ALint Internal_FadeInChannelTimed(ALint channel, ALmixer_Data* data, ALint loops, ALuint fade_ticks, ALint expire_ticks) 3437 static ALint Internal_FadeInChannelTimed(ALint channel, ALmixer_Data* data, ALint loops, ALuint fade_ticks, ALint expire_ticks)
3225 { 3438 {
3226 ALfloat value; 3439 ALfloat value;
3227 ALenum error; 3440 ALenum error;
4699 */ 4912 */
4700 delta_time = current_time - ALmixer_Channel_List[i].fade_start_time; 4913 delta_time = current_time - ALmixer_Channel_List[i].fade_start_time;
4701 t = (ALfloat) delta_time * ALmixer_Channel_List[i].fade_inv_time; 4914 t = (ALfloat) delta_time * ALmixer_Channel_List[i].fade_inv_time;
4702 current_volume = (1.0f-t) * ALmixer_Channel_List[i].fade_start_volume 4915 current_volume = (1.0f-t) * ALmixer_Channel_List[i].fade_start_volume
4703 + t * ALmixer_Channel_List[i].fade_end_volume; 4916 + t * ALmixer_Channel_List[i].fade_end_volume;
4917 /*
4704 fprintf(stderr, "start_vol=%f, end_vol:%f, current_volume: %f\n", ALmixer_Channel_List[i].fade_start_volume, ALmixer_Channel_List[i].fade_end_volume, current_volume); 4918 fprintf(stderr, "start_vol=%f, end_vol:%f, current_volume: %f\n", ALmixer_Channel_List[i].fade_start_volume, ALmixer_Channel_List[i].fade_end_volume, current_volume);
4705 4919 */
4706 /* Set the volume */ 4920 /* Set the volume */
4707 alSourcef(ALmixer_Channel_List[i].alsource, 4921 alSourcef(ALmixer_Channel_List[i].alsource,
4708 AL_GAIN, current_volume); 4922 AL_GAIN, current_volume);
4709 if((error = alGetError()) != AL_NO_ERROR) 4923 if((error = alGetError()) != AL_NO_ERROR)
4710 { 4924 {
8500 SDL_UnlockMutex(s_simpleLock); 8714 SDL_UnlockMutex(s_simpleLock);
8501 #endif 8715 #endif
8502 return retval; 8716 return retval;
8503 } 8717 }
8504 8718
8719 ALint ALmixer_SeekChannel(ALint channel, ALuint msec)
8720 {
8721 ALint retval;
8722 #ifdef ENABLE_ALMIXER_THREADS
8723 SDL_LockMutex(s_simpleLock);
8724 #endif
8725 retval = Internal_SeekChannel(channel, msec);
8726 #ifdef ENABLE_ALMIXER_THREADS
8727 SDL_UnlockMutex(s_simpleLock);
8728 #endif
8729 return retval;
8730 }
8731
8732 ALint ALmixer_SeekSource(ALuint source, ALuint msec)
8733 {
8734 ALint retval;
8735 #ifdef ENABLE_ALMIXER_THREADS
8736 SDL_LockMutex(s_simpleLock);
8737 #endif
8738 retval = Internal_SeekSource(source, msec);
8739 #ifdef ENABLE_ALMIXER_THREADS
8740 SDL_UnlockMutex(s_simpleLock);
8741 #endif
8742 return retval;
8743 }
8744
8505 ALint ALmixer_FadeInChannelTimed(ALint channel, ALmixer_Data* data, ALint loops, ALuint fade_ticks, ALint expire_ticks) 8745 ALint ALmixer_FadeInChannelTimed(ALint channel, ALmixer_Data* data, ALint loops, ALuint fade_ticks, ALint expire_ticks)
8506 { 8746 {
8507 ALint retval; 8747 ALint retval;
8508 #ifdef ENABLE_ALMIXER_THREADS 8748 #ifdef ENABLE_ALMIXER_THREADS
8509 SDL_LockMutex(s_simpleLock); 8749 SDL_LockMutex(s_simpleLock);