Yes conditional branches can be expensive causing pipeline stalls. But in my implementation using streams of rays there is only one hard to predict branch and that branch is only taken once per processed stream so it is not really that important. But a c++/assembly mix looks alittle bit messy. Thats why I removed the branch table from my inline assembly function to improve code readability at the expense of code size. Expanding the number of rays per stream to a multiple of four is for me not an option because rays are partitioned in place. Meaning that the filtered stream or output stream should be of the same length compared to the input stream. Thanks :)
Remco Hoogenboezem
Posts
-
Label adresses in inline assembly -
Label adresses in inline assemblyHello Stuart and David, Thank you for your replies. Both solutions given are practical I think. I intended to use the branch table inside a time ciritcal part of my ray-tracer (ray vs axis aligned bounding box intersection test). I am building a stream ray-tracer using the sse ALU processing four rays in parallel. But the number of rays to process is not always a multiple of four to process the last 1,2 or 3 rays I thought to use a branch table. But I think I will make a funciton one for each case and use a switch statement ouside of the filter functions making the code easier to read and the c++ compiler does emit the code I would like. Thank you for your help!!
-
Label adresses in inline assemblyHello, I would like to emit the lable addresses from a bit of inline assembly code into a branch table but I could not figure out how to do it. I would say it should look something like this. At least the compiler emits something like this for a switch statement. I am using visual studio 2005. __asm { mov eax,BRANCHTABLE mov ecx,"Number between 0 and N" jmp [eax+ecx*4] BRANCHTABLE &LABLE0 &LABLE1 &LABLE2 ... &LABLEN LABLE0: ... LABLE1: ... LABLE2: ... ... LABLEN } Thanks ;)
-
Question on DirectDrawHello, I am looking for a callback function or event (I prefere a callback function) that is called or signaled in case your surface is lost and you are able to restore it. In case of a change of display mode this can easily be done with the message WM_DISPLAYCHANGE. But in case the user presses for example crtl+alt+del (An other application gets exclusive acces to the hardware) then this event is not given. Thanks :)
-
Start a powerpoint slideshow from C++ (.pps file)Hi I would like to start a powerpoint slideshow from C++ the way it is done by the shell. I think this is possible by using OLE automation but I could not find a good example to help me on the way. I prefere to use slideshow viewer only if this is possible. (don't use powerpoint) I am not using MFC. Thanks: cool:
-
Loading the correct iconsHi, I am trying to make a custom treeview in C++ to display the shell's namespace. It works great for all folders except physical drives and remote or network folders. I can't get the correct icons for these folders. I am using the following code snippet to load the icons for the specified folder: (Only need to obtain the icon index) //Retrieve the icon closed for the folder if(SHGetFileInfo((LPCSTR)lpItemIDList1,0,&fileInfo,sizeof(SHFILEINFO),SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_SYSICONINDEX)==NULL) { lpMalloc->Free(lpItemIDList1); lpEnumIDList->Release(); if(lpSubFolder) { lpSubFolder->Release(); } return FALSE; } lpTreeNode->ImageIndex=fileInfo.iIcon; //Retrieve the icon opened for the folder if(SHGetFileInfo((LPCSTR)lpItemIDList1,0,&fileInfo,sizeof(SHFILEINFO),SHGFI_OPENICON|SHGFI_PIDL|SHGFI_SMALLICON|SHGFI_SYSICONINDEX)==NULL) { lpMalloc->Free(lpItemIDList1); lpEnumIDList->Release(); if(lpSubFolder) { lpSubFolder->Release(); } return FALSE; } lpTreeNode->SelectedIndex=fileInfo.iIcon; The pointer lpItemIDList1 points to a piddle that contains the absolute location of the specified folder. (Relative to the root aka desktop folder) I am only trying to display folders. Thanks :)
-
Blitting a palettized surface to a none palettized surfaceI have created a palettized (256 color entries) directdraw off-screen surface. And a none palettized directdraw primary surface. I would like to blit the palettized surface to the none palettized surface while maintaining the color information present in the palettized surface. The cooperation level is set to DDSCL_NORMAL. I have attached a clipper to the primary surface and I have attached a palette to the off-screen surface. This construction does not work! And the directdraw documentation gives me the awnser why not: "It is important to note that DirectDraw blits never perform color conversion; any palettes attached to the source or destination surface of a blit are ignored" Is their any solution to this problem without having to do the color conversion yourself? It would be a lot less complicated!! Thanks :cool:
-
Rounding up to a multiple of a numberI would like to round a LONG to a multiple of an other LONG. For example: I have got the number 5 and i would like to round it up to a multiple of 3. I wrote the following code to do this: lCurrent=((lMinimum+(lIncrement-1))/lIncrement)*lIncrement; In this piece of code lMinimum is de value that gets rounded up. And lIncrement is the value to wich lMinimum is rounded up. So if we choose the numbers mentioned above we get 6. This works fine for positive numbers but when we choose a negative number for lMinimum it goes wrong. I wrote another piece of code to handle negative numbers lCurrent=abs(lMinimum%lIncrement)+lMinimum; So combining the two we get: if(lMinimum>=0) { lCurrent=((lMinimum+(lIncrement-1))/lIncrement)*lIncrement; } else { lCurrent=abs(lMinimum%lIncrement)+lMinimum; } This is the obvious way and it contains one conditional branch. I was wondering of someone came accros a bit twiddling hack to do this more efficient. Thanks ;)
-
finding Audio LevelHello Poornima, You could also try the FFTW subroutine library. The functions are easy to use and competitive with vendor tuned code. :) http://www.fftw.org/
-
Compression/Decompression Wave File to MP3 and vice versaHello Cindy, I think you should read the msdn on audio compression manager. Look for the functions calls that start with acm. (e.g. acmDriverEnum) De audio compression manager features: · Transparent run-time audio compression and decompression · Waveform-audio data format selection · Waveform-audio data filter selection · Waveform-audio data format conversion · Waveform-audio data filtering You can choose any audio driver present on the current system. (I guess) Succes. :)
-
Hardware MonitoringHello honae, What kind of tests?? CPU arithmetic tests, 3D capabilities, memory bandwith, file I/O performance etc... ?? :confused:
-
Problem with wave audio input deviceHello Blake Miller, Thank you for your reply! I know that waveInReset returns all pending buffers to the application. But it returns all buffers with the dwBufferLength member marked to 0 on my system. Even the buffer that contains say 200 samples. (The buffer that was not returned using waveInStop) I am sorry but I don't think this would solve the problem. (I ve tryed it on my PC and on another PC) Thank you :)
-
Problem with wave audio input deviceHello everybody, A week ago or so I have posted a message with the same title. I have solved this problem. But now I ve got a new one. I do the following: Start recording with the wave audio input device. Using the function waveInStart() During recording all waveheaders that are returned to the application are processed and added to the wave audio input device again. Using the function waveInAddBuffer() Driver messages are processed using a dedicated thread. (Using the flag CALLBACK_THREAD in the function waveInOpen) After recording for a while the recording is stopped. Using the function waveInStop() Now I need to mark the last waveheader with a time stamp. Before I stop the wave audio input device I query the current sample using the function waveInGetPosition() (All waveheaders are of the same size) dwLastWaveHeader=(dwCurrentSample-1)/nSamplesInEachWaveHeader; Oke this works. But in some very very rare cases the current data record is not returned to the application. (Happens when the current buffer is only filled for say 200 samples and less) My question is how to make sure that the current buffer is returned to the application? :) Thank you
-
Problem with wave audio input deviceHello everybody, For my project I need to record some data from the wave audio inut device. To do this I have created a class CWaveIn wich simply encapsulate the standard windows calls waveInOpen() waveInClose() waveInAddBuffer() etc... When I open the wave audio input device I use the WAVE_MAPPER flag. I use a dedicated thread to process the driver messages. I only process the WIM_DATA driver messages. The dedicated thread calls a user defined callback function to store the signal to disk and do some computations on the data. These computations are CPU expensive so it is possible that at some point in time there are more than one WIM_DATA messages on the message queue of the dedicated thread. In my project I need to mark the first and the last waveheader in a serie of waveheaders with a start and stop time respectivly. Oke to mark the first waveheader is easy just simply set a flag when the user presses the start button and clear the flag in the callback function. But to mark the last waveheader is a lot more complicated. I use the waveInGetPosition() function directly after the user stopped the wave audio input device. (All waveheaders are of the same size) Devide this number by the size of the waveheaders and voila you have got the last waveheader. (Since recording started) Oke this works perfectly for large waveheaders. (0.1 seconds and bigger) But when I use small waveheaders I lose one WIM_DATA message in a series of WIM_DATA messages? The current position (waveinGetPosition) is one wavheader ahead of the number of waveheaders I ve received from the device driver. Thank you :)
-
faster method of bitmap readingHmm the fastest way to load files into memory that I know if is by using memory mapped files. Map the entire file into your process address space. I assume that you are using a bitmap file format?? You could do something like this: HANDLE hFile; HANDLE hFileMappingObject; BYTE * lpBaseAddress; BITMAPFILEHEADER * lpBitmapFileHeader; BITMAPINFOHEADER * lpBitmapInfoHeader; RGBQUAD * lpRGBQuad; BYTE * lpColorIndexArray; if(OpenDialog1->Execute()) { hFile=CreateFile(OpenDialog1->FileName.c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile==INVALID_HANDLE_VALUE) { MessageBox(Handle,"Could not open file","Error",MB_OK|MB_ICONERROR); return; } hFileMappingObject=CreateFileMapping(hFile,NULL,PAGE_READWRITE|SEC_COMMIT,0,0,NULL); if(hFileMappingObject==NULL) { MessageBox(Handle,"Could not create file mapping object","Error",MB_OK|MB_ICONERROR); CloseHandle(hFile); return; } lpBaseAddress=(BYTE*)MapViewOfFile(hFileMappingObject,FILE_MAP_WRITE,0,0,0); if(lpBaseAddress==NULL) { MessageBox(Handle,"Could not map view of file","Error",MB_OK|MB_ICONERROR); CloseHandle(hFileMappingObject); CloseHandle(hFile); return; } lpBitmapFileHeader=(BITMAPFILEHEADER*)&lpBaseAddress[0]; lpBitmapInfoHeader=(BITMAPINFOHEADER*)&lpBaseAddress[sizeof(BITMAPFILEHEADER)]; lpRGBQuad=(RGBQUAD*)&lpBaseAddress[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)]; lpColorIndexArray=&lpBaseAddress[lpBitmapFileHeader->bfOffBits]; //Use lpColorIndexArray to acces your RGB values UnmapViewOfFile(lpBaseAddress); CloseHandle(hFileMappingObject); CloseHandle(hFile); }
-
OpenGLYou could go to the website nehe.gamedev.net/ you will find some good tutorials on opengl at this site. :)
-
Question about waveInGetPositionThe system function call waveInGetPosition retrieves the current input position of the given waveform-audio input device. The function call returns the position in the parameter MMTIME in the given format. (if possible) In my application I use the TIME_SAMPLES format wich specifies the current position in an offset in samples since the last time the waveform-audio input device was reset. My question is: What would happen if a recording gets to long (nSamples>(2^32)-1). I think it just simply wraps around the current position but I am not sure about this. (I have never tried) And it would take me about 12 hours to figure out by myself. (4294967296/96000/3600=12.43) :zzz: Thanks. :)
-
Speed againHello hint_54 When I would like to know how much time it takes to execute a particulary piece of code and this piece of code is very short I read the CPU time stamp twice. (Assuming that you are running a pentium class processor) The CPU time stamp is a 64 bits counter that runs on the same frequency as your CPU does. So with this you ll be able to measure very short times very accurate. Oke this function is written in asm for the Borland compiler. //--------------------------------------------------------------------------- //Read CPU time stamp //--------------------------------------------------------------------------- __int64 CWaveIn::CPUTimeStamp(void) { asm { xor eax,eax xor ebx,ebx xor ecx,ecx xor edx,edx cpuid rdtsc } } //--------------------------------------------------------------------------- The instruction rdtsc reads the CPU time stamp and returns its value in register eax and edx. So you could do the folowing ULONGLONG qwStartTime; ULONGLONG qwStopTime; qwStartTime=CPUTimeStamp(); //Place code here... qwStopTime=CPUTimeStamp(); //Time? qwStopTime-qwStartTime; Succes :)
-
16 Byte alignment supportI would like to align some static variables (floats) to 16 byte boundary's so I can use SSE instructions to speed up calculations. In microsoft visual C++ this is very simple: __declspec(align(16)) float A[65536]; &A[0]=0x???????0 But for my current project I have to use Borland C++ compiler. The Borland compiler does not support the align keyword. It is very easy to align dynamic variables to 16 byte boundary's using the function VirtualAlloc: lpAddress=VirtualAlloc(NULL,65536*4,MEM_COMMIT,PAGE_READWRITE); lpAddress=0x????0000 But if it is possible I would like to use static variables. I have tryed the following: typedef struct { CHAR cPadding[16]; }PADDING; #pragma pack(16) PADDING padding; FLOAT A[65536]; #pragma pack() #pragma pack(16) LONG DOUBLE padding1; LONG padding2; SHORT padding3; FLOAT A[65536]; #pragma pack() but this does not work. Does anyone have experience with this?? Thank You in advance:)
-
How to get voice dataHello pakFari, You can use the standard windows functions to do this: MMRESULT waveInOpen ( LPHWAVEIN phwi, UINT uDeviceID, LPWAVEFORMATEX pwfx, DWORD dwCallback, DWORD dwCallbackInstance, DWORD fdwOpen ); MMRESULT waveInPrepareHeader ( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh ); MMRESULT waveInAddBuffer ( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh ); MMRESULT waveInStart ( HWAVEIN hwi ); MMRESULT waveInUnprepareHeader ( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh ); MMRESULT waveInClose ( HWAVEIN hwi ); Details on these functions can be found in de Win32 Developer's References. I wrote a little example program to demonstrate these functions. This example records 60 seconds of low quality audio from the wave audio input device. I use a simple event callback mechanisme to signal the thread when recording is done. There are more elegant way's of doing this. But i think it is up to you to discover how... HANDLE hEvent; HWAVEIN hWaveIn; WAVEFORMATEX WaveFormat= { 1, //wFormatTag 1, //nChannels 8000, //nSamplesPerSec 8000, //nAvgBytesPerSec 1, //nBlockAlign 8, //wBitsPerSample 0 //cbSize }; WAVEHDR WaveHeader; hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); if(hEvent==NULL) { //Handle error return; } //Open wave audio input device if(waveInOpen(&hWaveIn,WAVE_MAPPER,&WaveFormat,(DWORD)hEvent,0,CALLBACK_EVENT)!=MMSYSERR_NOERROR) { //Handle Error return; } WaveHeader.lpData=new BYTE[60*WaveFormat.nAvgBytesPerSec]; WaveHeader.dwBufferLength=60*WaveFormat.nAvgBytesPerSec; WaveHeader.dwFlags=0; //Prepare a wave header for waveform-audio input if(waveInPrepareHeader(hWaveIn,&WaveHeader,sizeof(WAVEHDR))!=MMSYSERR_NOERROR) { //Handle Error return; } //Send a input buffer to the given waveform-audio input device if(waveInAddBuffer(hWaveIn,&WaveHeader,sizeof(WAVEHDR))!=MMSYSERR_NOERROR) { //Handle Error return; } if(waveInStart(hWaveIn)!=MMSYSERR_NOERROR) { //Handle Error return; } ResetEvent(hEvent); WaitForSingleObject(hEvent,INFINI