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

📄 csoundinput.cpp

📁 vc环境下的pgp源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
												passedThreshold = TRUE;
												break;
											}
										}
										else
										{
											if(*p >= mThreshold)
											{
												passedThreshold = TRUE;
												break;
											}
										}
									}
									if(!passedThreshold)
									{
										// The sound did not pass the amplitude test,
										// ditch it all so it never gets sent.
										
										mDownDone = 0;
										SetStatus(FALSE);
									}
									else
									{
										mTrailSamples = mDefaultTrail;
										SetStatus(TRUE);
									}
								}
							}
							break;
						case 8:
							break;
							/*{//	mSampleSize == 8
							char *p, *s, *e;
							
							downSize = newlen / mDownsampleD;
							p = (char *)src;
							e = p + newlen / mDownsampleD * mDownsampleD;
							s = mDownBuf + mDownDone;
							for(;p<e;p++)
							{
								if(!toggle)
									*s++ = *p;
								if(++toggle == mDownsampleD)
									toggle=0;
							}
							mDownDone += downSize;
							break;}*/
					}
					if(mDownDone >= mFrameSize)
					{
						if(!mCompSnd)
						{
							mCompSnd = safe_malloc(mCFrameSize * mFrames + mCoderSizeSlack);
							mCompDone = 0;
							// Record the sampling instant for RTP
						}
						s = (short *)mDownBuf;
						e = (short *)(mDownBuf + mDownDone);
						d = (uchar *)mCompSnd + mCompDone + (mCompDone ? mCoderSizeSlack : 0);
						de = (uchar *)mCompSnd + (mCFrameSize * mFrames) + mCoderSizeSlack;
						switch(mCodec)
						{
							case 'GS4L':
							case 'GS7L':
							case 'GS6L':
							case 'GL80':
							case 'GS1L':
							case 'GSM4':
							case 'GSM7':
							case 'GSM6':
							case 'GS80':
							case 'GSM1':
								for(;(d < de) && (e-s >= 160);s+=160,d+=mCFrameSize)
								{
									gsm_encode(mGSM, s, d);
									mCompDone += mCFrameSize;
								}
								pgp_memcpy(mDownBuf, s, (char *)e-(char *)s);
								mDownDone = (char *)e-(char *)s;
								break;
							case 'ADP8':
								if(!mCompDone)
								{
									SHORT_TO_BUFFER(mADPCM.valprev, d);	d += sizeof(short);
									*d++ = mADPCM.index;
								}
								for(;(d < de) && (e-s >= 160);s+=160,d+=mCFrameSize)
								{
									adpcm_coder(s,(char *)d,mFrameSize/2,&mADPCM);
									mCompDone += mCFrameSize;
								}
								pgp_memcpy(mDownBuf, s, (char *)e-(char *)s);
								mDownDone = (char *)e-(char *)s;
								break;
#ifdef USEVOXWARE
							case 'VOXW':{
								VOXWARE_RETCODE voxerr;
								
								mVoxComVars.lpSpeechBuffer = (uchar *)s;
								mVoxComVars.lpCodedDataBuffer = d;
								voxerr = RTEncode(&mVoxComVars);	pgpAssert(IsntErr(voxerr));
								d += mCFrameSize;
								mCompDone += mCFrameSize;
								s += mFrameSize / 2;
								pgp_memcpy(mDownBuf, s, (char *)e-(char *)s);
								mDownDone = (char *)e-(char *)s;
								break;}
#endif
							case 0:
								break;
						}
						if(d >= de)
						{
							pgpAssert(d == de);	//make sure we didn't go over
							if(mOutQueue->GetSize() < SOUNDINPUTQUEUEMAX)
								mOutQueue->Send(_mt_voicePacket, mCompSnd,
											mFrames * mCFrameSize + mCoderSizeSlack, 1);
							else
							{
								safe_free(mCompSnd);
								gPacketWatch->OverflowOut(1);
							}
							mCompSnd = NIL;
							mCompDone = 0;
						}
					}
				}
			}
			mOutdex += newlen;
			mOutdex %= mSampleBufSize;
		}
#ifdef	PGP_MACINTOSH
		if(mOpen)
		{
			::SPBGetDeviceInfo(mSoundRef, siLevelMeterOnOff, &levelInfo);
			mLevelMeter->SetLevel(levelInfo & 0xFFFF);
		}
#endif
		mSoundMutex.Signal();
#ifdef	PGP_MACINTOSH
		Yield(mOutThread);
#elif	PGP_WIN32
		Yield();
#endif
	}
	return (void *)1L;
}

void
CSoundInput::SetGain(short gain)
{
#ifdef	PGP_MACINTOSH
	ulong step = 0x00010000;
	
	mGain = 0x00007FFF + (step / 256 * gain);
	if(mOpen)
		::SPBSetDeviceInfo(mSoundRef, siInputGain, &mGain);
#elif	PGP_WIN32
	mGain = gain;
#endif	//PGP_WIN32
}

void
CSoundInput::DisposeCodec(void)
{
	mSoundMutex.Wait();
	switch(mCodec)
	{
		case 'GSM4':
		case 'GSM6':
		case 'GSM7':
		case 'GS80':
		case 'GSM1':
		case 'GS4L':
		case 'GS6L':
		case 'GS7L':
		case 'GL80':
		case 'GS1L':
			gsm_destroy(mGSM);
			break;
#ifdef USEVOXWARE
		case 'VOXW':{
			VOXWARE_RETCODE voxerr;
			
			voxerr = RTFreeEncoder(&mVoxComVars);	pgpAssert(IsntErr(voxerr));
			break;}
#endif
		case 'ADP8':
		case 0:
			break;
	}
	mCodec = 0;
	mSoundMutex.Signal();
}

void
CSoundInput::SetCodec(ulong type)
{
	short inx;
	
	mSoundMutex.Wait();
	DisposeCodec();
	mIndex = mOutdex = 0;
	mCoderSizeSlack = 0;
	switch(type)
	{
#ifdef USEVOXWARE
		case 'VOXW':{
			VOXWARE_RETCODE voxerr;
			ushort framesPerPkt;
			
			#ifdef	PGP_MACINTOSH
				mCoderRate = 0x1f400000;
			#elif	PGP_WIN32
				mCoderRate = 8000.0;
			#endif
			mSampleSize = 16;
			mCFrameSize = 30;	// We use less than 30 byte packets with Voxware!!
			mFrames = 1;
			voxerr = RTInitEncoder(&mVoxComVars, &mVoxCoderReqs);	pgpAssert(IsntErr(voxerr));
			if((mVoxCoderReqs.dwSamplingRate == 8000) &&
				(mVoxCoderReqs.wBytesPerSample == 2))
			{
				framesPerPkt = ((mCFrameSize * 8) / mVoxCoderReqs.wNumBitsPerFrame);
				mVoxComVars.dwNumBytesInSpeechBuffer =
					framesPerPkt * (mVoxCoderReqs.wNumSamplesPerFrame * mVoxCoderReqs.wBytesPerSample);
				mVoxComVars.dwNumBytesInCodedDataBuffer =
					((framesPerPkt * mVoxCoderReqs.wNumBitsPerFrame) / 8);
				mVoxComVars.dwNumBytesInCodedDataBuffer +=
					(0 != ((framesPerPkt * mVoxCoderReqs.wNumBitsPerFrame) % 8));
				mFrameSize = mVoxComVars.dwNumBytesInSpeechBuffer;
				mCFrameSize = mVoxComVars.dwNumBytesInCodedDataBuffer;
			}
			break;}
#endif
		case 'ADP8':
			mSampleSize = 16;
			mFrameSize = 320;
			mCFrameSize = 80;
			mFrames = 4;
			memset(&mADPCM, 0, sizeof(adpcm_state));
			mCoderSizeSlack = 3;
			#ifdef	PGP_MACINTOSH
				mCoderRate = 0x1f400000;
			#elif	PGP_WIN32
				mCoderRate = 8000.0;
			#endif
			break;
		case 'GS4L':
		case 'GS6L':
		case 'GS7L':
		case 'GL80':
		case 'GS1L':				/* 160 shorts -> 29 bytes			*/
			mGSM = gsm_create();
			mFrameSize = 320;
			mCFrameSize = 29;
			mSampleSize = 16;
			switch(type)
			{
				case 'GS4L':		// 4410 hz
					#ifdef	PGP_MACINTOSH
						mCoderRate = 0x113A0000;
					#elif	PGP_WIN32
						mCoderRate = 4410.0;
					#endif
					mFrames = 2;
					break;
				case 'GS5L':		// 5512 hz
					#ifdef	PGP_MACINTOSH
						mCoderRate = 0x15880000;
					#elif	PGP_WIN32
						mCoderRate = 5512.0;
					#endif
					mFrames = 3;
					break;
				case 'GS6L':		// 6000 hz
					#ifdef	PGP_MACINTOSH
						mCoderRate = 0x17700000;
					#elif	PGP_WIN32
						mCoderRate = 6000.0;
					#endif
					mFrames = 3;
					break;
				case 'GS7L':		// 7350 hz
					#ifdef	PGP_MACINTOSH
						mCoderRate = 0x1cb60000;
					#elif	PGP_WIN32
						mCoderRate = 7350.0;
					#endif
					mFrames = 4;
					break;
				case 'GL80':		// 8000 hz
					#ifdef	PGP_MACINTOSH
						mCoderRate = 0x1f400000;
					#elif	PGP_WIN32
						mCoderRate = 8000.0;
					#endif
					mFrames = 5;
					break;
				case 'GS8L':		// 8820 hz
					#ifdef	PGP_MACINTOSH
						mCoderRate = 0x22740000;
					#elif	PGP_WIN32
						mCoderRate = 8820.0;
					#endif
					mFrames = 6;
					break;
				case 'GS1L':		// 11025 hz
					#ifdef	PGP_MACINTOSH
						mCoderRate = rate11025hz;
					#elif	PGP_WIN32
						mCoderRate = 11025.0;
					#endif
					mFrames = 6;
					break;
			}
			inx = 1;
			gsm_option(mGSM, GSM_OPT_LTP_CUT, &inx);
			break;
		case 'GSM4':
		case 'GSM6':
		case 'GSM7':
		case 'GS80':
		case 'GSM1':				/* 160 shorts -> 33 bytes		4.8:1 */
			mGSM = gsm_create();
			mFrameSize = 320;
			mCFrameSize = 33;
			mSampleSize = 16;
			switch(type)
			{
				case 'GSM4':		// 4410 hz
					#ifdef	PGP_MACINTOSH
						mCoderRate = 0x113A0000;
					#elif	PGP_WIN32
						mCoderRate = 4410.0;
					#endif
					mFrames = 2;
					break;
				case 'GSM6':		// 6000 hz
					#ifdef	PGP_MACINTOSH
						mCoderRate = 0x17700000;
					#elif	PGP_WIN32
						mCoderRate = 6000.0;
					#endif
					mFrames = 3;
					break;
				case 'GSM7':		// 7350 hz
					#ifdef	PGP_MACINTOSH
						mCoderRate = 0x1cb60000;
					#elif	PGP_WIN32
						mCoderRate = 7350.0;
					#endif
					mFrames = 4;
					break;
				case 'GS80':		// 8000 hz
					#ifdef	PGP_MACINTOSH
						mCoderRate = 0x1f400000;
					#elif	PGP_WIN32
						mCoderRate = 8000.0;
					#endif
					mFrames = 5;
					break;
				case 'GSM1':		// 11025 hz
					#ifdef	PGP_MACINTOSH
						mCoderRate = rate11025hz;
					#elif	PGP_WIN32
						mCoderRate = 11025.0;
					#endif
					mFrames = 6;
					break;
			}
			break;
		case 'rand':
			mFrames = 100;
			mFrameSize = 2;
			mCFrameSize = 2;
			mSampleSize = 16;
			break;
		default:
			/* unknown codec */
			pgp_errstring("CSoundInput: Bad Codec");
			break;
	}
	mUpSampleSize = FALSE;
	if(mHardwareIs16Bit)
	{
		if(mOpen)
		{
#ifdef PGP_MACINTOSH
			::SPBSetDeviceInfo(mSoundRef, siSampleSize, &mSampleSize);
#elif	PGP_WIN32
			//Not implemented yet, careful using 8 bit coders on WIN32.
			//We dont have any 8 bit coders right now.
#endif
		}
	}
	else if(mSampleSize == 16)
		mUpSampleSize = TRUE;
	/*
	// Use the following code to force 8 bit samples
	mUpSampleSize = TRUE;	inx=8;
	::SPBSetDeviceInfo(mSoundRef, siSampleSize, &inx);
	*/
	
	mSampleBufSize = INSAMPLEBUFMAX / mFrameSize * mFrameSize;
#ifdef	PGP_MACINTOSH
	mDefaultTrail = mCoderRate >> 16;	// send for half a second
#elif	PGP_WIN32
	mDefaultTrail = mCoderRate;			// send for half a second
#endif
	mCodec = type;
	// Tell the packet thread milliseconds between packets
	if(mPacketThread)
		mPacketThread->SetSound(1000.0 /
				((float)mDefaultTrail / ((float)(mFrames * (mFrameSize / 2)))));
	mTrailSamples = 0;
	mPFWindow->SetEncoder(type);
	mSoundMutex.Signal();
}

void
CSoundInput::Record(Boolean record)
{
#ifdef PGP_WIN32
	short i;
	int err;
#endif

	mSoundMutex.Wait();
	if(mRecording != record)
	{
		mRecording = record;
		if(mRecording)
		{
			SetStatus(TRUE);
			mLevelMeter->SetStatus(TRUE);
			Open();
			if(mCompSnd)
				safe_free(mCompSnd);
			mCompSnd = NIL;
			mCompDone = 0;
			mDownDone = 0;
			mTrailSamples = 0;
#ifdef	PGP_MACINTOSH
			mSPB.count = 0;
			mSPB.milliseconds = 0;
			mSPB.bufferLength = 0;
			mSPB.bufferPtr = NIL;
			::SPBRecord(&mSPB, TRUE);
#elif	PGP_WIN32
			SetThreadPriority(mThreadHandle, THREAD_PRIORITY_NORMAL);
			mHeaderIndex = sHeaderIndex = 0;
			for(i=0;i<NUMINPUTBUFFERS;i++)
			{
				if(!(mHeaders[i].dwFlags & WHDR_PREPARED))
				{
					mHeaders[i].dwBufferLength = RAWRECORDQUANT;
					mHeaders[i].lpData = (char *)mMemPtrs[i];
					err = waveInPrepareHeader(mWaveHandle, &(mHeaders[i]), sizeof(WAVEHDR));
					CheckWaveError("waveInPrepareHeader", err);
				}
				err = waveInAddBuffer(mWaveHandle, &(mHeaders[i]), sizeof(WAVEHDR));
				CheckWaveError("waveInAddBuffer", err);
			}
			// start recording
			err = waveInStart(mWaveHandle);
			CheckWaveError("waveInStart", err);
#endif
		}
		else
		{
			SetStatus(FALSE);
			mLevelMeter->SetStatus(FALSE);
#ifdef	PGP_MACINTOSH
			::SPBStopRecording(mSoundRef);
#elif	PGP_WIN32
			err = waveInReset(mWaveHandle);
			CheckWaveError("waveInReset", err);
#endif
			Close();
#ifdef	PGP_WIN32
			// Wait until all of the blocks are finished.
			// This is necessary to ensure that half duplex
			// machines do not open the output before the input
			// is finished.

			for(i=0;i<NUMINPUTBUFFERS;i++)
				while(mHeaders[i].dwFlags && !(mHeaders[i].dwFlags & WHDR_DONE))
					Sleep(0);
#endif
		}
	}
	mSoundMutex.Signal();
}

void
CSoundInput::Pause(Boolean pause)
{
	mSoundMutex.Wait();
	mPaused = pause;
	if(mCompSnd)
		safe_free(mCompSnd);
	mCompSnd = NIL;
	mCompDone = 0;
	mDownDone = 0;
	mTrailSamples = 0;
	SetStatus(!pause);
	mSoundMutex.Signal();
}

void
CSoundInput::SetOutput(LThread *outThread, CMessageQueue *outQueue)
{
	mSoundMutex.Wait();
	mOutThread = outThread;
	mOutQueue = outQueue;
	mSoundMutex.Signal();
}

void
CSoundInput::SetPacketThread(CPFPacketsOut *packetThread)
{
	mSoundMutex.Wait();
	mPacketThread = packetThread;
	mSoundMutex.Signal();
}

void
CSoundInput::SetThreshold(long thresh)
{
	// We are given a threshold value from 0-32767
	// representing the amplitude which we should
	// require before sending sound packets
	pgpAssert(thresh <= MAX_THRESHOLD);
	
	mThreshold = thresh;
	mTrailSamples = 0;
	if(mRecording)
		SetStatus(TRUE);
}

void
CSoundInput::SetStatus(Boolean status)
{
	// We set the window to the actual status just to let the user know,
	// but if we are not in a real call, we set our internal status
	// to false.
	mPFWindow->SetSoundInStatus(status);
	if(mPacketThread)
	{
		if(mCodec == 'rand')
			mPacketThread->SetSoundStatus(FALSE);
		else
			mPacketThread->SetSoundStatus(status);
	}
}

void
CSoundInput::AbortSync()
{
	mAbort = TRUE;
#ifdef PGP_WIN32
	long count;
	ReleaseSemaphore(siSemaphore, 1, &count);
#endif
}

void Amplify(short *samples, int numSamples, double gain)
{
    /*
     * The following is equivalent to gain * 256, but rounds to the
     * nearest integer instead of truncating the fractional part
     */
    short x = (gain * 512 + 1) / 2;

    while (numSamples--)
    {
		*samples = ((long)*samples * x) >> 8;
		samples++;
    }
}

⌨️ 快捷键说明

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