Пример #1
0
void	eladWorker:: run (void) {
int32_t	amount;
int	rc;
//
//	we build in a delay such that it can be expected that the
//	data is in place. We read app 100 times a second a buffer
//	per read we have BUFFERSIZE / 8 samples, so we wait

	fprintf (stderr, "New elad-worker\n");
	while (runnable) {
	   rc = libusb_bulk_transfer (functions -> getHandle (),
	                              (6 | LIBUSB_ENDPOINT_IN),
	                              (uint8_t *)buffer,
	                              BUFFER_SIZE * sizeof (int8_t),
	                              &amount,
	                              2000);
	   if (rc) {
              fprintf (stderr,
	               "Error in libusb_bulk_transfer: [%d] %s\n",
	               rc,
	               libusb_error_name (rc));
	      if (rc != 7)
	         break;
	   }

	   _I_Buffer	-> putDataIntoBuffer (buffer, amount);
	   usleep (20);
	   if (_I_Buffer -> GetRingBufferReadAvailable () > theRate / 10)
	      emit samplesAvailable (theRate / 10);
	}
	fprintf (stderr, "eladWorker now stopped\n");
}
Пример #2
0
bool AudioRingBuffer::isNotStarvedOrHasMinimumSamples(unsigned int numRequiredSamples) const {
    if (!_isStarved) {
        return true;
    } else {
        return samplesAvailable() >= numRequiredSamples;
    }
}
Пример #3
0
bool PositionalAudioRingBuffer::shouldBeAddedToMix(int numJitterBufferSamples) {
    if (!isNotStarvedOrHasMinimumSamples(NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL + numJitterBufferSamples)) {
        if (_shouldOutputStarveDebug) {
            _shouldOutputStarveDebug = false;
        }

        return false;
    } else if (samplesAvailable() < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL) {
        _isStarved = true;

        // reset our _shouldOutputStarveDebug to true so the next is printed
        _shouldOutputStarveDebug = true;

        return false;
    } else {
        // good buffer, add this to the mix
        _isStarved = false;

        // since we've read data from ring buffer at least once - we've started
        _hasStarted = true;

        return true;
    }

    return false;
}
Пример #4
0
int AudioRingBuffer::writeData(const char* data, int maxSize) {
    // make sure we have enough bytes left for this to be the right amount of audio
    // otherwise we should not copy that data, and leave the buffer pointers where they are
    int samplesToCopy = std::min((int)(maxSize / sizeof(int16_t)), _sampleCapacity);

    int samplesRoomFor = _sampleCapacity - samplesAvailable();
    if (samplesToCopy > samplesRoomFor) {
        // there's not enough room for this write.  erase old data to make room for this new data
        int samplesToDelete = samplesToCopy - samplesRoomFor;
        _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete);
        _overflowCount++;
        qCDebug(audio) << "Overflowed ring buffer! Overwriting old data";
    }

    if (_endOfLastWrite + samplesToCopy <= _buffer + _bufferLength) {
        memcpy(_endOfLastWrite, data, samplesToCopy * sizeof(int16_t));
    } else {
        int numSamplesToEnd = (_buffer + _bufferLength) - _endOfLastWrite;
        memcpy(_endOfLastWrite, data, numSamplesToEnd * sizeof(int16_t));
        memcpy(_buffer, data + (numSamplesToEnd * sizeof(int16_t)), (samplesToCopy - numSamplesToEnd) * sizeof(int16_t));
    }

    _endOfLastWrite = shiftedPositionAccomodatingWrap(_endOfLastWrite, samplesToCopy);

    return samplesToCopy * sizeof(int16_t);
}
Пример #5
0
bool DsfFileReader::readNextBlock()
{
	// return false if this is the end of the file
	if (!samplesAvailable()) {
		// fill the blockBuffer with the idle sample
		dsf2flac_uint8 idle = getIdleSample();
		for (dsf2flac_uint32 i=0; i<chanNum; i++)
			for (dsf2flac_uint32 j=0; j<blockSzPerChan; j++)
				blockBuffer[i][j] = idle;
		return false;
	}

	for (dsf2flac_uint32 i=0; i<chanNum; i++) {
		if (file.read_uint8(blockBuffer[i],blockSzPerChan)) {
			// if read failed fill the blockBuffer with the idle sample
			dsf2flac_uint8 idle = getIdleSample();
			for (dsf2flac_uint32 i=0; i<chanNum; i++)
				for (dsf2flac_uint32 j=0; j<blockSzPerChan; j++)
					blockBuffer[i][j] = idle;
			return false;
		}
	}

	blockCounter++;
	blockMarker=0;

	return true;
}
Пример #6
0
int AudioRingBuffer::writeSamplesWithFade(ConstIterator source, int maxSamples, float fade) {
    int samplesToCopy = std::min(maxSamples, _sampleCapacity);
    int samplesRoomFor = _sampleCapacity - samplesAvailable();
    if (samplesToCopy > samplesRoomFor) {
        // there's not enough room for this write.  erase old data to make room for this new data
        int samplesToDelete = samplesToCopy - samplesRoomFor;
        _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, samplesToDelete);
        _overflowCount++;
        qCDebug(audio) << "Overflowed ring buffer! Overwriting old data";
    }

    int16_t* bufferLast = _buffer + _bufferLength - 1;
    for (int i = 0; i < samplesToCopy; i++) {
        *_endOfLastWrite = (int16_t)((float)(*source) * fade);
        _endOfLastWrite = (_endOfLastWrite == bufferLast) ? _buffer : _endOfLastWrite + 1;
        ++source;
    }

    return samplesToCopy;
}
Пример #7
0
bool DsdiffFileReader::step()
{
	bool ok = true;
	
	if (!samplesAvailable())
		ok = false;
	else if (bufferMarker>=sampleBufferLenPerChan)
		ok = readNextBlock();
	
	if (ok) {
		for (dsf2flac_uint16 i=0; i<chanNum; i++)
			circularBuffers[i].push_front(sampleBuffer[i+bufferMarker*chanNum]);
		bufferMarker++;
	} else {
		for (dsf2flac_uint16 i=0; i<chanNum; i++)
			circularBuffers[i].push_front(getIdleSample());
	}
	
	posMarker++;
	return ok;
}
Пример #8
0
bool DsfFileReader::step()
{
	bool ok = true;
	
	if (!samplesAvailable())
		ok = false;
	else if (blockMarker>=blockSzPerChan)
		ok = readNextBlock();
	
	if (ok) {
		for (dsf2flac_uint32 i=0; i<chanNum; i++)
			circularBuffers[i].push_front(blockBuffer[i][blockMarker]);
		blockMarker++;
	} else {
		for (dsf2flac_uint32 i=0; i<chanNum; i++)
			circularBuffers[i].push_front(getIdleSample());
	}

	posMarker++;
	return ok;
}
Пример #9
0
qint64 AudioRingBuffer::readData(char *data, qint64 maxSize) {

    // only copy up to the number of samples we have available
    int numReadSamples = std::min((unsigned) (maxSize / sizeof(int16_t)), samplesAvailable());

    // If we're in random access mode, then we consider our number of available read samples slightly
    // differently. Namely, if anything has been written, we say we have as many samples as they ask for
    // otherwise we say we have nothing available
    if (_randomAccessMode) {
        numReadSamples = _endOfLastWrite ? (maxSize / sizeof(int16_t)) : 0;
    }

    if (_nextOutput + numReadSamples > _buffer + _sampleCapacity) {
        // we're going to need to do two reads to get this data, it wraps around the edge

        // read to the end of the buffer
        int numSamplesToEnd = (_buffer + _sampleCapacity) - _nextOutput;
        memcpy(data, _nextOutput, numSamplesToEnd * sizeof(int16_t));
        if (_randomAccessMode) {
            memset(_nextOutput, 0, numSamplesToEnd * sizeof(int16_t)); // clear it
        }
        
        // read the rest from the beginning of the buffer
        memcpy(data + (numSamplesToEnd * sizeof(int16_t)), _buffer, (numReadSamples - numSamplesToEnd) * sizeof(int16_t));
        if (_randomAccessMode) {
            memset(_buffer, 0, (numReadSamples - numSamplesToEnd) * sizeof(int16_t)); // clear it
        }
    } else {
        // read the data
        memcpy(data, _nextOutput, numReadSamples * sizeof(int16_t));
        if (_randomAccessMode) {
            memset(_nextOutput, 0, numReadSamples * sizeof(int16_t)); // clear it
        }
    }

    // push the position of _nextOutput by the number of samples read
    _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, numReadSamples);

    return numReadSamples * sizeof(int16_t);
}
Пример #10
0
int AudioRingBuffer::addSilentSamples(int silentSamples) {

    int samplesRoomFor = _sampleCapacity - samplesAvailable();
    if (silentSamples > samplesRoomFor) {
        // there's not enough room for this write. write as many silent samples as we have room for
        silentSamples = samplesRoomFor;
        qCDebug(audio) << "Dropping some silent samples to prevent ring buffer overflow";
    }

    // memset zeroes into the buffer, accomodate a wrap around the end
    // push the _endOfLastWrite to the correct spot
    if (_endOfLastWrite + silentSamples <= _buffer + _bufferLength) {
        memset(_endOfLastWrite, 0, silentSamples * sizeof(int16_t));
    } else {
        int numSamplesToEnd = (_buffer + _bufferLength) - _endOfLastWrite;
        memset(_endOfLastWrite, 0, numSamplesToEnd * sizeof(int16_t));
        memset(_buffer, 0, (silentSamples - numSamplesToEnd) * sizeof(int16_t));
    }
    _endOfLastWrite = shiftedPositionAccomodatingWrap(_endOfLastWrite, silentSamples);

    return silentSamples;
}
Пример #11
0
qint64 AudioRingBuffer::readData(char *data, qint64 maxSize) {

    // only copy up to the number of samples we have available
    int numReadSamples = std::min((unsigned) (maxSize / sizeof(int16_t)), samplesAvailable());

    if (_nextOutput + numReadSamples > _buffer + _sampleCapacity) {
        // we're going to need to do two reads to get this data, it wraps around the edge

        // read to the end of the buffer
        int numSamplesToEnd = (_buffer + _sampleCapacity) - _nextOutput;
        memcpy(data, _nextOutput, numSamplesToEnd * sizeof(int16_t));
        
        // read the rest from the beginning of the buffer
        memcpy(data + (numSamplesToEnd * sizeof(int16_t)), _buffer, (numReadSamples - numSamplesToEnd) * sizeof(int16_t));
    } else {
        // read the data
        memcpy(data, _nextOutput, numReadSamples * sizeof(int16_t));
    }

    // push the position of _nextOutput by the number of samples read
    _nextOutput = shiftedPositionAccomodatingWrap(_nextOutput, numReadSamples);

    return numReadSamples * sizeof(int16_t);
}
Пример #12
0
void	dabStick::newdataAvailable (int n) {
	samplesAvailable (n);
}
Пример #13
0
bool DsdiffFileReader::readNextBlock() {
	
	bool ok = true;
	// return false if this is the end of the file
	if (!samplesAvailable()) {
		errorMsg = "dsfFileReader::readNextBlock:no more data in file";
		ok = false;
	}
	
	dsf2flac_int64 samplesLeft = getLength()-getPosition();
	
	if (ok && checkIdent(compressionType,const_cast<dsf2flac_int8*>("DSD "))) {
		if (samplesLeft/samplesPerChar < sampleBufferLenPerChan) {
			// fill the blockBuffer with the idle sample
			for (dsf2flac_uint32 i=0; i<chanNum*sampleBufferLenPerChan; i++)
				sampleBuffer[i] = getIdleSample();
			if (file.read_uint8(sampleBuffer,chanNum*samplesLeft/samplesPerChar)) {
				errorMsg = "dsfFileReader::readNextBlock:file read error";
				ok = false;
			}
		} else if (file.read_uint8(sampleBuffer,chanNum*sampleBufferLenPerChan)) {
			errorMsg = "dsfFileReader::readNextBlock:file read error";
			ok = false;
		}
	} else if (ok && checkIdent(compressionType,const_cast<dsf2flac_int8*>("DST "))) {
		
		dsf2flac_uint64 chunkStart = file.tellg();
		dsf2flac_uint64 chunkSz;
		dsf2flac_int8 ident[5];
		ident[4]='\0';
		
		if (chunkStart > dstChunkEnd)
			ok = false;
		
		// read the chunk header
		if (ok)
			ok = readChunkHeader(ident,chunkStart,&chunkSz);
		
		// we might have a DSTC chunk, which we will ignore
		if (ok)
			if (checkIdent(ident,const_cast<dsf2flac_int8*>("DSTC")))
				ok = readChunkHeader(ident,chunkStart,&chunkSz);
				
		// decode
		if (ok)
			ok = readChunk_DSTF(chunkStart);

		// make sure we are in the right place for next time
		file.seekg(chunkStart + chunkSz);
	} else
		ok = false;
	
	
	if (!ok) {
		// fill the blockBuffer with the idle sample
		for (dsf2flac_uint32 i=0; i<chanNum*sampleBufferLenPerChan; i++)
			sampleBuffer[i] = getIdleSample();
	}
	
	bufferCounter++;
	bufferMarker=0;

	return ok;
}
	/// \brief Gets sample data from the oscilloscope and converts it.
	/// \return 0 on success, libusb error code on error.
	int Control::getSamples(bool process) {
        long int errorCode;


		// Save raw data to temporary buffer
        unsigned long int dataCount = bufferSize * BUUDAI_CHANNELS * bufferMulti;

        if (bufferMulti >= 2) {
            dataCount = dataCount + 4096;
        }

        unsigned long int dataLength = dataCount * 1;
		
		unsigned char data[dataLength];
		usbMutex.lock();
		unsigned char res = 0;
        device->controlTransfer(0, (unsigned char)FIFO_CONTROL, &res, 1, (unsigned char)FIFO_CONTROL_CLEAR, 0, 1);
        errorCode = device->bulkReadMulti(data, dataLength, 3);
        //errorCode = device->bulkRead(data, dataLength, 1);
        // device->controlTransfer(0, (unsigned char)FIFO_CONTROL, &res, 1, (unsigned char)FIFO_CONTROL_CLEAR, 0, 1);

		usbMutex.unlock();

        //usleep(1000000);

		if (errorCode < 0)
			return errorCode;

		// Process the data only if we want it
		if (process) {
			// How much data did we really receive?
			dataLength = errorCode;
            dataCount = dataLength;
			
			samplesMutex.lock();
			
            unsigned long int channelDataCount = dataCount / BUUDAI_CHANNELS;

			for (int channel = 0; channel < BUUDAI_CHANNELS; channel++) {
				// Reallocate memory for samples if the sample count has changed
				if (!samples[channel] || samplesSize[channel] != channelDataCount) {
					if (samples[channel])
                        delete samples[channel];
					samples[channel] = new double[channelDataCount];
					samplesSize[channel] = channelDataCount;
				}

				// Convert data from the oscilloscope and write it into the sample buffer
                unsigned long int bufferPosition = 0 ;//+ triggerPoint * 2;
                unsigned int bufferFraction = (dataCount / BUUDAI_CHANNELS) / 2; // only use a fraction of samplebuffer, scales with timebase via bufferMulti to catch slow signals on longer timebase.


                // For buffersizes < 2048 no initial shift is needed, as data fits in fifo without glitch

                if (bufferMulti >= 2) {
                    bufferPosition = 2048;
                }

                if (oldTriggerOffset >= 256 && oldTriggerOffset <= channelDataCount) {
                bufferPosition = oldTriggerOffset - 256;
}

                // Trigger Hack for rising signal


                double dataValueOld = 0;
                int hitCounter = 0;


                for (unsigned int triggerPositionIndex = 0; triggerPositionIndex < bufferFraction; triggerPositionIndex ++, bufferPosition += 2){
                 double dataValue = ((double) data[bufferPosition + channel]/sampleRange[channel] - offsetReal[channel])*gainSteps[gain[channel]]*cal[channel];

                 if (dataValue >= dataValueOld && dataValue >= triggerPositionOffset) {
                     hitCounter++;
                     if (hitCounter >= 4) {
                     bufferPositionOffset = bufferPosition;
                     oldTriggerOffset = bufferPosition;
                     hitCounter = 0;
                     break;
                     }

                 }

                 dataValueOld = dataValue;
                }

                // triggerPosition



                bufferPosition = int(bufferPositionOffset + (triggerPosition * 2));




                // shorten data due to trigger offset

                //channelDataCount = channelDataCount - bufferPosition;

                // put data on screen

                for (unsigned long int realPosition = 0; realPosition < channelDataCount ; realPosition++, bufferPosition += 2) {
					if (bufferPosition >= dataCount)
                        bufferPosition %= dataCount;
								
					samples[channel][realPosition] = ((double) data[bufferPosition + channel]/sampleRange[channel] - offsetReal[channel])*gainSteps[gain[channel]]*cal[channel];
				}
			}

			samplesMutex.unlock();

            // limit framerate and load but be somewhat in sync with samplerate to avoid glitches

            if (bufferMulti < 2) {
            usleep(32768);
            } else {
                // usleep(bufferSize);
            }
            emit samplesAvailable(&(samples), &(samplesSize), (double) samplerateMax / samplerateDivider, &(samplesMutex));

		} // if (process)

		return 0;
	}