public mainForm() { if (QueryPerformanceFrequency(out freq) == false) { throw new Win32Exception(); } InitializeComponent(); AsyncCompletionRoutineDelegate = new QuickUsb.BulkStreamCompletionRoutine(AsyncCompletionRoutine); StreamCompletionRoutineDelegate = new QuickUsb.BulkStreamCompletionRoutine(StreamCompletionRoutine); }
public mainForm() { InitializeComponent(); // We must keep an active reference to the delegate so it is not garbage collected cbDelegate = new QuickUsb.BulkStreamCompletionRoutine(CompletionRoutine); for (int k = 0; k < NumRequests; ++k) { // Allocate the BulkStream objects bulkStream[k] = new QuickUsb.BulkStream(); // Allocate the data objects BufferArray[k] = new ushort[BufferByteSize / 2]; } }
public mainForm() { InitializeComponent(); // We must keep an active reference to the delegate so it is not garbage collected cbDelegate = new QuickUsb.BulkStreamCompletionRoutine(CompletionRoutine); // Allocate buffers if (UserAllocatedBuffers) { for (int k = 0; k < NumBuffers; ++k) { // Allocate the data buffers in unmanaged memory BufferArray[k] = new ushort[BufferByteSize / 2]; } } }
public Form1() { InitializeComponent(); cbDelegate = new QuickUsb.BulkStreamCompletionRoutine(CompletionRoutine); pbFrame.Size = new Size(FrameWidth, FrameHeight); int width = (this.Width - this.ClientSize.Width) + pbFrame.Width + 6; int height = (this.Height - this.ClientSize.Height) + pbFrame.Height + statusStrip1.Height + 6; this.Size = new Size(width, height); image = new Bitmap(FrameWidth, FrameHeight, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); ColorPalette palette = image.Palette; for (int k = 0; k < palette.Entries.Length; ++k) { palette.Entries[k] = Color.FromArgb(255, k, k, k); } image.Palette = palette; // Set the initial image (black) pbFrame.Image = image; }
///////////////////////////////////// // QuickUSB Bulk Streaming Example // ///////////////////////////////////// static void Main(string[] args) { // The number of data buffers to use. An asynchronous data request is issued // for each data buffer, then the main thread waits for each request to complete // then issues a new asynchrnonous request using the same data buffer as the // completed request. To maximize throughout, the number of buffers should be // at least equal to the number of threads (see the SETTING_THREADS setting). uint NumBuffers = 4; // The byte size of the buffers. To maximize performance the buffer size should // be as large as possible and a power of 2. uint BufferByteSize = 512 * 1024; // 512 KB // The number of threads to process the data stream. If NumThreads > 0, then // you are multithreading and must make sure to process access to shared data // from within completion routines. Note that all threads may not be used. The // more processing a completion routine does the more likely another thread will // be used. ushort NumThreads = 4; // The number of processing threads allowed to execute completion routines // concurrenty. If NumThreads > 0, you are multithreading and // ThreadConcurrency must be at least 1. ushort ThreadConcurrency = 2; // The Streaming API (for data reads) can use either data buffers allocated // internally by the QuickUSB API or data buffers allocate by the user. This // example demonstrates how to do either. bool UserAllocatedBuffers = true; // Variables QuickUsb qusb; int k; string[] nameList; bool qResult; QuickUsb.Error qusbError; byte streamID; // The data buffers, BulkStream objects, and tag objects. Because these objects // are passed to and used by unmanaged code in QuickUSB land, they must be handled // with care. They cannot be relocated by the garbage collector and must either // be pinned or allocated in unmanaged memory. Refer to the QuickUsbBulkAsyncCs // sample on how to properly use user 'tag' data. ushort[][] BufferArray = new ushort[NumBuffers][]; // We must keep an active reference to the delegate so it is not garbage collected. // This reference must minimally stay alive until all pending asynchronous requests // have completed. QuickUsb.BulkStreamCompletionRoutine cbDelegate = new QuickUsb.BulkStreamCompletionRoutine(CompletionRoutine); // Query connected modules nameList = QuickUsb.FindModules(); if (nameList.Length == 0) { Console.WriteLine("No modules found."); return; } // Open the first module string name = nameList[0]; Console.WriteLine("Using Device: " + name); qusb = new QuickUsb(name); qResult = qusb.Open(name); if (!qResult) { qusb.Close(); return; } // Display the ID of the currently executing thread (the main thread) Console.WriteLine("Number of processors: " + Environment.ProcessorCount.ToString()); Console.WriteLine("Main thread id: " + Thread.CurrentThread.ManagedThreadId.ToString()); Console.WriteLine(); // Allocate buffers if (UserAllocatedBuffers) { for (k = 0; k < NumBuffers; ++k) { // Allocate the data buffers in unmanaged memory BufferArray[k] = new ushort[BufferByteSize / 2]; } } // Start throughput timer QueryPerformanceFrequency(out freq); QueryPerformanceCounter(out tStart); // Start the data stream Console.WriteLine("Acquiring data. Press any key to stop..."); if (UserAllocatedBuffers) { // Start streaming data to our user allocated data buffers qResult = qusb.ReadBulkDataStartStream(BufferArray, NumBuffers, BufferByteSize, cbDelegate, IntPtr.Zero, out streamID, NumThreads, ThreadConcurrency); } else { // Start streaming data to data buffers that will be allocated interally by the Streaming API qResult = qusb.ReadBulkDataStartStream(IntPtr.Zero, NumBuffers, BufferByteSize, cbDelegate, IntPtr.Zero, out streamID, NumThreads, ThreadConcurrency); } if (!qResult) { qusbError = qusb.LastError(); Console.WriteLine("ReadBulkDataStartStream failed with error {0}", qusbError); } else { // Wait will data gets acquired and processed in the background while (!Console.KeyAvailable) { //--------------------------------------------------------- // Performing some background tasks //--------------------------------------------------------- // If we are not multithreading the stream in this example, we must // allow time for processing requests. Processing requests simply // means checking if a request has completed, execute its completion // routine, and re-issue the requests. QuickUsb.ProcessStream will // return when either any request has completed or the specified time // has elapsed. if (NumThreads == 0) { qResult = qusb.ProcessStream(streamID, 50); if (!qResult) { qusbError = qusb.LastError(); Console.WriteLine("ProcessStream failed with error {0}", qusbError); break; } } else { // Our background threads are processing the stream so we will // just not hog the processor Thread.Sleep(50); } } // Stop the data stream Console.WriteLine("Stopping data aquisition"); qResult = qusb.StopStream(streamID, false); if (!qResult) { qusbError = qusb.LastError(); Console.WriteLine("BulkDataStopStream failed with error {0}", qusbError); } } // Stop the throughput timer QueryPerformanceCounter(out tEnd); tElapsed = (double)(tEnd - tStart) / (double)(freq); Console.WriteLine(); Console.WriteLine("Time elapsed: {0:0.000} s", tElapsed); Console.WriteLine("Total bytes transferred: {0:0.000} MB", ((float)TotalBytes / (1024.0 * 1024.0))); Console.WriteLine("Data rate: {0:0.000} MS/s", ((TotalBytes / (1024.0 * 1024.0)) / tElapsed)); Console.WriteLine(); // Report any leaks or errors Console.WriteLine("{0} transaction(s) failed", ErrorCount); Console.WriteLine(); foreach (KeyValuePair <int, int> kv in ThreadIds) { Console.WriteLine("Thread #{0} used for {1} completion routine callbacks", kv.Key, kv.Value); } // Close the module qResult = qusb.Close(); if (!qResult) { Console.WriteLine("QuickUSB Error: {0}", qusb.LastError()); return; } return; }
/////////////////////////////////// // QuickUSB Asynchronous Example // /////////////////////////////////// static void Main(string[] args) { // The number of data buffers to use. An asynchronous data request is issued // for each data buffer, then the main thread waits for each request to complete // then issues a new asynchrnonous request using the same data buffer as the // completed request. To maximize throughout, the number of buffers should be // at least equal to the number of threads (see the SETTING_THREADS setting). const int NumBuffers = 8; // The byte size of the buffers. To maximize performance the buffer size should // be as large as possible and a power of 2. const int BufferByteSize = 512 * 1024; // 512 KB // The number of times to issue a request for each buffer. const int LOOPS = 50; // Variables int k, j, Id = 0; string[] nameList; bool qResult; QuickUsb.Error qusbError; // Variables to track time and performace long tStart, tEnd, freq; double tElapsed; // The data buffers, BulkStream objects, and tag objects. Because these objects // are passed to and used by unmanaged code in QuickUSB land, they must be handled // with care. They cannot be relocated by the garbage collector and must either // be pinned or allocated in unmanaged memory. ushort[][] BufferArray = new ushort[NumBuffers][]; QuickUsb.BulkStream[] BulkStream = new QuickUsb.BulkStream[NumBuffers]; BulkStreamTag[] tag = new BulkStreamTag[NumBuffers]; // We must keep an active reference to the delegate so it is not garbage collected. // This reference must minimally stay alive until all pending asynchronous requests // have completed. QuickUsb.BulkStreamCompletionRoutine cbDelegate = new QuickUsb.BulkStreamCompletionRoutine(CompletionRoutine); // Query connected modules nameList = QuickUsb.FindModules(); if (nameList.Length == 0) { Console.WriteLine("No modules found."); return; } // Open the first module qusb = new QuickUsb(nameList[0]); qusb.Open(nameList[0]); // Allocate buffers for (k = 0; k < NumBuffers; ++k) { // Allocate the data buffers in unmanaged memory BufferArray[k] = new ushort[BufferByteSize / 2]; // Allocate the BulkStream objects BulkStream[k] = new QuickUsb.BulkStream(); // Create the tag object as normal. We will later get a pinned reference to this // object to use in issuing the request, that we will later be able to use to // reconstruct a reference to the managed tag object in the completion routine. // We can do this because the tag data is never accessed or modified in unmanaged // land and only ever used in managed land. tag[k] = new BulkStreamTag(); } // Start throughput timer QueryPerformanceFrequency(out freq); QueryPerformanceCounter(out tStart); Console.WriteLine("Acquiring data...please wait"); // Aquire for (j = 0; j < (LOOPS + 1); ++j) { for (k = 0; k < NumBuffers; ++k) { // If this is not the first loop, wait for the last transaction to complete if (j != 0) { // Wait for the transaction to complete. Once this function returns successfully // the completion routine has already been executed and the transaction is // entirely complete. qResult = qusb.BulkWait(BulkStream[k], false); if (!qResult) { qusbError = qusb.LastError(); Console.WriteLine("Request failed (QuickUSB Error: {0})", qusb.LastError()); } else { // Now that this request has completed we may process the data here or in the // completion routine, though it is better to perform all processing in the // completion routine as they can be multi-threaded, allowing the main thread // to simply issue and re-issue data requests. } } // If this is not the last loop, issue a new transaction if (j != LOOPS) { //Console.WriteLine("Issuing Request #{0}", (Id + 1)); // Issue a new transaction tag[k].Id = ++Id; qResult = qusb.ReadBulkDataAsync( BufferArray[k], BufferByteSize, BulkStream[k], cbDelegate, GCHandle.ToIntPtr(GCHandle.Alloc(tag[k]))); if (!qResult) { Console.WriteLine(String.Format("QuickUSB Error: {0}", qusb.LastError())); qusb.Close(); return; } else { ++RefCount; ++TransCount; } } } } // Stop the throughput timer QueryPerformanceCounter(out tEnd); tElapsed = (double)(tEnd - tStart) / (double)(freq); Console.WriteLine(); Console.WriteLine("Time elapsed: {0:0.000} s", tElapsed); Console.WriteLine("Total bytes transferred: {0:0.000} MB", ((float)TotalBytes / (1024.0 * 1024.0))); Console.WriteLine("Data rate: {0:0.000} MS/s", ((TotalBytes / (1024.0 * 1024.0)) / tElapsed)); Console.WriteLine(); // Close the module qResult = qusb.Close(); if (!qResult) { Console.WriteLine("QuickUSB Error: {0}", qusb.LastError()); return; } // Report any leaks or errors Console.WriteLine("{0} transaction(s) issued in total", TransCount); Console.WriteLine("{0} transaction(s) failed", ErrorCount); Console.WriteLine("{0} transaction(s) are still outstanding", RefCount); return; }