#include "precomp.h" // SHORT g_BeepSamples[] = {195,-4352,-14484,-8778,397,-1801,2376,12278,6830,-2053}; SHORT g_BeepSamples[] = {195,-4352,-12484,-8778,397,-1801,2376,10278,6830,-2053}; #define BL 1024 #if 0 DEFWAVEFORMAT g_wfDefList[] = { {WAVE_FORMAT_PCM, 1, 22050, 22050, 1, 8, 0}, {WAVE_FORMAT_PCM, 1, 11025, 11025, 1, 8, 0}, {WAVE_FORMAT_PCM, 1, 8000, 8000, 1, 8, 0}, {WAVE_FORMAT_PCM, 1, 5510, 5510, 1, 8, 0}, {WAVE_FORMAT_ADPCM, 1, 11025, 11025/2, BL, 4, 32, (BL-7)*2+2, 7, 0x0100,0x0000,0x0200,0xFF00,0x0000,0x0000,0x00C0,0x0040,0x00F0,0x0000,0x01CC,0xFF30,0x0188,0xFF18}, {WAVE_FORMAT_ADPCM, 1, 8000, 8000/2, BL, 4, 32, (BL-7)*2+2, 7, 0x0100,0x0000,0x0200,0xFF00,0x0000,0x0000,0x00C0,0x0040,0x00F0,0x0000,0x01CC,0xFF30,0x0188,0xFF18}, {WAVE_FORMAT_ADPCM, 1, 5510, 5510/2, BL, 4, 32, (BL-7)*2+2, 7, 0x0100,0x0000,0x0200,0xFF00,0x0000,0x0000,0x00C0,0x0040,0x00F0,0x0000,0x01CC,0xFF30,0x0188,0xFF18}, {WAVE_FORMAT_PCM, 1, 11025, 11025, 1, 8, 0}, }; #endif DEFWAVEFORMAT g_wfDefList[] = { {WAVE_FORMAT_VOXWARE,1,8000, 16000, 2, 16, 0}, {WAVE_FORMAT_PCM, 1, 8000, 8000, 1, 8, 0}, {WAVE_FORMAT_PCM, 1, 5510, 5510, 1, 8, 0}, {WAVE_FORMAT_ADPCM, 1, 8000, 4096, 256, 4, 32, 500, 7, 0x0100,0x0000,0x0200,0xFF00,0x0000,0x0000,0x00C0,0x0040,0x00F0,0x0000,0x01CC,0xFF30,0x0188,0xFF18}, {WAVE_FORMAT_ADPCM, 1, 5510, 2755, 256, 4, 32, 500, 7, 0x0100,0x0000,0x0200,0xFF00,0x0000,0x0000,0x00C0,0x0040,0x00F0,0x0000,0x01CC,0xFF30,0x0188,0xFF18}, {WAVE_FORMAT_GSM610,1, 8000, 1625, 65, 0, 2, 320, 240, 0}, {WAVE_FORMAT_ALAW, 1, 8000, 8000, 1, 8, 0}, {WAVE_FORMAT_PCM, 1, 11025, 11025, 1, 8, 0}, {WAVE_FORMAT_PCM, 1, 8000, 16000, 2, 16, 0}, }; WAVEFORMATEX * GetDefWaveFormat ( int idx ) { return ((idx < DWF_NumOfWaveFormats) ? (WAVEFORMATEX *) &g_wfDefList[idx] : (WAVEFORMATEX *) NULL); } ULONG GetWaveFormatSize ( PVOID pwf ) { return (((WAVEFORMAT *) pwf)->wFormatTag == WAVE_FORMAT_PCM ? sizeof (PCMWAVEFORMAT) : sizeof (PCMWAVEFORMAT) + sizeof (WORD) + ((WAVEFORMATEX *) pwf)->cbSize); } BOOL IsSameWaveFormat ( PVOID pwf1, PVOID pwf2 ) { UINT u1 = GetWaveFormatSize (pwf1); UINT u2 = GetWaveFormatSize (pwf2); BOOL fSame = FALSE; if (u1 == u2) { fSame = ! CompareMemory1 ((char *)pwf1, (char *)pwf2, u1); } return fSame; } void FillSilenceBuf ( WAVEFORMATEX *pwf, PBYTE pb, ULONG cb ) { if (pwf && pb) { if ((pwf->wFormatTag == WAVE_FORMAT_PCM) && (pwf->wBitsPerSample == 8)) { FillMemory (pb, cb, (BYTE) 0x80); } else { ZeroMemory (pb, cb); } } } void MakeDTMFBeep(WAVEFORMATEX *pwf, PBYTE pb, ULONG cb) { SHORT *pShort = (SHORT*)pb; int nBeepMod = sizeof (g_BeepSamples) / sizeof(g_BeepSamples[0]); int nIndex, nLoops = 0; BYTE bSample; if (pwf->wBitsPerSample == 16) { nLoops = cb / 2; for (nIndex=0; nIndex < nLoops; nIndex++) { pShort[nIndex] = g_BeepSamples[(nIndex % nBeepMod)]; } } else { nLoops = cb; for (nIndex=0; nIndex < nLoops; nIndex++) { bSample = (g_BeepSamples[(nIndex % nBeepMod)] >> 8) & 0x00ff; bSample = bSample ^ 0x80; pb[nIndex] = bSample; } } } char CompareMemory1 ( char * p1, char * p2, UINT u ) { char i; while (u--) { i = *p1++ - *p2++; if (i) return i; } return 0; } short CompareMemory2 ( short * p1, short * p2, UINT u ) { short i; while (u--) { i = *p1++ - *p2++; if (i) return i; } return 0; } long CompareMemory4 ( long * p1, long * p2, UINT u ) { long i; while (u--) { i = *p1++ - *p2++; if (i) return i; } return 0; } const DWORD WIN98GOLDBUILD = 1998; const DWORD WIN98GOLDMAJOR = 4; const DWORD WIN98GOLDMINOR = 10; inline bool ISWIN98GOLD() { OSVERSIONINFO osVersion; BOOL bRet; osVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); bRet = GetVersionEx(&osVersion); if ( bRet && ( (osVersion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) && (osVersion.dwMajorVersion == WIN98GOLDMAJOR) && (osVersion.dwMinorVersion == WIN98GOLDMINOR) // && // (osVersion.dwBuildNumber == WIN98GOLDBUILD) ) ) { return true; } return false; } // dwPacketSize is the size of the audio payload (excludes RTP header) // pwf represents the compressed audio format HRESULT InitAudioFlowspec(FLOWSPEC *pFlowspec, WAVEFORMATEX *pwf, DWORD dwPacketSize) { DWORD dwPacketOverhead = 0; OSVERSIONINFO osVersion; DWORD dwTotalSize; BOOL bRet; // on Windows 2000 and Win98 OSR, the FLOWSPEC needs to be set without regard // to the UDP/IP headers. // On Win98 Gold, FLOWSPEC needs to account for IP/UDP headers // no way to detect this without explicitly checking the version number if (ISWIN98GOLD()) { dwPacketOverhead = IP_HEADER_SIZE + UDP_HEADER_SIZE; } dwTotalSize = dwPacketOverhead + dwPacketSize + sizeof(RTP_HDR); // rather than specify the exact minimum bandwidth we need for audio, // make it slightly larger (10%) to account for bursts and beginning // of talk spurts // peakbandwidth is set another increment above TR, and bucket size // is adjusted high as well pFlowspec->TokenRate = (dwTotalSize * pwf->nAvgBytesPerSec) / dwPacketSize; pFlowspec->TokenRate = (11 * pFlowspec->TokenRate) / 10; // peak bandwidth is an ADDITIONAL 10% greater than TokenRate, so it's // really a 21% increase over the theoretical minimum pFlowspec->PeakBandwidth = (11 * pFlowspec->TokenRate) / 10; pFlowspec->TokenBucketSize = dwTotalSize * 4; pFlowspec->MinimumPolicedSize = dwTotalSize; pFlowspec->MaxSduSize = pFlowspec->MinimumPolicedSize; pFlowspec->Latency = QOS_NOT_SPECIFIED; pFlowspec->DelayVariation = QOS_NOT_SPECIFIED; pFlowspec->ServiceType = SERVICETYPE_GUARANTEED; return S_OK; } HRESULT InitVideoFlowspec(FLOWSPEC *pFlowspec, DWORD dwMaxBitRate, DWORD dwMaxFrag, DWORD dwAvgPacketSize) { DWORD dwPacketOverhead = 0; // I-Frames will be fragmented into 3 or 4 packets // and will be about 1000 bytes each // P-Frames average about 250 - 500 bytes each // we'll assume the reservation is a NetMeeting to NetMeeting call // so there will be few I-Frames sent if (ISWIN98GOLD()) { dwPacketOverhead = IP_HEADER_SIZE + UDP_HEADER_SIZE; } // for 28.8 modems, 11kbits/sec have already been allocated for audio // so only allocate 17kbits/sec for video. This means that some packets // will be "non-conforming" and may receive less than a best-effort services. // but this is believed to be better than having no RSVP/QOS at all // if this becomes an issue, then it may be better to have no RSVP/QOS at all // maxBitRate will be equal to 14400 (14.4 modem), 28000 (28.8 modem), 85000 (ISDN/DSL), or 621700 (LAN) // (* .70, so really it can be: 10080, 20160, 59500, 435190) if (dwMaxBitRate <= BW_144KBS_BITS) { dwMaxBitRate = 4000; // is it worth it to attempt QOS at 14.4 ? } else if (dwMaxBitRate <= BW_288KBS_BITS) { dwMaxBitRate = 17000; } pFlowspec->TokenRate = dwMaxBitRate / 8; pFlowspec->MaxSduSize = dwMaxFrag + dwPacketOverhead + sizeof(RTP_HDR); pFlowspec->MinimumPolicedSize = dwAvgPacketSize + dwPacketOverhead; pFlowspec->PeakBandwidth = (DWORD)(pFlowspec->TokenRate * 1.2); pFlowspec->TokenBucketSize = dwMaxFrag * 3; pFlowspec->Latency = QOS_NOT_SPECIFIED; pFlowspec->DelayVariation = QOS_NOT_SPECIFIED; pFlowspec->ServiceType = SERVICETYPE_CONTROLLEDLOAD; return S_OK; }