See what's going on with flipcode!




This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

 

  SoundServer
  Submitted by



SoundServer - Written by Arnaud Carré (aka Leonard / OXYGENE)
Part of the "Leonard Homepage Articles".
http://leonard.oxg.free.fr
Read the complete article on my web page: PART 1: Using WaveOut API.
How to make a SoundServer under windows, to play various sound.
WARNING: This sample plays a 44.1Khz, 16bits, mono sound. Should be quite easy to modify ! :-) arnaud.carre@freesurf.fr WARNING: You have to link this with the Windows MultiMedia library. (WINMM.LIB)

Currently browsing [soundserver.zip] (2,401 bytes) - [SoundServer.h] - (1,489 bytes)

/*********************************************************************************

SoundServer - Written by Arnaud Carré (aka Leonard / OXYGENE) Part of the "Leonard Homepage Articles".

PART 1: Using WaveOut API. How to make a SoundServer under windows, to play various sound. WARNING: This sample plays a 44.1Khz, 16bits, mono sound. Should be quite easy to modify ! :-)

Read the complete article on my web page:

http://leonard.oxg.free.fr arnaud.carre@freesurf.fr

WARNING: You have to link this with the Windows MultiMedia library. (WINMM.LIB)

*********************************************************************************/


#ifndef __SOUNDSERVER__ #define __SOUNDSERVER__

#define REPLAY_RATE 44100 #define REPLAY_DEPTH 16 #define REPLAY_SAMPLELEN (REPLAY_DEPTH/8) #define REPLAY_NBSOUNDBUFFER 2 typedef void (*USER_CALLBACK) (void *pBuffer,long bufferLen);

class CSoundServer {

public:

CSoundServer(); ~CSoundServer();

BOOL open( USER_CALLBACK pUserCallback, long totalBufferedSoundLen=4000); // Buffered sound, in ms void close(void);

// Do *NOT* call this internal function: void fillNextBuffer(void);

private: BOOL m_bServerRunning; HWND m_hWnd; long m_bufferSize; long m_currentBuffer; HWAVEOUT m_hWaveOut; WAVEHDR m_waveHeader[REPLAY_NBSOUNDBUFFER]; void *m_pSoundBuffer[REPLAY_NBSOUNDBUFFER]; USER_CALLBACK m_pUserCallback; };

#endif

Currently browsing [soundserver.zip] (2,401 bytes) - [SoundServer.cpp] - (3,753 bytes)

/*********************************************************************************

SoundServer - Written by Arnaud Carré (aka Leonard / OXYGENE) Part of the "Leonard Homepage Articles". http://leonard.oxg.free.fr Read the complete article on my web page:

PART 1: Using WaveOut API. How to make a SoundServer under windows, to play various sound. WARNING: This sample plays a 44.1Khz, 16bits, mono sound. Should be quite easy to modify ! :-)

arnaud.carre@freesurf.fr

WARNING: You have to link this with the Windows MultiMedia library. (WINMM.LIB)

*********************************************************************************/


#include <windows.h> #include "SoundServer.h"

// Internal WaveOut API callback function. We just call our sound handler ("playNextBuffer") static void CALLBACK waveOutProc(HWAVEOUT hwo,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2) { if (uMsg == WOM_DONE) { CSoundServer *pServer = (CSoundServer*)dwInstance; if (pServer) pServer->fillNextBuffer(); } }

CSoundServer::CSoundServer() { m_pUserCallback = NULL; m_bServerRunning = FALSE; m_currentBuffer = 0; }

CSoundServer::~CSoundServer() { close(); }

BOOL CSoundServer::open(USER_CALLBACK pUserCallback,long totalBufferedSoundLen) {

m_pUserCallback = pUserCallback; m_bufferSize = ((totalBufferedSoundLen * REPLAY_RATE) / 1000) * REPLAY_SAMPLELEN; m_bufferSize /= REPLAY_NBSOUNDBUFFER;

WAVEFORMATEX wfx; wfx.wFormatTag = 1; // PCM standart. wfx.nChannels = 1; // Mono wfx.nSamplesPerSec = REPLAY_RATE; wfx.nAvgBytesPerSec = REPLAY_RATE*REPLAY_SAMPLELEN; wfx.nBlockAlign = REPLAY_SAMPLELEN; wfx.wBitsPerSample = REPLAY_DEPTH; wfx.cbSize = 0; MMRESULT errCode = waveOutOpen( &m_hWaveOut, WAVE_MAPPER, &wfx, (DWORD)waveOutProc, (DWORD)this, // User data. (DWORD)CALLBACK_FUNCTION);

if (errCode != MMSYSERR_NOERROR) return FALSE;

// Alloc the sample buffers. for (int i=0;i<REPLAY_NBSOUNDBUFFER;i++) { m_pSoundBuffer[i] = malloc(m_bufferSize); memset(&m_waveHeader[i],0,sizeof(WAVEHDR)); }

// Fill all the sound buffers m_currentBuffer = 0; for (i=0;i<REPLAY_NBSOUNDBUFFER;i++) fillNextBuffer();

m_bServerRunning = TRUE; return TRUE; }



void CSoundServer::close(void) {

if (m_bServerRunning) { m_pUserCallback = NULL; waveOutReset(m_hWaveOut); // Reset tout. for (int i=0;i<REPLAY_NBSOUNDBUFFER;i++) { if (m_waveHeader[m_currentBuffer].dwFlags & WHDR_PREPARED) waveOutUnprepareHeader(m_hWaveOut,&m_waveHeader[i],sizeof(WAVEHDR));

free(m_pSoundBuffer[i]); } waveOutClose(m_hWaveOut); m_bServerRunning = FALSE; } }



void CSoundServer::fillNextBuffer(void) {

// check if the buffer is already prepared (should not !) if (m_waveHeader[m_currentBuffer].dwFlags&WHDR_PREPARED) waveOutUnprepareHeader(m_hWaveOut,&m_waveHeader[m_currentBuffer],sizeof(WAVEHDR));

// Call the user function to fill the buffer with anything you want ! :-) if (m_pUserCallback) m_pUserCallback(m_pSoundBuffer[m_currentBuffer],m_bufferSize);

// Prepare the buffer to be sent to the WaveOut API m_waveHeader[m_currentBuffer].lpData = (char*)m_pSoundBuffer[m_currentBuffer]; m_waveHeader[m_currentBuffer].dwBufferLength = m_bufferSize; waveOutPrepareHeader(m_hWaveOut,&m_waveHeader[m_currentBuffer],sizeof(WAVEHDR));

// Send the buffer the the WaveOut queue waveOutWrite(m_hWaveOut,&m_waveHeader[m_currentBuffer],sizeof(WAVEHDR));

m_currentBuffer++; if (m_currentBuffer >= REPLAY_NBSOUNDBUFFER) m_currentBuffer = 0;

}

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

 

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.