Jump to content

Joey P

QRC Senior Moderator
  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by Joey P

  1. Joey P

    Context specify packet size

    I see that the file is missing the extension data packet, this is required. This shares the 4000 byte chunk with the context and goes first. The proper format can be found in the WBT File Format Documentation, as part of the WBT API documentation.
  2. There is little to no actual performance difference, when you do it dynamically you have to keep track of when things exist / nullness / lifecycle / etc. With that being said, unless you are using the class for callbacks, there is no good reason to not just spawn a WbtSystem wherever and whenever you need one on the stiack. The communications between the API classes and the daemon are instantiated in a behind the scenes singleton, so all of the really heavy lifing only happens the first time. However, if you are using callbacks with Qt please be advised that the callbacks happen on a separate thread, and should not interact directly with *any* QObjects, this is not safe. (http://doc.qt.io/qt-4.8/threads-qobject.html#signals-and-slots-across-threads)
  3. Joey P

    Context specify packet size

    File IO can be achieved by: Opening up a read iterator Iterating until you encounter context. Writing that context to a file Continuing to iterate through the stream, writing each 4000 byte context to the file and every 33 * 4000 byte data segment to the same file To answer your second question, currently packet sizes are fixed per QVRT specification to ensure quick reading / parsing operations.
  4. Joey P

    Tutorial section needed

    This is a good idea, we’re happy to provide a user community where tutorial type content beyond that which is included in the development kit by QRC can be easily posted or shared with others. This is part of our goal for this forum system, which is still building user base as the WBT becomes adopted by more and more groups. A way to do this with what we have, would be to post whatever content you (or others) may think valuable to share in the discussion area of each product. For example, in the WBT the discussion area is here: http://forum.qrctech.com/forum/22-wbt-discussion/. This was what we had envisioned as a way for users to talk with out users in a Non-QA format, what do you think of using that. We’d certainly welcome any content you’d like to add to enrich that area and help your fellow WBT users.. Beyond that, if there’s specific tutorial items you’d suggest QRC create, we’d welcome your thoughts and get someone assigned to creating them as quickly as we’re able. -Admin
  5. Joey P

    WbtAPI for directly streaming

    Can you be more specific on how to prefill the write iterator with data? You can prefill the write iterator's circular buffer by putting the desired data into each buffer chunk of the iterator and calling next, repeating the process for each buffer that was allocated by the creation of the iterator. The API docs really help here: A QVRT data stream is a packetized QVRT data stream that carries raw IQ data as well as other pertinent metadata establishing context (center frequency, sample rate, endpoints, etc). This stream uses a chunked circular buffer implementation to safely allow one writer and multiple readers. Each chunk of this buffer is divided into two areas: The IF Data Packet area- which contains 33 consecutive IF Data packets (each 4000 bytes) and the Context area- which contains a 4000 byte block containing context data (consisting of one Extension Data + one IF Context Packet). The WbtVRTWriteIterator operates by traversing the QVRT data stream buffer one buffered chunk at a time. The created stream can have multiple readers connected to it. This can be accomplished by either specifying this stream's WbtCommon::Streams::StreamInformationBlock in the constructor for WbtApi::WbtVRTReadIterator or moving an exiting reader to it usingWbtApi::WbtSystem::MoveReaderToNewStream method. Specification of all data and context packets used within a QVRT stream can be found within the WBT File Format document. So in short: 1. getCurrentLocationToWriteContext () and write your context information there, per the QVRT format documentation (you don't need to do this every time, just the first time, and any time your data would change) 2. getCurrentLocationToWriteData () and write 33 data packets at a time, per the QVRT format documentation 3. setContextAvailable() - If you performed step 1 4. ++ operator - to advance the buffer. Do this for the number of buffer chunks that you had set up in the bufferSize parameter of the write iterator 5. move the streams to the iterator 6. setStreamStarted () Do i only need to create a new WbtSystem obj and call startPlayback on it? Beforehand, you also need to get the information about the file you want to play, to set up the sample rate and center frequency. This can be accomplished using the following methods in WbtSystem. getRecordingInfo updateTunerSettings
  6. Sorry, misunderstood. If you do have a GRC gui component, it counts and should work. Have you tried the tutorial example? How the tutorial behaves should shed some light into the issue.
  7. As of this time, there is no proper way to have an app without a GUI component, due to how the signaling and API works at this time. At the very least, there needs to be an "about screen" with an icon.
  8. Joey P

    WbtAPI for directly streaming

    There is a way, however, it is fairly roundabout so we are actively working to improve this functionality. Expect to see something a lot more convenient within the next quarter. The current process is, 1. Create a WbtVRTWriteIterator, this will give you a handle to a new and empty shared buffer. 2. Prefill the write iterator with data, using the WBT File Format as a guide. (IF Data packets go into the main buffer area and context / extension data pairs go into the 4000 byte context section.) 3. Start a file that has the same radio configuration parameters (enabled tuners, span, bandwidth and center frequency) of what is intended to be streamed. This can be accomplished using WbtApi::WbtSystem::startPlayback. 4.Use WbtApi::WbtSystem::getActiveStreams to enumerate the active stream buffers on the system, that should include the file being played as well as the new stream created using the WbtVRTWriteIterator. 5. Use the function, WbtApi::WbtSystem::MoveAllReadersToNewStream to redirect all of the listeners from the old stream (including the radio, as well as any other listening apps) to the new one. Now, all data that has been written, or is being written to your write iterator will be streamed to the radio.
  9. Add the following line to your main.cpp. MainWindow w; w.move(-2000,-2000); w.show(); This will ensure that the window is moved outside of the screen area before it is captured by the app framework.
  10. Joey P

    QVRT Context packet Metadata Timestamp

    With combined tuners, this is usually the case, however, you can have situations where you have two separate streams of two separate sample rates interleaved in one file. In these situations, you would not be able to rely on this assumption. For the combined case, your example would indeed work. But not for all configurations that use Radio_AB as a radio selection.
  11. Joey P

    Wbtclient broadcast messages

    As of now, that is the only notification sent to users about actions performed within the GUI. There are no notifications for green arrow buttons. As for determining when tuner parameters (CF, bandwidth, etc) change, settings changed callbacks within the WbtSystem class can be used.
  12. Joey P

    QVRT Context packet Metadata Timestamp

    Thank you for the additional information. We're looking into the issue and will reply with additional information soon.
  13. Joey P

    QVRT Context packet Metadata Timestamp

    I would say that this is indeed not the expected behavior. Does this happen consistently, or just with some files? The things that come to mind that could cause this are: 1. Loss of GPS sync 2. Issues traversing file with file read iterator. Two things that would help us get to the bottom of this would be either: a) a source code snippet b) versions of software where file is captured and version of API used
  14. Joey P

    High Sample Rate Tuner Bandwidths

    Understood. Let us know if there is anything else we can do to help!
  15. Joey P

    High Sample Rate Tuner Bandwidths

    Apps should not experience any issues going into the future as a result of using these values. Because we do not allow bandwidths that are larger than the sample rate (for data integrity reasons), you can always be assured that the min and max values will be safe. I would feel free to use it and not worry about getting (or the possibility of) out of range values.
  16. Good question! You are close. The QVRT format in the buffers has headers and footers interspersed, So for every 4000 bytes within the buffer chunk, you are going to have 20 bytes of headers and footers and 3980 bytes worth of samples. The following will get you the amount of samples: // divide by 4 bytes since the samples are stored as 2 16-bit numbers, then account for headers samples += it.getCurrentSizeBytes() / 4 * 995 / 1000;
  17. Joey P

    Setting Sample Rate Independent of Bandwidth

    In the WBT GUI, decoupling sample rate and bandwidth can be achieved by navigating to the Settings page under the System tab and selecting the option Override Sample Rate. With this option enabled, the sample rate and bandwidth can be set independently. For the API, we will soon be posting a new version of the API that has specific functions handling the setting of the sample rate and bandwidth independently from within the WbtSystem class.
  18. Joey P

    WBT Bandwidth

    At this time the WBT's minimum bandwidth is 700 kHz. We plan to reduce this to allow for longer recording and handling of narrower channels.
  19. Joey P


    As of right now, channelization options for WBT are as follows: WBT App with GNU Radio - Channelization can be accomplished Development Environment though the use of the channelizer and filter blocks present in GNU Radio.Separate Tuners - Another option is to use a tuner for each channel, specifying the desired bandwidth on the main screen or via the API. In cases where narrower bandwidths are needed, WBT Apps can be employed to apply further filtering.It is also worth mentioning that we are currently working to provide hardware accelerated channelization functionality.
  20. Joey P

    Software Updates

    Yes, there is a bootable USB update stick that can be created for the WBT using tools and instructions that can be found in the private customer support area of the main QRC website. This process does require an internet connection to QRC on a computer (for file download purposes), but does not require placing any WBTs themselves on any sort of network.
  21. Joey P

    Detect Record press

    Current API is Does it contain methods to intercept Record/Stop button? If yes, where exactly are they? If not, is there a rough estimation of when this will be implemented? It does not. Currently, our API does not interact with the display elements of the WBT or have visibility of the Qt signals and slots. Even though there is the possibility that this functionality may be added in the future, there are no near-term plans to integrate this functionality, nor is a long term plan finalized on how / when we would allow intercepting of events across process boundaries. In the meantime, I would implement such desired control functionality within the application itself, or listen and react to stream stop events as the API has no ownership or access to the main WBT form controls at this time.
  22. Joey P

    _tunerOffset purpose

    The tuner offset parameter is used exclusively for shifting playback to another frequency. For example if you record a signal and want to shift your playback up by 5 MHz, you would specify 5.0 as your tuner offset for your playback RfParameters.
  23. Because the WBT uses direct conversion SDRs for recording and playback,the local oscillator (LO) is set to the center frequency. This is an artifact of the direct conversion process. In order to minimize the effects of this on recording and playback, there is a built-in filter to remove the LO contribution from the data. While this filtering out of the DC offset does cause issues with narrowband signals that are located at the center frequency of the tuner, it has such a narrow bandwidth that it doesn’t generally affect wider signals. The best way to work around this is to make sure you don’t center the tuner on narrow signals you wish to record, but offset it slight (The 5 kHz you mention above works, in general if it’s a narrow signal try to make sure none of it passes through the center of the tuner to avoid distortions). For wider signals, especially the modern signals like WCDMA, LTE, WiFi they’re all designed to work with 0IF radios and can be centered without concern.
  24. Joey P

    What is the .qvrt IQ data format?

    The I (real) and Q (imaginary) components of the complex sample data are stored as a fixed point representations of decimal numbers that go from -1 to ~1. There is no "unit" per-se, the extents of the values represent the extents of the data that the ADC / tuner returns. The following third party link has reasonably good explanatory value as to the nature of the data itself: http://whiteboard.ping.se/SDR/IQ Now, expanding on this further with a usage example: To get the data out of the QVRT file and into a more useful / usable dBm power values, the following process can be used: Note: The API's QVRTFileReadIterator's getCurrentIQDataFloat function will perform steps 1-4 .1. Read the raw IQ values from the file. Each IFData packet at this time contrains 995 IQ pairs stored in big-endian,,Q0-15 (a fixed point format). In short the data is formatted as Big Endian 16 Bit I, followed by a Big endian 16 bit Q followed by the next Big Endian 16 Bit I, followed by a Big endian 16 bit Q, and so on. 2. Swap The bytes for each I and Q to change the data from big to little endian. This will turn the sequence of bytes from: I(Low Byte), I(High Byte), Q(Low Byte), Q(High Byte)... to I(High Byte), I(Low Byte), Q(High Byte), Q(Low Byte)... 3. Convert each I and Q from Q0-15 to floating point. Do this by treating each (flipped) value as a 16 bit signed integer, converting that integer to a single precision floating point number, and then dividing that number by 32768.0 to scale the data. The result will be a series of numbers ranging from -1.0 to ~1.0. 4. Scale floating point IQ data taking into account gain settings and calibration values from the IF Context / Data extension packets. multiply the following value by all I and Q values: sqrtf(powf(10.0, (rx_offset - rx_gain)/10.0f)) where rx_offset is the calibration offset and rx_gain is the receive gain setting. 5. Calculate instantaneous dBm power values from transformed IQ data For each scaled IQ pair, get dBm in the following manner power_mW = 10.0f * log10f( I * I + Q * Q)
  25. We will definitely look into this and if there is a fix to be made (I anticipate there will be) we will get an updated beta build to you shortly (to replace the beta build you are using presently). Sorry for the inconvenience.