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); }
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 }
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; }
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); } }
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; }
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; }
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; }
void SOUND_set_frequency(int sound, int freq) { IDirectSoundBuffer_SetFrequency(sample_buffers[sound],freq) ; }