⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win_snd.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 5 页
字号:

    if (nosound)
        return;

    dsbuffer = StackSounds[handle].lpSndBuf;

#ifdef SURROUND
    if (dsbuffer == NULL)
        return;

    dssurround = StackSounds[handle].lpSurround;
    if (dssurround)
    {
        dssurround->lpVtbl->GetStatus(dssurround, &dwStatus);
        surround_inuse = (dwStatus & (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING));
    }
        // If pan changed to stereo...
    if (sep != -128)
    {
        if (surround_inuse)
        {
            dssurround->lpVtbl->Stop(dssurround);
            surround_inuse = FALSE;
                        
        }
    }
    else 
        // Just update volumes and start the surround if need
        if (!surround_inuse)
        {
            I_UpdateSoundVolume(dssurround, vol);
            I_UpdateSoundPanning(dsbuffer, 0);
            dsbuffer->lpVtbl->GetCurrentPosition(dsbuffer, &pos, NULL);
            dssurround->lpVtbl->SetCurrentPosition(dssurround, pos);
            dssurround->lpVtbl->Play(dssurround, 0, 0, 0);
                        
            surround_inuse = TRUE;
        }
        else
            I_UpdateSoundVolume(dssurround, vol);
    I_UpdateSoundVolume(dsbuffer, vol);

    if (!surround_inuse)
        I_UpdateSoundPanning(dsbuffer, sep);

#else

    if (dsbuffer) {
        I_UpdateSoundVolume (dsbuffer, vol);
        I_UpdateSoundPanning (dsbuffer, sep);
    }
#endif
}


//
// Shutdown DirectSound
//
void I_ShutdownSound(void)
{
    int i;

    CONS_Printf("I_ShutdownSound()\n");

#ifdef HW3SOUND
    if (hws_mode != HWS_DEFAULT_MODE)
    {
        HW3S_Shutdown();
        Shutdown3DSDriver();
        return;
    }
#endif
    // release any temporary 'duplicated' secondary buffers
    for (i=0; i<MAXSTACKSOUNDS; i++)
        if (StackSounds[i].lpSndBuf)
            // stops the sound and release it if it is a duplicate
            I_StopSound (i);
    
    if (DSnd)
    {
        IDirectSound_Release(DSnd);
        DSnd = NULL;
    }
}


// ==========================================================================
// Startup DirectSound
// ==========================================================================
void I_StartupSound()
{
    HRESULT             hr;
    LPDIRECTSOUNDBUFFER lpDsb;
    DSBUFFERDESC        dsbdesc;
    WAVEFORMATEX        wfm;
    int                 cooplevel;
    int                 frequency;
    int                 p;

#ifdef HW3SOUND
    char                *sdrv_name;
    snddev_t            snddev;
#endif

    sound_started = false;
    
    if (nosound)
        return;

    // Secure and configure sound device first.
    CONS_Printf("I_StartupSound: ");

    // frequency of primary buffer may be set at cmd-line
    p = M_CheckParm ("-freq");
    if (p && p < myargc-1) {
        frequency = atoi(myargv[p+1]);
        CONS_Printf (" requested frequency of %d hz\n", frequency);
    }
    else
        frequency = 22050;

    // Set cooperative level
    // Cooperative sound with other applications can be requested at cmd-line
    if (M_CheckParm("-coopsound"))
        cooplevel = DSSCL_PRIORITY;
    else
        cooplevel = DSSCL_EXCLUSIVE;

#ifdef HW3SOUND
    if (M_CheckParm("-ds3d"))
    {
        hws_mode = HWS_DS3D;
        sdrv_name = "s_ds3d.dll";
    }; 

    // There must be further sound drivers (such as A3D and EAX)!!!

    if (hws_mode != HWS_DEFAULT_MODE)
    {
        if (Init3DSDriver(sdrv_name))
        {
            //nosound = true;
            I_AddExitFunc(I_ShutdownSound);
            snddev.cooplevel = cooplevel;
            snddev.bps = 16;
            snddev.hWnd = hWndMain;
            snddev.sample_rate = frequency;
            if (HW3S_Init(I_Error, &snddev))
            {
                CONS_Printf("HW 3D sound started\n");
                return;
            }
            // Falls back to default sound system
            HW3S_Shutdown();
            Shutdown3DSDriver();
        }
        hws_mode = HWS_DEFAULT_MODE;
    }
#endif

    // Create DirectSound, use the default sound device
    hr = DirectSoundCreate( NULL, &DSnd, NULL);
    if ( FAILED( hr ) ) {
        CONS_Printf (" DirectSoundCreate FAILED\n"
                     " there is no sound device or the sound device is under\n"
                     " the control of another application\n" );
        nosound = true;
        return;
    }

    // register exit code, now that we have at least DirectSound to close
    I_AddExitFunc (I_ShutdownSound);
       
    hr = DSnd->lpVtbl->SetCooperativeLevel (DSnd, hWndMain, cooplevel);
    if ( FAILED( hr ) ) {
        CONS_Printf (" SetCooperativeLevel FAILED\n");
        nosound = true;
        return;
    }

    // Set up DSBUFFERDESC structure.
    ZeroMemory (&dsbdesc, sizeof(DSBUFFERDESC) );
    dsbdesc.dwSize        = sizeof(DSBUFFERDESC);
    dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER |
                      DSBCAPS_CTRLVOLUME;
    dsbdesc.dwBufferBytes = 0;      // Must be 0 for primary buffer
    dsbdesc.lpwfxFormat = NULL;     // Must be NULL for primary buffer

    // Set up structure for the desired format
    ZeroMemory (&wfm, sizeof(WAVEFORMATEX));
    wfm.wFormatTag = WAVE_FORMAT_PCM;
    wfm.nChannels = 2;                              //STEREO SOUND!
    wfm.nSamplesPerSec = frequency;
    wfm.wBitsPerSample = 16;
    wfm.nBlockAlign = wfm.wBitsPerSample / 8 * wfm.nChannels;
    wfm.nAvgBytesPerSec = wfm.nSamplesPerSec * wfm.nBlockAlign;

    // Gain access to the primary buffer
    hr = DSnd->lpVtbl->CreateSoundBuffer (DSnd, &dsbdesc, &lpDsb, NULL);
    if ( FAILED( hr ) ) {
        CONS_Printf ("CreateSoundBuffer FAILED: %s (ErrNo %d)\n", DXErrorToString(hr), hr);
        nosound = true;
        return;
    }

    // Set the primary buffer to the desired format,
    // but only if we are allowed to do it
    if (cooplevel >= DSSCL_PRIORITY)
    {
        if (SUCCEEDED ( hr ))
        {
            // Set primary buffer to the desired format. If this fails,
            // we'll just ignore and go with the default.
            hr = lpDsb->lpVtbl->SetFormat (lpDsb, &wfm);
            if (FAILED(hr))
                CONS_Printf ("I_StartupSound :  couldn't set primary buffer format.\n");
        }
        // move any on-board sound memory into a contiguous block
        // to make the largest portion of free memory available.

        CONS_Printf (" Compacting onboard sound-memory...");
        hr = DSnd->lpVtbl->Compact (DSnd);
        CONS_Printf (" %s\n", SUCCEEDED(hr) ? "done" : "FAILED");
    }

    // set the primary buffer to play continuously, for performance
    // "... this method will ensure that the primary buffer is playing even when no secondary
    // buffers are playing; in that case, silence will be played. This can reduce processing
    // overhead when sounds are started and stopped in sequence, because the primary buffer
    // will be playing continuously rather than stopping and starting between secondary buffers."
    hr = lpDsb->lpVtbl->Play (lpDsb, 0, 0, DSBPLAY_LOOPING);
    if ( FAILED ( hr ) )
        CONS_Printf (" Primary buffer continuous play FAILED\n");

#ifdef DEBUGSOUND
    {
    DSCAPS              DSCaps;
    DSCaps.dwSize = sizeof(DSCAPS);
    hr = DSnd->lpVtbl->GetCaps (DSnd, &DSCaps);
    if (SUCCEEDED (hr))
    {
        if (DSCaps.dwFlags & DSCAPS_CERTIFIED)
            CONS_Printf ("This driver has been certified by Microsoft\n");
        if (DSCaps.dwFlags & DSCAPS_EMULDRIVER)
            CONS_Printf ("No driver with DirectSound support installed (no hardware mixing)\n");
        if (DSCaps.dwFlags & DSCAPS_PRIMARY16BIT)
            CONS_Printf ("Supports 16-bit primary buffer\n");
        if (DSCaps.dwFlags & DSCAPS_PRIMARY8BIT)
            CONS_Printf ("Supports 8-bit primary buffer\n");
        if (DSCaps.dwFlags & DSCAPS_SECONDARY16BIT)
            CONS_Printf ("Supports 16-bit, hardware-mixed secondary buffers\n");
        if (DSCaps.dwFlags & DSCAPS_SECONDARY8BIT)
            CONS_Printf ("Supports 8-bit, hardware-mixed secondary buffers\n");

        CONS_Printf ("Maximum number of hardware buffers: %d\n", DSCaps.dwMaxHwMixingStaticBuffers);
        CONS_Printf ("Size of total hardware memory: %d\n", DSCaps.dwTotalHwMemBytes);
        CONS_Printf ("Size of free hardware memory= %d\n", DSCaps.dwFreeHwMemBytes);
        CONS_Printf ("Play Cpu Overhead (%% cpu cycles): %d\n", DSCaps.dwPlayCpuOverheadSwBuffers);
    }
    else
        CONS_Printf (" couldn't get sound device caps.\n");
    }
#endif

    // save pointer to the primary DirectSound buffer for volume changes
    DSndPrimary = lpDsb;

    ZeroMemory (StackSounds, sizeof(StackSounds));

    CONS_Printf("sound initialised.\n");
    sound_started = true;
}


// ==========================================================================
//
// MUSIC API using MidiStream
//
// ==========================================================================

#define MIDBUFFERSIZE   128*1024L       // buffer size for Mus2Midi conversion  (ugly code)
#define SPECIAL_HANDLE_CLEANMIDI  -1999 // tell I_StopSong() to do a full (slow) midiOutReset() on exit

static  BOOL            bMusicStarted;
static  char*           pMus2MidData;       // buffer allocated at program start for Mus2Mid conversion

static  UINT        uMIDIDeviceID, uCallbackStatus;
static  HMIDISTRM   hStream;
static  HANDLE      hBufferReturnEvent; // for synch between the callback thread and main program thread
                                        // (we need to synch when we decide to stop/free stream buffers)

static  int         nCurrentBuffer = 0, nEmptyBuffers;

static  BOOL        bBuffersPrepared = FALSE;
static  DWORD       dwVolCache[MAX_MIDI_IN_TRACKS];
        DWORD       dwVolumePercent;    // accessed by win_main.c

        // this is accessed by mid2strm.c conversion code
        BOOL        bMidiLooped = FALSE, bMidiPlaying = FALSE, bMidiPaused = FALSE;
        CONVERTINFO ciStreamBuffers[NUM_STREAM_BUFFERS];

#define STATUS_KILLCALLBACK         100     // Signals that the callback should die
#define STATUS_CALLBACKDEAD         200     // Signals callback is done processing
#define STATUS_WAITINGFOREND    300     // Callback's waiting for buffers to play

#define DEBUG_CALLBACK_TIMEOUT 2000         // Wait 2 seconds for callback
                                        // faB: don't freeze the main code if we debug..

#define VOL_CACHE_INIT              127     // for dwVolCache[]

static BOOL bMidiCanSetVolume;          // midi caps

static void Mid2StreamFreeBuffers( void );
static void CALLBACK MidiStreamCallback (HMIDIIN hMidi, UINT uMsg, DWORD dwInstance,
                                                 DWORD dwParam1, DWORD dwParam2 );
static BOOL StreamBufferSetup( unsigned char* pMidiData, int iMidiSize );

// -------------------
// MidiErrorMessageBox
// Calls the midiOutGetErrorText() function and displays the text which
// corresponds to a midi subsystem error code.
// -------------------
static void MidiErrorMessageBox(MMRESULT mmr)
{
    char szTemp[256];

    /*szTemp[0] = '\2';   //white text to stand out*/
    midiOutGetErrorText (mmr, szTemp/*+1*/, sizeof(szTemp));
    CONS_Printf (szTemp);
    /*MessageBox (GetActiveWindow(), szTemp+1, "LEGACY",
                MB_OK | MB_ICONSTOP );*/
    //wsprintf( szDebug, "Midi subsystem error: %s", szTemp );
}


// ----------------
// I_InitAudioMixer
// ----------------
#ifdef TESTCODE
void I_InitAudioMixer (void)
{
    UINT        cMixerDevs;
    cMixerDevs = mixerGetNumDevs();
    CONS_Printf ("%d mixer devices available\n", cMixerDevs);
}
#endif


// -----------
// I_InitMusic
// Startup Midi device for streaming output
// -----------
void I_InitMusic(void)
{
    DWORD       idx;
    MMRESULT    mmrRetVal;
    UINT        cMidiDevs;
    MIDIOUTCAPS MidiOutCaps;
    char*       szTechnology;

    bMusicStarted = false;
    
    CONS_Printf("I_InitMusic()\n");
    
    if (nomusic)
        return;

    // check out number of MIDI devices available
    //
    cMidiDevs = midiOutGetNumDevs();
    if (!cMidiDevs) {
        CONS_Printf ("No MIDI devices available, music is disabled\n");
        nomusic = true;
        return;
    }
#ifdef DEBUGMIDISTREAM
    else {
        CONS_Printf ("%d MIDI devices available\n", cMidiDevs);
    }
#endif

    if( M_CheckParm("-winmidi") )
        uMIDIDeviceID = atoi(M_GetNextParm());
    else
        uMIDIDeviceID = MIDI_MAPPER;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -