Exemple #1
0
	void playSoundWav(uint8_t channel, const uint8_t *data, uint8_t volume, int loops = 0) {
		uint32_t size = READ_LE_UINT32(data + 4) + 8;
		// check format for QuickLoad
		bool canQuickLoad = (AUDIO_S16SYS == AUDIO_S16LSB);
		if (canQuickLoad) {
			if (memcmp(data + 8, "WAVEfmt ", 8) == 0 && READ_LE_UINT32(data + 16) == 16) {
				const uint8_t *fmt = data + 20;
				const int format = READ_LE_UINT16(fmt);
				const int channels = READ_LE_UINT16(fmt + 2);
				const int rate = READ_LE_UINT32(fmt + 4);
				const int bits = READ_LE_UINT16(fmt + 14);
				debug(DBG_SND, "wave format %d channels %d rate %d bits %d", format, channels, rate, bits);
				canQuickLoad = (format == 1 && channels == 2 && rate == kMixFreq && bits == 16);
			}
                }
		if (canQuickLoad) {
			Mix_Chunk *chunk = Mix_QuickLoad_WAV(const_cast<uint8_t *>(data));
			playSound(channel, volume, chunk, loops);
		} else {
			SDL_RWops *rw = SDL_RWFromConstMem(data, size);
			Mix_Chunk *chunk = Mix_LoadWAV_RW(rw, 1);
			playSound(channel, volume, chunk, loops);
		}
	}
Exemple #2
0
// Volume 0-I2X (1)
int CAudioChannel::Start (short nSound, int nSoundClass, fix nVolume, int nPan, int bLooping, 
								  int nLoopStart, int nLoopEnd, int nSoundObj, int nSpeed, 
								  const char *pszWAV, CFixVector* vPos)
{
	CSoundSample*	soundP = NULL;
	int			bPersistent = (nSoundObj > -1) || bLooping || (nVolume > I2X (1));

if (!(pszWAV && *pszWAV && gameOpts->sound.bUseSDLMixer)) {
	if (nSound < 0)
		return -1;
	if (!gameData.pig.sound.nSoundFiles [gameStates.sound.bD1Sound])
		return -1;
	soundP = gameData.pig.sound.sounds [gameStates.sound.bD1Sound] + nSound % gameData.pig.sound.nSoundFiles [gameStates.sound.bD1Sound];
	if (!(soundP->data [soundP->bCustom].Buffer () && soundP->nLength [soundP->bCustom]))
		return -1;
	}
if (m_info.bPlaying) {
	m_info.bPlaying = 0;
	if (m_info.nSoundObj > -1)
		audio.EndSoundObject (m_info.nSoundObj);
	if (soundQueue.Channel () == audio.FreeChannel ())
		soundQueue.End ();
	}
#if USE_OPENAL
if (m_info.source == 0xFFFFFFFF) {
	CFloatVector	fPos;

	DigiALError ();
	alGenSources (1, &m_info.source);
	if (DigiALError ())
		return -1;
	alSourcei (m_info.source, AL_BUFFER, soundP->buffer);
	if (DigiALError ())
		return -1;
	alSourcef (m_info.source, AL_GAIN, ((nVolume < I2X (1)) ? X2F (nVolume) : 1) * 2 * X2F (m_info.nVolume));
	alSourcei (m_info.source, AL_LOOPING, (ALuint) ((nSoundObj > -1) || bLooping || (nVolume > I2X (1))));
	fPos.Assign (vPos ? *vPos : OBJECTS [LOCALPLAYER.nObject].nPosition.vPos);
	alSourcefv (m_info.source, AL_POSITION, reinterpret_cast<ALfloat*> (fPos));
	alSource3f (m_info.source, AL_VELOCITY, 0, 0, 0);
	alSource3f (m_info.source, AL_DIRECTION, 0, 0, 0);
	if (DigiALError ())
		return -1;
	alSourcePlay (m_info.source);
	if (DigiALError ())
		return -1;
	}
#endif
#if USE_SDL_MIXER
if (gameOpts->sound.bUseSDLMixer) {
	if (m_info.mixChunkP) {
		Mix_HaltChannel (m_info.nChannel);
		if (m_info.bBuiltIn)
			m_info.bBuiltIn = 0;
		else
			Mix_FreeChunk (m_info.mixChunkP);
		m_info.mixChunkP = NULL;
		}
	}
#endif
if (m_info.bResampled) {
	m_info.sample.Destroy ();
	m_info.bResampled = 0;
	}
#if USE_SDL_MIXER
if (gameOpts->sound.bUseSDLMixer) {
	//resample to two channels
	m_info.nChannel = audio.FreeChannel ();
	if (pszWAV && *pszWAV) {
		if (!(m_info.mixChunkP = LoadAddonSound (pszWAV, &m_info.bBuiltIn)))
			return -1;
		}
	else {
		int l;
		if (soundP->bHires) {
			l = soundP->nLength [soundP->bCustom];
			m_info.sample.SetBuffer (soundP->data [soundP->bCustom].Buffer (), 1, l);
			m_info.mixChunkP = Mix_QuickLoad_WAV (reinterpret_cast<Uint8*> (m_info.sample.Buffer ()));
			}
		else {
			if (gameOpts->sound.bHires [0])
				return -1;	//cannot mix hires and standard sounds
			l = Resample (soundP, gameStates.sound.bD1Sound && (gameOpts->sound.digiSampleRate != SAMPLE_RATE_11K), songManager.MP3 ());
			if (l <= 0)
				return -1;
			if (nSpeed < I2X (1))
				l = Speedup (soundP, nSpeed);
#if MAKE_WAV
			m_info.mixChunkP = Mix_QuickLoad_WAV (reinterpret_cast<Uint8*> (m_info.sample.Buffer ()));
#else
			m_info.mixChunkP = Mix_QuickLoad_RAW (reinterpret_cast<Uint8*> (m_info.sample.Buffer ()), l);
#endif
			}
		}
	Mix_VolPan (m_info.nChannel, nVolume, nPan);
	Mix_PlayChannel (m_info.nChannel, m_info.mixChunkP, bLooping ? -1 : nLoopEnd - nLoopStart);
	}
else 
#else
if (pszWAV && *pszWAV)
	return -1;
#endif
 {
	if (gameStates.sound.bD1Sound && (gameOpts->sound.digiSampleRate != SAMPLE_RATE_11K)) {
		int l = Resample (soundP, 0, 0);
		if (l <= 0)
			return -1;
		m_info.nLength = l;
		}
	else {
		m_info.sample.SetBuffer (soundP->data [soundP->bCustom].Buffer (), 1, m_info.nLength = soundP->nLength [soundP->bCustom]);
		}
	if (nSpeed < I2X (1))
		Speedup (soundP, nSpeed);
	}
m_info.nVolume = FixMul (audio.Volume (), nVolume);
m_info.nPan = nPan;
m_info.nPosition = 0;
m_info.nSoundObj = nSoundObj;
m_info.nSoundClass = nSoundClass;
m_info.bLooped = bLooping;
#if USE_OPENAL
m_info.loops = bLooping ? -1 : nLoopEnd - nLoopStart + 1;
#endif
m_info.nSound = nSound;
m_info.bPersistent = 0;
m_info.bPlaying = 1;
m_info.bPersistent = bPersistent;
return audio.FreeChannel ();
}
Exemple #3
0
// Volume 0-F1_0
int DigiStartSound (short soundnum, fix volume, int pan, int looping,
                    int loop_start, int loop_end, int soundobj, int speed,
                    char *pszWAV)
{
    int i, starting_channel;
    struct sound_slot *ssp;
    digi_sound *gsp;

    if (!gameStates.sound.digi.bInitialized)
        return -1;
    if (!(pszWAV && gameOpts->sound.bUseSDLMixer)) {
        if (soundnum < 0)
            return -1;
        gsp = gameData.pig.snd.sounds [gameOpts->sound.bD1Sound] + soundnum % gameData.pig.snd.nSoundFiles [gameOpts->sound.bD1Sound];
        if (!(gsp->data && gsp->length))
            return -1;
        Assert(gsp->data != (void *) -1);
    }
    starting_channel = gameStates.sound.digi.nNextChannel;
#if 0 //USE_SDL_MIXER
    if (gameOpts->sound.bUseSDLMixer) {
        do {
            if ((SoundSlots [gameStates.sound.digi.nNextChannel].soundno == soundnum) &&
                    SoundSlots [gameStates.sound.digi.nNextChannel].persistent)
                goto foundChannel;
            gameStates.sound.digi.nNextChannel++;
            if (gameStates.sound.digi.nNextChannel >= gameStates.sound.digi.nMaxChannels)
                gameStates.sound.digi.nNextChannel = 0;
        } while (gameStates.sound.digi.nNextChannel != starting_channel);
#endif
        while (1) {
            if (!SoundSlots [gameStates.sound.digi.nNextChannel].playing)
                break;
            if (!SoundSlots [gameStates.sound.digi.nNextChannel].persistent)
                break;	// use this channel!
            gameStates.sound.digi.nNextChannel++;
            if (gameStates.sound.digi.nNextChannel >= gameStates.sound.digi.nMaxChannels)
                gameStates.sound.digi.nNextChannel = 0;
            if (gameStates.sound.digi.nNextChannel == starting_channel) {
                //mprintf((1, "OUT OF SOUND CHANNELS!!!\n"));
                return -1;
            }
        }
#if 0
    }
foundChannel:
#endif
    ssp = SoundSlots + gameStates.sound.digi.nNextChannel;
    if (ssp->playing) {
        ssp->playing = 0;
        if (ssp->soundobj > -1)
            DigiEndSoundObj (ssp->soundobj);
        if (SoundQ_channel == gameStates.sound.digi.nNextChannel)
            SoundQEnd();
    }
#if USE_SDL_MIXER
    if (ssp->mixChunk) {
        Mix_HaltChannel (ssp->channel);
        Mix_FreeChunk (ssp->mixChunk);
        ssp->mixChunk = NULL;
    }
#endif
#ifndef NDEBUG
    VerifySoundChannelFree (gameStates.sound.digi.nNextChannel);
#endif
    if (ssp->bResampled) {
        d_free (ssp->samples);
        ssp->bResampled = 0;
    }
#if USE_SDL_MIXER
    if (gameOpts->sound.bUseSDLMixer) {
        //resample to two channels
        ssp->channel = gameStates.sound.digi.nNextChannel;
        if (pszWAV) {
#if 0
            if (!(ssp->samples = CFReadData (pszWAV, gameFolders.szDataDir, 0)))
                return -1;
            ssp->mixChunk = Mix_QuickLoad_WAV ((Uint8 *) ssp->samples);
#else
            char	szWAV [FILENAME_LEN];
            if (!CFExtract (pszWAV, gameFolders.szDataDir, 0, "d2x-temp.wav"))
                return -1;
#	ifdef _WIN32
            sprintf (szWAV, "%s%sd2x-temp.wav", gameFolders.szDataDir, *gameFolders.szDataDir ? "/" : "");
#	else
            sprintf (szWAV, "%s%sd2x-temp.wav", gameFolders.szHomeDir, *gameFolders.szHomeDir ? "/" : "");
#	endif
            ssp->mixChunk = Mix_LoadWAV (szWAV);
#endif
        }
        else {
            int l = DigiResampleSound (gsp, ssp, gameOpts->sound.bD1Sound && (gameOpts->sound.digiSampleRate != SAMPLE_RATE_11K));
            if (l <= 0)
                return -1;
            if (speed < F1_0)
                l = DigiSpeedupSound (gsp, ssp, speed);
            ssp->mixChunk = Mix_QuickLoad_RAW (ssp->samples, l);
        }
        Mix_VolPan (gameStates.sound.digi.nNextChannel, volume, pan);
        Mix_PlayChannel (gameStates.sound.digi.nNextChannel, ssp->mixChunk, looping ? -1 : loop_end - loop_start);
    }
    else
#else if (pszWAV)
    return -1;
#endif
    {
        if (gameOpts->sound.bD1Sound && (gameOpts->sound.digiSampleRate != SAMPLE_RATE_11K)) {
            int l = DigiResampleSound (gsp, ssp, 0);
            if (l <= 0)
                return -1;
            ssp->length = l;
        }
        else {
            ssp->samples = gsp->data;
            ssp->length = gsp->length;
        }
        if (speed < F1_0)
            DigiSpeedupSound (gsp, ssp, speed);
    }
    ssp->volume = FixMul (gameStates.sound.digi.nVolume, volume);
    ssp->pan = pan;
    ssp->position = 0;
    ssp->soundobj = soundobj;
    ssp->looped = looping;
    ssp->soundno = soundnum;
    ssp->persistent = 0;
    ssp->playing = 1;
    ssp->persistent = (soundobj > -1) || looping || (volume > F1_0);
    i = gameStates.sound.digi.nNextChannel;
    if (++gameStates.sound.digi.nNextChannel >= gameStates.sound.digi.nMaxChannels)
        gameStates.sound.digi.nNextChannel = 0;
    return i;
}