static void WAV_WriteAudio(GF_AudioOutput *dr) { LPWAVEHDR hdr; HRESULT hr; u32 i; WAVCTX(); if (!ctx->hwo) return; WaitForSingleObject(ctx->event, INFINITE); if (ctx->exit_request) return; for (i=0; i<ctx->num_buffers; i++) { /*get buffer*/ hdr = &ctx->wav_hdr[i]; if (hdr->dwFlags & WHDR_DONE) { waveOutUnprepareHeader(ctx->hwo, hdr, sizeof(WAVEHDR)); hdr->dwBufferLength = ctx->buffer_size; /*update delay*/ ctx->delay = 1000 * i * ctx->buffer_size / ctx->fmt.nAvgBytesPerSec; /*fill it*/ hdr->dwBufferLength = dr->FillBuffer(dr->audio_renderer, hdr->lpData, ctx->buffer_size); hdr->dwFlags = 0; hr = waveOutPrepareHeader(ctx->hwo, hdr, sizeof(WAVEHDR)); /*write it*/ waveOutWrite(ctx->hwo, hdr, sizeof(WAVEHDR)); } } }
static void cubeb_submit_buffer(cubeb_stream * stm, WAVEHDR * hdr) { long got; MMRESULT r; got = stm->data_callback(stm, stm->user_ptr, hdr->lpData, hdr->dwBufferLength / bytes_per_frame(stm->params)); if (got < 0) { /* XXX handle this case */ assert(0); return; } else if ((DWORD) got < hdr->dwBufferLength / bytes_per_frame(stm->params)) { r = waveOutUnprepareHeader(stm->waveout, hdr, sizeof(*hdr)); assert(r == MMSYSERR_NOERROR); hdr->dwBufferLength = got * bytes_per_frame(stm->params); r = waveOutPrepareHeader(stm->waveout, hdr, sizeof(*hdr)); assert(r == MMSYSERR_NOERROR); stm->draining = 1; } assert(hdr->dwFlags & WHDR_PREPARED); r = waveOutWrite(stm->waveout, hdr, sizeof(*hdr)); assert(r == MMSYSERR_NOERROR); }
/***************************************************************************** * PlayWaveOut: play a buffer through the WaveOut device *****************************************************************************/ static int PlayWaveOut( aout_instance_t *p_aout, HWAVEOUT h_waveout, WAVEHDR *p_waveheader, aout_buffer_t *p_buffer ) { MMRESULT result; /* Prepare the buffer */ if( p_buffer != NULL ) p_waveheader->lpData = p_buffer->p_buffer; else /* Use silence buffer instead */ p_waveheader->lpData = p_aout->output.p_sys->p_silence_buffer; p_waveheader->dwUser = p_buffer ? (DWORD_PTR)p_buffer : (DWORD_PTR)1; p_waveheader->dwBufferLength = p_aout->output.p_sys->i_buffer_size; p_waveheader->dwFlags = 0; result = waveOutPrepareHeader( h_waveout, p_waveheader, sizeof(WAVEHDR) ); if( result != MMSYSERR_NOERROR ) { msg_Err( p_aout, "waveOutPrepareHeader failed" ); return VLC_EGENERIC; } /* Send the buffer to the waveOut queue */ result = waveOutWrite( h_waveout, p_waveheader, sizeof(WAVEHDR) ); if( result != MMSYSERR_NOERROR ) { msg_Err( p_aout, "waveOutWrite failed" ); return VLC_EGENERIC; } return VLC_SUCCESS; }
SoundLib2dBuf::SoundLib2dBuf() { // Allocate the buffer unsigned int numSamples = g_prefsManager->GetInt("SoundBufferSize", 2000); m_buffer = new StereoSample[numSamples]; // Clear the buffer memset(m_buffer, 0, numSamples * sizeof(StereoSample)); // Register the buffer with Windows memset(&m_header, 0, sizeof(WAVEHDR)); m_header.lpData = (char*)m_buffer; int blockAlign = 4; // 2 channels * 2 bytes per sample m_header.dwBufferLength = numSamples * blockAlign; m_header.dwFlags = WHDR_DONE; int result = waveOutPrepareHeader(s_device, &m_header, sizeof(WAVEHDR)); DarwiniaReleaseAssert(result == MMSYSERR_NOERROR, "Couldn't init buffer"); // Play the buffer static int count = 0; if (count < 4) { count++; result = waveOutWrite(s_device, &m_header, sizeof(WAVEHDR)); DarwiniaReleaseAssert(result == MMSYSERR_NOERROR, "Couldn't send sound data"); } }
int win32_audio_play(short *buffer, int buffer_len) { int i, current_to_play, remained_to_play; short *des, *src; remained_to_play = buffer_len; while (remained_to_play > 0) { while (ri == ((wi + 1) % WO_MAX_BUCKETS)) Sleep(100); /* wait until there are available buckets */ if (WHDR_DONE == (wOutHdr[wi].dwFlags & WHDR_DONE)) waveOutUnprepareHeader(wOutDev, &wOutHdr[wi], sizeof(WAVEHDR)); current_to_play = (remained_to_play > WO_BUCKET_SIZE) ? WO_BUCKET_SIZE : remained_to_play; if (0 < current_to_play) { des = (short *) wOutHdr[wi].lpData; src = (short *) &(buffer[buffer_len - remained_to_play]); for (i = 0; i < current_to_play; i++) des[i] = src[i]; wOutHdr[wi].dwBufferLength = current_to_play * sizeof(short); waveOutPrepareHeader(wOutDev, &wOutHdr[wi], sizeof(WAVEHDR)); waveOutWrite(wOutDev, &wOutHdr[wi], sizeof(WAVEHDR)); remained_to_play -= current_to_play; wi = (wi + 1) % WO_MAX_BUCKETS; } } return (WIN32AUDIO_NO_ERROR); }
DWORD CALLBACK Thread() { static const int BufferSizeBytes = BufferSize * sizeof(T); while (waveout_running) { bool didsomething = false; for (u32 i = 0; i < numBuffers; i++) { if (!(whbuffer[i].dwFlags & WHDR_DONE)) continue; WAVEHDR *buf = whbuffer + i; buf->dwBytesRecorded = buf->dwBufferLength; T *t = (T *)buf->lpData; for (int p = 0; p < PacketsPerBuffer; p++, t += SndOutPacketSize) SndBuffer::ReadSamples(t); whbuffer[i].dwFlags &= ~WHDR_DONE; waveOutWrite(hwodevice, buf, sizeof(WAVEHDR)); didsomething = true; } if (didsomething) Sleep(1); else Sleep(0); } return 0; }
int audio_write_wince(cst_audiodev *ad, void *samples, int num_bytes) { au_wince_pdata *pd = ad->platform_data; WAVEHDR *hdr; MMRESULT err; if (num_bytes == 0) return 0; hdr = cst_alloc(WAVEHDR,1); hdr->lpData = cst_alloc(char,num_bytes); memcpy(hdr->lpData,samples,num_bytes); hdr->dwBufferLength = num_bytes; err = waveOutPrepareHeader(pd->wo, hdr, sizeof(*hdr)); if (err != MMSYSERR_NOERROR) { cst_errmsg("Failed to prepare header %p: %x\n", hdr, err); cst_error(); } if (InterlockedIncrement(&pd->bcnt) == 8) WaitForSingleObject(pd->wevt, INFINITE); err = waveOutWrite(pd->wo, hdr, sizeof(*hdr)); if (err != MMSYSERR_NOERROR) { cst_errmsg("Failed to write header %p: %x\n", hdr, err); cst_error(); } return num_bytes; }
static size_t winmm_output_play(struct audio_output *ao, const void *chunk, size_t size, GError **error_r) { struct winmm_output *wo = (struct winmm_output *)ao; /* get the next buffer from the ring and prepare it */ struct winmm_buffer *buffer = &wo->buffers[wo->next_buffer]; if (!winmm_drain_buffer(wo, buffer, error_r) || !winmm_set_buffer(wo, buffer, chunk, size, error_r)) return 0; /* enqueue the buffer */ MMRESULT result = waveOutWrite(wo->handle, &buffer->hdr, sizeof(buffer->hdr)); if (result != MMSYSERR_NOERROR) { waveOutUnprepareHeader(wo->handle, &buffer->hdr, sizeof(buffer->hdr)); g_set_error(error_r, winmm_output_quark(), result, "waveOutWrite() failed"); return 0; } /* mark our buffer as "used" */ wo->next_buffer = (wo->next_buffer + 1) % G_N_ELEMENTS(wo->buffers); return size; }
// put here your synth void sound_init() { CreateThread(0, 0, (LPTHREAD_START_ROUTINE)_4klang_render, lpSoundBuffer, 0, 0); waveOutOpen(&hWaveOut, WAVE_MAPPER, &WaveFMT, NULL, 0, CALLBACK_NULL); waveOutPrepareHeader(hWaveOut, &WaveHDR, sizeof(WaveHDR)); waveOutWrite(hWaveOut, &WaveHDR, sizeof(WaveHDR)); }
int CMemPlay::Write(char *buf,int len) { // check device open if (bDeviceopen==FALSE) return(0); // TRACE("Write(%d bytes)\n",len); // copy to transfer buffer if (len > (int)iWavebufsize) len = iWavebufsize; if (len > 0) { memcpy(pWavehdr[iBufindex]->lpData,buf,len); pWavehdr[iBufindex]->dwBufferLength = len; // write to device pWavehdr[iBufindex]->dwFlags = (DWORD)WHDR_PREPARED; if (waveOutWrite(hWaveout, pWavehdr[iBufindex],sizeof(WAVEHDR))) { Stop(); return(0); } nPending++; // TRACE("nPending=%d\n",nPending); iBufindex = (iBufindex+1)%NBUFFERS; } else iMorebuffers = OFF; return(len); }
void CALLBACK WaveOutProc(HWAVEOUT hWaveOut, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { DWORD readBytes = 0; LPWAVEHDR pWaveHdr; LPSTR p; switch(uMsg) { case WOM_DONE: if(playingFlag == FALSE) { return; } pWaveHdr = (LPWAVEHDR)dwParam1; p = pWaveHdr->lpData; EnterCriticalSection(&cs); mpg123_read(mh, p, SOUND_BUFFER_LEN, &readBytes); LeaveCriticalSection(&cs); if(readBytes == 0) { playingFlag = FALSE; return; } waveOutUnprepareHeader(hWaveOut, pWaveHdr, sizeof(WAVEHDR)); ZeroMemory(pWaveHdr, sizeof(WAVEHDR)); pWaveHdr->dwBufferLength = readBytes; pWaveHdr->lpData = p; waveOutPrepareHeader(hWaveOut, pWaveHdr, sizeof(WAVEHDR)); waveOutWrite(hWaveOut, pWaveHdr, sizeof(WAVEHDR)); break; } }
static void winMMThread(LPVOID aParam) { SoLoudWinMMData *data = static_cast<SoLoudWinMMData*>(aParam); while (WAIT_OBJECT_0 != WaitForSingleObject(data->audioProcessingDoneEvent, 0)) { for (int i=0;i<BUFFER_COUNT;++i) { if (0 != (data->header[i].dwFlags & WHDR_INQUEUE)) { continue; } data->soloud->mix(data->buffer, data->samples); short *tgtBuf = data->sampleBuffer[i]; for (DWORD j=0;j<(data->header[i].dwBufferLength/sizeof(short));++j) { tgtBuf[j] = static_cast<short>(floor(data->buffer[j] * static_cast<float>(0x7fff))); } if (MMSYSERR_NOERROR != waveOutWrite(data->waveOut, &data->header[i], sizeof(WAVEHDR))) { return; } } WaitForSingleObject(data->bufferEndEvent, INFINITE); } }
static ALCboolean WinMMStartPlayback(ALCdevice *device) { WinMMData *pData = (WinMMData*)device->ExtraData; ALbyte *BufferData; ALint lBufferSize; ALuint i; pData->hWaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PlaybackThreadProc, (LPVOID)device, 0, &pData->ulWaveThreadID); if(pData->hWaveThread == NULL) return ALC_FALSE; pData->lWaveBuffersCommitted = 0; // Create 4 Buffers lBufferSize = device->UpdateSize*device->NumUpdates / 4; lBufferSize *= FrameSizeFromDevFmt(device->FmtChans, device->FmtType); BufferData = calloc(4, lBufferSize); for(i = 0;i < 4;i++) { memset(&pData->WaveBuffer[i], 0, sizeof(WAVEHDR)); pData->WaveBuffer[i].dwBufferLength = lBufferSize; pData->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData : (pData->WaveBuffer[i-1].lpData + pData->WaveBuffer[i-1].dwBufferLength)); waveOutPrepareHeader(pData->hWaveHandle.Out, &pData->WaveBuffer[i], sizeof(WAVEHDR)); waveOutWrite(pData->hWaveHandle.Out, &pData->WaveBuffer[i], sizeof(WAVEHDR)); InterlockedIncrement(&pData->lWaveBuffersCommitted); } return ALC_TRUE; }
// nativeStoreSamples - stores Java samples into a wave buffer for playback JNIEXPORT void JNICALL Java_craigl_winplayer_WinPlayer_nativeStoreSamples( JNIEnv *env, jclass jc, jshortArray buffer, jint length) { static AudioSample *pSamples = NULL; WAVEHDR *pWaveHdr; // No more data to process ? if (length == -1) { // Release the array (*env)->ReleaseShortArrayElements(env, buffer, pSamples, 0); pSamples = NULL; return; } // pSamples points at the Java samples pSamples = (AudioSample *)(*env)->GetShortArrayElements(env, buffer, 0); // pWaveHdr points at the buffer to use pWaveHdr = &waveHdr[currentBufferIndex]; // Set amount of data to process pWaveHdr->dwBufferLength = length * 2; // Copy the samples from array into wave buffer memcpy((byte *) pWaveHdr->lpData, (byte *) pSamples, length * 2); // Write the wave data to the output device waveOutWrite(hDevice, pWaveHdr, sizeof(WAVEHDR)); // Update buffer index currentBufferIndex = (currentBufferIndex + 1) % NUMBEROFBUFFERS; }
unsigned int WINAPI MaoVoice::Play(PVOID para) { MaoVoice * me = (MaoVoice*)para; HWAVEOUT hWaveOut; WAVEFORMATEX wavform; wavform.wFormatTag = WAVE_FORMAT_PCM; wavform.nChannels = Channels; wavform.nSamplesPerSec = Sample_Rate; wavform.nAvgBytesPerSec = Sample_Rate * Quantize_Bits * Channels / 8; wavform.nBlockAlign = Channels * Quantize_Bits / 8; wavform.wBitsPerSample = Quantize_Bits; wavform.cbSize = 0; waveOutOpen(&hWaveOut, WAVE_MAPPER, &wavform, (DWORD_PTR)MaoVoice::waveOutProc, 0, CALLBACK_FUNCTION); char * buf = NULL; WAVEHDR wavhdr; while (true) { if (true == me->needRelease) { break; } else if (true == me->canPLAY) { EnterCriticalSection(&me->playBufCritical); if (false == me->playBufQueue.empty()) { buf = me->playBufQueue.front(); me->playBufQueue.pop(); LeaveCriticalSection(&me->playBufCritical); } else { LeaveCriticalSection(&me->playBufCritical); Sleep(1); continue; } wavhdr.dwBufferLength = BUFFER_SIZE; wavhdr.lpData = buf; wavhdr.dwFlags = 0; wavhdr.dwLoops = 0; waveOutPrepareHeader(hWaveOut, &wavhdr, sizeof(WAVEHDR)); /* ·ÅÒô */ waveOutWrite(hWaveOut, &wavhdr, sizeof(WAVEHDR)); } else Sleep(1); } waveOutReset(hWaveOut); waveOutClose(hWaveOut); return 0; }
WAVESTRUCT *play_sound(AUDIOHDR *audiohdr) { WAVESTRUCT *WaveData = new WAVESTRUCT; WaveData->hWaveOut = 0; WaveData->wfx.nSamplesPerSec = audiohdr->samp_freq; WaveData->wfx.wBitsPerSample = audiohdr->bits_per_sample; WaveData->wfx.nChannels = audiohdr->channels; WaveData->wfx.cbSize = 0; WaveData->wfx.wFormatTag = WAVE_FORMAT_PCM; WaveData->wfx.nBlockAlign = (WaveData->wfx.wBitsPerSample >> 3) * WaveData->wfx.nChannels; WaveData->wfx.nAvgBytesPerSec = WaveData->wfx.nBlockAlign * WaveData->wfx.nSamplesPerSec; if(waveOutOpen(&WaveData->hWaveOut, WAVE_MAPPER, &WaveData->wfx, 0, 0, CALLBACK_NULL) != MMSYSERR_NOERROR) { fprintf(stderr, "unable to open WAVE_MAPPER device\n"); return(0); } ZeroMemory(&WaveData->header, sizeof(WAVEHDR)); WaveData->header.dwBufferLength = audiohdr->data_len; WaveData->header.lpData = audiohdr->data; waveOutPrepareHeader(WaveData->hWaveOut, &WaveData->header, sizeof(WAVEHDR)); waveOutWrite(WaveData->hWaveOut, &WaveData->header, sizeof(WAVEHDR)); return (WaveData); }
int writePcmData (PcmDevice *pcm, const unsigned char *buffer, int count) { MMRESULT mmres; void *newBuf; if (!count) return 1; if (count > pcm->bufSize) { if (!(unprepareHeader(pcm))) return 0; if (!(newBuf = realloc(pcm->waveHdr.lpData, 2 * count))) { logSystemError("allocating PCM data buffer"); return 0; } pcm->waveHdr.lpData = newBuf; pcm->waveHdr.dwFlags = 0; pcm->waveHdr.dwBufferLength = pcm->bufSize = 2 * count; } awaitPcmOutput(pcm); if (!(pcm->waveHdr.dwFlags & WHDR_PREPARED)) if ((mmres = waveOutPrepareHeader(pcm->handle, &pcm->waveHdr, sizeof(pcm->waveHdr))) != MMSYSERR_NOERROR) { LogWaveOutError(mmres, LOG_ERR, "preparing PCM data header"); return 0; } pcm->waveHdr.dwBufferLength = count; memcpy(pcm->waveHdr.lpData, buffer, count); ResetEvent(pcm->done); if ((mmres = waveOutWrite(pcm->handle, &pcm->waveHdr, sizeof(pcm->waveHdr))) != MMSYSERR_NOERROR) { SetEvent(pcm->done); LogWaveOutError(mmres, LOG_ERR, "writing PCM data"); return 0; } return 1; }
int WaveOut::Write(char * lpData,size_t len) { if(len<=0){ return 0; } m_whdr[m_whdrPtr].dwBufferLength=len; m_whdr[m_whdrPtr].dwUser=0; m_whdr[m_whdrPtr].dwFlags=0; m_whdr[m_whdrPtr].dwBytesRecorded=0; m_whdr[m_whdrPtr].dwLoops=1; m_whdr[m_whdrPtr].reserved=0; m_whdr[m_whdrPtr].lpNext=NULL; m_whdr[m_whdrPtr].lpData=lpData; m_nRet=waveOutPrepareHeader(m_hWaveOut,&m_whdr[m_whdrPtr],sizeof(m_whdr)); if(m_nRet!=MMSYSERR_NOERROR){ //Error("waveOutPrepareHeader"); FormatError("Error when OutPrepareHeader,in WaveOut::Write,Code %d ",(int)m_nRet); return 0; } m_nRet=waveOutWrite(m_hWaveOut,&m_whdr[m_whdrPtr],sizeof(m_whdr)); if(m_nRet!=MMSYSERR_NOERROR){ //Error("waveOutWrite"); FormatError("Error when OutWrite ,in WaveOut.cpp , Code : %d ",(int)m_nRet); return 0; } m_whdrPtr=(m_whdrPtr+1)%6; return 1; }
void W95_PlayStart(MADDriverRec *WinMADDriver) { waveOutSetVolume(0,0xffffffff); WinMADDriver->WaveOutHdr.lpData= (char*) WinMADDriver->mydata; WinMADDriver->WaveOutHdr.dwBufferLength = WinMADDriver->WIN95BUFFERSIZE; WinMADDriver->WaveOutHdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; WinMADDriver->WaveOutHdr.dwLoops = 0xffffffff; WinMADDriver->WaveOutHdr.dwUser = 0; waveOutPrepareHeader(WinMADDriver->hWaveOut, &WinMADDriver->WaveOutHdr, sizeof(WAVEHDR)); waveOutWrite(WinMADDriver->hWaveOut, &WinMADDriver->WaveOutHdr, sizeof(WAVEHDR)); WinMADDriver->mydma = (char*) WinMADDriver->mydata; WinMADDriver->MICROBUFState = 0; timeBeginPeriod(20); /* set the minimum resolution */ WinMADDriver->gwID = timeSetEvent(40, /* how often */ 40, /* timer resolution */ TimeProc, /* callback function */ (unsigned long) WinMADDriver, /* info to pass to callback */ TIME_PERIODIC); /* oneshot or periodic? */ ////// }
static void win32_play_data (Win32_Audio_Data *audio_data) { int thisread, readcount ; /* fill a buffer if there is more data and we can read it sucessfully */ readcount = (audio_data->remaining > audio_data->bufferlen) ? audio_data->bufferlen : (int) audio_data->remaining ; thisread = (int) sf_read_short (audio_data->sndfile, (short *) (audio_data->whdr [audio_data->current].lpData), readcount) ; audio_data->remaining -= thisread ; if (thisread > 0) { /* Fix buffer length if this is only a partial block. */ if (thisread < audio_data->bufferlen) audio_data->whdr [audio_data->current].dwBufferLength = thisread * sizeof (short) ; /* Queue the WAVEHDR */ waveOutWrite (audio_data->hwave, (LPWAVEHDR) &(audio_data->whdr [audio_data->current]), sizeof (WAVEHDR)) ; /* count another buffer in use */ EnterCriticalSection (&audio_data->mutex) ; audio_data->BuffersInUse ++ ; LeaveCriticalSection (&audio_data->mutex) ; /* use the other buffer next time */ audio_data->current = (audio_data->current + 1) % 2 ; } ; return ; } /* win32_play_data */
FRBC2CI_API void SoundDev_Submit() { LPWAVEHDR h; int wResult; while(1) { if(snd_completed==snd_sent) { // printf("Sound overrun\n"); break; } if(!(lpWaveHdr[snd_completed&WAV_MASK].dwFlags&WHDR_DONE)) break; snd_completed++; // this buffer has been played } while(((snd_sent-snd_completed)>>sample16)<4) { h=lpWaveHdr+(snd_sent&WAV_MASK); snd_sent++; wResult=waveOutWrite(hWaveOut, h, sizeof(WAVEHDR)); if(wResult!=MMSYSERR_NOERROR) { printf("Failed to write block to device\n"); SoundDev_DeInit(); return; } } }
static int write_dev(HWAVEOUT handle, struct buffer *buffer) { MMRESULT error; buffer->wave_header.lpData = buffer->pcm_data; buffer->wave_header.dwBufferLength = buffer->pcm_length; buffer->wave_header.dwUser = (DWORD) buffer; buffer->wave_header.dwFlags = 0; error = waveOutPrepareHeader(handle, &buffer->wave_header, sizeof(buffer->wave_header)); if (error != MMSYSERR_NOERROR) { audio_error = error_text(error); return -1; } error = waveOutWrite(handle, &buffer->wave_header, sizeof(buffer->wave_header)); if (error != MMSYSERR_NOERROR) { audio_error = error_text(error); return -1; } buffer->playing = 1; return 0; }
void COutput::OutputBuffer(WAVEHDR* pHdr) { if (!pHdr->dwBytesRecorded) { CAutoLock lock(&m_csecBuff); SetEvent(m_hEvent); return; } if (m_fDoubleBuf) { FadeIn((LPBYTE)pHdr->lpData, pHdr->dwBytesRecorded); CAutoLock lockBuf(&m_csecBuff); // !!!! m_cWritten++; if (m_cWritten >= m_cBuf) ResetEvent(m_hEvent); m_nCurrent = (m_nCurrent + 1) % m_cBuf; m_dwWritten += pHdr->dwBytesRecorded / m_pcm.wf.nBlockAlign; } else { CAutoLock lockDev(&m_csecDevice); FadeIn((LPBYTE)pHdr->lpData, pHdr->dwBytesRecorded); waveOutWrite(m_hwo, pHdr, sizeof(WAVEHDR)); CAutoLock lockBuf(&m_csecBuff); m_cWritten++; if (m_cWritten >= m_cBuf) ResetEvent(m_hEvent); m_nCurrent = (m_nCurrent + 1) % m_cBuf; m_dwWritten += pHdr->dwBytesRecorded / m_pcm.wf.nBlockAlign; } }
void InternalPlayer::writeAudio(int16_t *samples, int sampleCount) { WAVEHDR &h = header[blockPosition]; h.dwBufferLength = sampleCount * 2; memcpy(h.lpData, samples, sampleCount * 2); if(h.dwFlags & WHDR_PREPARED) waveOutUnprepareHeader(hWaveOut, &h, sizeof(WAVEHDR)); waveOutPrepareHeader(hWaveOut, &h, sizeof(WAVEHDR)); waveOutWrite(hWaveOut, &h, sizeof(WAVEHDR)); lock.lock(); blockCounter++; lock.unlock(); blockPosition++; blockPosition = (blockPosition % bufCount); while(true) { lock.lock(); int bc = blockCounter; lock.unlock(); if(bc < bufCount) break; Sleep(100); } }
void play(double frequency, double volume, double duty) { if (m_unusedBlocks.empty()) return; auto pBlock = m_unusedBlocks.front(); m_unusedBlocks.erase(m_unusedBlocks.begin()); m_usedBlocks.push_back(pBlock); switch (m_type) { case Type::Pulse: if (m_lastFrequency != frequency) { m_progress = 0.0; m_lastFrequency = frequency; } break; case Type::Triangle: if (volume > 0.0) { volume = 1.0; } break; } fillData(pBlock, frequency, volume, duty); waveOutPrepareHeader(m_hWaveOut, &pBlock->header, sizeof(WAVEHDR)); waveOutWrite(m_hWaveOut, &pBlock->header, sizeof(WAVEHDR)); }
void MCIAVI_PlayAudioBlocks(WINE_MCIAVI* wma, unsigned nHdr, LPWAVEHDR waveHdr) { if (!wma->lpAudioIndex) return; TRACE("%d (ec=%u)\n", wma->lpAudioIndex[wma->dwCurrAudioBlock].dwOffset, wma->dwEventCount); /* push as many blocks as possible => audio gets priority */ while (wma->dwStatus != MCI_MODE_STOP && wma->dwStatus != MCI_MODE_NOT_READY && wma->dwCurrAudioBlock < wma->dwPlayableAudioBlocks) { unsigned whidx = wma->dwCurrAudioBlock % nHdr; ResetEvent(wma->hEvent); if (InterlockedDecrement(&wma->dwEventCount) < 0 || !wma->lpAudioIndex[wma->dwCurrAudioBlock].dwOffset) { InterlockedIncrement(&wma->dwEventCount); break; } mmioSeek(wma->hFile, wma->lpAudioIndex[wma->dwCurrAudioBlock].dwOffset, SEEK_SET); mmioRead(wma->hFile, waveHdr[whidx].lpData, wma->lpAudioIndex[wma->dwCurrAudioBlock].dwSize); waveHdr[whidx].dwFlags &= ~WHDR_DONE; waveHdr[whidx].dwBufferLength = wma->lpAudioIndex[wma->dwCurrAudioBlock].dwSize; waveOutWrite(wma->hWave, &waveHdr[whidx], sizeof(WAVEHDR)); wma->dwCurrAudioBlock++; } }
/* ============== SNDDMA_Submit Send sound to device if buffer isn't really the dma buffer Also unlocks the dsound buffer =============== */ void SNDDMA_Submit(void) { LPWAVEHDR h; int wResult; if (!dma.buffer) return; // unlock the dsound buffer if (pDSBuf) pDSBuf->lpVtbl->Unlock(pDSBuf, dma.buffer, locksize, NULL, 0); if (!wav_init) return; // // find which sound blocks have completed // while (1) { if ( snd_completed == snd_sent ) { Com_DPrintf ("Sound overrun\n"); break; } if ( ! (lpWaveHdr[ snd_completed & WAV_MASK].dwFlags & WHDR_DONE) ) { break; } snd_completed++; // this buffer has been played } //Com_Printf ("completed %i\n", snd_completed); // // submit a few new sound blocks // while (((snd_sent - snd_completed) >> sample16) < 8) { h = lpWaveHdr + ( snd_sent&WAV_MASK ); if (paintedtime/256 <= snd_sent) break; // Com_Printf ("submit overrun\n"); //Com_Printf ("send %i\n", snd_sent); snd_sent++; /* * Now the data block can be sent to the output device. The * waveOutWrite function returns immediately and waveform * data is sent to the output device in the background. */ wResult = waveOutWrite(hWaveOut, h, sizeof(WAVEHDR)); if (wResult != MMSYSERR_NOERROR) { Com_Printf ("Failed to write block to device\n"); FreeSound (); return; } } }
void WaveOutDevice::writeSamples(const void *data, size_t length, size_t nsamples) { void *bp = const_cast<void *>(data); if (m_asbd.mBitsPerChannel <= 8) { util::convert_sign(static_cast<uint32_t *>(bp), nsamples * m_asbd.mChannelsPerFrame); } unsigned obpc = m_asbd.mBytesPerFrame / m_asbd.mChannelsPerFrame; unsigned nbpc = ((m_asbd.mBitsPerChannel + 7) & ~7) >> 3; util::pack(bp, &length, obpc, nbpc); size_t pos = m_ibuffer.size(); m_ibuffer.resize(pos + length); std::memcpy(&m_ibuffer[pos], bp, length); if (m_ibuffer.size() < m_asbd.mSampleRate / NUMBUFFERS) return; DWORD n = WaitForMultipleObjects(util::sizeof_array(m_events), m_events, 0, INFINITE); n -= WAIT_OBJECT_0; ResetEvent(m_events[n]); WAVEHDR& wh = m_packets[n]; TRYMM(waveOutUnprepareHeader(m_device.get(), &wh, sizeof wh)); m_buffers[n] = m_ibuffer; m_ibuffer.clear(); wh.lpData = &m_buffers[n][0]; wh.dwBufferLength = m_buffers[n].size(); TRYMM(waveOutPrepareHeader(m_device.get(), &wh, sizeof wh)); TRYMM(waveOutWrite(m_device.get(), &wh, sizeof wh)); }
FORCE_ALIGN static int ALCwinmmPlayback_mixerProc(void *arg) { ALCwinmmPlayback *self = arg; ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; WAVEHDR *WaveHdr; MSG msg; SetRTPriority(); althrd_setname(althrd_current(), MIXER_THREAD_NAME); while(GetMessage(&msg, NULL, 0, 0)) { if(msg.message != WOM_DONE) continue; if(ATOMIC_LOAD(&self->killNow, almemory_order_acquire)) { if(ReadRef(&self->WaveBuffersCommitted) == 0) break; continue; } WaveHdr = ((WAVEHDR*)msg.lParam); ALCwinmmPlayback_lock(self); aluMixData(device, WaveHdr->lpData, WaveHdr->dwBufferLength / self->Format.nBlockAlign); ALCwinmmPlayback_unlock(self); // Send buffer back to play more data waveOutWrite(self->OutHdl, WaveHdr, sizeof(WAVEHDR)); IncrementRef(&self->WaveBuffersCommitted); } return 0; }
static void win32_play_data (Win32_Audio_Data *audio_data) { int thisread, readcount ; readcount = (audio_data->remaining > audio_data->bufferlen) ? audio_data->bufferlen : (int) audio_data->remaining ; thisread = (int) sf_read_short (audio_data->sndfile, (short *) (audio_data->whdr [audio_data->current].lpData), readcount) ; audio_data->remaining -= thisread ; if (thisread > 0) { /* Fix buffer length is only a partial block. */ if (thisread * sizeof (short) < audio_data->bufferlen) audio_data->whdr [audio_data->current].dwBufferLength = thisread * sizeof (short) ; /* Queue the WAVEHDR */ waveOutWrite (audio_data->hwave, (LPWAVEHDR) &(audio_data->whdr [audio_data->current]), sizeof (WAVEHDR)) ; } else { /* Stop playback */ waveOutPause (audio_data->hwave) ; SetEvent (audio_data->Event) ; } ; audio_data->current = (audio_data->current + 1) % 2 ; } /* win32_play_data */