X-Git-Url: http://deadsoftware.ru/gitweb?p=d2df-sdl.git;a=blobdiff_plain;f=src%2Fengine%2Fe_sound_sdl.inc;h=f71805ef50324de7d8d9b171871d7a783605753a;hp=0104f3a3eca925907ba1ea2cbc9f68dafe6d3364;hb=59b0e5dfe65548c5fa24cc64136417c37b495573;hpb=0968d19494ddf24230a822c02acbe3a3334bc3ad diff --git a/src/engine/e_sound_sdl.inc b/src/engine/e_sound_sdl.inc index 0104f3a..f71805e 100644 --- a/src/engine/e_sound_sdl.inc +++ b/src/engine/e_sound_sdl.inc @@ -1,10 +1,31 @@ +(* Copyright (C) Doom 2D: Forever Developers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License ONLY. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *) interface uses - sdl2, - SDL2_mixer, - e_log, - SysUtils; + {$IFDEF USE_MEMPOOL}mempool,{$ENDIF} + {$IFDEF USE_SDL} + SDL, SDL_mixer, + {$DEFINE SDL1MIXER} + {$UNDEF SDL2MIXER} + {$ELSE} + SDL2, SDL2_mixer, + {$UNDEF SDL1MIXER} + {$DEFINE SDL2MIXER} + {$ENDIF} + envvars, e_log, SysUtils; type TSoundRec = record @@ -12,10 +33,11 @@ type Sound: PMix_Chunk; Music: PMix_Music; isMusic: Boolean; + Loops: Boolean; nRefs: Integer; end; - TBasicSound = class (TObject) + TBasicSound = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF} private FChanNum: Integer; // <0: no channel allocated @@ -55,8 +77,8 @@ const function e_InitSoundSystem(NoOutput: Boolean = False): Boolean; -function e_LoadSound(FileName: string; var ID: DWORD; isMusic: Boolean): Boolean; -function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; isMusic: Boolean): Boolean; +function e_LoadSound(FileName: string; var ID: DWORD; isMusic: Boolean; ForceNoLoop: Boolean = False): Boolean; +function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; isMusic: Boolean; ForceNoLoop: Boolean = False): Boolean; // returns channel number or -1 function e_PlaySound(ID: DWORD): Integer; @@ -76,10 +98,12 @@ procedure e_SoundUpdate(); var e_SoundsArray: array of TSoundRec = nil; + e_TimidityDecoder: Boolean; (* sdl_mixer special *) + implementation uses - g_window, g_options, BinEditor; + g_window, g_options; const N_CHANNELS = 512; @@ -102,7 +126,7 @@ var procedure chanFinished (chan: Integer); cdecl; begin - //e_WriteLog(Format('chanFinished: %d', [chan]), MSG_NOTIFY); + //e_WriteLog(Format('chanFinished: %d', [chan]), TMsgType.Notify); if (chan >= 0) and (chan < N_CHANNELS) then begin if ChanSIds[chan].id <> NO_SOUND_ID then @@ -121,33 +145,33 @@ procedure dumpMusicType (ms: PMix_Music); begin if ms = nil then begin - e_WriteLog('MUSIC FORMAT: NONE', MSG_NOTIFY); + e_WriteLog('MUSIC FORMAT: NONE', TMsgType.Notify); end else begin case Mix_GetMusicType(ms^) of TMix_MusicType.MUS_NONE: - e_WriteLog('MUSIC FORMAT: NONE', MSG_NOTIFY); + e_WriteLog('MUSIC FORMAT: NONE', TMsgType.Notify); TMix_MusicType.MUS_CMD: - e_WriteLog('MUSIC FORMAT: CMD', MSG_NOTIFY); + e_WriteLog('MUSIC FORMAT: CMD', TMsgType.Notify); TMix_MusicType.MUS_WAV: - e_WriteLog('MUSIC FORMAT: WAV', MSG_NOTIFY); + e_WriteLog('MUSIC FORMAT: WAV', TMsgType.Notify); TMix_MusicType.MUS_MOD: - e_WriteLog('MUSIC FORMAT: MOD', MSG_NOTIFY); + e_WriteLog('MUSIC FORMAT: MOD', TMsgType.Notify); TMix_MusicType.MUS_MID: - e_WriteLog('MUSIC FORMAT: MID', MSG_NOTIFY); + e_WriteLog('MUSIC FORMAT: MID', TMsgType.Notify); TMix_MusicType.MUS_OGG: - e_WriteLog('MUSIC FORMAT: OGG', MSG_NOTIFY); + e_WriteLog('MUSIC FORMAT: OGG', TMsgType.Notify); TMix_MusicType.MUS_MP3: - e_WriteLog('MUSIC FORMAT: MP3', MSG_NOTIFY); + e_WriteLog('MUSIC FORMAT: MP3', TMsgType.Notify); TMix_MusicType.MUS_MP3_MAD: - e_WriteLog('MUSIC FORMAT: MP3_MAD', MSG_NOTIFY); + e_WriteLog('MUSIC FORMAT: MP3_MAD', TMsgType.Notify); TMix_MusicType.MUS_FLAC: - e_WriteLog('MUSIC FORMAT: FLAC', MSG_NOTIFY); + e_WriteLog('MUSIC FORMAT: FLAC', TMsgType.Notify); TMix_MusicType.MUS_MODPLUG: - e_WriteLog('MUSIC FORMAT: MODPLUG', MSG_NOTIFY); + e_WriteLog('MUSIC FORMAT: MODPLUG', TMsgType.Notify); otherwise - e_WriteLog('MUSIC FORMAT: UNKNOWN', MSG_NOTIFY); + e_WriteLog('MUSIC FORMAT: UNKNOWN', TMsgType.Notify); end; end; end; @@ -158,46 +182,63 @@ var rfreq: Integer; rformat: UInt16; rchans: Integer; + flags: Integer; begin if SoundInitialized then begin Result := true; Exit end; Result := False; SoundInitialized := False; - + + {$IFDEF HEADLESS} + // HACK: shit this into env and hope for the best + SetEnvVar('SDL_AUDIODRIVER', 'dummy'); + {$ENDIF} + if NoOutput then begin Result := true; Exit end; // wow, this is actually MIDI player! // we need module player - res := Mix_Init(MIX_INIT_FLAC or MIX_INIT_MOD or MIX_INIT_MODPLUG or MIX_INIT_MP3 or MIX_INIT_OGG or MIX_INIT_FLUIDSYNTH); - e_WriteLog(Format('SDL: res=0x%x', [res]), MSG_NOTIFY); - if (res and MIX_INIT_FLAC) <> 0 then e_WriteLog('SDL: FLAC playback is active', MSG_NOTIFY); - if (res and MIX_INIT_MOD) <> 0 then e_WriteLog('SDL: MOD playback is active', MSG_NOTIFY); - if (res and MIX_INIT_MODPLUG) <> 0 then e_WriteLog('SDL: MODPLUG playback is active', MSG_NOTIFY); - if (res and MIX_INIT_MP3) <> 0 then e_WriteLog('SDL: MP3 playback is active', MSG_NOTIFY); - if (res and MIX_INIT_OGG) <> 0 then e_WriteLog('SDL: OGG playback is active', MSG_NOTIFY); - if (res and MIX_INIT_FLUIDSYNTH) <> 0 then e_WriteLog('SDL: FLUIDSYNTH playback is active', MSG_NOTIFY); - - e_WriteLog(Format('SDL: initializing mixer at %d with buffer %d', [gsSDLSampleRate, gsSDLBufferSize]), MSG_NOTIFY); - res := Mix_OpenAudio(gsSDLSampleRate, AUDIO_S16LSB, 2, gsSDLBufferSize); + flags := MIX_INIT_FLAC or MIX_INIT_MOD or MIX_INIT_MP3 or MIX_INIT_OGG or MIX_INIT_FLUIDSYNTH; + {$IFDEF SDL2MIXER} + flags := flags or MIX_INIT_MODPLUG; + {$ENDIF} + res := Mix_Init(flags); + e_WriteLog(Format('SDL: res=0x%x', [res]), TMsgType.Notify); + if (res and MIX_INIT_FLAC) <> 0 then e_WriteLog('SDL: FLAC playback is active', TMsgType.Notify); + if (res and MIX_INIT_MOD) <> 0 then e_WriteLog('SDL: MOD playback is active', TMsgType.Notify); + {$IFDEF SDL2MIXER} + if (res and MIX_INIT_MODPLUG) <> 0 then e_WriteLog('SDL: MODPLUG playback is active', TMsgType.Notify); + {$ENDIF} + if (res and MIX_INIT_MP3) <> 0 then e_WriteLog('SDL: MP3 playback is active', TMsgType.Notify); + if (res and MIX_INIT_OGG) <> 0 then e_WriteLog('SDL: OGG playback is active', TMsgType.Notify); + if (res and MIX_INIT_FLUIDSYNTH) <> 0 then e_WriteLog('SDL: FLUIDSYNTH playback is active', TMsgType.Notify); + + e_WriteLog(Format('SDL: initializing mixer at %d with buffer %d', [gsSDLSampleRate, gsSDLBufferSize]), TMsgType.Notify); + res := Mix_OpenAudio(gsSDLSampleRate, MIX_DEFAULT_FORMAT, 2, gsSDLBufferSize); if res = -1 then begin - e_WriteLog('Error initializing SDL mixer:', MSG_FATALERROR); - e_WriteLog(Mix_GetError(), MSG_FATALERROR); + e_WriteLog('Error initializing SDL mixer:', TMsgType.Fatal); + e_WriteLog(Mix_GetError(), TMsgType.Fatal); Exit; end; if Mix_QuerySpec(@rfreq, @rformat, @rchans) > 0 then begin - e_WriteLog(Format('SDL: frequency=%d; format=%u; channels=%d', [rfreq, rformat, rchans]), MSG_NOTIFY); + e_WriteLog(Format('SDL: frequency=%d; format=%u; channels=%d', [rfreq, rformat, rchans]), TMsgType.Notify); end; for i := 0 to Mix_GetNumChunkDecoders()-1 do begin - e_WriteLog(Format('SDL: chunk decoder %s is avalable', [Mix_GetChunkDecoder(i)]), MSG_NOTIFY); + e_WriteLog(Format('SDL: chunk decoder %s is avalable', [Mix_GetChunkDecoder(i)]), TMsgType.Notify); end; + + e_TimidityDecoder := false; for i := 0 to Mix_GetNumMusicDecoders()-1 do begin - e_WriteLog(Format('SDL: music decoder %s is avalable', [Mix_GetMusicDecoder(i)]), MSG_NOTIFY); + case AnsiString(Mix_GetMusicDecoder(i)) of + 'TIMIDITY': e_TimidityDecoder := true; + end; + e_WriteLog(Format('SDL: music decoder %s is avalable', [Mix_GetMusicDecoder(i)]), TMsgType.Notify); end; Mix_AllocateChannels(N_CHANNELS); @@ -267,7 +308,7 @@ begin end; end; -function e_LoadSound(FileName: String; var ID: DWORD; isMusic: Boolean): Boolean; +function e_LoadSound(FileName: String; var ID: DWORD; isMusic: Boolean; ForceNoLoop: Boolean = False): Boolean; var find_id: DWORD; begin @@ -275,13 +316,13 @@ begin Result := False; if not SoundInitialized then Exit; - if isMusic then e_WriteLog('Loading music '+FileName+'...', MSG_NOTIFY) - else e_WriteLog('Loading sound '+FileName+'...', MSG_NOTIFY); + if isMusic then e_WriteLog('Loading music '+FileName+'...', TMsgType.Notify) + else e_WriteLog('Loading sound '+FileName+'...', TMsgType.Notify); { if isMusic then begin - e_WriteLog('IGNORING MUSIC FROM FILE', MSG_WARNING); + e_WriteLog('IGNORING MUSIC FROM FILE', TMsgType.Warning); Exit; end; } @@ -290,16 +331,17 @@ begin e_SoundsArray[find_id].Data := nil; e_SoundsArray[find_id].isMusic := isMusic; + e_SoundsArray[find_id].Loops := isMusic and not ForceNoLoop; e_SoundsArray[find_id].nRefs := 0; if isMusic then begin - e_WriteLog(Format(' MUSIC SLOT: %u', [find_id]), MSG_NOTIFY); + e_WriteLog(Format(' MUSIC SLOT: %u', [find_id]), TMsgType.Notify); e_SoundsArray[find_id].Music := Mix_LoadMUS(PAnsiChar(FileName)); if e_SoundsArray[find_id].Music = nil then begin - e_WriteLog(Format('ERROR LOADING MUSIC:', [find_id]), MSG_WARNING); - e_WriteLog(Mix_GetError(), MSG_WARNING); + e_WriteLog(Format('ERROR LOADING MUSIC:', [find_id]), TMsgType.Warning); + e_WriteLog(Mix_GetError(), TMsgType.Warning); Exit; end; dumpMusicType(e_SoundsArray[find_id].Music); @@ -315,7 +357,7 @@ begin Result := True; end; -function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; isMusic: Boolean): Boolean; +function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; isMusic: Boolean; ForceNoLoop: Boolean = False): Boolean; var find_id: DWORD; rw: PSDL_RWops; @@ -330,7 +372,7 @@ begin { if isMusic then begin - e_WriteLog('IGNORING MUSIC FROM MEMORY', MSG_WARNING); + e_WriteLog('IGNORING MUSIC FROM MEMORY', TMsgType.Warning); Exit; end; } @@ -344,7 +386,7 @@ begin Inc(pc, $400); pData := Pointer(pc); Dec(Length, $400); - e_WriteLog('MUSIC: MP3 ID3 WORKAROUND APPLIED!', MSG_WARNING); + e_WriteLog('MUSIC: MP3 ID3 WORKAROUND APPLIED!', TMsgType.Warning); end; } @@ -356,16 +398,21 @@ begin e_SoundsArray[find_id].Data := pData; if isid3 then e_SoundsArray[find_id].Data := nil; e_SoundsArray[find_id].isMusic := isMusic; + e_SoundsArray[find_id].Loops := isMusic and not ForceNoLoop; e_SoundsArray[find_id].nRefs := 0; if isMusic then begin - e_WriteLog(Format(' MUSIC SLOT: %u', [find_id]), MSG_NOTIFY); - e_SoundsArray[find_id].Music := Mix_LoadMUS_RW(rw, 0); + e_WriteLog(Format(' MUSIC SLOT: %u', [find_id]), TMsgType.Notify); + {$IFDEF SDL1MIXER} + e_SoundsArray[find_id].Music := Mix_LoadMUS_RW(rw); + {$ELSE} + e_SoundsArray[find_id].Music := Mix_LoadMUS_RW(rw, 0); + {$ENDIF} if e_SoundsArray[find_id].Music = nil then begin - e_WriteLog(Format('ERROR LOADING MUSIC:', [find_id]), MSG_WARNING); - e_WriteLog(Mix_GetError(), MSG_WARNING); + e_WriteLog(Format('ERROR LOADING MUSIC:', [find_id]), TMsgType.Warning); + e_WriteLog(Mix_GetError(), TMsgType.Warning); end else begin @@ -400,6 +447,7 @@ end; function e_PlaySound (ID: DWORD): Integer; var res: Integer = -1; + loops: Integer = 0; begin Result := -1; if not SoundInitialized then Exit; @@ -408,7 +456,8 @@ begin begin if e_SoundsArray[ID].nRefs >= gMaxSimSounds then Exit; Inc(e_SoundsArray[ID].nRefs); - res := Mix_PlayChannel(-1, e_SoundsArray[ID].Sound, 0); + if e_SoundsArray[ID].Loops then loops := -1; + res := Mix_PlayChannel(-1, e_SoundsArray[ID].Sound, loops); if res >= 0 then begin ChanSIds[res].id := ID; @@ -426,7 +475,8 @@ begin begin if not e_isMusic(ID) then Exit; Mix_HaltMusic(); - res := Mix_PlayMusic(e_SoundsArray[ID].Music, -1); + if e_SoundsArray[ID].Loops then loops := -1; + res := Mix_PlayMusic(e_SoundsArray[ID].Music, loops); if res >= 0 then res := N_MUSCHAN; if SoundMuted then Mix_VolumeMusic(0) else Mix_VolumeMusic(MusVolume); Result := res; @@ -559,7 +609,7 @@ begin end; if vol < 0 then vol := 0 else if vol > 1 then vol := 1; ChanSIds[i].oldvol := trunc(vol*MIX_MAX_VOLUME); - //if i = 0 then e_WriteLog(Format('modifying volumes: vol=%f; newvol=%d', [vol, ChanSIds[i].oldvol]), MSG_WARNING); + //if i = 0 then e_WriteLog(Format('modifying volumes: vol=%f; newvol=%d', [vol, ChanSIds[i].oldvol]), TMsgType.Warning); if ChanSIds[i].muted then Mix_Volume(i, 0) else Mix_Volume(i, ChanSIds[i].oldvol); end; ovol := Mix_VolumeMusic(-1); @@ -591,11 +641,11 @@ begin if ChanSIds[i].muted <> SoundMuted then begin ChanSIds[i].muted := SoundMuted; - //e_WriteLog(Format('gmuting sound for channel %d', [i]), MSG_WARNING); + //e_WriteLog(Format('gmuting sound for channel %d', [i]), TMsgType.Warning); if ChanSIds[i].muted then Mix_Volume(i, 0) else Mix_Volume(i, ChanSIds[i].oldvol); end; end; - //if SoundMuted then e_WriteLog('muting music', MSG_NOTIFY) else e_WriteLog(Format('unmuting music (%d)', [MusVolume]), MSG_NOTIFY); + //if SoundMuted then e_WriteLog('muting music', TMsgType.Notify) else e_WriteLog(Format('unmuting music (%d)', [MusVolume]), TMsgType.Notify); if SoundMuted then Mix_VolumeMusic(0) else Mix_VolumeMusic(MusVolume); end; @@ -682,7 +732,7 @@ begin if (FID = NO_SOUND_ID) or not SoundInitialized then Exit; FChanNum := e_PlaySoundPanVolume(FID, Pan, Volume); Result := (FChanNum >= 0); - //if e_isMusic(FID) then e_WriteLog(Format('playing music (%u)', [FID]), MSG_NOTIFY); + //if e_isMusic(FID) then e_WriteLog(Format('playing music (%u)', [FID]), TMsgType.Notify); //TODO: aPos end; @@ -704,15 +754,15 @@ begin Result := False; if e_isSound(FID) then begin - //e_WriteLog(Format('IsPlaying: FID=%u; FChanNum=%d', [FID, FChanNum]), MSG_WARNING); + //e_WriteLog(Format('IsPlaying: FID=%u; FChanNum=%d', [FID, FChanNum]), TMsgType.Warning); chan := Channel; if chan < 0 then begin - //e_WriteLog(Format('IsPlaying: FID=%u; ONA', [FID]), MSG_WARNING); + //e_WriteLog(Format('IsPlaying: FID=%u; ONA', [FID]), TMsgType.Warning); Exit; end; //Result := (Mix_Playing(chan) > 0) - //e_WriteLog(Format('IsPlaying: FID=%u; TAN', [FID]), MSG_WARNING); + //e_WriteLog(Format('IsPlaying: FID=%u; TAN', [FID]), TMsgType.Warning); Result := True; end else if e_isMusic(FID) then @@ -818,12 +868,12 @@ begin begin chan := Channel; if chan < 0 then Exit; - //e_WriteLog(Format('SetVolume: chan=%d; Volume=%f', [chan, Volume]), MSG_WARNING); + //e_WriteLog(Format('SetVolume: chan=%d; Volume=%f', [chan, Volume]), TMsgType.Warning); e_chanSetVol(chan, Volume); end else if e_isMusic(FID) then begin - //e_WriteLog(Format('SetVolume: chan=MUSIC; Volume=%f', [Volume]), MSG_WARNING); + //e_WriteLog(Format('SetVolume: chan=MUSIC; Volume=%f', [Volume]), TMsgType.Warning); e_chanSetVol(N_MUSCHAN, Volume); end; end; @@ -880,7 +930,7 @@ begin if chan < 0 then Exit; if ChanSIds[chan].muted <> Enable then begin - //e_WriteLog(Format('muting sound for channel %d', [cnan]), MSG_WARNING); + //e_WriteLog(Format('muting sound for channel %d', [cnan]), TMsgType.Warning); ChanSIds[chan].muted := Enable; if ChanSIds[chan].muted then Mix_Volume(chan, 0) else Mix_Volume(chan, ChanSIds[chan].oldvol); end;