char* RTPSink::rtpmapLine() const { if (rtpPayloadType() >= 96) { // the payload format type is dynamic char* encodingParamsPart; if (numChannels() != 1) { encodingParamsPart = new char[1 + 20 /* max int len */]; sprintf(encodingParamsPart, "/%d", numChannels()); } else { encodingParamsPart = strDup(""); } char const* const rtpmapFmt = "a=rtpmap:%d %s/%d%s\r\n"; unsigned rtpmapFmtSize = strlen(rtpmapFmt) + 3 /* max char len */ + strlen(rtpPayloadFormatName()) + 20 /* max int len */ + strlen(encodingParamsPart); char* rtpmapLine = new char[rtpmapFmtSize]; sprintf(rtpmapLine, rtpmapFmt, rtpPayloadType(), rtpPayloadFormatName(), rtpTimestampFrequency(), encodingParamsPart); delete[] encodingParamsPart; return rtpmapLine; } else { // The payload format is staic, so there's no "a=rtpmap:" line: return strDup(""); } }
void CFunc::GetChannels(int& src, int& dst) const { src = dst = 0; CMyString sDescr = DescrName(); CMyString srcStr = firstChanStr(sDescr); CMyString dstStr = firstChanStr(sDescr); src = numChannels(srcStr); if (dstStr.IsEmpty()) dst = src; else dst = numChannels(dstStr); UpdateChannels(src, dst); }
/** Waits until there is n frames of data to read from s, Then puts the data in buffer. @param s The SoundStream to read from @param buffer The chunk buffer to put the data into. (s->channels of at least n length) This is padded with zeros (up to n) if there is less than n frames read. @param n The number of frames to read @return The number of frames read. */ int SoundFile::blockingRead(SoundStream *s, float **buffer, int n) { int c; myassert(s); myassert(n >= 0 && n <= bufferSize()); int ret = s->readFloats(buffer, n, numChannels()); if(ret < n) { //if not all bytes are read for(c=0; c<numChannels(); c++) { //set remaining bytes to zeros //memset(buffer[c]+ret, 0, (n-ret) * sizeof(float)); std::fill(buffer[c]+ret, buffer[c]+n, 0.0f); } } return ret; }
//int SoundFile::readChunk(int n, SoundStream *s) int SoundFile::readChunk(int n) { int c; //if(!s) s = stream; int ret = blockingRead(stream, tempWindowBuffer, n); if(equalLoudness()) { applyEqualLoudnessFilter(n); ret = blockingWrite(filteredStream, tempWindowBufferFiltered, ret); } if(ret < n) return ret; FilterState filterState; lock(); //nextChunk(); for(c=0; c<numChannels(); c++) { channels(c)->shift_left(n); //channels(c)->highPassFilter->getState(&filterState); toChannelBuffer(c, n); channels(c)->processNewChunk(&filterState); } //incrementChunkNum(); setCurrentChunk(currentStreamChunk()); unlock(); return ret; }
Boolean LiveAMRAudioRTPSink::sourceIsCompatibleWithUs( MediaSource& source ) { // Our source must be an AMR audio source: if (!source.isAMRAudioSource()) return False; // Also, the source must be wideband iff we asked for this: LiveAMRAudioDeviceSource& amrSource = (LiveAMRAudioDeviceSource&)source; if ((amrSource.isWideband()^sourceIsWideband()) != 0) return False; // Also, the source must have the same number of channels that we // specified. (It could, in principle, have more, but we don't // support that.) if (amrSource.numChannels() != numChannels()) return False; // Also, because in our current implementation we output only one // frame in each RTP packet, this means that for multi-channel audio, // each 'frame-block' will be split over multiple RTP packets, which // may violate the spec. Warn about this: if (amrSource.numChannels() > 1) { envir() << "AMRAudioRTPSink: Warning: Input source has " << amrSource.numChannels() << " audio channels. In the current implementation, the multi-frame frame-block will be split over multiple RTP packets\n"; } return True; }
void SoundFile::applyEqualLoudnessFilter(int n) { int c, j; for(c=0; c<numChannels(); c++) { //printf("before: %f == %f\n", channels(c)->filterStateX1, channels(c)->highPassFilter->_x[0]); //printf("before: %f == %f\n", channels(c)->filterStateX2, channels(c)->highPassFilter->_x[1]); //printf("before: %f == %f\n", channels(c)->filterStateY1, channels(c)->highPassFilter->_y[0]); //printf("before: %f == %f\n", channels(c)->filterStateY2, channels(c)->highPassFilter->_y[1]); /* tempWindowBufferDouble[c][-2] = channels(c)->filterStateX1; tempWindowBufferDouble[c][-1] = channels(c)->filterStateX2; tempWindowBufferFilteredDouble[c][-2] = channels(c)->filterStateY1; tempWindowBufferFilteredDouble[c][-1] = channels(c)->filterStateY2; double *b = &*(channels(c)->highPassFilter->_b.begin()); double *a = &*(channels(c)->highPassFilter->_a.begin()); //printf("%lf, %lf, %lf, %lf, %lf\n", b[0], b[1], b[2], a[0], a[1]); //channels(c)->highPassFilter->print(); //convert all the tempWindowBuffer from floats to doubles in one go float *xFloat = tempWindowBuffer[c]; double *x = tempWindowBufferDouble[c]; float *xFloatEnd = xFloat + n; while(xFloat != xFloatEnd) *x++ = double(*xFloat++); x = tempWindowBufferDouble[c]; float *yFloat = tempWindowBufferFiltered[c]; double *y = tempWindowBufferFilteredDouble[c]; for(j=0; j<n; j++) { *y = b[0]*x[0] + b[1]*x[-1] + b[2]*x[-2] - a[0]*y[-1] - a[1]*y[-2]; // *y = y[-1]; // *y = b[0]*x[-2] + b[1]*x[-1] + b[2]*x[0] - a[0]*y[-2] - a[1]*y[-1]; // *y = (y[-2] + y[-1] + x[0]) / 3.0f; *yFloat = bound(*y, -1.0, 1.0); y++; x++; yFloat++; //tempWindowBuffer2[c][j] = bound(double(tempWindowBuffer[c][j]), -1.0, 1.0); //tempWindowBuffer2[c][j] = bound(filter->apply(tempWindowBuffer[c][j]), -1.0, 1.0); } channels(c)->filterStateX1 = tempWindowBufferDouble[c][n-2]; channels(c)->filterStateX2 = tempWindowBufferDouble[c][n-1]; channels(c)->filterStateY1 = tempWindowBufferFilteredDouble[c][n-2]; channels(c)->filterStateY2 = tempWindowBufferFilteredDouble[c][n-1]; */ //float *tempTest = (float*)malloc(n*sizeof(float)); //channels(c)->highPassFilter->apply(tempWindowBuffer[c], tempTest, n); channels(c)->highPassFilter->filter(tempWindowBuffer[c], tempWindowBufferFiltered[c], n); for(j=0; j<n; j++) tempWindowBufferFiltered[c][j] = bound(tempWindowBufferFiltered[c][j], -1.0f, 1.0f); //for(j=0; j<n; j++) // if(tempWindowBufferFiltered[c][j] != tempTest[j]) printf("Filter Diff %d : %f, %f, %f\n", j, tempWindowBuffer[c][j], tempWindowBufferFiltered[c][j], tempTest[j]); //printf("after: %f == %f\n", channels(c)->filterStateX1, channels(c)->highPassFilter->_x[0]); //printf("after: %f == %f\n", channels(c)->filterStateX2, channels(c)->highPassFilter->_x[1]); //printf("after: %f == %f\n", channels(c)->filterStateY1, channels(c)->highPassFilter->_y[0]); //printf("after: %f == %f\n", channels(c)->filterStateY2, channels(c)->highPassFilter->_y[1]); //free(tempTest); } }
AudioFile::AudioFile(const char *filepath, AudioFileMode mode) { int sfmode; switch (mode) { case AudioFileModeReadOnly: sfmode = SFM_READ; break; case AudioFileModeWriteOnly: sfmode = SFM_WRITE; break; case AudioFileModeReadWrite: sfmode = SFM_RDWR; break; } _pimpl = new pimpl; _pimpl->mode = mode; _pimpl->sndfile = sf_open(filepath, sfmode, &_pimpl->sfInfo); _pimpl->totalSize = _pimpl->sfInfo.channels * _pimpl->sfInfo.frames; _pimpl->readIndex = 0; _pimpl->currentBufIndex = 0; _pimpl->samplesRead = 0; size_t framesPerBuffer = FRAMES_PER_FILE_BUFFER; if (framesPerBuffer > numFrames()) { framesPerBuffer = numFrames(); _pimpl->bufferSize = framesPerBuffer * numChannels(); _pimpl->needsBuffer = false; _pimpl->bufs[0] = new float[_pimpl->bufferSize]; _pimpl->bufs[1] = NULL; } else { _pimpl->bufferSize = framesPerBuffer * numChannels(); _pimpl->bufs[0] = new float[_pimpl->bufferSize]; _pimpl->bufs[1] = new float[_pimpl->bufferSize]; _pimpl->needsBuffer = true; } sf_seek(_pimpl->sndfile, 0, SF_SEEK_SET); _pimpl->framesBuffered = sf_read_float(_pimpl->sndfile, &(_pimpl->bufs[0][0]), _pimpl->bufferSize) / numChannels(); sf_seek(_pimpl->sndfile, _pimpl->framesBuffered, SF_SEEK_SET); AUtilDispatchThread(file_buffer_worker, _pimpl); }
void AField::verbose() const { std::cout<<"\n field:" <<"\n n channels "<<numChannels(); std::map<std::string, TypedBuffer * >::const_iterator it = m_channels.begin(); for(; it!=m_channels.end(); ++it) std::cout<<"\n channel[\""<<it->first<<"\"]"; }
void SoundFile::processNewChunk() { FilterState filterState; for(int j=0; j<numChannels(); j++) { channels(j)->lock(); //channels(j)->highPassFilter->getState(&filterState); channels(j)->processNewChunk(&filterState); channels(j)->unlock(); } }
void SoundFile::toChannelBuffers(int n) { int c; lock(); myassert(n >= 0 && n <= bufferSize()); for(c=0; c<numChannels(); c++) { channels(c)->shift_left(n); toChannelBuffer(c, n); } unlock(); }
void ImageWrapper::initializeImage(const unsigned int width, const unsigned int height, const unsigned int stride, uint8_t*const data, const PixelType pixelType) { validate(width, height, stride, data, pixelType); m_width = width; m_height = height; m_stride = stride; m_data = data; m_pixelType = pixelType; m_variant = dataVariantFromPixelType(pixelType); // set the matrix specific fields m_cols = m_width * numChannels(); m_valueType = valueTypeFromPixelType(pixelType); }
void ImageWrapper::validate(const unsigned int width, const unsigned int height, const unsigned int stride, const uint8_t*const data, const runtime::Image::PixelType pixelType) const { if(width == 0 || height == 0) return; // check row length if(width * depth(pixelType) * numChannels(pixelType) > stride) throw WrongArgument("Too small stride."); // check total data size unsigned int dataSize = stride * (height - 1) + width; if(data + dataSize > m_buffer + m_bufferSize) throw WrongArgument("Too small buffer."); }
bool SoundFile::setupPlayChunk() { int c; int n = framesPerChunk(); int ret = blockingRead(stream, tempWindowBuffer, n); if(equalLoudness()) ret = blockingRead(filteredStream, tempWindowBufferFiltered, n); if(ret < n) return false; lock(); for(c=0; c<numChannels(); c++) { channels(c)->shift_left(n); toChannelBuffer(c, n); if(gdata->doingActive() && channels(c) == gdata->getActiveChannel()) { channels(c)->processChunk(currentChunk()+1); } } setCurrentChunk(currentStreamChunk()); unlock(); return true; }
void SoundFile::jumpToChunk(int chunk) { //if(chunk == currentChunk()) return; int c; lock(); int pos = chunk * framesPerChunk() - offset(); if(pos < 0) { stream->jump_to_frame(0); if(equalLoudness()) filteredStream->jump_to_frame(0); for(c=0; c<numChannels(); c++) channels(c)->reset(); //readN(stream, bufferSize() + pos); readN(bufferSize() + pos); } else { stream->jump_to_frame(pos); if(equalLoudness()) filteredStream->jump_to_frame(pos); //readN(stream, bufferSize()); readN(bufferSize()); } /* int n = bufferSize() / framesPerChunk(); if(chunk+offset() < n) { stream->jump_to_frame(0); for(c=0; c<numChannels(); c++) channels(c)->reset(); if(chunk+offset() >= 0) { for(int j=0; j<chunk+offset(); j++) readChunk(); } } else { //if(chunk == currentChunk()+1) { readChunk(); return; } stream->jump_to_frame((chunk+offset()-n) * framesPerChunk()); for(int j=0; j<n; j++) readChunk(); } */ setCurrentChunk(chunk); //for(c=0; c<numChannels(); c++) { // if(channels(c) == gdata->getActiveChannel()) channels(c)->processChunk(currentChunk()); //} unlock(); }
//free up all the memory of everything used void SoundFile::uninit() { if(gdata->audioThread.playSoundFile() == this || gdata->audioThread.recSoundFile() == this) { gdata->stop(); } if(stream) { delete stream; stream = NULL; } if(filteredStream) { delete filteredStream; filteredStream = NULL; //Delete the temporary filtered file from disk! if(::remove(filteredFilename) == -1) fprintf(stderr, "Error removing file %s\n", filteredFilename); } setFilename(NULL); setFilteredFilename(NULL); //if(channelInsertPtrs) { delete channelInsertPtrs; channelInsertPtrs = NULL; } for(int j=0; j<numChannels(); j++) { delete channels(j); delete[] (tempWindowBuffer[j]-16); delete[] (tempWindowBufferDouble[j]-16); delete[] (tempWindowBufferFiltered[j]-16); delete[] (tempWindowBufferFilteredDouble[j]-16); } channels.resize(0); delete[] tempWindowBuffer; tempWindowBuffer = NULL; delete[] tempWindowBufferDouble; tempWindowBufferDouble = NULL; delete[] tempWindowBufferFiltered; tempWindowBufferFiltered = NULL; delete[] tempWindowBufferFilteredDouble; tempWindowBufferFilteredDouble = NULL; setFramesPerChunk(0); _startTime = 0.0; _chunkNum = 0; _offset = 0; }
TiXmlElement* CqDisplayServerImage::serialiseToXML() { TiXmlElement* imageXML = new TiXmlElement("Image"); TiXmlElement* typeXML = new TiXmlElement("Type"); TiXmlText* typeText = new TiXmlText("managed"); typeXML->LinkEndChild(typeText); imageXML->LinkEndChild(typeXML); TiXmlElement* nameXML = new TiXmlElement("Name"); TiXmlText* nameText = new TiXmlText(name()); nameXML->LinkEndChild(nameText); imageXML->LinkEndChild(nameXML); if(filename().empty()) { TiXmlElement* dataXML = new TiXmlElement("Bitmap"); std::stringstream base64Data; size_t dataLen = m_displayData->width() * m_displayData->height() * numChannels() * sizeof(TqUchar); std::copy( base64_text(BOOST_MAKE_PFTO_WRAPPER(m_displayData->rawData())), base64_text(BOOST_MAKE_PFTO_WRAPPER(m_displayData->rawData() + dataLen)), std::ostream_iterator<char>(base64Data)); TiXmlText* dataTextXML = new TiXmlText(base64Data.str()); dataTextXML->SetCDATA(true); dataXML->LinkEndChild(dataTextXML); imageXML->LinkEndChild(dataXML); } else { TiXmlElement* filenameXML = new TiXmlElement("Filename"); TiXmlText* filenameText = new TiXmlText(filename()); filenameXML->LinkEndChild(filenameText); imageXML->LinkEndChild(filenameXML); } return(imageXML); }
void SoundFile::finishRecordChunk(int n) { if(equalLoudness()) applyEqualLoudnessFilter(n); FilterState filterState; lock(); for(int c=0; c<numChannels(); c++) { channels(c)->shift_left(n); //std::copy(tempWindowBuffer[c], tempWindowBuffer[c]+n, channels(c)->end() - n); //channels(c)->highPassFilter->getState(&filterState); toChannelBuffer(c, n); //if(channels(c) == gdata->getActiveChannel()) channels(c)->processNewChunk(&filterState); } unlock(); int ret = blockingWrite(stream, tempWindowBuffer, n); if(ret < n) fprintf(stderr, "Error writing to disk\n"); if(equalLoudness()) ret = blockingWrite(filteredStream, tempWindowBufferFiltered, n); if(ret < n) fprintf(stderr, "Error writing to disk\n"); setCurrentChunk(currentStreamChunk()); }
void run() { ofPixels pixels; const int w = 320; const int h = 240; for(ofPixelFormat pixelFormat=OF_PIXELS_GRAY; pixelFormat<OF_PIXELS_NUM_FORMATS; pixelFormat = (ofPixelFormat)(pixelFormat+1)) { pixels.allocate(w,h,pixelFormat); int bpp = bitsPerPixel(pixelFormat); string format = formatName(pixelFormat); test_eq(pixels.getBitsPerChannel(),8,"getBitsPerChannel() " + format); test_eq(pixels.getBitsPerPixel(),bpp,"getBitsPerPixel() " + format); test_eq(pixels.getBytesPerChannel(),1,"getBytesPerChannel() " + format); test_eq(pixels.getBytesPerPixel(),bpp/8,"getBytesPerPixel() " + format); test_eq(pixels.getBytesStride(),w*bpp/8,"getBytesStride() " + format); test_eq(pixels.getWidth(),w,"getWidth() " + format); test_eq(pixels.getHeight(),h,"getHeight() " + format); if(hasImageFormat(pixelFormat)) { test_eq(pixels.getImageType(),imageType(pixelFormat),"getImageType() " + format); } if(hasChannels(pixelFormat)) { test_eq(pixels.getNumChannels(),numChannels(pixelFormat),"getNumChannels() " + format); } test_eq(pixels.getNumPlanes(),getNumPlanes(pixelFormat),"getNumPlanes() " + format); test_eq(pixels.getPixelFormat(),pixelFormat,"getPixelFormat() " + format); test_eq((uint64_t)pixels.getPlane(0).getData(), (uint64_t)pixels.getData(),"getPlane(0)==getData() " + format); test_eq(pixels.getTotalBytes(),w*h*bpp/8,"getTotalBytes() " + format); if(hasWorkingIterators(pixelFormat)) { test_eq((uint64_t)pixels.getLine(0).begin(), (uint64_t)pixels.getData(),"getLine(0).begin()==getData() " + format); test_eq((uint64_t)pixels.getLine(0).end(), (uint64_t)pixels.getData()+(w*bpp/8),"getLine(0).end()==getData()+(w*3) " + format); test_eq((uint64_t)pixels.getLine(h-1).begin(), (uint64_t)pixels.getData()+(w*bpp/8*(h-1)),"getLine(h-1).begin()==getData()+(w*bpp/8*(h-1)) " + format); test_eq((uint64_t)pixels.getLine(h-1).end(), (uint64_t)pixels.end(),"getLine(h-1).end()==end() " + format); test_eq((uint64_t)&pixels.getLine(0).getPixel(10)[0], (uint64_t)pixels.getData()+(10*bpp/8),"getLine(0).getPixel(10)[0]==pixels.getData()+(10*bpp/8)"); } } }
/** Writes n frames of data to s from buffer. @param s The SoundStream to write to @param buffer The chunk buffer data to use. (s->channels of at least n length) @param n The number of frames to write @return The number of frames written. */ int SoundFile::blockingWrite(SoundStream *s, float **buffer, int n) { if(s == NULL) return n; return s->writeFloats(buffer, n, numChannels()); }
bool SoundFile::openWrite(const char *filename_, int rate_, int channels_, int bits_, int windowSize_, int stepSize_) { uninit(); setSaved(false); //_offset = (windowSize_ / stepSize_) / 2; _offset = windowSize_ / 2; fprintf(stderr, "--------Recording------------\n"); fprintf(stderr, "filename = %s\n", filename_); fprintf(stderr, "rate = %d\n", rate_); fprintf(stderr, "channels = %d\n", channels_); fprintf(stderr, "bits = %d\n", bits_); fprintf(stderr, "windowSize = %d\n", windowSize_); fprintf(stderr, "stepSize = %d\n", stepSize_); fprintf(stderr, "-----------------------------\n"); setFramesPerChunk(stepSize_); setFilename(filename_); //setFilteredFilename((QString(filename)+QString("~")).ascii()); setFilteredFilename(getNextTempFilename()); stream = new WaveStream; filteredStream = new WaveStream; if(stream->open_write(filename, rate_, channels_, bits_)) { fprintf(stderr, "Error opening %s for writting\n", filename); delete stream; stream = NULL; delete filteredStream; filteredStream = NULL; QString s = QString("Error opening ") + QString(filename) + QString(" for writing.\nPossible cause: temp folder is read-only or disk is out of space.\nPlease select a writable Temp Folder"); QMessageBox::warning(mainWindow, "Error", s, QMessageBox::Ok, QMessageBox::NoButton); mainWindow->menuPreferences(); return false; } if(filteredStream->open_write(filteredFilename, rate_, channels_, bits_)) { fprintf(stderr, "Error opening %s for writting\n", filteredFilename); delete stream; stream = NULL; delete filteredStream; filteredStream = NULL; QString s = QString("Error opening ") + QString(filteredFilename) + QString(" for writing.\nPossible cause: temp folder is read-only or disk is out of space.\nPlease select a writable Temp Folder"); QMessageBox::warning(mainWindow, "Error", s, QMessageBox::Ok, QMessageBox::NoButton); mainWindow->menuPreferences(); return false; } //printf("in_channels = %d\n", gdata->in_channels); //printf("stream->channels=%d\n", stream->channels); channels.resize(stream->channels); fprintf(stderr, "channels = %d\n", numChannels()); for(int j=0; j<numChannels(); j++) { channels(j) = new Channel(this, windowSize_); fprintf(stderr, "channel size = %d\n", channels(j)->size()); //channels(j)->setParent(this); channels(j)->setColor(gdata->getNextColor()); //channels(j)->setPitchMethod(gdata->pitch_method[0]); } myTransforms.init(windowSize_, 0, stream->freq, gdata->doingEqualLoudness()); //setup the tempChunkBuffers tempWindowBuffer = new float*[numChannels()]; tempWindowBufferDouble = new double*[numChannels()]; tempWindowBufferFiltered = new float*[numChannels()]; tempWindowBufferFilteredDouble = new double*[numChannels()]; for(int c=0; c<numChannels(); c++) { tempWindowBuffer[c] = (new float[bufferSize()+16]) + 16; //array ranges from -16 to bufferSize() tempWindowBufferDouble[c] = (new double[bufferSize()+16]) + 16; //array ranges from -16 to bufferSize() tempWindowBufferFiltered[c] = (new float[bufferSize()+16]) + 16; //array ranges from -16 to bufferSize() tempWindowBufferFilteredDouble[c] = (new double[bufferSize()+16]) + 16; //array ranges from -16 to bufferSize() } _doingDetailedPitch = gdata->doingDetailedPitch(); return true; }
bool SoundFile::openRead(const char *filename_) { uninit(); setSaved(true); setFilename(filename_); //setFilteredFilename((QString(filename)+QString("~")).ascii()); setFilteredFilename(getNextTempFilename()); fprintf(stderr, "Opening file: %s\n(FilteredFilename: %s)\n", filename, filteredFilename); //#ifdef USE_SOX // stream = new SoxStream; //#else if(str_case_cmp(getFileExtension(filename), "wav") == 0) { stream = new WaveStream; filteredStream = new WaveStream; } //#ifdef USE_OGG // else if(str_case_cmp(getFileExtension(filename), "ogg") == 0) { // stream = new OggStream; // } //#endif else { fprintf(stderr, "Cannot open file of this type. %s\n", filename); return false; } //#endif if(stream->open_read(filename)) { fprintf(stderr, "Error opening %s\n", filename); return false; } //if(filteredStream->open_read((QString(filename) + QString("~")).ascii())) { if(filteredStream->open_write(filteredFilename, stream->freq, stream->channels, stream->bits)) { fprintf(stderr, "Error opening %s\n", filteredFilename); delete stream; stream = NULL; QString s = QString("Error opening ") + QString(filteredFilename) + QString(" for writing.\nPossible cause: temp folder is read-only or disk is out of space.\nPlease select a writable Temp Folder"); QMessageBox::warning(mainWindow, "Error", s, QMessageBox::Ok, QMessageBox::NoButton); mainWindow->menuPreferences(); return false; } channels.resize(stream->channels); int windowSize_ = gdata->getAnalysisBufferSize(stream->freq); fprintf(stderr, "channels = %d\n", numChannels()); int stepSize_ = gdata->getAnalysisStepSize(stream->freq); //_offset = (windowSize_ / stepSize_) / 2; _offset = windowSize_ / 2; setFramesPerChunk(stepSize_); // The user needs to be able to set this for(int j=0; j<numChannels(); j++) { channels(j) = new Channel(this, windowSize_); fprintf(stderr, "channel size = %d\n", channels(j)->size()); //channels(j)->setParent(this); channels(j)->setColor(gdata->getNextColor()); //channels(j)->setPitchMethod(gdata->pitch_method[0]); } myTransforms.init(windowSize_, 0, stream->freq, gdata->doingEqualLoudness()); fprintf(stderr, "----------Opening------------\n"); fprintf(stderr, "filename = %s\n", filename_); fprintf(stderr, "rate = %d\n", rate()); fprintf(stderr, "channels = %d\n", numChannels()); fprintf(stderr, "bits = %d\n", bits()); fprintf(stderr, "windowSize = %d\n", windowSize_); fprintf(stderr, "stepSize = %d\n", stepSize_); fprintf(stderr, "-----------------------------\n"); //setup the tempChunkBuffers tempWindowBuffer = new float *[numChannels()]; tempWindowBufferDouble = new double *[numChannels()]; tempWindowBufferFiltered = new float *[numChannels()]; tempWindowBufferFilteredDouble = new double *[numChannels()]; for(int c=0; c<numChannels(); c++) { tempWindowBuffer[c] = (new float[bufferSize()+16]) + 16; //array ranges from -16 to bufferSize() tempWindowBufferDouble[c] = (new double[bufferSize()+16]) + 16; //array ranges from -16 to bufferSize() tempWindowBufferFiltered[c] = (new float[bufferSize()+16]) + 16; //array ranges from -16 to bufferSize() tempWindowBufferFilteredDouble[c] = (new double[bufferSize()+16]) + 16; //array ranges from -16 to bufferSize() } _doingDetailedPitch = gdata->doingDetailedPitch(); return true; }
/** Lock the mutex's of all the channels */ void SoundFile::lock() { mutex->lock(); for(int j=0; j<numChannels(); j++) channels(j)->lock(); }
/** Unlock the mutex's of all the channels */ void SoundFile::unlock() { for(int j=0; j<numChannels(); j++) channels(j)->unlock(); mutex->unlock(); }
void FxMixer::masterMix( sampleFrame * _buf ) { const int fpp = Engine::mixer()->framesPerPeriod(); if( m_sendsMutex.tryLock() ) { // add the channels that have no dependencies (no incoming senders, ie. no receives) // to the jobqueue. The channels that have receives get added when their senders get processed, which // is detected by dependency counting. // also instantly add all muted channels as they don't need to care about their senders, and can just increment the deps of // their recipients right away. MixerWorkerThread::resetJobQueue( MixerWorkerThread::JobQueue::Dynamic ); for( FxChannel * ch : m_fxChannels ) { ch->m_muted = ch->m_muteModel.value(); if( ch->m_muted ) // instantly "process" muted channels { ch->processed(); ch->done(); } else if( ch->m_receives.size() == 0 ) { ch->m_queued = true; MixerWorkerThread::addJob( ch ); } } while( m_fxChannels[0]->state() != ThreadableJob::Done ) { MixerWorkerThread::startAndWaitForJobs(); } m_sendsMutex.unlock(); } // handle sample-exact data in master volume fader ValueBuffer * volBuf = m_fxChannels[0]->m_volumeModel.valueBuffer(); if( volBuf ) { for( int f = 0; f < fpp; f++ ) { m_fxChannels[0]->m_buffer[f][0] *= volBuf->values()[f]; m_fxChannels[0]->m_buffer[f][1] *= volBuf->values()[f]; } } const float v = volBuf ? 1.0f : m_fxChannels[0]->m_volumeModel.value(); MixHelpers::addSanitizedMultiplied( _buf, m_fxChannels[0]->m_buffer, v, fpp ); // clear all channel buffers and // reset channel process state for( int i = 0; i < numChannels(); ++i) { BufferManager::clear( m_fxChannels[i]->m_buffer, Engine::mixer()->framesPerPeriod() ); m_fxChannels[i]->reset(); m_fxChannels[i]->m_queued = false; // also reset hasInput m_fxChannels[i]->m_hasInput = false; m_fxChannels[i]->m_dependenciesMet = 0; } }
/////////////////////////////////////////////////////////// // // Returns a data handler for the waveform // /////////////////////////////////////////////////////////// ptr<handlers::dataHandler> waveform::getIntegerData(std::uint32_t channel, std::int32_t paddingValue) { PUNTOEXE_FUNCTION_START(L"waveform::getIntegerData"); static std::int32_t uLawDecompressTable[256] = { -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956, -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764, -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412, -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316, -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, -876, -844, -812, -780, -748, -716, -684, -652, -620, -588, -556, -524, -492, -460, -428, -396, -372, -356, -340, -324, -308, -292, -276, -260, -244, -228, -212, -196, -180, -164, -148, -132, -120, -112, -104, -96, -88, -80, -72, -64, -56, -48, -40, -32, -24, -16, -8, 0, 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, 876, 844, 812, 780, 748, 716, 684, 652, 620, 588, 556, 524, 492, 460, 428, 396, 372, 356, 340, 324, 308, 292, 276, 260, 244, 228, 212, 196, 180, 164, 148, 132, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0 }; static std::int32_t aLawDecompressTable[256] = { -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, -22016,-20992,-24064,-23040,-17920,-16896,-19968,-18944, -30208,-29184,-32256,-31232,-26112,-25088,-28160,-27136, -11008,-10496,-12032,-11520,-8960, -8448, -9984, -9472, -15104,-14592,-16128,-15616,-13056,-12544,-14080,-13568, -344, -328, -376, -360, -280, -264, -312, -296, -472, -456, -504, -488, -408, -392, -440, -424, -88, -72, -120, -104, -24, -8, -56, -40, -216, -200, -248, -232, -152, -136, -184, -168, -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, -688, -656, -752, -720, -560, -528, -624, -592, -944, -912, -1008, -976, -816, -784, -880, -848, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848 }; // Lock the dataset during the interpretation of the // dataset /////////////////////////////////////////////////////////// lockObject lockDataSet(m_pDataSet); // Get the original data /////////////////////////////////////////////////////////// ptr<handlers::dataHandler> waveformData(m_pDataSet->getDataHandler(0x5400, 0x0, 0x1010, 0, false)); std::string sourceDataType(waveformData->getDataType()); // Get the interpretation, number of channels, number of // samples /////////////////////////////////////////////////////////// std::string waveformInterpretation(getInterpretation()); std::uint32_t numChannels(getChannels()); std::uint32_t numSamples(getSamples()); std::uint32_t originalPaddingValue(0); bool bPaddingValueExists(false); ptr<handlers::dataHandler> paddingTagHandler(m_pDataSet->getDataHandler(0x5400, 0, 0x100A, 0, false)); if(paddingTagHandler != 0) { originalPaddingValue = paddingTagHandler->getUnsignedLong(0); bPaddingValueExists = true; } // Allocate a buffer for the destination data /////////////////////////////////////////////////////////// ptr<buffer> waveformBuffer(new buffer(0, "SL")); ptr<handlers::dataHandler> destinationHandler(waveformBuffer->getDataHandler(true, numSamples)); // Copy the data to the destination for unsigned values /////////////////////////////////////////////////////////// std::uint32_t waveformPointer(channel); std::uint32_t destinationPointer(0); if(sourceDataType == "UB" || sourceDataType == "US") { for(std::uint32_t copySamples (numSamples); copySamples != 0; --copySamples) { std::uint32_t unsignedData(waveformData->getUnsignedLong(waveformPointer)); waveformPointer += numChannels; if(bPaddingValueExists && unsignedData == originalPaddingValue) { destinationHandler->setSignedLong(destinationPointer++, paddingValue); continue; } destinationHandler->setUnsignedLong(destinationPointer++, unsignedData); } return destinationHandler; } // Copy the data to the destination for signed values /////////////////////////////////////////////////////////// int highBit(getBitsAllocated() - 1); std::uint32_t testBit = ((std::uint32_t)1) << highBit; std::uint32_t orBits = ((std::uint32_t)((std::int32_t)-1)) << highBit; for(std::uint32_t copySamples (numSamples); copySamples != 0; --copySamples) { std::uint32_t unsignedData = waveformData->getUnsignedLong(waveformPointer); waveformPointer += numChannels; if(bPaddingValueExists && unsignedData == originalPaddingValue) { destinationHandler->setSignedLong(destinationPointer++, paddingValue);; continue; } if((unsignedData & testBit) != 0) { unsignedData |= orBits; } destinationHandler->setSignedLong(destinationPointer++, (std::int32_t)unsignedData); } // Now decompress uLaw or aLaw if(waveformInterpretation == "AB") // 8bits aLaw { for(std::uint32_t aLawSamples(0); aLawSamples != numSamples; ++aLawSamples) { std::uint32_t compressed(destinationHandler->getUnsignedLong(aLawSamples)); if(bPaddingValueExists && compressed == originalPaddingValue) { continue; } std::int32_t decompressed(aLawDecompressTable[compressed]); destinationHandler->setSignedLong(aLawSamples, decompressed); } } // Now decompress uLaw or aLaw if(waveformInterpretation == "MB") // 8bits aLaw { for(std::uint32_t uLawSamples(0); uLawSamples != numSamples; ++uLawSamples) { std::uint32_t compressed(destinationHandler->getUnsignedLong(uLawSamples)); if(bPaddingValueExists && compressed == originalPaddingValue) { continue; } std::int32_t decompressed(uLawDecompressTable[compressed]); destinationHandler->setSignedLong(uLawSamples, decompressed); } } return destinationHandler; PUNTOEXE_FUNCTION_END(); }
//shift all the channels data left by n frames void SoundFile::shift_left(int n) { for(int j=0; j<numChannels(); j++) { channels(j)->shift_left(n); } }