⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 frame.c

📁 IP网络语音通讯软件源代码. 不可多得的语音源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
						mreq.imr_multiaddr.s_addr = multiAddr[i].s_addr;
						if (setsockopt(s->asdata, IPPROTO_IP, what,
								(char *) &mreq, sizeof mreq) == -1) {
				            int serr = WSAGetLastError();
					            
					        MsgBox(hwnd, MB_ICONSTOP | MB_OK,
					                Format(9),
					                (LPSTR) (join ? Format(10) : Format(11)), inet_ntoa(multiAddr[i]),
					                serr, SockerrToString(serr));
						} else {
							setsockopt(s->asctrl, IPPROTO_IP, what, (char *) &mreq, sizeof mreq);
						}
					}
				}
			}
			s = s->asnext;
		}		
	}
	what = join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP; 
	mreq.imr_interface.s_addr = htonl(INADDR_ANY);
	for (i = 0; i < multiMemberships; i++) {
		mreq.imr_multiaddr.s_addr = multiAddr[i].s_addr;
		if (setsockopt(sCommand, IPPROTO_IP, what,
				(char *) &mreq, sizeof mreq) == -1) {
            int serr = WSAGetLastError();
	            
	        MsgBox(hwnd, MB_ICONSTOP | MB_OK,
	                Format(9),
	                (LPSTR) (join ? Format(10) : Format(11)), inet_ntoa(multiAddr[i]),
	                serr, SockerrToString(serr));
		} else {
			setsockopt(sControl, IPPROTO_IP, what, (char *) &mreq, sizeof mreq);
		}
		if (!join && multiName[i] != NULL) {
			GlobalFreePtr(multiName[i]);
			multiName[i] = NULL;
		}	
	}
	recursed--;
}
#endif

/*  ISHALFDUPLEX  --  Try to open audio input and output simultaneously.
					  If it fails, mark the hardware half-duplex.  */
					  
static int isHalfDuplex(HWND hwnd)
{
    PCMWAVEFORMAT wfi;
	MMRESULT woo;
	int hdx = FALSE;

#ifdef POINTY_HEAD
{
	HGLOBAL h, h1;
	LPSTR p;

	h = GlobalAlloc(GPTR, 1024);
	p = GlobalLock(h);
	h1 = GlobalHandle(p);
	GlobalUnlockPtr(h);
	GlobalFree(h);
}
#endif
	
	if (waAudio11025) {
		samplesPerSecond = 11025;
		bytesPerSecond = samplesPerSecond * 2;
	}
    	
	wfi.wf.wFormatTag = WAVE_FORMAT_PCM;
	wfi.wf.nChannels = audioChannels;
	
	//	Input initialisation
    	
	while (TRUE) {
    	wfi.wf.nSamplesPerSec = samplesPerSecond;
    	wfi.wf.nAvgBytesPerSec = bytesPerSecond;
    	wfi.wf.nBlockAlign = sampleAlignment;
    	wfi.wBitsPerSample = bitsPerSample;
 		woo = waveInOpen(&hWaveIn, waAudioInDevice, (LPWAVEFORMATxx) &wfi,
 				0L, 0L, WAVE_FORMAT_QUERY);
 		if (bitsPerSample > 8 && woo == WAVERR_BADFORMAT) {
 			audioIs8Bit = TRUE;
 		} 
	 				
 		/* If our preferred mode (16 bit) isn't supported, try falling
 		   back to bottom-feeder 8 bit per sample mode. */			
	
 		if ((audioUse8Bit || woo == WAVERR_BADFORMAT) && (bitsPerSample > 8)) {
 			bitsPerSample /= 2;
 			sampleAlignment /= 2;
 			bytesPerSecond /= 2;	
	    	wfi.wf.nAvgBytesPerSec = bytesPerSecond;
	    	wfi.wf.nBlockAlign = sampleAlignment;
	    	wfi.wBitsPerSample = bitsPerSample;
	 		woo = waveInOpen(&hWaveIn, waAudioInDevice, (LPWAVEFORMATxx) &wfi,
	 				0L, 0L, WAVE_FORMAT_QUERY);
 		}
	 		
 		/* If we've failed to initialise in either 16 or 8 bit mode
 		   at 8000 samples per second, it's possible the sound card
 		   doesn't support any sampling mode below the Windows standard
 		   of 11025 samples per second.  Have another go-round and see
 		   if 11025 works. */
	 		
 		if (woo == WAVERR_BADFORMAT && samplesPerSecond == 8000) {
 			samplesPerSecond = 11025;
 			bitsPerSample = 16;
 			sampleAlignment = bitsPerSample / 8;
 			bytesPerSecond = samplesPerSecond * sampleAlignment;  
 		} else {
 			break;
 		}
 	} 
	if (woo != 0) {
    	MessageBox(hwnd, rstring(IDS_T_WAVE_RECORD_FORMAT_ERR),
	   		NULL, MB_OK | MB_ICONEXCLAMATION);
		return -1;
	}
    if ((woo = waveInOpen(&hWaveIn, waAudioInDevice,
		  (LPWAVEFORMATxx) &wfi, (DWORD) (UINT) hwnd, 0L, (DWORD) CALLBACK_WINDOW)) != 0) {
    	char et[MAXERRORLENGTH];
			    
    	waveInGetErrorText(woo, et, sizeof et);
    	MessageBox(hwnd, et, rstring(IDS_T_ERR_OPEN_WAVE_INPUT), MB_OK | MB_ICONEXCLAMATION);
		return -1;
    }
    aboutInBits = bitsPerSample;
    aboutInSamples = samplesPerSecond;
    
    /* If workaround is set, close input now and mark half-duplex
       without waiting for the open of output to fail. */
    
    if (waAudioHalf) {
    	waveInClose(hWaveIn);
    	hdx = halfDuplex = TRUE;
    }
    
    //	Output initialisation

	while (TRUE) {
 		woo = waveOutOpen(&hWaveOut, waAudioOutDevice, (LPWAVEFORMATxx) &wfi,
 								0L, 0L, WAVE_FORMAT_QUERY);
 		if (bitsPerSample > 8 && woo == WAVERR_BADFORMAT) {
 			audioIs8Bit = TRUE;
 		} 
	 				
 		/* If our preferred mode (16 bit, 11025 samples/second) isn't
 		   supported, try falling back to bottom-feeder 8 bit per sample
 		   mode. */			
	
 		if ((audioUse8Bit || woo == WAVERR_BADFORMAT) && bitsPerSample > 8) {
 			bitsPerSample /= 2;
 			sampleAlignment /= 2;
 			bytesPerSecond /= 2;	
	    	wfi.wf.nAvgBytesPerSec = bytesPerSecond;
	    	wfi.wf.nBlockAlign = sampleAlignment;
	    	wfi.wBitsPerSample = bitsPerSample;
	 		woo = waveOutOpen(&hWaveOut, waAudioOutDevice, (LPWAVEFORMATxx) &wfi,
	 				0L, 0L, WAVE_FORMAT_QUERY);
 		}
	 		
 		/* If we've failed to initialise in either 16 or 8 bit mode
 		   at 8000 samples per second, it's possible the sound card
 		   doesn't support any sampling mode below the Windows standard
 		   of 11025 samples per second.  Have another go-round and see
 		   if 11025 works. */
	 		
 		if (woo == WAVERR_BADFORMAT && samplesPerSecond == 8000) {
 			samplesPerSecond = 11025;
 			bitsPerSample = 16;
 			sampleAlignment = bitsPerSample / 8;
 			bytesPerSecond = samplesPerSecond * sampleAlignment;  
 		} else {
 			break;
 		}
 	} 
 		
	if (woo != 0) {				
    	char et[MAXERRORLENGTH];
	    	
    	waveOutGetErrorText(woo, et, sizeof et);
    	MessageBox(hwnd, et, rstring(IDS_T_WAVE_PLAY_FORMAT_ERR),
	   		MB_OK | MB_ICONEXCLAMATION);
    	hdx = -1;
		goto FatalAudioExit;
	}
    if ((woo = waveOutOpen(&hWaveOut, waAudioOutDevice,
		  (LPWAVEFORMATxx) &wfi, (DWORD) (UINT) hwnd, 0, (DWORD) CALLBACK_WINDOW)) != 0) {
    	char et[MAXERRORLENGTH];
	    	
    	/* The next line looks wrong, doesn't it?  But I've seen drivers
    	   for half-duplex sound boards that return NOTSUPPORTED instead
    	   of ALLOCATED when you try to open input and output at the
    	   same time. */
		    
	    if (!waAudioHalf && (woo == MMSYSERR_ALLOCATED || woo == MMSYSERR_NOTSUPPORTED)) {
			hdx = halfDuplex = TRUE;
			waveInClose(hWaveIn);
			if (waveOutOpen(&hWaveOut, waAudioOutDevice,
		  			(LPWAVEFORMATxx) &wfi, (DWORD) (UINT) hwnd, 0,
		  			(DWORD) CALLBACK_WINDOW) == 0) {
			    aboutOutBits = bitsPerSample;
			    aboutOutSamples = samplesPerSecond;
			    waveOutClose(hWaveOut);
			    goto HdxAudioExit;						  		
		  	}
	    } else {	
	    	waveOutGetErrorText(woo, et, sizeof et);
	        MessageBox(hwnd, et, rstring(IDS_T_ERR_OPEN_WAVE_OUTPUT),
				MB_OK | MB_ICONEXCLAMATION);
			hdx = -1;
	    }
	} else {
	    aboutOutBits = bitsPerSample;
	    aboutOutSamples = samplesPerSecond;
		waveOutClose(hWaveOut);
	}
	
FatalAudioExit:
	if (!waAudioHalf) {
    	waveInClose(hWaveIn);
    }
HdxAudioExit:
    return hdx;
}					  

/*	WAVEOUTSHUTDOWN  --  Shutdown wave audio output, if open.  */
						 
static void waveOutShutdown(void)
{
	if (outputActive) {
		V waveOutReset(hWaveOut);
		if (outputPending) {
			outputInShutdown = TRUE;
	    	propUpdateAudio();
		} else {
			V waveOutClose(hWaveOut);
			outputActive = FALSE;
	    	propUpdateAudio();
		}
	}
}
/*	INPUTSAMPLECOUNT  --  Calculate best sample count for an audio input
						  buffer based on the current compression
						  modes and the characteristics of the audio
						  hardware.  */
						   
int inputSampleCount(void)
{
	int l = 0;
	
	switch (protocolSent) {
		case PROTOCOL_SPEAKFREE:	
			l = lpc10compress ? (180 * (compression ? 20 : 10)) :
					(lpccompress ? (compression ? LPC_FRAME_SIZE * 20 : LPC_FRAME_SIZE * 10) : 
						((gsmcompress || voxcompress) ?
							(compression ? 3200 : 1600) :
							((512 - (sizeof(soundbuf) - BUFL)) * (compression ? 2 : 1))));
			if (adpcmcompress) {
				l *= 2;
				l -= 4;				  	// Leave room for state at the end
			}
			break;
			
		case PROTOCOL_RTP:
			if (waProtUseLargerRTCPackets) {
				l = lpccompress ? (LPC_FRAME_SIZE * 10) :
						(gsmcompress ? 1600 : 480);
			} else {
				l = (gsmcompress | lpccompress | adpcmcompress) ? (160 * 4) : 480;
			}
			break;
				
		case PROTOCOL_VAT:
			l = (gsmcompress | lpccompress | adpcmcompress) ? (160 * 4) : 320;
			break;	
	}
	return l;
}						  													 

/*	INPUTBUFFERLENGTH  --  Calculate best length in bytes for an audio input
						   buffer based on the current compression
						   modes and the characteristics of the audio
						   hardware.  */
						   
static int inputBufferLength(void)
{
	return (bitsPerSample / 8) * inputSampleCount();
}						  													 

/*	STARTWAVEINPUT  --  Activate wave audio input.  Returns TRUE
						if successful, FALSE if no input will be
						forthcoming for some twiddley reason or
						another.  The window handle is simply used
						as the parent for the message boxes announcing
						the bad news.  */

int startWaveInput(HWND hwnd)
{
    //	Attempt to initialise the audio input port
    
    if (!inputActive) {
    	int i;
	    PCMWAVEFORMAT wfi;    
    	MMRESULT woo;
    	
    	wfi.wf.wFormatTag = WAVE_FORMAT_PCM;
    	wfi.wf.nChannels = audioChannels;
    	
    	while (TRUE) {
	    	wfi.wf.nSamplesPerSec = samplesPerSecond;
	    	wfi.wf.nAvgBytesPerSec = bytesPerSecond;
	    	wfi.wf.nBlockAlign = sampleAlignment;
	    	wfi.wBitsPerSample = bitsPerSample;
	 		woo = waveInOpen(&hWaveIn, waAudioInDevice, (LPWAVEFORMATxx) &wfi,
	 				0L, 0L, WAVE_FORMAT_QUERY);
	 		if (bitsPerSample > 8 && woo == WAVERR_BADFORMAT) {
	 			audioIs8Bit = TRUE;
	 		} 
	 				
	 		/* If our preferred mode (16 bit) isn't supported, try falling
	 		   back to bottom-feeder 8 bit per sample mode. */			
	
	 		if ((audioUse8Bit || woo == WAVERR_BADFORMAT) && (bitsPerSample > 8)) {
	 			bitsPerSample /= 2;
	 			sampleAlignment /= 2;
	 			bytesPerSecond /= 2;	
		    	wfi.wf.nAvgBytesPerSec = bytesPerSecond;
		    	wfi.wf.nBlockAlign = sampleAlignment;
		    	wfi.wBitsPerSample = bitsPerSample;
		 		woo = waveInOpen(&hWaveIn, waAudioInDevice, (LPWAVEFORMATxx) &wfi,
		 				0L, 0L, WAVE_FORMAT_QUERY);
	 		}
	 		
	 		/* If we've failed to initialise in either 16 or 8 bit mode
	 		   at 8000 samples per second, it's possible the sound card
	 		   doesn't support any sampling mode below the Windows standard
	 		   of 11025 samples per second.  Have another go-round and see
	 		   if 11025 works. */
	 		
	 		if (woo == WAVERR_BADFORMAT && samplesPerSecond == 8000) {
	 			samplesPerSecond = 11025;
	 			bitsPerSample = 16;
	 			sampleAlignment = bitsPerSample / 8;
	 			bytesPerSecond = samplesPerSecond * sampleAlignment;  
	 		} else {
	 			break;
	 		}
	 	} 
		if (woo != 0) {
        	MessageBox(hwnd, rstring(IDS_T_WAVE_RECORD_FORMAT_ERR),
		   		NULL, MB_OK | MB_ICONEXCLAMATION);
			return FALSE;
    	}
    	for (i = 0; i < 2; i++) {
		    if ((woo = waveInOpen(&hWaveIn, waAudioInDevice,
				  (LPWAVEFORMATxx) &wfi, (DWORD) (UINT) hwndMDIFrame, 0L, (DWORD) CALLBACK_WINDOW)) != 0) {
		    	char et[MAXERRORLENGTH];
			    
	    	
		    	/* The next line looks wrong, doesn't it?  But I've seen drivers
		    	   for half-duplex sound boards that return NOTSUPPORTED instead
		    	   of ALLOCATED when you try to open input and output at the
		    	   same time. */
		    
			    if (i == 0 && outputActive && (woo == MMSYSERR_ALLOCATED || 
			    		woo == MMSYSERR_NOTSUPPORTED)) {
			    
			    	/* Okay, the preponderance of evidence points at our
			    	   machine being burdened with a half-duplex audio
			    	   device--one where the fact that we're playing audio
			    	   prevents from from simultaneously receiving it.
			    	   This is bad.  Let's proceed as we'd have done on

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -