Exemple #1
0
  virtual typename Source<T>::Range Read() override {
    auto r = buffer.Write();
    if (!r.IsEmpty()) {
      unsigned n = Read(r.data, r.size);
      buffer.Append(n);
    }

    return buffer.Read();
  }
Exemple #2
0
 virtual void DataReceived(const void *data, size_t length) {
   mutex.Lock();
   auto range = buffer.Write();
   if (range.length < length)
     length = range.length;
   memcpy(range.data, data, length);
   buffer.Append(length);
   mutex.Unlock();
   SendNotification();
 }
Exemple #3
0
  virtual typename Source<T>::Range read() {
    auto r = buffer.Write();
    if (!r.IsEmpty()) {
      unsigned n = read(r.data, r.length);
      buffer.Append(n);
    }

    r = buffer.Read();
    return typename Source<T>::Range(r.data, r.length);
  }
Exemple #4
0
  void BinaryReceived(const void *_data, size_t length) {
    const uint8_t *data = (const uint8_t *)_data, *end = data + length;

    do {
      /* append new data to buffer, as much as fits there */
      auto range = binary_buffer.Write();
      if (range.IsEmpty()) {
        /* overflow: reset buffer to recover quickly */
        binary_buffer.Clear();
        continue;
      }

      size_t nbytes = std::min(size_t(range.length), size_t(end - data));
      memcpy(range.data, data, nbytes);
      data += nbytes;
      binary_buffer.Append(nbytes);

      while (true) {
        range = binary_buffer.Read();
        if (range.IsEmpty())
          break;

        size_t nbytes = HandleBinary(range.data, range.length);
        if (nbytes == 0) {
          if (binary_buffer.IsFull())
            binary_buffer.Clear();
          break;
        }

        binary_buffer.Consume(nbytes);
      }
    } while (data < end);
  }
Exemple #5
0
  bool Fill(TimeoutClock &timeout) {
    const auto dest = buffer.Write();
    if (dest.IsEmpty())
      /* already full */
      return false;

    const Port::WaitResult wresult =
      port.WaitRead(env, timeout.GetRemainingOrZero());
    if (wresult != Port::WaitResult::READY)
      return false;

    const int nbytes = port.Read(dest.data, dest.length);
    if (nbytes <= 0)
      return false;

    buffer.Append(nbytes);
    return true;
  }
Exemple #6
0
  virtual void OnNotification() {
    while (true) {
      char data[64];
      size_t length;

      {
        ScopeLock protect(mutex);
        auto range = buffer.Read();
        if (range.IsEmpty())
          break;

        length = std::min(ARRAY_SIZE(data), size_t(range.length));
        memcpy(data, range.data, length);
        buffer.Consume(length);
      }

      terminal.Write(data, length);
    }
  }
Exemple #7
0
  char *GetLine() {
    const auto src = buffer.Read();
    char *const end = src.data + src.length;

    /* a NMEA line starts with a dollar symbol ... */
    char *dollar = std::find(src.data, end, '$');
    if (dollar == end) {
      buffer.Clear();
      return nullptr;
    }

    char *start = dollar + 1;

    /* ... and ends with an asterisk */
    char *asterisk = std::find(start, end, '*');
    if (asterisk + 3 > end)
      /* need more data */
      return nullptr;

    /* verify the checksum following the asterisk (two hex digits) */

    const uint8_t calculated_checksum = NMEAChecksum(start, asterisk - start);

    const char checksum_buffer[3] = { asterisk[1], asterisk[2], 0 };
    char *endptr;
    const uint8_t parsed_checksum = strtoul(checksum_buffer, &endptr, 16);
    if (endptr != checksum_buffer + 2 ||
        parsed_checksum != calculated_checksum) {
      buffer.Clear();
      return nullptr;
    }

    buffer.Consume(asterisk + 3 - src.data);

    *asterisk = 0;
    return start;
  }
Exemple #8
0
 void Flush() {
   port.Flush();
   buffer.Clear();
 }
Exemple #9
0
 virtual void consume(unsigned n) {
   buffer.Consume(n);
   position += n;
 }
// Mix data from each application stream and write result to the shared MMAP stream.
void *AAudioServiceEndpointPlay::callbackLoop() {
    aaudio_result_t result = AAUDIO_OK;
    int64_t timeoutNanos = getStreamInternal()->calculateReasonableTimeout();

    // result might be a frame count
    while (mCallbackEnabled.load() && getStreamInternal()->isActive() && (result >= 0)) {
        // Mix data from each active stream.
        mMixer.clear();

        { // brackets are for lock_guard
            int index = 0;
            int64_t mmapFramesWritten = getStreamInternal()->getFramesWritten();

            std::lock_guard <std::mutex> lock(mLockStreams);
            for (const auto clientStream : mRegisteredStreams) {
                int64_t clientFramesRead = 0;

                if (!clientStream->isRunning()) {
                    continue;
                }

                sp<AAudioServiceStreamShared> streamShared =
                        static_cast<AAudioServiceStreamShared *>(clientStream.get());

                {
                    // Lock the AudioFifo to protect against close.
                    std::lock_guard <std::mutex> lock(streamShared->getAudioDataQueueLock());

                    FifoBuffer *fifo = streamShared->getAudioDataFifoBuffer_l();
                    if (fifo != nullptr) {

                        // Determine offset between framePosition in client's stream
                        // vs the underlying MMAP stream.
                        clientFramesRead = fifo->getReadCounter();
                        // These two indices refer to the same frame.
                        int64_t positionOffset = mmapFramesWritten - clientFramesRead;
                        streamShared->setTimestampPositionOffset(positionOffset);

                        float volume = 1.0; // to match legacy volume
                        bool underflowed = mMixer.mix(index, fifo, volume);
                        if (underflowed) {
                            streamShared->incrementXRunCount();
                        }
                        clientFramesRead = fifo->getReadCounter();
                    }
                }

                if (clientFramesRead > 0) {
                    // This timestamp represents the completion of data being read out of the
                    // client buffer. It is sent to the client and used in the timing model
                    // to decide when the client has room to write more data.
                    Timestamp timestamp(clientFramesRead, AudioClock::getNanoseconds());
                    streamShared->markTransferTime(timestamp);
                }

                index++; // just used for labelling tracks in systrace
            }
        }

        // Write mixer output to stream using a blocking write.
        result = getStreamInternal()->write(mMixer.getOutputBuffer(),
                                            getFramesPerBurst(), timeoutNanos);
        if (result == AAUDIO_ERROR_DISCONNECTED) {
            AAudioServiceEndpointShared::disconnectRegisteredStreams();
            break;
        } else if (result != getFramesPerBurst()) {
            ALOGW("AAudioServiceEndpoint(): callbackLoop() wrote %d / %d",
                  result, getFramesPerBurst());
            break;
        }
    }

    return NULL; // TODO review
}
Exemple #11
0
 void PFLAX() {
   binary = true;
   binary_buffer.Clear();
 }
Exemple #12
0
 virtual void Consume(unsigned n) override {
   buffer.Consume(n);
   position += n;
 }
bool
WesterboerVW921Device::DataReceived(const void *_data, size_t length,
                                    struct NMEAInfo &info)
{
  assert(_data != NULL);
  assert(length > 0);

  bool result = false;

  const char *data = (const char *)_data, *end = data + length;

  do {
    // append new data to buffer, as much as fits there
    auto range = buffer.Write();
    if (range.IsEmpty()) {
      // overflow: reset buffer to recover quickly
      buffer.Clear();
      continue;
    }

    size_t nbytes = std::min(size_t(range.length), size_t(end - data));
    memcpy(range.data, data, nbytes);
    data += nbytes;
    buffer.Append(nbytes);

    while (true) {
      // read data from the buffer, to see if there's a dollar character
      range = buffer.Read();
      if (range.IsEmpty())
        break;

      // Search for the dollar sign (sync byte)
      char *dollar = (char *)memchr(range.data, '$', range.length);
      if (dollar == NULL)
        // no dollar sign here: wait for more data
        break;

      // Make sure there are at least 5 bytes in the buffer to
      // read the sentence header
      unsigned remaining_length = range.length - (dollar - range.data);
      if (remaining_length < 5)
        break;

      // Check this is a Westerboer sentence
      if (dollar[1] != 'w') {
        // Skip this sentence
        buffer.Consume(dollar - range.data + 1);
        continue;
      }

      // Read the length of the sentence
      uint8_t sentence_length = (uint8_t)dollar[2];

      // Check if the sentence was completely received already
      if (remaining_length < sentence_length)
        break;

      if (!CheckChecksum(dollar, sentence_length)) {
        // Skip this sentence
        buffer.Consume(dollar - range.data + 1);
        continue;
      }

      // Read the sentence identification number
      uint8_t sentence_number = (uint8_t)dollar[4];

      // Parse the sentence
      SentenceReceived(sentence_number, dollar, sentence_length, info);

      buffer.Consume(dollar - range.data + sentence_length);

      result = true;
    }
  } while (data < end);

  return result;
}