示例#1
0
void I2_SetPitch(sndsource_t *src, float pitch)
{
    int newfreq = src->freq * pitch;
    if(newfreq < DSBFREQUENCY_MIN) newfreq = DSBFREQUENCY_MIN;
    if(newfreq > DSBFREQUENCY_MAX) newfreq = DSBFREQUENCY_MAX;
    IDirectSoundBuffer_SetFrequency(src->source, newfreq);
}
示例#2
0
文件: i_sound.c 项目: dorienh/smmu
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
}
示例#3
0
static HRESULT WINAPI DSoundRender_PrepareReceive(BaseRenderer *iface, IMediaSample *pSample)
{
    DSoundRenderImpl *This = impl_from_BaseRenderer(iface);
    HRESULT hr;
    AM_MEDIA_TYPE *amt;

    if (IMediaSample_GetMediaType(pSample, &amt) == S_OK)
    {
        AM_MEDIA_TYPE *orig = &This->renderer.pInputPin->pin.mtCurrent;
        WAVEFORMATEX *origfmt = (WAVEFORMATEX *)orig->pbFormat;
        WAVEFORMATEX *newfmt = (WAVEFORMATEX *)amt->pbFormat;

        if (origfmt->wFormatTag == newfmt->wFormatTag &&
            origfmt->nChannels == newfmt->nChannels &&
            origfmt->nBlockAlign == newfmt->nBlockAlign &&
            origfmt->wBitsPerSample == newfmt->wBitsPerSample &&
            origfmt->cbSize ==  newfmt->cbSize)
        {
            if (origfmt->nSamplesPerSec != newfmt->nSamplesPerSec)
            {
                hr = IDirectSoundBuffer_SetFrequency(This->dsbuffer,
                                                     newfmt->nSamplesPerSec);
                if (FAILED(hr))
                    return VFW_E_TYPE_NOT_ACCEPTED;
                FreeMediaType(orig);
                CopyMediaType(orig, amt);
                IMediaSample_SetMediaType(pSample, NULL);
            }
        }
        else
            return VFW_E_TYPE_NOT_ACCEPTED;
    }
    return S_OK;
}
示例#4
0
void windows_osd_interface::update_audio_stream(const INT16 *buffer, int samples_this_frame)
{
	int bytes_this_frame = samples_this_frame * stream_format.nBlockAlign;
	DWORD play_position, write_position;
	HRESULT result;

	// if no sound, there is no buffer
	if (stream_buffer == NULL)
		return;

#ifdef USE_AUDIO_SYNC
	// if we are active, update the sampling frequency
	if (audio_sync && machine().video().speed_percent() > 0.0f)
	{
		IDirectSoundBuffer_SetFrequency(stream_buffer, machine().sample_rate() * machine().video().speed_percent());
	}
#endif /* USE_AUDIO_SYNC */

	// determine the current play position
	result = IDirectSoundBuffer_GetCurrentPosition(stream_buffer, &play_position, &write_position);
	if (result == DS_OK)
	{
		DWORD stream_in;

//DWORD orig_write = write_position;
		// normalize the write position so it is always after the play position
		if (write_position < play_position)
			write_position += stream_buffer_size;

		// normalize the stream in position so it is always after the write position
		stream_in = stream_buffer_in;
		if (stream_in < write_position)
			stream_in += stream_buffer_size;

		// now we should have, in order:
		//    <------pp---wp---si--------------->

		// if we're between play and write positions, then bump forward, but only in full chunks
		while (stream_in < write_position)
		{
//printf("Underflow: PP=%d  WP=%d(%d)  SI=%d(%d)  BTF=%d\n", (int)play_position, (int)write_position, (int)orig_write, (int)stream_in, (int)stream_buffer_in, (int)bytes_this_frame);
			buffer_underflows++;
			stream_in += bytes_this_frame;
		}

		// if we're going to overlap the play position, just skip this chunk
		if (stream_in + bytes_this_frame > play_position + stream_buffer_size)
		{
//printf("Overflow: PP=%d  WP=%d(%d)  SI=%d(%d)  BTF=%d\n", (int)play_position, (int)write_position, (int)orig_write, (int)stream_in, (int)stream_buffer_in, (int)bytes_this_frame);
			buffer_overflows++;
			return;
		}

		// now we know where to copy; let's do it
		stream_buffer_in = stream_in % stream_buffer_size;
		copy_sample_data(buffer, bytes_this_frame);
	}
}
示例#5
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;
}
示例#6
0
文件: dsoundrender.c 项目: r6144/wine
static HRESULT WINAPI DSoundRender_Receive(BaseInputPin *pin, IMediaSample * pSample)
{
    DSoundRenderImpl *This = (DSoundRenderImpl*)pin->pin.pinInfo.pFilter;
    LPBYTE pbSrcStream = NULL;
    LONG cbSrcStream = 0;
    REFERENCE_TIME tStart, tStop;
    HRESULT hr;
    AM_MEDIA_TYPE *amt;

    TRACE("%p %p\n", pin, pSample);

    /* Slightly incorrect, Pause completes when a frame is received so we should signal
     * pause completion here, but for sound playing a single frame doesn't make sense
     */

    EnterCriticalSection(&This->filter.csFilter);

    if (This->pInputPin->end_of_stream || This->pInputPin->flushing)
    {
        LeaveCriticalSection(&This->filter.csFilter);
        return S_FALSE;
    }

    if (This->filter.state == State_Stopped)
    {
        LeaveCriticalSection(&This->filter.csFilter);
        return VFW_E_WRONG_STATE;
    }

    if (IMediaSample_GetMediaType(pSample, &amt) == S_OK)
    {
        AM_MEDIA_TYPE *orig = &This->pInputPin->pin.mtCurrent;
        WAVEFORMATEX *origfmt = (WAVEFORMATEX *)orig->pbFormat;
        WAVEFORMATEX *newfmt = (WAVEFORMATEX *)amt->pbFormat;

        if (origfmt->wFormatTag == newfmt->wFormatTag &&
            origfmt->nChannels == newfmt->nChannels &&
            origfmt->nBlockAlign == newfmt->nBlockAlign &&
            origfmt->wBitsPerSample == newfmt->wBitsPerSample &&
            origfmt->cbSize ==  newfmt->cbSize)
        {
            if (origfmt->nSamplesPerSec != newfmt->nSamplesPerSec)
            {
                hr = IDirectSoundBuffer_SetFrequency(This->dsbuffer,
                                                     newfmt->nSamplesPerSec);
                if (FAILED(hr))
                {
                    LeaveCriticalSection(&This->filter.csFilter);
                    return VFW_E_TYPE_NOT_ACCEPTED;
                }
                FreeMediaType(orig);
                CopyMediaType(orig, amt);
                IMediaSample_SetMediaType(pSample, NULL);
            }
        }
        else
        {
            LeaveCriticalSection(&This->filter.csFilter);
            return VFW_E_TYPE_NOT_ACCEPTED;
        }
    }

    hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
    if (FAILED(hr))
    {
        ERR("Cannot get pointer to sample data (%x)\n", hr);
        LeaveCriticalSection(&This->filter.csFilter);
        return hr;
    }

    hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
    if (FAILED(hr))
        ERR("Cannot get sample time (%x)\n", hr);
    else
        MediaSeekingPassThru_RegisterMediaTime(This->seekthru_unk, tStart);

    if (This->rtLastStop != tStart && (IMediaSample_IsDiscontinuity(pSample) == S_FALSE))
        WARN("Unexpected discontinuity: Last: %u.%03u, tStart: %u.%03u\n",
            (DWORD)(This->rtLastStop / 10000000), (DWORD)((This->rtLastStop / 10000)%1000),
            (DWORD)(tStart / 10000000), (DWORD)((tStart / 10000)%1000));
    This->rtLastStop = tStop;

    if (IMediaSample_IsPreroll(pSample) == S_OK)
    {
        TRACE("Preroll!\n");
        LeaveCriticalSection(&This->filter.csFilter);
        return S_OK;
    }

    if (This->filter.state == State_Paused)
    {
        SetEvent(This->state_change);
        LeaveCriticalSection(&This->filter.csFilter);
        WaitForSingleObject(This->blocked, INFINITE);
        EnterCriticalSection(&This->filter.csFilter);
        if (This->filter.state == State_Stopped)
        {
            LeaveCriticalSection(&This->filter.csFilter);
            return VFW_E_WRONG_STATE;
        }

        if (This->filter.state == State_Paused)
        {
            /* Assuming we return because of flushing */
            TRACE("Flushing\n");
            LeaveCriticalSection(&This->filter.csFilter);
            return S_OK;
        }
        SetEvent(This->state_change);
    }

    cbSrcStream = IMediaSample_GetActualDataLength(pSample);
    TRACE("Sample data ptr = %p, size = %d\n", pbSrcStream, cbSrcStream);

#if 0 /* For debugging purpose */
    {
        int i;
        for(i = 0; i < cbSrcStream; i++)
        {
	    if ((i!=0) && !(i%16))
                TRACE("\n");
            TRACE("%02x ", pbSrcStream[i]);
        }
        TRACE("\n");
    }
#endif

    hr = DSoundRender_SendSampleData(This, pbSrcStream, cbSrcStream);
    SetEvent(This->state_change);
    LeaveCriticalSection(&This->filter.csFilter);
    return hr;
}
示例#7
0
文件: i_sound.c 项目: dorienh/smmu
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;
}
示例#8
0
void SOUND_set_frequency(int sound, int freq)
{
	IDirectSoundBuffer_SetFrequency(sample_buffers[sound],freq) ;
}