WASAPI - Streamcopy mittels thread



  • Mahlzeit,

    Ich versuche den Audio-stream von einer Endpointdevice mittels Loopback auf eine andere device zu kopieren.
    Das ganze funktioniert teilweise, nur habe ich auf der Ziel-device keinen sauberen audiostream, es tönt zwar - aber nicht schön.

    Das Initialisieren der stream-devices, GetBuffer usw. scheint also zu funktionieren, nur das kopieren des Stream's scheint nicht ganz hinzuhauen. Ich kopiere den Stream in einem zyklischen Thread mit ThreadPriority::Highest dennoch kriege ich kein schönes Audiosignal...

    Stream-Copy:

    HRESULT ChannelDeviceHandler::CopyStream(){
    
    	HRESULT hr;
    	BYTE *pSrcData; 
    	BYTE *pDstData;
        UINT32 availableFrames; 
        DWORD flags;
    	UINT32 numFramesPadding;
    	UINT32 numFramesAvailable;
    	UINT32 bufSize;
    
    	//Copy Stream
    	//-------------
    	for(UINT channel = 1; channel <= CHANNELNUM; channel++){
    
    		if (this->channelVar[channel].pAudioClient != NULL){
    			hr = this->channelVar[channel].pAudioClient->GetCurrentPadding(&numFramesPadding);
    
    			numFramesAvailable = this->channelVar[channel].bufferFrameCount - numFramesPadding;		//Size Outstream
    			hr = this->pSrcCaptureClient->GetNextPacketSize(&availableFrames); 		//Size Instream
    
    			if (numFramesAvailable>availableFrames){	//Output > Input
    				bufSize = availableFrames;
    			}
    			else{
    				bufSize = numFramesAvailable;
    			}
    
    			if (bufSize > 0) { 
    
    				//Get Buffers
    				//-----------
    				pDstData = NULL;
    				pSrcData = NULL;
    
    				hr = this->channelVar[channel].pRenderClient->GetBuffer(bufSize, &pDstData);
    				hr = this->pSrcCaptureClient->GetBuffer(&pSrcData, &availableFrames, &flags, NULL, NULL);
    
    				//Copy Datastream
    				for(UINT32 i = 0; i < (bufSize*8); i++){
    
    					*pDstData++ = *pSrcData++;
    				}
    
    				hr = this->channelVar[channel].pRenderClient->ReleaseBuffer(bufSize, flags);
    				hr = this->pSrcCaptureClient->ReleaseBuffer(bufSize);
    
    			}
    
    		}
    	}
    
    	//free(pBuffer);
    	return 0;
    
    };
    

    Thread:

    CyclicThread::CyclicThread(ChannelDeviceHandler *chHandler){
    	HRESULT hr;
    
    	//Copy Object reference to member
    	this->chHandler = chHandler;
    
    }
    
    void CyclicThread::CyclicProc(){
    
    	while(true){
    
    		this->chHandler->CyclicCall(1, 0.01);
    		//Thread::Sleep();
    	}
    
    }
    
    private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
    
    				 DWORD dwRet;
    				 HRESULT hr;
    				 LPWSTR devName = (LPWSTR) malloc(200);
    
    				 //Create Object
    				 channelDevice = new ChannelDeviceHandler();
    				 cycle = gcnew CyclicThread(channelDevice);
    
    				 dwRet = GetPrivateProfileString(TEXT("Devices"),TEXT("DevName1"),TEXT(""),devName,200, TEXT("c:\\myFile.ini"));
    
    				 if(wcscmp(devName,TEXT(""))){
    					 comboBox1->Items->Add(gcnew String(devName));
    					 comboBox1->SelectedItem = gcnew String(devName);
    				 }
    
    				 //Start Capture
    				 hr= channelDevice->StartLoopBackCapture();
    
    				 //start thread
    				 cycThread = gcnew Thread( gcnew ThreadStart(cycle, &CyclicThread::CyclicProc ) );
    				 cycThread->Priority = ThreadPriority::Highest;
    				 cycThread->Start();
    
    				 //free PTR
    				 free(devName);
    
    			 }
    

    Wenn ich den Thread langsamer mache (mittels Sleep(5)), wird das Signal schlechter, daher denke ich dass es ein Timing-Problem sein könnte, aber was soll ich machen wenn ein eigener Thread mit ThreadPriority::Highest nicht reicht?

    PS:
    -Die Pufferzeit der Soundkarte ist HnsRequestedDuration = 100000 -> 10ms
    -Framesize = 8 Byte sollte auch stimmen (2 Kanäle, 32Bit auflösung)
    -Das ganze läuft unter VC++ Express 2010 - CLR FORM's-Projekt



  • PS: CyclicCall() ruft CopyStream() auf...


Anmelden zum Antworten