📄 sdl_audio.c
字号:
#if 0 /* Don't fail SDL_Init() if audio isn't available. SDL_OpenAudio() will handle it at that point. *sigh* */ return(-1);#endif } } current_audio = audio; if ( current_audio ) { current_audio->name = bootstrap[i]->name; if ( !current_audio->LockAudio && !current_audio->UnlockAudio ) { current_audio->LockAudio = SDL_LockAudio_Default; current_audio->UnlockAudio = SDL_UnlockAudio_Default; } } return(0);}char *Our_SDL_AudioDriverName(char *namebuf, int maxlen){ if ( current_audio != NULL ) { strncpy(namebuf, current_audio->name, maxlen-1); namebuf[maxlen-1] = '\0'; return(namebuf); } return(NULL);}int Our_SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained){ SDL_AudioDevice *audio; /* Start up the audio driver, if necessary */ if ( ! current_audio ) { if ((Our_SDL_AudioInit(getenv("SDL_AUDIODRIVER")) < 0) || (current_audio == NULL) ) { return(-1); } } audio = current_audio; if (audio->opened) { SDL_SetError("Audio device is already opened"); return(-1); } /* Verify some parameters */ if ( desired->callback == NULL ) { SDL_SetError("SDL_OpenAudio() passed a NULL callback"); return(-1); } switch ( desired->channels ) { case 1: /* Mono */ case 2: /* Stereo */ case 4: /* surround */ case 6: /* surround */ break; default: SDL_SetError("1 (mono) and 2 (stereo) channels supported"); return(-1); }#if defined(macintosh) || (defined(__riscos__) && !defined(DISABLE_THREADS)) /* FIXME: Need to implement PPC interrupt asm for SDL_LockAudio() */#else#if defined(__MINT__) && !defined(ENABLE_THREADS) /* Uses interrupt driven audio, without thread */#else /* Create a semaphore for locking the sound buffers */ audio->mixer_lock = SDL_CreateMutex(); if ( audio->mixer_lock == NULL ) { SDL_SetError("Couldn't create mixer lock"); Our_SDL_CloseAudio(); return(-1); }#endif /* __MINT__ */#endif /* macintosh */ /* Calculate the silence and size of the audio specification */ SDL_CalculateAudioSpec(desired); /* Open the audio subsystem */ memcpy(&audio->spec, desired, sizeof(audio->spec)); audio->convert.needed = 0; audio->enabled = 1; audio->paused = 1;#ifndef ENABLE_AHI/* AmigaOS opens audio inside the main loop */ audio->opened = audio->OpenAudio(audio, &audio->spec)+1; if ( ! audio->opened ) { SDL_CloseAudio(); return(-1); }#else D(bug("Locking semaphore...")); SDL_mutexP(audio->mixer_lock); audio->thread = SDL_CreateThread(SDL_RunAudio, audio); D(bug("Created thread...\n")); if ( audio->thread == NULL ) { SDL_mutexV(audio->mixer_lock); Our_SDL_CloseAudio(); SDL_SetError("Couldn't create audio thread"); return(-1); } while(!audio_configured) SDL_Delay(100);#endif /* If the audio driver changes the buffer size, accept it */ if ( audio->spec.samples != desired->samples ) { desired->samples = audio->spec.samples; SDL_CalculateAudioSpec(desired); } /* Allocate a fake audio memory buffer */ audio->fake_stream = SDL_AllocAudioMem(audio->spec.size); if ( audio->fake_stream == NULL ) { Our_SDL_CloseAudio(); SDL_OutOfMemory(); return(-1); } /* See if we need to do any conversion */ if ( obtained != NULL ) { memcpy(obtained, &audio->spec, sizeof(audio->spec)); } else if ( desired->freq != audio->spec.freq || desired->format != audio->spec.format || desired->channels != audio->spec.channels ) { // wmay if (desired->format == AUDIO_FORMAT_HW_AC3) { return -1; } /* Build an audio conversion block */ if ( SDL_BuildAudioCVT(&audio->convert, desired->format, desired->channels, desired->freq, audio->spec.format, audio->spec.channels, audio->spec.freq) < 0 ) { Our_SDL_CloseAudio(); return(-1); } if ( audio->convert.needed ) { audio->convert.len = desired->size; audio->convert.buf =(Uint8 *)SDL_AllocAudioMem( audio->convert.len*audio->convert.len_mult); if ( audio->convert.buf == NULL ) { Our_SDL_CloseAudio(); SDL_OutOfMemory(); return(-1); } } }#ifndef ENABLE_AHI /* Start the audio thread if necessary */ switch (audio->opened) { case 1: /* Start the audio thread */ audio->thread = SDL_CreateThread(SDL_RunAudio, audio); if ( audio->thread == NULL ) { Our_SDL_CloseAudio(); SDL_SetError("Couldn't create audio thread"); return(-1); } break; default: /* The audio is now playing */ break; }#else SDL_mutexV(audio->mixer_lock); D(bug("SDL_OpenAudio USCITA...\n"));#endif return(0);}SDL_audiostatus Our_SDL_GetAudioStatus(void){ SDL_AudioDevice *audio = current_audio; SDL_audiostatus status; status = SDL_AUDIO_STOPPED; if ( audio && audio->enabled ) { if ( audio->paused ) { status = SDL_AUDIO_PAUSED; } else { status = SDL_AUDIO_PLAYING; } } return(status);}void Our_SDL_PauseAudio (int pause_on){ SDL_AudioDevice *audio = current_audio; if ( audio ) { audio->paused = pause_on; }}void Our_SDL_LockAudio (void){ SDL_AudioDevice *audio = current_audio; /* Obtain a lock on the mixing buffers */ if ( audio && audio->LockAudio ) { audio->LockAudio(audio); }}void Our_SDL_UnlockAudio (void){ SDL_AudioDevice *audio = current_audio; /* Release lock on the mixing buffers */ if ( audio && audio->UnlockAudio ) { audio->UnlockAudio(audio); }}void Our_SDL_CloseAudio (void){ Our_SDL_AudioQuit();}int Our_SDL_HasAudioDelay (void){ SDL_AudioDevice *audio = current_audio; if (audio && audio->AudioDelay != NULL) { return 1; } return 0;}int Our_SDL_AudioDelay (void){ SDL_AudioDevice *audio = current_audio; if (audio && audio->AudioDelay != NULL) { return (audio->AudioDelay(audio)); } else { return (-1); }}void Our_SDL_AudioQuit(void){ SDL_AudioDevice *audio = current_audio; if ( audio ) { audio->enabled = 0; if ( audio->thread != NULL ) { SDL_WaitThread(audio->thread, NULL); } if ( audio->mixer_lock != NULL ) { SDL_DestroyMutex(audio->mixer_lock); } if ( audio->fake_stream != NULL ) { SDL_FreeAudioMem(audio->fake_stream); } if ( audio->convert.needed ) { SDL_FreeAudioMem(audio->convert.buf); }#ifndef ENABLE_AHI if ( audio->opened ) { audio->CloseAudio(audio); audio->opened = 0; }#endif /* Free the driver data */ if (audio->free) audio->free(audio); current_audio = NULL; }}#define NUM_FORMATS 6static int format_idx;static int format_idx_sub;static Uint16 format_list[NUM_FORMATS][NUM_FORMATS] = { { AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB }, { AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB }, { AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8 }, { AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8 }, { AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U8, AUDIO_S8 }, { AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U8, AUDIO_S8 },};Uint16 SDL_FirstAudioFormat(Uint16 format){ for ( format_idx=0; format_idx < NUM_FORMATS; ++format_idx ) { if ( format_list[format_idx][0] == format ) { break; } } format_idx_sub = 0; return(SDL_NextAudioFormat());}Uint16 SDL_NextAudioFormat(void){ if ( (format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS) ) { return(0); } return(format_list[format_idx][format_idx_sub++]);}void SDL_CalculateAudioSpec(SDL_AudioSpec *spec){ switch (spec->format) { case AUDIO_U8: spec->silence = 0x80; break; default: spec->silence = 0x00; break; } if (spec->format == AUDIO_FORMAT_HW_AC3) { spec->size = 256 * 6 * 2 * 2; } else { spec->size = (spec->format&0xFF)/8; spec->size *= spec->channels; spec->size *= spec->samples; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -