Пример #1
0
SINT CachingReaderChunk::readSampleFrames(
        const Mixxx::AudioSourcePointer& pAudioSource,
        SINT* pMaxReadableFrameIndex) {
    DEBUG_ASSERT(pMaxReadableFrameIndex);

    const SINT frameIndex = frameForIndex(getIndex());
    const SINT maxFrameIndex = math_min(
            *pMaxReadableFrameIndex, pAudioSource->getMaxFrameIndex());
    const SINT framesRemaining =
            *pMaxReadableFrameIndex - frameIndex;
    const SINT framesToRead =
            math_min(kFrames, framesRemaining);

    SINT seekFrameIndex =
            pAudioSource->seekSampleFrame(frameIndex);
    if (frameIndex != seekFrameIndex) {
        // Failed to seek to the requested index. The file might
        // be corrupt and decoding should be aborted.
        qWarning() << "Failed to seek chunk position:"
                << "actual =" << seekFrameIndex
                << ", expected =" << frameIndex
                << ", maximum =" << maxFrameIndex;
        if (frameIndex >= seekFrameIndex) {
            // Simple strategy to compensate for seek inaccuracies in
            // faulty files: Try to skip some samples up to the requested
            // seek position. But only skip twice as many frames/samples
            // as have been requested to avoid decoding great portions of
            // the file for small read requests on seek errors.
            const SINT framesToSkip = frameIndex - seekFrameIndex;
            if (framesToSkip <= (2 * framesToRead)) {
                seekFrameIndex += pAudioSource->skipSampleFrames(framesToSkip);
            }
        }
        if (frameIndex != seekFrameIndex) {
            // Unexpected/premature end of file -> prevent further
            // seeks beyond the current seek position
            *pMaxReadableFrameIndex = math_min(seekFrameIndex, *pMaxReadableFrameIndex);
            // Don't read any samples on a seek failure!
            m_frameCount = 0;
            return m_frameCount;
        }
    }

    DEBUG_ASSERT(frameIndex == seekFrameIndex);
    DEBUG_ASSERT(CachingReaderChunk::kChannels
            == Mixxx::AudioSource::kChannelCountStereo);
    m_frameCount = pAudioSource->readSampleFramesStereo(
            framesToRead, m_sampleBuffer, kSamples);
    if (m_frameCount < framesToRead) {
        qWarning() << "Failed to read chunk samples:"
                << "actual =" << m_frameCount
                << ", expected =" << framesToRead;
        // Adjust the max. readable frame index for future
        // read requests to avoid repeated invalid reads.
        *pMaxReadableFrameIndex = frameIndex + m_frameCount;
    }

    return m_frameCount;
}
Пример #2
0
void DlgPrefEQ::validate_levels() {
    m_highEqFreq = math_max(math_min(m_highEqFreq, kFrequencyUpperLimit),
                            kFrequencyLowerLimit);
    m_lowEqFreq = math_max(math_min(m_lowEqFreq, kFrequencyUpperLimit),
                           kFrequencyLowerLimit);
    if (m_lowEqFreq == m_highEqFreq) {
        if (m_lowEqFreq == kFrequencyLowerLimit) {
            ++m_highEqFreq;
        } else if (m_highEqFreq == kFrequencyUpperLimit) {
            --m_lowEqFreq;
        } else {
            ++m_highEqFreq;
        }
    }
}
Пример #3
0
SINT SoundSourceOpus::readSampleFramesStereo(
        SINT numberOfFrames, CSAMPLE* sampleBuffer,
        SINT sampleBufferSize) {
    DEBUG_ASSERT(isValidFrameIndex(m_curFrameIndex));
    DEBUG_ASSERT(getSampleBufferSize(numberOfFrames, true) <= sampleBufferSize);

    const SINT numberOfFramesTotal = math_min(
            numberOfFrames, getMaxFrameIndex() - m_curFrameIndex);

    CSAMPLE* pSampleBuffer = sampleBuffer;
    SINT numberOfFramesRemaining = numberOfFramesTotal;
    while (0 < numberOfFramesRemaining) {
        int readResult = op_read_float_stereo(m_pOggOpusFile,
                pSampleBuffer,
                numberOfFramesRemaining * 2); // stereo
        if (0 < readResult) {
            m_curFrameIndex += readResult;
            pSampleBuffer += readResult * 2; // stereo
            numberOfFramesRemaining -= readResult;
        } else {
            qWarning() << "Failed to read sample data from OggOpus file:"
                    << readResult;
            break; // abort
        }
    }

    DEBUG_ASSERT(isValidFrameIndex(m_curFrameIndex));
    DEBUG_ASSERT(numberOfFramesTotal >= numberOfFramesRemaining);
    return numberOfFramesTotal - numberOfFramesRemaining;
}
Пример #4
0
SINT SoundSourceOpus::readSampleFrames(
        SINT numberOfFrames, CSAMPLE* sampleBuffer) {
    DEBUG_ASSERT(isValidFrameIndex(m_curFrameIndex));

    const SINT numberOfFramesTotal = math_min(
            numberOfFrames, getMaxFrameIndex() - m_curFrameIndex);

    CSAMPLE* pSampleBuffer = sampleBuffer;
    SINT numberOfFramesRemaining = numberOfFramesTotal;
    while (0 < numberOfFramesRemaining) {
        int readResult = op_read_float(m_pOggOpusFile,
                pSampleBuffer,
                frames2samples(numberOfFramesRemaining), NULL);
        if (0 < readResult) {
            m_curFrameIndex += readResult;
            pSampleBuffer += frames2samples(readResult);
            numberOfFramesRemaining -= readResult;
        } else {
            qWarning() << "Failed to read sample data from OggOpus file:"
                    << readResult;
            break; // abort
        }
    }

    DEBUG_ASSERT(isValidFrameIndex(m_curFrameIndex));
    DEBUG_ASSERT(numberOfFramesTotal >= numberOfFramesRemaining);
    return numberOfFramesTotal - numberOfFramesRemaining;
}
Пример #5
0
void CachingReader::process() {
    ReaderStatusUpdate status;
    while (m_readerStatusFIFO.read(&status, 1) == 1) {
        CachingReaderChunkForOwner* pChunk = static_cast<CachingReaderChunkForOwner*>(status.chunk);
        if (pChunk) {
            // Take over control of the chunk from the worker.
            // This has to be done before freeing all chunks
            // after a new track has been loaded (see below)!
            pChunk->takeFromWorker();
            if (status.status != CHUNK_READ_SUCCESS) {
                // Discard chunks that are empty (EOF) or invalid
                freeChunk(pChunk);
            }
        }
        if (status.status == TRACK_NOT_LOADED) {
            m_readerStatus = status.status;
        } else if (status.status == TRACK_LOADED) {
            m_readerStatus = status.status;
            // Reset the max. readable frame index
            m_maxReadableFrameIndex = status.maxReadableFrameIndex;
            // Free all chunks with sample data from a previous track
            freeAllChunks();
        }
        // Adjust the max. readable frame index
        if (m_readerStatus == TRACK_LOADED) {
            m_maxReadableFrameIndex = math_min(status.maxReadableFrameIndex, m_maxReadableFrameIndex);
        } else {
            m_maxReadableFrameIndex = Mixxx::AudioSource::getMinFrameIndex();
        }
    }
}
Пример #6
0
long cog_min(struct cog *c) {
  long min;
  switch(c->type) {
  case COG_CONCAT:
    min =  math_min(cog_min(c->data.concat.lhs), cog_min(c->data.concat.rhs));
    break;
  case COG_BTREE:
    min = cog_min(c->data.btree.lhs);
    if(min ==  MAX_VALUE) {
      min = cog_min(c->data.btree.rhs);
    }
    break;
  case COG_SORTEDARRAY:
    if(c->data.sortedarray.records == NULL) {
      min = MAX_VALUE;
    } else {
      min = buffer_key(c->data.sortedarray.records, c->data.sortedarray.start);
    }
    break;
  case COG_ARRAY:
    fprintf(stderr, "Unhandled case: Array min\n");
    exit(-1);
  }
  return min;
}
Пример #7
0
void EffectChainSlot::slotChainEffectChanged(unsigned int effectSlotNumber,
                                             bool shouldEmit) {
    //qDebug() << debugString() << "slotChainEffectChanged" << effectSlotNumber;
    if (m_pEffectChain) {
        const QList<EffectPointer> effects = m_pEffectChain->effects();
        EffectSlotPointer pSlot;
        EffectPointer pEffect;

        if (effects.size() > m_slots.size()) {
            qWarning() << debugString() << "has too few slots for effect";
        }

        if (effectSlotNumber < (unsigned) m_slots.size()) {
            pSlot = m_slots.at(effectSlotNumber);
        }
        if (effectSlotNumber < (unsigned) effects.size()) {
            pEffect = effects.at(effectSlotNumber);
        }
        if (pSlot != nullptr) {
            pSlot->loadEffect(pEffect);
        }

        m_pControlNumEffects->forceSet(math_min(
            static_cast<unsigned int>(m_slots.size()),
            m_pEffectChain->numEffects()));

        if (shouldEmit) {
            emit(updated());
        }
    }
}
Пример #8
0
cog *partition_cog(cog *c) {
  int records = cog_length(c);
  
  if(c->type == COG_ARRAY && records < BLOCK_SIZE) {
    record_sort(c->data.array.records->data, c->data.array.start, c->data.array.start + c->data.array.len);
    convert_to_sortedarray(c);
    return c;
  }
  
  iterator iter = scan_full_array(c);
  int count=0;

  cog *ret = NULL;
  while(records > 0) {
    count++;
    cog *store = array_load(iter, math_min(records, BLOCK_SIZE));
    records -= store->data.array.len;
    record_sort(store->data.array.records->data, 0, store->data.array.len);
    convert_to_sortedarray(store);
   
    if(ret == NULL) {
      ret = store;
    } else {
      ret = make_concat(ret, store);
    }
  }

  if(ret == NULL) {
    ret = make_sortedarray(0, 0, NULL);
  }
  cleanup(c);
  iter_cleanup(iter);
  return ret;
}
Пример #9
0
void BpmControl::slotAdjustBeatsFaster(double v) {
    BeatsPointer pBeats = m_pBeats;
    if (v > 0 && pBeats && (pBeats->getCapabilities() & Beats::BEATSCAP_SETBPM)) {
        double new_bpm = math_min(200.0, pBeats->getBpm() + .01);
        pBeats->setBpm(new_bpm);
    }
}
Пример #10
0
void EngineNetworkStream::write(const CSAMPLE* buffer, int frames) {
    if (m_pWorker.isNull()) {
        return;
    }

    //qDebug() << "EngineNetworkStream::write()" << frames;
    if (!m_pWorker->threadWaiting()) {
        // no thread waiting, so we can advance the stream without
        // buffering
        m_streamFramesWritten += frames;
        return;
    }
    int writeAvailable = m_pOutputFifo->writeAvailable();
    int writeRequired = frames * m_numOutputChannels;
    if (writeAvailable < writeRequired) {
        qDebug() << "EngineNetworkStream::write() buffer full, loosing samples";
        NetworkStreamWorker::debugState();
        m_writeOverflowCount++;
    }
    int copyCount = math_min(writeAvailable, writeRequired);
    if (copyCount > 0) {
        (void)m_pOutputFifo->write(buffer, copyCount);
        // we advance the frame only by the samples we have actually copied
        // This means in case of buffer full (where we loose some frames)
        // we do not get out of sync, and the syncing code tries to catch up the
        // stream by writing silence, once the buffer is free.
        m_streamFramesWritten += copyCount / m_numOutputChannels;
    }
    scheduleWorker();
}
Пример #11
0
void WaveformWidgetFactory::setFrameRate(int frameRate) {
    m_frameRate = math_min(120, math_max(1, frameRate));
    if (m_config) {
        m_config->set(ConfigKey("[Waveform]","FrameRate"), ConfigValue(m_frameRate));
    }
    m_vsyncThread->setUsSyncIntervalTime(1e6 / m_frameRate);
}
Пример #12
0
unsigned int SoundSourceCoreAudio::read(unsigned long size, const SAMPLE *destination) {
    //if (!m_decoder) return 0;
    OSStatus err;
    SAMPLE *destBuffer(const_cast<SAMPLE*>(destination));
    UInt32 numFrames = 0;//(size / 2); /// m_inputFormat.mBytesPerFrame);
    unsigned int totalFramesToRead = size/2;
    unsigned int numFramesRead = 0;
    unsigned int numFramesToRead = totalFramesToRead;

    while (numFramesRead < totalFramesToRead) { //FIXME: Hardcoded 2
    	numFramesToRead = totalFramesToRead - numFramesRead;

		AudioBufferList fillBufList;
		fillBufList.mNumberBuffers = 1; //Decode a single track?
		fillBufList.mBuffers[0].mNumberChannels = m_inputFormat.mChannelsPerFrame;
		fillBufList.mBuffers[0].mDataByteSize = math_min(1024, numFramesToRead*4);//numFramesToRead*sizeof(*destBuffer); // 2 = num bytes per SAMPLE
		fillBufList.mBuffers[0].mData = (void*)(&destBuffer[numFramesRead*2]);

			// client format is always linear PCM - so here we determine how many frames of lpcm
			// we can read/write given our buffer size
		numFrames = numFramesToRead; //This silly variable acts as both a parameter and return value.
		err = ExtAudioFileRead (m_audioFile, &numFrames, &fillBufList);
		//The actual number of frames read also comes back in numFrames.
		//(It's both a parameter to a function and a return value. wat apple?)
		//XThrowIfError (err, "ExtAudioFileRead");
		if (!numFrames) {
				// this is our termination condition
			break;
		}
		numFramesRead += numFrames;
    }
    return numFramesRead*2;
}
Пример #13
0
/*-------------------------------------------------------------------------*
 * PL_FD_TELL_INTERV_INTERV                                                *
 *                                                                         *
 *-------------------------------------------------------------------------*/
Bool
Pl_Fd_Tell_Interv_Interv(WamWord *fdv_adr, int min, int max)
{
  int nb_elem;
  int propag;
  int min1, max1;


  min1 = Min(fdv_adr);
  max1 = Max(fdv_adr);

  min = math_max(min, min1);
  max = math_min(max, max1);

  if (min > max)		/* detects also if the initial   */
    return FALSE;		/* interval (min, max) was empty */

  if (min == max)
    Update_Range_From_Int(fdv_adr, min, propag);
  else
    {
      nb_elem = max - min + 1;
      Update_Interval_From_Interval(fdv_adr, nb_elem, min, max, propag);
    }

  if (propag)
    All_Propagations(fdv_adr, propag);

  return TRUE;
}
Пример #14
0
void update_object_orientation(void)
{
	static int mx = 0, my = 0, last_mouse_x = 0, last_mouse_y = 0;
	static int arcball = 0;
	
	IF_FAILED(init);
	
	if(!disable_mouse) {
		
		if(!arcball && input_get_mousebtn_state(MOUSE_LEFTBTN)) {
			arcball = 1;
			
			input_get_mouse_position(&mx, &my);
			
			last_mouse_x = mx;
			last_mouse_y = my;
		} else if(arcball && !input_get_mousebtn_state(MOUSE_LEFTBTN)) {
			arcball = 0;
			return;
		}
		
		if(arcball) {
			input_get_mouse_position(&mx, &my);
			
			if(mx < 0)
				mx = 0;
			else if(mx > window_width)
				mx = window_width;
			if(my < 0)
				my = 0;
			else if(my > window_height)
				my = window_height;
			
			if(last_mouse_x != mx || last_mouse_y != my) {
				// получаем вектора вращения виртуальной сферы
				vector3f v1 = compute_sphere_vector(last_mouse_x, last_mouse_y);
				vector3f v2 = compute_sphere_vector(mx, my);
				
				// угол вращения
				rot_angle = RAD_TO_DEG(math_acosf(math_min(1.0f, vec3f_dot(v1, v2))));
				
				matrix3f rotmat3, model3, rotmodel3;
				mat4_submat(rotmat3, 3, 3, rotmat);
				mat4_submat(model3, 3, 3, modelmat);
				
				mat3_mult2(rotmodel3, rotmat3, model3);
				
				// получаем ось вращения (переводим её в систему координат объекта)
				rot_axis = mat3_mult_vec3(rotmodel3, vec3f_norm(vec3f_cross(v1, v2)));
				
				// домножаем матрицу вращения
				mat4_rotate_axis_mult(rotmat, rot_angle, rot_axis);
				
				last_mouse_x = mx;
				last_mouse_y = my;
			}
		}
	}
}
Пример #15
0
long SoundSourceModPlug::seek(long filePos)
{
    if (m_fileLength > 0) {
        m_seekPos = math_min((unsigned long)filePos, m_fileLength);
        return m_seekPos;
    }
    return 0;
}
Пример #16
0
int SoundSourceModPlug::open() {
    ScopedTimer t("SoundSourceModPlug::open()");

    if (m_pModFile == NULL) {
        // an error occured
        t.cancel();
        qDebug() << "[ModPlug] Could not load module file: "
                 << m_qFilename;
        return ERR;
    }

    // estimate size of sample buffer (for better performance)
    // beware: module length estimation is unreliable due to loops
    // song milliseconds * 2 (bytes per sample)
    //                   * 2 (channels)
    //                   * 44.1 (samples per millisecond)
    //                   + some more to accomodate short loops etc.
    // approximate and align with CHUNKSIZE yields:
    // (((milliseconds << 2) >> 10 /* to seconds */)
    //      div 11 /* samples to chunksize ratio */)
    //      << 19 /* align to chunksize */
    int estimate = ((ModPlug::ModPlug_GetLength(m_pModFile) >> 8) / 11) << 19;
    estimate = math_min(estimate, s_bufferSizeLimit);
    m_sampleBuf.reserve(estimate);
    qDebug() << "[ModPlug] Reserved " << m_sampleBuf.capacity()
             << " bytes for samples";

    // decode samples to sample buffer
    int bytesRead = -1;
    int currentSize = 0;
    while((bytesRead != 0) && (m_sampleBuf.length() < s_bufferSizeLimit)) {
        // reserve enough space in sample buffer
        m_sampleBuf.resize(currentSize + CHUNKSIZE);
        bytesRead = ModPlug::ModPlug_Read(m_pModFile,
                                          m_sampleBuf.data() + currentSize,
                                          CHUNKSIZE);
        // adapt to actual size
        currentSize += bytesRead;
        if (bytesRead != CHUNKSIZE) {
            m_sampleBuf.resize(currentSize);
            bytesRead = 0; // we reached the end of the file
        }
    }
    qDebug() << "[ModPlug] Filled Sample buffer with " << m_sampleBuf.length()
             << " bytes.";
    qDebug() << "[ModPlug] Sample buffer has "
             << m_sampleBuf.capacity() - m_sampleBuf.length()
             << " bytes unused capacity.";

    // The sample buffer holds 44.1kHz 16bit integer stereo samples.
    // We count the number of samples by dividing number of
    // bytes in m_sampleBuf by 2 (bytes per sample).
    m_fileLength = m_sampleBuf.length() >> 1;
    m_iSampleRate = 44100; // ModPlug always uses 44.1kHz
    m_opened = true;
    m_seekPos = 0;
    return OK;
}
Пример #17
0
void CachingReaderWorker::processChunkReadRequest(
        ChunkReadRequest* request,
        ReaderStatusUpdate* update) {
    //qDebug() << "Processing ChunkReadRequest for" << chunk_number;

    // Initialize the output parameter
    update->chunk = request->chunk;
    update->chunk->frameCount = 0;

    const int chunk_number = request->chunk->chunk_number;
    if (!m_pAudioSource || chunk_number < 0) {
        update->status = CHUNK_READ_INVALID;
        return;
    }

    const SINT chunkFrameIndex =
            frameForChunk(chunk_number);
    if (!m_pAudioSource->isValidFrameIndex(chunkFrameIndex)) {
        // Frame index out of range
        update->status = CHUNK_READ_INVALID;
        return;
    }

    const SINT seekFrameIndex =
            m_pAudioSource->seekSampleFrame(chunkFrameIndex);
    if (seekFrameIndex != chunkFrameIndex) {
        // Failed to seek to the requested index.
        // Corrupt file? -> Stop reading!
        qWarning() << "Failed to seek chunk position";
        update->status = CHUNK_READ_INVALID;
        return;
    }

    const SINT framesRemaining =
            m_pAudioSource->getFrameIndexMax() - seekFrameIndex;
    const SINT framesToRead =
            math_min(kFramesPerChunk, framesRemaining);
    if (0 >= framesToRead) {
        // No more data available for reading
        update->status = CHUNK_READ_EOF;
        return;
    }

    const SINT framesRead =
            m_pAudioSource->readSampleFramesStereo(
                    framesToRead, request->chunk->stereoSamples, kSamplesPerChunk);
    DEBUG_ASSERT(framesRead <= framesToRead);
    if (framesRead < framesToRead) {
        // Failed to read data! Corrupt file?
        qWarning() << "Failed to read chunk samples";
        update->status = CHUNK_READ_INVALID;
        return;
    }
    DEBUG_ASSERT(framesRead == framesToRead);

    update->status = CHUNK_READ_SUCCESS;
    update->chunk->frameCount = framesRead;
}
Пример #18
0
double ControlLinPotmeterBehavior::valueToWidgetParameter(double dValue) {
    if (dValue > m_dMaxValue) {
        dValue = m_dMaxValue;
    } else if (dValue < m_dMinValue) {
        dValue = m_dMinValue;
    }
    double dNorm = (dValue - m_dMinValue) / m_dValueRange;
    return math_min(dNorm * 128, 127);
}
Пример #19
0
extracted_components *extract_partitions(cog *c, long low, long high) {
  double_struct *ret_struct;
  ret_struct = amerge(c, low, high);
  c = ret_struct->cog;
  iter_cleanup(ret_struct->iter);
  free(ret_struct);
  extracted_components *ret; 
  if(c->type == COG_BTREE) {
    if(c->data.btree.sep <= low) {
      ret = extract_partitions(c->data.btree.rhs, low, high);
      ret->lhs = ret->lhs == NULL ? c->data.btree.lhs : make_btree(c->data.btree.lhs, ret->lhs, c->data.btree.sep);
    } else if(c->data.btree.sep >= high) {
      ret = extract_partitions(c->data.btree.lhs, low, high);
      ret->rhs = ret->rhs == NULL ? c->data.btree.rhs : make_btree(ret->rhs, c->data.btree.rhs, c->data.btree.sep);
    } else {
      ret = extract_partitions(c->data.btree.lhs, low, c->data.btree.sep);
      struct extracted_components *ret2 = extract_partitions(c->data.btree.rhs, c->data.btree.sep, high);
      ret->rhs = ret2->rhs;

      if(ret->iter == NULL) {
        ret->iter = ret2->iter;
        ret->low_key = ret2->low_key;
        ret->high_key = ret2->high_key;
      } else if(ret2->iter != NULL) {
        ret->iter = iter_concat(ret->iter, ret2->iter);
        ret->low_key = math_min(ret->low_key, ret2->low_key);
        ret->high_key = math_max(ret->high_key, ret2->high_key);
      }
    }
    
    return ret;
  } else if(c->type == COG_SORTEDARRAY) {
    int start = c->data.sortedarray.start;
    int len = c->data.sortedarray.len;
    buffer b = c->data.sortedarray.records;
    int low_index = record_binarysearch(b->data, low, start, len);
    int high_index = record_binarysearch(b->data, high, start, len);
    while((low_index < high_index) && (b->data[low_index].key < low)) {
      low_index++;
    }
    while((low_index-1 >= start) && (b->data[low_index-1].key >= low)) {
      low_index--;
    }
    while((high_index < (start+len)) && (b->data[high_index].key <= high)) {
      high_index++;
    }
    cog *lhs = low_index > start ? make_sortedarray(start, low_index - start, b) : NULL;
    cog *rhs = high_index < (start+len) ? make_sortedarray(high_index, start + len - high_index, b) : NULL;
    iterator iter = low_index < high_index ? scan(c, low, high) : NULL;
    long low_key = iter == NULL ? MAX_VALUE :  buffer_key(b, low_index);
    long high_key = iter == NULL ? MIN_VALUE : buffer_key(b, high_index - 1);

    return make_extracted_components(lhs, rhs, low_key, high_key, iter);
  } else {
    return NULL;    
  }
}
Пример #20
0
SINT SoundSourceOggVorbis::readSampleFrames(
        SINT numberOfFrames, CSAMPLE* sampleBuffer,
        SINT sampleBufferSize, bool readStereoSamples) {
    DEBUG_ASSERT(isValidFrameIndex(m_curFrameIndex));
    DEBUG_ASSERT(getSampleBufferSize(numberOfFrames, readStereoSamples) <= sampleBufferSize);

    const SINT numberOfFramesTotal = math_min(
            numberOfFrames, getMaxFrameIndex() - m_curFrameIndex);

    CSAMPLE* pSampleBuffer = sampleBuffer;
    SINT numberOfFramesRemaining = numberOfFramesTotal;
    while (0 < numberOfFramesRemaining) {
        float** pcmChannels;
        int currentSection;
        // Use 'long' here, because ov_read_float() returns this type.
        // This is an exception from the rule not to any types with
        // differing sizes on different platforms.
        // https://bugs.launchpad.net/mixxx/+bug/1094143
        const long readResult = ov_read_float(&m_vf, &pcmChannels,
                numberOfFramesRemaining, &currentSection);
        if (0 < readResult) {
            m_curFrameIndex += readResult;
            if (kChannelCountMono == getChannelCount()) {
                if (readStereoSamples) {
                    for (long i = 0; i < readResult; ++i) {
                        *pSampleBuffer++ = pcmChannels[0][i];
                        *pSampleBuffer++ = pcmChannels[0][i];
                    }
                } else {
                    for (long i = 0; i < readResult; ++i) {
                        *pSampleBuffer++ = pcmChannels[0][i];
                    }
                }
            } else if (readStereoSamples || (kChannelCountStereo == getChannelCount())) {
                for (long i = 0; i < readResult; ++i) {
                    *pSampleBuffer++ = pcmChannels[0][i];
                    *pSampleBuffer++ = pcmChannels[1][i];
                }
            } else {
                for (long i = 0; i < readResult; ++i) {
                    for (SINT j = 0; j < getChannelCount(); ++j) {
                        *pSampleBuffer++ = pcmChannels[j][i];
                    }
                }
            }
            numberOfFramesRemaining -= readResult;
        } else {
            qWarning() << "Failed to read from OggVorbis file:" << readResult;
            break; // abort
        }
    }

    DEBUG_ASSERT(isValidFrameIndex(m_curFrameIndex));
    DEBUG_ASSERT(numberOfFramesTotal >= numberOfFramesRemaining);
    return numberOfFramesTotal - numberOfFramesRemaining;
}
Пример #21
0
void WaveformWidgetFactory::setDefaultZoom(int zoom) {
    m_defaultZoom = math_max(WaveformWidgetRenderer::s_waveformMinZoom,
                             math_min(zoom, WaveformWidgetRenderer::s_waveformMaxZoom));
    if (m_config) {
        m_config->set(ConfigKey("[Waveform]","DefaultZoom"), ConfigValue(m_defaultZoom));
    }

    for (int i = 0; i < m_waveformWidgetHolders.size(); i++) {
        m_waveformWidgetHolders[i].m_waveformViewer->setZoom(m_defaultZoom);
    }
}
Пример #22
0
SampleBuffer::WritableChunk SingularSampleBuffer::writeToTail(SINT size) {
    DEBUG_ASSERT_CLASS_INVARIANT_SingularSampleBuffer;

    const SINT tailLength = math_min(size, getTailCapacity());
    const SampleBuffer::WritableChunk tailChunk(
            m_primaryBuffer, m_tailOffset, tailLength);
    m_tailOffset += tailLength;

    DEBUG_ASSERT_CLASS_INVARIANT_SingularSampleBuffer;
    return tailChunk;
}
Пример #23
0
SampleBuffer::WritableSlice ReadAheadSampleBuffer::growForWriting(SINT maxWriteLength) {
    DEBUG_ASSERT_CLASS_INVARIANT_ReadAheadSampleBuffer;

    const SINT tailLength = math_min(maxWriteLength, writableLength());
    const SampleBuffer::WritableSlice tailSlice(
            m_sampleBuffer, m_readableRange.end(), tailLength);
    m_readableRange.growBack(tailLength);

    DEBUG_ASSERT_CLASS_INVARIANT_ReadAheadSampleBuffer;
    return tailSlice;
}
Пример #24
0
unsigned SoundSourceModPlug::read(unsigned long size,
                                  const SAMPLE* pDestination)
{
    unsigned maxLength = m_sampleBuf.length() >> 1;
    unsigned copySamples = math_min(maxLength - m_seekPos, size);

    memcpy((unsigned char*) pDestination,
           m_sampleBuf.constData() + (m_seekPos << 1), copySamples << 1);

    m_seekPos += copySamples;
    return copySamples;
}
Пример #25
0
SINT SoundSourceModPlug::readSampleFrames(
        SINT numberOfFrames, CSAMPLE* sampleBuffer) {
    DEBUG_ASSERT(0 <= numberOfFrames);
    DEBUG_ASSERT(isValidFrameIndex(m_seekPos));
    const SINT readFrames = math_min(getFrameCount() - m_seekPos, numberOfFrames);

    const SINT readSamples = frames2samples(readFrames);
    const SINT readOffset = frames2samples(m_seekPos);
    SampleUtil::convertS16ToFloat32(sampleBuffer, &m_sampleBuf[readOffset], readSamples);
    m_seekPos += readFrames;

    return readFrames;
}
Пример #26
0
bool CachingReaderChunk::isReadable(
        const Mixxx::AudioSourcePointer& pAudioSource,
        SINT maxReadableFrameIndex) const {
    DEBUG_ASSERT(Mixxx::AudioSource::getMinFrameIndex() <= maxReadableFrameIndex);

    if (!isValid() || pAudioSource.isNull()) {
        return false;
    }
    const SINT frameIndex = frameForIndex(getIndex());
    const SINT maxFrameIndex = math_min(
            maxReadableFrameIndex, pAudioSource->getMaxFrameIndex());
    return frameIndex <= maxFrameIndex;
}
Пример #27
0
SINT ReadAheadSampleBuffer::shrinkAfterWriting(SINT maxShrinkLength) {
    DEBUG_ASSERT_CLASS_INVARIANT_ReadAheadSampleBuffer;

    const SINT shrinkLength = math_min(maxShrinkLength, readableLength());
    m_readableRange.shrinkBack(shrinkLength);
    // If the buffer has become empty reset the write head back to the start
    // of the available memory
    if (m_readableRange.empty()) {
        m_readableRange = IndexRange::between(0, 0);
    }

    DEBUG_ASSERT_CLASS_INVARIANT_ReadAheadSampleBuffer;
    return shrinkLength;
}
Пример #28
0
long SoundSourceSndFile::seek(long filepos)
{
    unsigned long filepos2 = (unsigned long)filepos;
    if (filelength>0)
    {
        filepos2 = math_min(filepos2,filelength);
        sf_seek(fh, (sf_count_t)filepos2/2, SEEK_SET);
        //Note that we don't error check sf_seek because it reports
        //benign errors under normal usage (ie. we sometimes seek past the end
        //of a song, and it will stop us.)
        return filepos2;
    }
    return 0;
}
Пример #29
0
void EngineNetworkStream::read(CSAMPLE* buffer, int frames) {
    int readAvailable = m_pOutputFifo->readAvailable();
    int readRequired = frames * m_numInputChannels;
    int copyCount = math_min(readAvailable, readRequired);
    if (copyCount > 0) {
        (void)m_pOutputFifo->read(buffer, copyCount);
        buffer += copyCount;
    }
    if (readAvailable < readRequired) {
        // Fill missing Samples with silence
        int silenceCount = readRequired - readAvailable;
        qDebug() << "EngineNetworkStream::write flushed" << readRequired
                 << "samples";
        SampleUtil::clear(buffer, silenceCount);
    }
}
Пример #30
0
SampleBuffer::ReadableChunk SingularSampleBuffer::readFromTail(SINT size) {
    DEBUG_ASSERT_CLASS_INVARIANT_SingularSampleBuffer;

    const SINT tailLength = math_min(size, getSize());
    m_tailOffset -= tailLength;
    const SampleBuffer::ReadableChunk tailChunk(
            m_primaryBuffer, m_tailOffset, tailLength);
    if (isEmpty()) {
        // Internal buffer becomes empty and can safely be reset
        // to extend the tail capacity for future growth
        resetOffsets();
    }

    DEBUG_ASSERT_CLASS_INVARIANT_SingularSampleBuffer;
    return tailChunk;
}