示例#1
0
        /*
         * the main method
         * receives a Flow message and prints out its associated information
         * If the message belongs to another class, an exception is thrown.
         */
        virtual void _receive_msg(std::shared_ptr<const Msg>&& m, int /* index */)
        {
            if ( m->type() == MSG_ID(Flow) )
            {
                auto flow = static_cast<const Flow *>(m.get());
                std::stringstream ss;
                const FlowKey& fk = flow->key();
                int duration = flow->end_time() - flow->start_time();
                ss<<"packets="<<flow->packets() << ",";
                ss<<"bytes="<<flow->bytes() << ",";
                ss<<"start="<<flow->start_time() << ",";
                ss<<"end="<<flow->end_time() << ",";
                ss<<"duration.us="<<duration<< ",";
                ss<<"source.ip4="<<ip_to_string(fk.src_ip4)<< ",";
                ss<<"source.port="<<fk.src_port<< ",";
                ss<<"destination.ip4="<<ip_to_string(fk.dst_ip4)<< ",";
                ss<<"destination.port="<<fk.dst_port;
                /*
                ss<<"Flow of  "<< flow->packets() << " packets and "<<flow->bytes()<<" bytes begin at "<<flow->start_time()<<" end at "<<flow->end_time()<< "duration (ms.) "<<duration <<std::endl;
                ss<<"SRC IP "<<ip_to_string(fk.src_ip4)<<" SRC port "<<fk.src_port<<std::endl;
                ss<<"DST IP "<<ip_to_string(fk.dst_ip4)<<" DST port "<<fk.dst_port<<std::endl;
                //ss<<"protocol "<<fk.proto<<std::endl;
                */
                blocklog(ss.str(),log_info);


            }
                else
            {
                throw std::runtime_error("Flowprinter: wrong message type");
            }
        }
示例#2
0
unsigned long Node::LocalClient::send(const char *command)
	throw()
{
	if (!_impl)
		return 0;
	_LocalClientImpl *impl = (_LocalClientImpl *)_impl;
	Mutex::Lock _l(impl->inUseLock);

	try {
		uint32_t convId = (uint32_t)rand();
		if (!convId)
			convId = 1;

		std::vector<std::string> tmp;
		tmp.push_back(std::string(command));
		std::vector< Buffer<ZT_NODECONFIG_MAX_PACKET_SIZE> > packets(NodeConfig::encodeControlMessage(impl->key,convId,tmp));

		for(std::vector< Buffer<ZT_NODECONFIG_MAX_PACKET_SIZE> >::iterator p(packets.begin());p!=packets.end();++p)
			impl->sock->send(impl->localDestAddr,p->data(),p->size(),-1);

		return convId;
	} catch ( ... ) {
		return 0;
	}
}
示例#3
0
  void Fragment::send (Message_ptr m)
  {
    if (Data const* data = static_cast<Data const*> (m->find (Data::id)))
    {
      size_t max_payload_size (
        params_.max_packet_size () - max_service_size);

      if (data->size () <= max_payload_size)
      {
        u64 sn;
        {
          Lock l (mutex_);
          sn = sn_++;
        }

        m->add (Profile_ptr (new SN (sn)));

        out_->send (m);
        return;
      }

      char const* p = data->buf ();
      size_t size (data->size ());

      // Need fragmentation.
      //
      u32 packets (size / max_payload_size + (size % max_payload_size ? 1 : 0));

      // cerr << "size : " << size << endl
      //      << "packs: " << packets << endl;

      for (u32 i (1); i <= packets; ++i)
      {
        Message_ptr part (new Message);

        size_t s (i == packets ? size % max_payload_size : max_payload_size);

        // cerr << "pack: " << s << endl;

        u64 sn;
        {
          Lock l (mutex_);
          sn = sn_++;
        }

        part->add (Profile_ptr (new SN (sn)));
        part->add (Profile_ptr (new Part (i, packets, size)));
        part->add (Profile_ptr (new Data (p, s)));

        out_->send (part);

        p += s;
      }
    }
  }
示例#4
0
/*
 * @param target_name [String] The target name
 * @param packet_name [String] The packet name. Must be a defined packet name
 *   and not 'LATEST'.
 *@return [Packet] The telemetry packet for the given target and packet name
 */
static VALUE packet(VALUE self, VALUE target_name, VALUE packet_name)
{
  volatile VALUE packet = Qnil;
  volatile VALUE target_packets = Qnil;
  volatile VALUE upcase_target_name = Qnil;
  volatile VALUE upcase_packet_name = Qnil;

  target_packets = packets(self, target_name);

  upcase_packet_name = rb_funcall(packet_name, id_method_to_s, 0);
  upcase_packet_name = rb_funcall(upcase_packet_name, id_method_upcase, 0);
  packet = rb_hash_aref(target_packets, upcase_packet_name);
  if (!(RTEST(packet))) {
    upcase_target_name = rb_funcall(target_name, id_method_to_s, 0);
    upcase_target_name = rb_funcall(upcase_target_name, id_method_upcase, 0);
    rb_raise(rb_eRuntimeError, "Telemetry packet '%s %s' does not exist", RSTRING_PTR(upcase_target_name), RSTRING_PTR(upcase_packet_name));
  }

  return packet;
}
/*
 * This callback is called when |AudioFileStreamParseBytes| has enough data to
 * extract one or more MP3 packets.
 */
void
AppleMP3Reader::AudioSampleCallback(UInt32 aNumBytes,
                                    UInt32 aNumPackets,
                                    const void *aData,
                                    AudioStreamPacketDescription *aPackets)
{
  LOGD("got %u bytes, %u packets\n", aNumBytes, aNumPackets);

  // 1 frame per packet * num channels * 32-bit float
  uint32_t decodedSize = MAX_AUDIO_FRAMES * mAudioChannels *
                         sizeof(AudioDataValue);

  // descriptions for _decompressed_ audio packets. ignored.
  nsAutoArrayPtr<AudioStreamPacketDescription>
    packets(new AudioStreamPacketDescription[MAX_AUDIO_FRAMES]);

  // This API insists on having MP3 packets spoon-fed to it from a callback.
  // This structure exists only to pass our state and the result of the parser
  // on to the callback above.
  PassthroughUserData userData = { this, aNumPackets, aNumBytes, aData, aPackets, false };

  do {
    // Decompressed audio buffer
    nsAutoArrayPtr<uint8_t> decoded(new uint8_t[decodedSize]);

    AudioBufferList decBuffer;
    decBuffer.mNumberBuffers = 1;
    decBuffer.mBuffers[0].mNumberChannels = mAudioChannels;
    decBuffer.mBuffers[0].mDataByteSize = decodedSize;
    decBuffer.mBuffers[0].mData = decoded.get();

    // in: the max number of packets we can handle from the decoder.
    // out: the number of packets the decoder is actually returning.
    UInt32 numFrames = MAX_AUDIO_FRAMES;

    OSStatus rv = AudioConverterFillComplexBuffer(mAudioConverter,
                                                  PassthroughInputDataCallback,
                                                  &userData,
                                                  &numFrames /* in/out */,
                                                  &decBuffer,
                                                  packets.get());

    if (rv && rv != kNeedMoreData) {
      LOGE("Error decoding audio stream: %x\n", rv);
      break;
    }

    // If we decoded zero frames then AudiOConverterFillComplexBuffer is out
    // of data to provide.  We drained its internal buffer completely on the
    // last pass.
    if (numFrames == 0 && rv == kNeedMoreData) {
      LOGD("FillComplexBuffer out of data exactly\n");
      break;
    }

    int64_t time = FramesToUsecs(mCurrentAudioFrame, mAudioSampleRate).value();
    int64_t duration = FramesToUsecs(numFrames, mAudioSampleRate).value();

    LOGD("pushed audio at time %lfs; duration %lfs\n",
         (double)time / USECS_PER_S, (double)duration / USECS_PER_S);

    AudioData *audio = new AudioData(mDecoder->GetResource()->Tell(),
                                     time, duration, numFrames,
                                     reinterpret_cast<AudioDataValue *>(decoded.forget()),
                                     mAudioChannels, mAudioSampleRate);
    mAudioQueue.Push(audio);

    mCurrentAudioFrame += numFrames;

    if (rv == kNeedMoreData) {
      // No error; we just need more data.
      LOGD("FillComplexBuffer out of data\n");
      break;
    }
  } while (true);
}
示例#6
0
_Use_decl_annotations_
bool BspCompiler::FindBestSplit(Triangle** triangles, uint32_t count, const Triangle** splitTriangle, Triangle** front, uint32_t* frontCount, Triangle** back, uint32_t* backCount)
{
    const Triangle* candidate = nullptr;
    int32_t score = 0;

#if defined(PARALLEL_BSP)
    if (count > 1000)
    {
        // Divide up workload and spin up multiple SplitTriangleTasks

        uint32_t numGroups = std::min((int)(count / 1000), 16);
        std::vector<std::shared_ptr<FindBestSplitPacket>> packets(numGroups + 1);
        std::vector<HANDLE> threads(numGroups + 1);

        for (uint32_t i = 0; i < packets.size(); ++i)
        {
            packets[i].reset(new FindBestSplitPacket);
        }

        uint32_t countPerGroup = count / numGroups;
        uint32_t countDispatched = 0;

        const Triangle* start = *triangles;
        for (uint32_t i = 0; i < numGroups; ++i)
        {
            auto& packet = packets[i];
            packet->start = start;
            packet->head = *triangles;
            packet->count = count;
            packet->numTriangles = countPerGroup;
            threads[i] = CreateThread(nullptr, 0, FindBestSplitTaskThreadProc, packet.get(), 0, nullptr);

            for (uint32_t j = 0; j < countPerGroup; ++j)
            {
                start = start->Next;
            }

            countDispatched += countPerGroup;
        }

        if (countDispatched < count)
        {
            auto& packet = packets[numGroups];
            packet->start = start;
            packet->head = *triangles;
            packet->count = count;
            packet->numTriangles = count - countDispatched;
            threads[numGroups] = CreateThread(nullptr, 0, FindBestSplitTaskThreadProc, packet.get(), 0, nullptr);
            ++numGroups;
        }

        WaitForMultipleObjects(numGroups, threads.data(), TRUE, INFINITE);

        for (uint32_t i = 0; i < numGroups; ++i)
        {
            CloseHandle(threads[i]);
        }

        // aggregate best
        const Triangle* best = nullptr;
        int32_t bestScore = 0;

        for (uint32_t i = 0; i < numGroups; ++i)
        {
            if (packets[i]->result)
            {
                if (best == nullptr || packets[i]->candidateScore < bestScore)
                {
                    best = packets[i]->candidateTriangle;
                    bestScore = packets[i]->candidateScore;
                }
            }
        }

        if (best == nullptr)
        {
            return false;
        }

        candidate = best;
        score = bestScore;
    }
    else
#endif
    {
        FindBestSplitPacket packet;
        packet.head = *triangles;
        packet.count = count;
        packet.start = *triangles;
        packet.numTriangles = count;
        FindBestSplitTask(&packet);
        if (!packet.result)
        {
            return false;
        }

        candidate = packet.candidateTriangle;
        score = packet.candidateScore;
    }

    *splitTriangle = candidate;
    const XMFLOAT4& plane = candidate->Plane;

    (*frontCount) = 0;
    (*backCount) = 0;

    Triangle* t = *triangles;
    while (t != nullptr)
    {
        Triangle* next = t->Next;

        if (t == candidate)
        {
            // self. insert in front
            PUSH(front, t);
            ++(*frontCount);
        }
        else
        {
            float d0 = DistToPlane(plane, t->v0.Position);
            float d1 = DistToPlane(plane, t->v1.Position);
            float d2 = DistToPlane(plane, t->v2.Position);

            if (ABS(d0) < epsilon && ABS(d1) < epsilon && ABS(d2) < epsilon)
            {
                XMVECTOR tplane = XMLoadFloat4(&t->Plane);

                // coplanar case
                if (XMVectorGetX(XMVector3Dot(XMLoadFloat4(&plane), tplane)) > 0)
                {
                    // same facing direction
                    PUSH(front, t);
                    ++(*frontCount);
                }
                else
                {
                     PUSH(back, t);
                    ++(*backCount);
                }
            }
            else if (d0 > -epsilon && d1 > -epsilon && d2 > -epsilon)
            {
                // front of plane
                PUSH(front, t);
                ++(*frontCount);
            }
            else if (d0 < epsilon && d1 < epsilon && d2 < epsilon)
            {
                // fully behind plane
                PUSH(back, t);
                ++(*backCount);
            }
            else
            {
                // intersect
                SplitTriangle(t, plane, front, back);
            }
        }

        t = next;
    }

    return true;
}
  DetectionSet DynVolNN::detect(const ImRGBZ&im,DetectionFilter filter) const 
  {
    SphericalOccupancyMap SOM(im);

    vector<MatchPacket> packets(templates.size());
    TaskBlock proc_templates("proc_templates");
    tbb::concurrent_unordered_set<size_t> checked_templates;
    for(int iter = 0; iter < templates.size(); ++iter)
    {
      proc_templates.add_callee([&,iter]()
				{
				  Timer timer;
				  timer.tic();
				  const DynVolTempl&t = templates.at(iter);
				  packets.at(iter) = MatchPacket(SOM,t,[&](const Mat&t)
								 {
								   size_t hash = hash_code(t);
								   auto r = checked_templates.insert(hash);
								   if(!r.second)
								   {
								     cout << "template duplicate skipped! " <<
								       hash << endl;
								   }
								   return !r.second;
								 });
				  long interval = timer.toc();
				  lock_guard<mutex> l(monitor);
				  performance_times[(t.z_min - min_z)/50] += interval;
				  performance_counts[(t.z_min - min_z)/50] ++;
				});
    }
    proc_templates.execute();
    log_file << safe_printf("info: % checked among % templates",checked_templates.size(),templates.size()) << endl;
    std::sort(packets.begin(),packets.end());
    for(int iter = 0; iter < 1; ++iter, iter *= 2)
    {
      string fn = im.filename;
      for(char&c : fn)
	if(c == '/')
	  c = '_';
      packets.at(iter).log(safe_printf("packet_[%]_[%]_",fn,iter),SOM);
    }

    log_times();
    DetectionSet all_dets;
    TaskBlock take_dets("take_dets");
    int stride = 1;
    for(int yIter = stride/2; yIter < im.rows(); yIter += stride)
      take_dets.add_callee([&,yIter]()
			   {
			     for(int xIter = stride/2; xIter < im.cols(); xIter += stride)
			     {
			       float max_resp = -inf;
			       Rect max_bb;
			       for(auto && packet : packets)
			       {
				 if(packet.bb.size().area() <= 0)
				   continue;
				 
				 if(yIter < packet.r.rows && xIter < packet.r.cols)
				 {
				   float resp = packet.r.at<float>(yIter,xIter);
				   if(resp > max_resp)
				   {
				     max_resp = resp;
				     max_bb   = Rect(Point(xIter,yIter),packet.bb.size());
				   }				   
				 }				 
			       }//end for packet

			       auto det = make_shared<Detection>();
			       det->BB = max_bb;
			       det->resp = max_resp;
			       static mutex m; lock_guard<mutex> l(m);
			       all_dets.push_back(det);	  	
			     }// end for xIter
			   });  	
    take_dets.execute();
    all_dets = sort(all_dets);   
    return (all_dets);
  }
nsresult
AppleATDecoder::DecodeSample(mp4_demuxer::MP4Sample* aSample)
{
  // Array containing the queued decoded audio frames, about to be output.
  nsTArray<AudioDataValue> outputData;
  UInt32 channels = mOutputFormat.mChannelsPerFrame;
  // Pick a multiple of the frame size close to a power of two
  // for efficient allocation.
  const uint32_t MAX_AUDIO_FRAMES = 128;
  const uint32_t maxDecodedSamples = MAX_AUDIO_FRAMES * channels;

  // Descriptions for _decompressed_ audio packets. ignored.
  nsAutoArrayPtr<AudioStreamPacketDescription>
    packets(new AudioStreamPacketDescription[MAX_AUDIO_FRAMES]);

  // This API insists on having packets spoon-fed to it from a callback.
  // This structure exists only to pass our state.
  PassthroughUserData userData =
    { channels, (UInt32)aSample->size, aSample->data };

  // Decompressed audio buffer
  nsAutoArrayPtr<AudioDataValue> decoded(new AudioDataValue[maxDecodedSamples]);

  do {
    AudioBufferList decBuffer;
    decBuffer.mNumberBuffers = 1;
    decBuffer.mBuffers[0].mNumberChannels = channels;
    decBuffer.mBuffers[0].mDataByteSize =
      maxDecodedSamples * sizeof(AudioDataValue);
    decBuffer.mBuffers[0].mData = decoded.get();

    // in: the max number of packets we can handle from the decoder.
    // out: the number of packets the decoder is actually returning.
    UInt32 numFrames = MAX_AUDIO_FRAMES;

    OSStatus rv = AudioConverterFillComplexBuffer(mConverter,
                                                  _PassthroughInputDataCallback,
                                                  &userData,
                                                  &numFrames /* in/out */,
                                                  &decBuffer,
                                                  packets.get());

    if (rv && rv != kNoMoreDataErr) {
      LOG("Error decoding audio stream: %d\n", rv);
      return NS_ERROR_FAILURE;
    }

    if (numFrames) {
      outputData.AppendElements(decoded.get(), numFrames * channels);
    }

    if (rv == kNoMoreDataErr) {
      break;
    }
  } while (true);

  if (outputData.IsEmpty()) {
    return NS_OK;
  }

  size_t numFrames = outputData.Length() / channels;
  int rate = mOutputFormat.mSampleRate;
  CheckedInt<Microseconds> duration = FramesToUsecs(numFrames, rate);
  if (!duration.isValid()) {
    NS_WARNING("Invalid count of accumulated audio samples");
    return NS_ERROR_FAILURE;
  }

#ifdef LOG_SAMPLE_DECODE
  LOG("pushed audio at time %lfs; duration %lfs\n",
      (double)aSample->composition_timestamp / USECS_PER_S,
      (double)duration.value() / USECS_PER_S);
#endif

  nsAutoArrayPtr<AudioDataValue> data(new AudioDataValue[outputData.Length()]);
  PodCopy(data.get(), &outputData[0], outputData.Length());
  nsRefPtr<AudioData> audio = new AudioData(aSample->byte_offset,
                                            aSample->composition_timestamp,
                                            duration.value(),
                                            numFrames,
                                            data.forget(),
                                            channels,
                                            rate);
  mCallback->Output(audio);
  return NS_OK;
}
示例#9
0
void
AppleATDecoder::SampleCallback(uint32_t aNumBytes,
                               uint32_t aNumPackets,
                               const void* aData,
                               AudioStreamPacketDescription* aPackets)
{
    // Pick a multiple of the frame size close to a power of two
    // for efficient allocation.
    const uint32_t MAX_AUDIO_FRAMES = 128;
    const uint32_t decodedSize = MAX_AUDIO_FRAMES * mConfig.channel_count *
                                 sizeof(AudioDataValue);

    // Descriptions for _decompressed_ audio packets. ignored.
    nsAutoArrayPtr<AudioStreamPacketDescription>
    packets(new AudioStreamPacketDescription[MAX_AUDIO_FRAMES]);

    // This API insists on having packets spoon-fed to it from a callback.
    // This structure exists only to pass our state and the result of the
    // parser on to the callback above.
    PassthroughUserData userData =
    { this, aNumPackets, aNumBytes, aData, aPackets, false };

    do {
        // Decompressed audio buffer
        nsAutoArrayPtr<uint8_t> decoded(new uint8_t[decodedSize]);

        AudioBufferList decBuffer;
        decBuffer.mNumberBuffers = 1;
        decBuffer.mBuffers[0].mNumberChannels = mOutputFormat.mChannelsPerFrame;
        decBuffer.mBuffers[0].mDataByteSize = decodedSize;
        decBuffer.mBuffers[0].mData = decoded.get();

        // in: the max number of packets we can handle from the decoder.
        // out: the number of packets the decoder is actually returning.
        UInt32 numFrames = MAX_AUDIO_FRAMES;

        OSStatus rv = AudioConverterFillComplexBuffer(mConverter,
                      _PassthroughInputDataCallback,
                      &userData,
                      &numFrames /* in/out */,
                      &decBuffer,
                      packets.get());

        if (rv && rv != kNeedMoreData) {
            LOG("Error decoding audio stream: %#x\n", rv);
            mCallback->Error();
            break;
        }
        LOG("%d frames decoded", numFrames);

        // If we decoded zero frames then AudioConverterFillComplexBuffer is out
        // of data to provide.  We drained its internal buffer completely on the
        // last pass.
        if (numFrames == 0 && rv == kNeedMoreData) {
            LOG("FillComplexBuffer out of data exactly\n");
            mCallback->InputExhausted();
            break;
        }

        const int rate = mOutputFormat.mSampleRate;
        const int channels = mOutputFormat.mChannelsPerFrame;

        int64_t time = mCurrentAudioTimestamp;
        int64_t duration = FramesToUsecs(numFrames, rate).value();

        LOG("pushed audio at time %lfs; duration %lfs\n",
            (double)time / USECS_PER_S, (double)duration / USECS_PER_S);

        AudioData* audio = new AudioData(mSamplePosition,
                                         time, duration, numFrames,
                                         reinterpret_cast<AudioDataValue*>(decoded.forget()),
                                         channels, rate);
        mCallback->Output(audio);
        mHaveOutput = true;

        if (rv == kNeedMoreData) {
            // No error; we just need more data.
            LOG("FillComplexBuffer out of data\n");
            mCallback->InputExhausted();
            break;
        }
    } while (true);
}
void AdapterTimeSeriesDataSetTest::test_deserialise_timing()
{
    try {
        // Create configuration node.
        _fixedSizePackets = "false";
        _config = _configXml(_fixedSizePackets, _dataBitSize,
                _udpPacketsPerIteration, _samplesPerPacket,
                _outputChannelsPerSubband, _subbandsPerPacket, _nRawPolarisations);

        typedef TYPES::i16complex i16c;

        // Construct the adapter.
        AdapterTimeSeriesDataSet adapter(_config);

        // Construct a data blob to adapt into.
        TimeSeriesDataSetC32 timeSeries;

        unsigned nTimes = (_udpPacketsPerIteration * _samplesPerPacket);
        unsigned nTimeBlocks = nTimes / _outputChannelsPerSubband;
        unsigned nData = _subbandsPerPacket * _nRawPolarisations * _samplesPerPacket;
        size_t packetSize = sizeof(UDPPacket::Header) + (nData * _dataBitSize * 2) / 8;
        size_t chunkSize = packetSize * _udpPacketsPerIteration;

        // Configure the adapter setting the data blob, chunk size and service data.
        adapter.config(&timeSeries, chunkSize, QHash<QString, DataBlob*>());

        // Create and fill UDP packets.
        std::vector<UDPPacket> packets(_udpPacketsPerIteration);
        unsigned index = 0;

        for (unsigned i = 0; i < _udpPacketsPerIteration; ++i)
        {
            // Fill in the header
            packets[i].header.version             = uint8_t(0 + i);
            packets[i].header.sourceInfo          = uint8_t(1 + i);
            packets[i].header.configuration       = uint16_t(_dataBitSize);
            packets[i].header.station             = uint16_t(3 + i);
            packets[i].header.nrBeamlets          = uint8_t(4 + i);
            packets[i].header.nrBlocks            = uint8_t(5 + i);
            packets[i].header.timestamp           = uint32_t(6 + i);
            packets[i].header.blockSequenceNumber = uint32_t(7 + i);

            // Fill in the data
            for (unsigned ii = 0, t = 0; t < _samplesPerPacket; ++t) {
                for (unsigned c = 0; c < _subbandsPerPacket; ++c) {
                    for (unsigned p = 0; p < _nRawPolarisations; ++p) {
                        i16c* data = reinterpret_cast<i16c*>(packets[i].data);
                        index = _nRawPolarisations * (t * _subbandsPerPacket + c) + p;
                        data[index] = i16c(ii++, i);
                    }
                }
            }
        }


        // Stick the chunk of packets into an QIODevice (buffer).
        {
            QBuffer buffer;
            buffer.setData(reinterpret_cast<char*>(&packets[0]), chunkSize);
            buffer.open(QBuffer::ReadOnly);
            adapter.deserialise(&buffer);
        }

        QBuffer buffer;
        buffer.setData(reinterpret_cast<char*>(&packets[0]), chunkSize);
        buffer.open(QBuffer::ReadOnly);

        QTime timer;
        timer.start();
        adapter.deserialise(&buffer);
        int elapsed = timer.elapsed();

//        std::cout << timeSeries.timeSeries(0) <<

        cout << endl;
        cout << "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" << endl;
        cout << "[AdapterTimeSeriesDataSet]: deserialise() " << endl;
        cout << "- nChan = " << _outputChannelsPerSubband << endl << endl;
        if (_verbose) {
            cout << "- nBlocks = " << nTimeBlocks << endl;
            cout << "- nSubbands = " << _subbandsPerPacket << endl;
            cout << "- nPols = " << _nRawPolarisations << endl;
            cout << "- nTimes = " << nTimes << endl;
        }
        cout << "* Elapsed = " << elapsed << " ms." << endl;
        cout << "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" << endl;

    }
    catch (const QString& err) {
        CPPUNIT_FAIL(err.toStdString().data());
    }
}
/**
 * @details
 * Method to test the deserialise() method of the adapter.
 */
void AdapterTimeSeriesDataSetTest::test_deserialise()
{
    try {
        // Create configuration node.
        _config = _configXml(_fixedSizePackets, _dataBitSize,
                _udpPacketsPerIteration, _samplesPerPacket,
                _outputChannelsPerSubband, _subbandsPerPacket, _nRawPolarisations);

        typedef TYPES::i8complex i8c;
        typedef TYPES::i16complex i16c;

        // Construct the adapter.
        AdapterTimeSeriesDataSet adapter(_config);

        // Construct a data blob to adapt into.
        TimeSeriesDataSetC32 timeSeries;

        size_t chunkSize = sizeof(UDPPacket) * _udpPacketsPerIteration;

        // Configure the adapter setting the data blob, chunk size and service data.
        adapter.config(&timeSeries, chunkSize, QHash<QString, DataBlob*>());

        // Create and fill a UDP packet.
        std::vector<UDPPacket> packets(_udpPacketsPerIteration);
        unsigned index = 0;
        for (unsigned i = 0; i < _udpPacketsPerIteration; ++i) {

            // Fill in the header
            packets[i].header.version             = uint8_t(0 + i);
            packets[i].header.sourceInfo          = uint8_t(1 + i);
            packets[i].header.configuration       = uint16_t(_dataBitSize);
            packets[i].header.station             = uint16_t(3 + i);
            packets[i].header.nrBeamlets          = uint8_t(4 + i);
            packets[i].header.nrBlocks            = uint8_t(5 + i);
            packets[i].header.timestamp           = uint32_t(6 + i);
            packets[i].header.blockSequenceNumber = uint32_t(7 + i);

            // Fill in the data
            for (unsigned ii = 0, t = 0; t < _samplesPerPacket; ++t) {
                for (unsigned c = 0; c < _subbandsPerPacket; ++c) {
                    for (unsigned p = 0; p < _nRawPolarisations; ++p) {

                        if (_dataBitSize == 8) {
                            i8c* data = reinterpret_cast<i8c*>(packets[i].data);
                            index = _nRawPolarisations * (t * _subbandsPerPacket + c) + p;
                            data[index] = i8c(ii++, i);
                        }
                        else if (_dataBitSize == 16) {
                            i16c* data = reinterpret_cast<i16c*>(packets[i].data);
                            index = _nRawPolarisations * (t * _subbandsPerPacket + c) + p;
                            data[index] = i16c(ii++, i);
                        }

                    }
                }
            }
        }


        // Stick the packet into an QIODevice.
        QBuffer buffer;
        buffer.setData(reinterpret_cast<char*>(&packets[0]), chunkSize);
        buffer.open(QBuffer::ReadOnly);


        adapter.deserialise(&buffer);
    }
    catch (const QString& err) {
        CPPUNIT_FAIL(err.toStdString().data());
    }
}