Mercurial > almixer_isolated
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); |