Beispiel #1
0
void I_UpdateSoundParams(int channel, int vol, int sep, int pitch)
{
// proff 07/04/98: Added for CYGWIN32 compatibility
#ifdef HAVE_LIBDSOUND

  int DSB_Status;
  if (noDSound == true)
    return;

// proff 07/26/98: Added volume check
  if (vol==0)
    {
      IDirectSoundBuffer_Stop(lpSecondaryDSB[channel]);
      return;
    }
  IDirectSoundBuffer_SetVolume(lpSecondaryDSB[channel],VOL(vol));
  IDirectSoundBuffer_SetPan(lpSecondaryDSB[channel],SEP(sep));
  IDirectSoundBuffer_SetFrequency
    (lpSecondaryDSB[channel], ChannelInfo[channel].samplerate+PITCH(pitch));
  if (ChannelInfo[channel].playing == true)
    {
      IDirectSoundBuffer_GetStatus(lpSecondaryDSB[channel], &DSB_Status);
      if ((DSB_Status & DSBSTATUS_PLAYING) == 0)
	IDirectSoundBuffer_Play(lpSecondaryDSB[channel], 0, 0, 0);
    }
#endif // HAVE_LIBDSOUND
}
Beispiel #2
0
static HRESULT WINAPI DSoundRender_CompleteConnect(BaseRenderer * iface, IPin * pReceivePin)
{
    DSoundRenderImpl *This = impl_from_BaseRenderer(iface);
    const AM_MEDIA_TYPE * pmt = &This->renderer.pInputPin->pin.mtCurrent;
    HRESULT hr = S_OK;
    WAVEFORMATEX *format;
    DSBUFFERDESC buf_desc;

    TRACE("(%p)->(%p)\n", This, pReceivePin);
    dump_AM_MEDIA_TYPE(pmt);

    TRACE("MajorType %s\n", debugstr_guid(&pmt->majortype));
    TRACE("SubType %s\n", debugstr_guid(&pmt->subtype));
    TRACE("Format %s\n", debugstr_guid(&pmt->formattype));
    TRACE("Size %d\n", pmt->cbFormat);

    format = (WAVEFORMATEX*)pmt->pbFormat;

    This->buf_size = format->nAvgBytesPerSec;

    memset(&buf_desc,0,sizeof(DSBUFFERDESC));
    buf_desc.dwSize = sizeof(DSBUFFERDESC);
    buf_desc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN |
                       DSBCAPS_CTRLFREQUENCY | DSBCAPS_GLOBALFOCUS |
                       DSBCAPS_GETCURRENTPOSITION2;
    buf_desc.dwBufferBytes = This->buf_size;
    buf_desc.lpwfxFormat = format;
    hr = IDirectSound_CreateSoundBuffer(This->dsound, &buf_desc, &This->dsbuffer, NULL);
    This->writepos = This->buf_size;
    if (FAILED(hr))
        ERR("Can't create sound buffer (%x)\n", hr);

    if (SUCCEEDED(hr))
    {
        hr = IDirectSoundBuffer_SetVolume(This->dsbuffer, This->volume);
        if (FAILED(hr))
            ERR("Can't set volume to %d (%x)\n", This->volume, hr);

        hr = IDirectSoundBuffer_SetPan(This->dsbuffer, This->pan);
        if (FAILED(hr))
            ERR("Can't set pan to %d (%x)\n", This->pan, hr);
        hr = S_OK;
    }

    if (FAILED(hr) && hr != VFW_E_ALREADY_CONNECTED)
    {
        if (This->dsbuffer)
            IDirectSoundBuffer_Release(This->dsbuffer);
        This->dsbuffer = NULL;
    }

    return hr;
}
Beispiel #3
0
static	BOOL	ModifyChannel( Channel *channel, geSound_Cfg *cfg )
{
	int Error, Vol, Pan, Freq;
	assert(channel);
	
	if( !cfg )
		return( TRUE );
	ClearDupBuffers(channel);
	if( cfg->Volume != channel->cfg.Volume )
	{
		Vol = (DWORD)((1.0 - cfg->Volume  ) * DSBVOLUME_MIN);
		Error = IDirectSoundBuffer_SetVolume(channel->buffer, Vol);
		if (Error != DS_OK)
		{
			geErrorLog_Add(GE_ERR_DS_ERROR, NULL);
			return FALSE;
		}
		channel->cfg.Volume = cfg->Volume;
	}

	if( cfg->Pan != channel->cfg.Pan )
	{
		Pan = (int)(cfg->Pan  * DSBPAN_RIGHT);
		Error = IDirectSoundBuffer_SetPan(channel->buffer, Pan);
		if (Error != DS_OK)
		{
			geErrorLog_Add(GE_ERR_DS_ERROR, NULL);
			return FALSE;
		}
		channel->cfg.Pan = cfg->Pan;
	}


	if( cfg->Frequency != channel->cfg.Frequency )
	{

		Freq = (DWORD)(channel->BaseFreq * cfg->Frequency);
		
		if(Freq < 0)
			Freq = 0;

		Error = IDirectSoundBuffer_SetFrequency(channel->buffer, Freq);
		if (Error != DS_OK)
		{
			geErrorLog_Add(GE_ERR_DS_ERROR, NULL);
			return FALSE;
		}
		channel->cfg.Frequency = cfg->Frequency;
	}

	return TRUE;
}
Beispiel #4
0
static HRESULT WINAPI Basicaudio_put_Balance(IBasicAudio *iface,
                                             LONG lBalance) {
    ICOM_THIS_MULTI(DSoundRenderImpl, IBasicAudio_vtbl, iface);

    TRACE("(%p/%p)->(%d)\n", This, iface, lBalance);

    if (lBalance < DSBPAN_LEFT || lBalance > DSBPAN_RIGHT)
        return E_INVALIDARG;

    if (This->dsbuffer) {
        if (FAILED(IDirectSoundBuffer_SetPan(This->dsbuffer, lBalance)))
            return E_FAIL;
    }

    This->pan = lBalance;
    return S_OK;
}
Beispiel #5
0
// Pan is linear, from 0 to 1. 0.5 is in the center.
void I2_SetPan(sndsource_t *src, float pan)
{
    int ds_pan = 0;

    if(pan < 0) pan = 0;
    if(pan > 1) pan = 1;

    pan *= 2;
    pan -= 1;
    if(pan >= 1)
        ds_pan = DSBPAN_RIGHT;
    else if(pan <= -1)
        ds_pan = DSBPAN_LEFT;
    else if(pan == 0)
        ds_pan = 0;
    else if(pan > 0)
        ds_pan = -100 * 20 * log10(1-pan);// - log10(1-pan));
    else
        ds_pan = 100 * 20 * log10(1+pan);
    IDirectSoundBuffer_SetPan(src->source, ds_pan);
}
Beispiel #6
0
static HRESULT WINAPI DSoundRender_InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
{
    BaseInputPin *This = (BaseInputPin *)iface;
    PIN_DIRECTION pindirReceive;
    DSoundRenderImpl *DSImpl;
    HRESULT hr = S_OK;

    TRACE("(%p)->(%p, %p)\n", This, pReceivePin, pmt);
    dump_AM_MEDIA_TYPE(pmt);

    EnterCriticalSection(This->pin.pCritSec);
    {
        DSImpl = (DSoundRenderImpl*)This->pin.pinInfo.pFilter;
        DSImpl->rtLastStop = -1;

        if (This->pin.pConnectedTo)
            hr = VFW_E_ALREADY_CONNECTED;

        if (SUCCEEDED(hr) && This->pin.pFuncsTable->pfnCheckMediaType((BasePin*)This, pmt) != S_OK)
            hr = VFW_E_TYPE_NOT_ACCEPTED;

        if (SUCCEEDED(hr))
        {
            IPin_QueryDirection(pReceivePin, &pindirReceive);

            if (pindirReceive != PINDIR_OUTPUT)
            {
                ERR("Can't connect from non-output pin\n");
                hr = VFW_E_INVALID_DIRECTION;
            }
        }

        if (SUCCEEDED(hr))
        {
            WAVEFORMATEX *format;
            DSBUFFERDESC buf_desc;

            TRACE("MajorType %s\n", debugstr_guid(&pmt->majortype));
            TRACE("SubType %s\n", debugstr_guid(&pmt->subtype));
            TRACE("Format %s\n", debugstr_guid(&pmt->formattype));
            TRACE("Size %d\n", pmt->cbFormat);

            format = (WAVEFORMATEX*)pmt->pbFormat;

            DSImpl->buf_size = format->nAvgBytesPerSec;

            memset(&buf_desc,0,sizeof(DSBUFFERDESC));
            buf_desc.dwSize = sizeof(DSBUFFERDESC);
            buf_desc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN |
                               DSBCAPS_CTRLFREQUENCY |
                               DSBCAPS_GETCURRENTPOSITION2;
            buf_desc.dwBufferBytes = DSImpl->buf_size;
            buf_desc.lpwfxFormat = format;
            hr = IDirectSound_CreateSoundBuffer(DSImpl->dsound, &buf_desc, &DSImpl->dsbuffer, NULL);
            if (FAILED(hr))
                ERR("Can't create sound buffer (%x)\n", hr);
        }

        if (SUCCEEDED(hr))
        {
            hr = IDirectSoundBuffer_SetVolume(DSImpl->dsbuffer, DSImpl->volume);
            if (FAILED(hr))
                ERR("Can't set volume to %d (%x)\n", DSImpl->volume, hr);

            hr = IDirectSoundBuffer_SetPan(DSImpl->dsbuffer, DSImpl->pan);
            if (FAILED(hr))
                ERR("Can't set pan to %d (%x)\n", DSImpl->pan, hr);

            DSImpl->write_pos = 0;
            hr = S_OK;
        }

        if (SUCCEEDED(hr))
        {
            CopyMediaType(&This->pin.mtCurrent, pmt);
            This->pin.pConnectedTo = pReceivePin;
            IPin_AddRef(pReceivePin);
        }
        else if (hr != VFW_E_ALREADY_CONNECTED)
        {
            if (DSImpl->dsbuffer)
                IDirectSoundBuffer_Release(DSImpl->dsbuffer);
            DSImpl->dsbuffer = NULL;
        }
    }
    LeaveCriticalSection(This->pin.pCritSec);

    return hr;
}
Beispiel #7
0
int I_StartSound(sfxinfo_t *sound, int vol, int sep, int pitch, int pri)
{
  int channel=0;

  // proff 07/04/98: Added for CYGWIN32 compatibility
#ifdef HAVE_LIBDSOUND
  HRESULT error;
  char *snddata;
  int sndlength;

  if (noDSound == true)
    return channel;

  // load sound data if we have not already  

  I_CacheSound(sound);

  // find a free channel

  channel = I_GetFreeChannel();

  // proff 07/26/98: Added volume check
  // proff 10/31/98: Added Stop before updating sound-data

  error = IDirectSoundBuffer_Stop(lpSecondaryDSB[channel]);
  ChannelInfo[channel].playing = false;
  
  if (vol==0)
    return channel;

  snddata = sound->data;

  ChannelInfo[channel].samplerate = (snddata[3] << 8) + snddata[2];
// proff 10/31/98: Use accurate time for this one
  ChannelInfo[channel].endtime = 
    I_GetTime_RealTime() + 
    (sound->length * 35) / ChannelInfo[channel].samplerate + 1;

  // skip past header

  snddata += 8;
  sndlength = sound->length - 8;

  error = IDirectSoundBuffer_SetCurrentPosition(lpSecondaryDSB[channel],0);

  // proff 11/09/98: Added for a slight speedup
  if (sound != ChannelInfo[channel].sfx)
    {
      DWORD *hand1,*hand2;
      DWORD len1,len2;

      ChannelInfo[channel].sfx = sound;
      error = IDirectSoundBuffer_Lock(lpSecondaryDSB[channel],0,65535,
				      &hand1,&len1,&hand2,&len2,
				      DSBLOCK_FROMWRITECURSOR);
      if (len1 >= sndlength) 
	{
	  memset(hand1, 128, len1);
	  memcpy(hand1, snddata , sndlength);
	  memset(hand2, 128, len2);
	}
      else 
	{
	  memcpy(hand1, snddata, len1);
	  memcpy(hand2, &((char *)snddata)[len1], sndlength-len1);
	}
      
      error = IDirectSoundBuffer_Unlock
	(lpSecondaryDSB[channel], hand1, len1, hand2, len2);
    }
  IDirectSoundBuffer_SetVolume(lpSecondaryDSB[channel], VOL(vol));
  IDirectSoundBuffer_SetPan(lpSecondaryDSB[channel], SEP(sep));
  IDirectSoundBuffer_SetFrequency(lpSecondaryDSB[channel], 
				  ChannelInfo[channel].samplerate+PITCH(pitch));
  error = IDirectSoundBuffer_Play(lpSecondaryDSB[channel], 0, 0, 0);
  ChannelInfo[channel].playing = true;

#endif // HAVE_LIBDSOUND
  return channel;
}
Beispiel #8
0
int digi_start_sound_object(int obj)
{
 int slot;
 HRESULT hr;

   if (!digi_initialised)
    return -1;
  slot = get_free_slot();

   if (slot<0)
    return -1;

  SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
  SoundSlots[slot].samples = Sounddat(SoundObjects[obj].soundnum)->data;
  SoundSlots[slot].length = Sounddat(SoundObjects[obj].soundnum)->length;
  SoundSlots[slot].volume = fixmul(digi_volume, SoundObjects[obj].volume);
  SoundSlots[slot].pan = SoundObjects[obj].pan;
  SoundSlots[slot].position = 0;
  SoundSlots[slot].looped = (SoundObjects[obj].flags & SOF_PLAY_FOREVER);
  SoundSlots[slot].playing = 1;

  memset(&waveformat, 0, sizeof(waveformat));
  waveformat.wFormatTag=WAVE_FORMAT_PCM;
  waveformat.wBitsPerSample = Sounddat(SoundObjects[obj].soundnum)->bits;
  waveformat.nChannels = 1;
  waveformat.nSamplesPerSec = Sounddat(SoundObjects[obj].soundnum)->freq;
  waveformat.nBlockAlign =
  waveformat.nChannels * (waveformat.wBitsPerSample/8);
  waveformat.nAvgBytesPerSec =
  waveformat.nSamplesPerSec * waveformat.nBlockAlign;

  memset(&dsbd, 0, sizeof(dsbd));
  dsbd.dwSize = sizeof(dsbd);
  dsbd.dwFlags = (DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLPAN|DSBCAPS_CTRLVOLUME) | DSBCAPS_GETCURRENTPOSITION2;
  dsbd.dwReserved=0;
  dsbd.dwBufferBytes = SoundSlots[slot].length;
  dsbd.lpwfxFormat = &waveformat;

  hr = IDirectSound_CreateSoundBuffer(lpds, &dsbd, &SoundSlots[slot].lpsb, NULL);
   if ( hr != DS_OK )
    {
      abort();
    }
   {
    char *ptr1, *ptr2;
    DWORD len1, len2;
     IDirectSoundBuffer_Lock(SoundSlots[slot].lpsb, 0, SoundSlots[slot].length,
                             (void **)&ptr1, &len1, (void **)&ptr2, &len2, 0);
     memcpy(ptr1, SoundSlots[slot].samples, MIN(len1,(int)SoundSlots[slot].length));
     IDirectSoundBuffer_Unlock(SoundSlots[slot].lpsb, (void *)ptr1, len1, (void *)ptr2, len2);
   }
  IDirectSoundBuffer_SetPan(SoundSlots[slot].lpsb, ((int)(f2fl(SoundSlots[slot].pan) * 20000))-10000);
  IDirectSoundBuffer_SetVolume(SoundSlots[slot].lpsb,D1vol2DSvol(SoundSlots[slot].volume));
  IDirectSoundBuffer_Play(SoundSlots[slot].lpsb, 0, 0, SoundSlots[slot].looped?DSBPLAY_LOOPING:0);

  SoundObjects[obj].signature = next_signature++;
  SoundObjects[obj].handle = slot;

  SoundObjects[obj].flags |= SOF_PLAYING;
  //added on 980905 by adb to add sound kill system from original sos digi.c
  reset_sounds_on_channel(slot);
  //end edit by adb
 
  return 0;
}
Beispiel #9
0
int digi_start_sound(int soundnum, fix volume, fix pan)
{
 int ntries;
 int slot;
 HRESULT hr;

   if (!digi_initialised)
    return -1;

  //added on 980905 by adb from original source to add sound kill system
  // play at most digi_max_channel samples, if possible kill sample with low volume
  ntries = 0;

TryNextChannel:
   if ( (SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing)  )
    {
       if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries<digi_max_channels) )
        {
         //mprintf(( 0, "Not stopping loud sound %d.\n", next_handle ));
          next_handle++;
           if ( next_handle >= digi_max_channels )
            next_handle = 0;
          ntries++;
          goto TryNextChannel;
        }
      //mprintf(( 0, "[SS:%d]", next_handle ));
      DS_release_slot(SampleHandles[next_handle],1);
      SampleHandles[next_handle] = -1;
    }
  //end edit by adb

  slot = get_free_slot();
   if (slot<0)
    return -1;

  SoundSlots[slot].soundno = soundnum;
  SoundSlots[slot].samples = Sounddat(soundnum)->data;
  SoundSlots[slot].length = Sounddat(soundnum)->length;
  SoundSlots[slot].volume = fixmul(digi_volume, volume);
  SoundSlots[slot].pan = pan;
  SoundSlots[slot].position = 0;
  SoundSlots[slot].looped = 0;
  SoundSlots[slot].playing = 1;

  memset(&waveformat, 0, sizeof(waveformat));
  waveformat.wFormatTag=WAVE_FORMAT_PCM;
  waveformat.wBitsPerSample = Sounddat(soundnum)->bits;
  waveformat.nChannels = 1;
  waveformat.nSamplesPerSec = Sounddat(soundnum)->freq;
  waveformat.nBlockAlign =
    waveformat.nChannels * (waveformat.wBitsPerSample/8);
  waveformat.nAvgBytesPerSec =
    waveformat.nSamplesPerSec * waveformat.nBlockAlign;

  memset(&dsbd, 0, sizeof(dsbd));
  dsbd.dwSize = sizeof(dsbd);
  dsbd.dwFlags = (DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLPAN|DSBCAPS_CTRLVOLUME) | DSBCAPS_GETCURRENTPOSITION2;
  dsbd.dwReserved=0;
  dsbd.dwBufferBytes = SoundSlots[slot].length;
  dsbd.lpwfxFormat = &waveformat;

  hr = IDirectSound_CreateSoundBuffer(lpds, &dsbd, &SoundSlots[slot].lpsb, NULL);
   if ( hr != DS_OK )
    {
      printf("Createsoundbuffer failed! hr=0x%X\n", (int)hr);
      abort();
    }

   {
    char *ptr1, *ptr2;
    DWORD len1, len2;
     IDirectSoundBuffer_Lock(SoundSlots[slot].lpsb, 0, Sounddat(soundnum)->length,
                             (void **)&ptr1, &len1, (void **)&ptr2, &len2, 0);
     memcpy(ptr1,Sounddat(soundnum)->data, MIN((int) len1, Sounddat(soundnum)->length));
     IDirectSoundBuffer_Unlock(SoundSlots[slot].lpsb, ptr1, len1, ptr2, len2);
   }

  IDirectSoundBuffer_SetPan(SoundSlots[slot].lpsb, ((int)(f2fl(pan) * 20000.0))-10000);
  IDirectSoundBuffer_SetVolume(SoundSlots[slot].lpsb, D1vol2DSvol(SoundSlots[slot].volume));
  IDirectSoundBuffer_Play(SoundSlots[slot].lpsb, 0, 0, 0);

   //added on 980905 by adb to add sound kill system from original sos digi.c
   reset_sounds_on_channel(slot);
   SampleHandles[next_handle] = slot;
   next_handle++;
    if ( next_handle >= digi_max_channels )
     next_handle = 0;
 //end edit by adb

  return slot;
}