void SingleResConvolutionTransform::init() { if(GetSamplingRate()<=0) return; for(size_t h=0; h<size(); h++) if(m_convolutions[h]!=NULL) delete m_convolutions[h]; m_components.resize(GetNbSemitones()); m_convolutions.resize(GetNbSemitones()); m_formants.resize(GetNbSemitones()); for(size_t h=0; h<size(); h++) m_convolutions[h] = new Convolution(m_latency_factor, m_gauss_factor, int(h)+GetSemitoneMin()); }
void AutocorrelationAlgo::init() { setMinMaxLength(int(GetSamplingRate()/h2f(GetSemitoneMax())), int(GetSamplingRate()/h2f(GetSemitoneMin()))); }
/* * on peut imaginer des cas qui mettent en échec cette procédure: * on selectionne un zéro qui n'en n'est pas un une periode plus * tard et si un autre zéro se trouve dans la zone de tolérance la longeur * ainsi calculée entre ces deux zéro (qui ne se correspondent donc pas) sera fausse. * example: une fréquence très basse avec une seule harmonique très très * haute. * - il faut utiliser des zéros significatifs ... et ... et ... et voilà . * - ou encore écarter les solutions trop élognées de la moyenne */ double GetAveragePeriodFromApprox(const std::deque<double>& queue, int approx, int n) { if(GetAFreq()<=0.0 || GetSamplingRate()<=0.0 || int(queue.size())<approx) return 0.0; deque<int> ups; // the upper peeks // parse the whole buffer, for n zeros for(int i=0; int(ups.size())<n && i+1<int(queue.size()); i++) if(queue[i]<0 && queue[i+1]>0) // if it cross the axis ups.push_back(i); // cout << "approx=" << approx << " ups.size()=" << ups.size(); if(ups.empty()) return 0.0; double ht = f2hf(double(GetSamplingRate())/approx); int period_low_bound = int(GetSamplingRate()/h2f(ht+1))-2; int period_high_bound = int(GetSamplingRate()/h2f(ht-1))+2; // cout << " ht=" << ht << " lb=" << period_low_bound << " rb=" << period_high_bound; // cout << " periods=("; double period = 0.0; int count = 0; for(int i=0; i<int(ups.size()) && count<n; i++) { int i_seek = ups[i] + approx; int lower_i_seek = i_seek; int low_bound = ups[i] + period_low_bound; int higher_i_seek = i_seek; int high_bound = std::min(int(queue.size())-1, ups[i]+period_high_bound); // cout << "{" << low_bound << ":" << i_seek << ":" << high_bound << "}"; if(low_bound+1>=int(queue.size())) i = ups.size(); // stop loop else { if(!(queue[i_seek]<=0.0 && queue[i_seek+1]>0.0)) { while(lower_i_seek>low_bound && !(queue[lower_i_seek]<=0.0 && queue[lower_i_seek+1]>0.0)) lower_i_seek--; while(higher_i_seek<high_bound && !(queue[higher_i_seek]<=0.0 && queue[higher_i_seek+1]>0.0)) higher_i_seek++; if(i_seek-lower_i_seek < higher_i_seek-i_seek) // take the nearest to i_seek i_seek = lower_i_seek; else i_seek = higher_i_seek; } // cout << i_seek << "=>"; if(low_bound<i_seek && i_seek<high_bound) { double per = InterpolatedPeriod(queue, ups[i], i_seek); // cout << "f=" << GetSamplingRate()/per << " "; period += per; count++; } } } if(count==0) return 0.0; period /= count; // cout << ")=" << GetSamplingRate()/period << "(" << count << ")" << endl; return period; }
double GetAverageWaveLengthFromApproxEnergy(const std::deque<double>& queue, double approx, int n) { assert(GetSamplingRate()>0); if(queue.size()<approx*1.5) return 0.0; // cout << queue.size() << "=>" << approx << " n=" << n << endl; double wave_length = 0.0; int count = 0; int seek = 0; while(count<n && seek<int(queue.size()) && seek!=-1) { // cout << "new " << flush; // in one period, compute the energy over approx/4 int w = int(approx/4); // TODO ptr un peu long if(w<4) w=4; vector<double> en; for(int i=0; i<w/2; i++) en.push_back(0.0); for(int i=w/2; int(en.size())<int(1.25*approx); i++) { en.push_back(0.0); for(int j=-w/2; j<=w/2 && seek+i+j<int(queue.size()); j++) en.back() += queue[seek+i+j]; //*queue[seek+i+j] } // find the highest energy peak int i_max = 0; double en_max = 0.0; for(int i=0; i<int(en.size()); i++) { if(en[i]>en_max) { en_max = en[i]; i_max = i; } } seek += i_max; // cout << "max-seek=" << seek << " " << flush; int old_seek=seek; // go back to the previous zero while(seek>=0 && !(queue[seek]<=0 && queue[seek+1]>0) && seek>old_seek-approx/2) seek--; // cout << "zero-seek=" << seek << " " << flush; if(seek<0 || seek<=old_seek-approx/2) { seek += int(approx); // cout << endl; continue; } int left = seek; int right = int(left + approx); int sright = right; int downlimit = int(left + 0.75*approx); int bright = right; int uplimit = int(left + 1.25*approx); // look for the nearest zero of right while(sright+1<int(queue.size()) && sright>downlimit && !(queue[sright]<=0 && queue[sright+1]>0)) sright--; while(bright+1<int(queue.size()) && bright<uplimit && !(queue[bright]<=0 && queue[bright+1]>0)) bright++; if(sright>=int(queue.size()) || bright>=int(queue.size())) { seek = -1; // cout << endl; continue; } double sw = InterpolatedPeriod(queue, left, sright); double bw = InterpolatedPeriod(queue, left, bright); // keep the nearest one after approx double wl = 0.0; if(abs(sw-approx)<abs(bw-approx)) wl = sw; else wl = bw; // cout << "wl=" << wl << flush; wave_length += wl; count++; seek += int(0.9*approx); // cout << endl; } // cout << "("<<count<<")"<< flush; if(count==0) return 0.0; wave_length /= count; // cout << GetSamplingRate()/wave_length << endl; return wave_length; }
void MyByteOut(WORD port, BYTE data) { dprintf3(("Received write to Port %4X, Data %2X", port, data)); switch (port - BasePort) { case RESET_PORT: if (data == 1) { ResetState = Reset1Written; } else { if (ResetState == Reset1Written && data == 0) { ResetState = ResetNotStarted; /* * OK - reset everything */ CloseWaveDevice(); /* * Reset state machines */ DSPReadState = Reset; DSPWriteState = WriteCommand; GetVersionFirst = TRUE; } } break; case WRITE_PORT: /* * Use the state to see if it's data */ switch (DSPWriteState) { case WriteCommand: WriteCommandByte(data); break; case CardIdent: IdentByte = data; DSPReadState = ReadIdent; DSPWriteState = WriteCommand; break; case SetTimeConstant: TimeConstant = (DWORD)data; dprintf2(("Set sampling rate %d", GetSamplingRate())); DSPWriteState = WriteCommand; break; case BlockSizeFirstByte: SBBlockSize = (DWORD)data; DSPWriteState = BlockSizeSecondByte; break; case BlockSizeSecondByte: SBBlockSize = SBBlockSize + ((DWORD)data << 8) + 1; DSPWriteState = WriteCommand; dprintf2(("Block size set to 0x%x", SBBlockSize)); break; case BlockSizeFirstByteWrite: SBBlockSize = (DWORD)data; DSPWriteState = BlockSizeSecondByteWrite; break; case BlockSizeSecondByteWrite: SBBlockSize = SBBlockSize + ((DWORD)data << 8) + 1; DSPWriteState = WriteCommand; StartTransfer(FALSE, FALSE); break; case BlockSizeFirstByteRead: SBBlockSize = (DWORD)data; DSPWriteState = BlockSizeSecondByteRead; break; case BlockSizeSecondByteRead: SBBlockSize = SBBlockSize + ((DWORD)data << 8) + 1; DSPWriteState = WriteCommand; StartTransfer(TRUE, FALSE); break; case DirectWaveOut: case MidiWrite: /* * Just discard for now */ DSPWriteState = WriteCommand; break; } break; } }
BOOL SetupWave(PVOID TransferAddress) { DWORD SampleRate; UINT rc; /* * Make sure we've got a device - we may have one which does * not match the current sampling rate. */ if (TimeConstant != 0xFFFF) { SampleRate = GetSamplingRate(); if (SampleRate != WaveFormat.wf.nSamplesPerSec) { /* * Search for a suitable format */ if (!TestWaveFormat(SampleRate)) { /* * If this did not work it may be too fast * or slow so move it into our compass */ if (SampleRate > 22050) { SampleRate = 22050; } else { if (SampleRate < 11025) { SampleRate = 11025; } } /* * Device may only support discrete rates */ if (!TestWaveFormat(SampleRate)) { if (SampleRate > (11025 + 22050) / 2) { SampleRate == 22050; } else { SampleRate = 11025; } } } /* * Open the device with the new format if it's changed */ if (SampleRate != WaveFormat.wf.nSamplesPerSec) { dprintf3(("Format changed")); CloseWaveDevice(); WaveFormat.wf.nSamplesPerSec = SampleRate; WaveFormat.wf.nAvgBytesPerSec = SampleRate; dprintf2(("Setting %d samples per second", SampleRate)); } } TimeConstant = 0xFFFF; } if (hWave == NULL) { dprintf3(("Opening wave device")); OpenWaveDevice(); } else { dprintf3(("Resetting wave device prior to play")); (Input ? waveInReset : waveOutReset)(hWave); } /* * Set up any wave buffers etc if necessary */ if (hWave) { if (WaveHdr[0].lpData != (LPSTR)TransferAddress || BlockSize != WaveHdr[0].dwBufferLength) { (Input ? waveInUnprepareHeader : waveOutUnprepareHeader) (hWave, &WaveHdr[0], sizeof(WAVEHDR)); if (WaveHdr[1].dwFlags & WHDR_PREPARED) { (Input ? waveInUnprepareHeader : waveOutUnprepareHeader) (hWave, &WaveHdr[1], sizeof(WAVEHDR)); } } WaveHdr[0].lpData = (LPSTR)TransferAddress; WaveHdr[0].dwBufferLength = BlockSize; WaveHdr[1].lpData = (LPSTR)TransferAddress + BlockSize; WaveHdr[1].dwBufferLength = BlockSize; if (Auto && AutoThread == NULL) { dprintf3(("Creating event")); if (AutoEvent == NULL) { AutoEvent = CreateEvent(NULL, 0, 0, NULL); if (AutoEvent != NULL) { DWORD Id; dprintf2(("Creating thread")); AutoThread = CreateThread(NULL, 300, AutoThreadEntry, NULL, 0, &Id); if (AutoThread == NULL) { dprintf2(("Create thread failed code %d", GetLastError())); } } else { dprintf2(("Create event failed code %d", GetLastError())); } } } if (!(WaveHdr[0].dwFlags & WHDR_PREPARED)) { (Input ? waveInPrepareHeader : waveOutPrepareHeader) (hWave, &WaveHdr[0], sizeof(WAVEHDR)); } if (Auto) { if (!(WaveHdr[1].dwFlags & WHDR_PREPARED)) { (Input ? waveInPrepareHeader : waveOutPrepareHeader) (hWave, &WaveHdr[1], sizeof(WAVEHDR)); } } /* * Actually do it! */ dprintf2(("Writing %d bytes to wave device", WaveHdr[0].dwBufferLength)); rc = (Input ? waveInAddBuffer : waveOutWrite) (hWave, &WaveHdr[0], sizeof(WAVEHDR)); if (rc != MMSYSERR_NOERROR) { dprintf1(("Failed to write to /read from wave device - %d", rc)); } if (Auto) { (Input ? waveInAddBuffer : waveOutWrite) (hWave, &WaveHdr[1], sizeof(WAVEHDR)); } if (Input) { waveInStart(hWave); } } return TRUE; }
static void GetProgConfig( BsBitStream* bitstream, ADIF_INFO* adifInfo ) { unsigned long data; int i, tmp; /* Instance Tag */ BsGetBit( bitstream, &data, 4 ); /* profile */ BsGetBit( bitstream, &data, 2 ); tmp = (int)data; if ( CheckProfile(tmp) ) CommonExit(1,"Illegal profile"); adifInfo->profile = tmp; /* Sampling frequency index */ BsGetBit( bitstream, &data, 4 ); tmp = GetSamplingRate((int)data); if ( !tmp ) CommonExit(1,"Illegal frequency index"); adifInfo->samplingRate = tmp; /* number of front channel elements: only one element (SCE or CPE) is supported */ BsGetBit( bitstream, &data, 4 ); if ( data != 1) CommonExit(1,"Unsupported number of front channels"); /* number of side channel elements (not supported) */ BsGetBit( bitstream, &data, 4 ); if ( data ) CommonExit(1,"Unsupported channel element"); /* number of back channel elements (not supported) */ BsGetBit( bitstream, &data, 4 ); if ( data ) CommonExit(1,"Unsupported channel element"); /* number of LFE channel elements (not supported) */ BsGetBit( bitstream, &data, 2 ); if ( data ) CommonExit(1,"Unsupported channel element"); /* number of data elements (not supported) */ BsGetBit( bitstream, &data, 3 ); if ( data ) CommonExit(1,"Unsupported channel element"); /* number of coupling channel elements (not supported) */ BsGetBit( bitstream, &data, 4 ); if ( data ) CommonExit(1,"Unsupported channel element"); /* mono mixdown present */ BsGetBit( bitstream, &data, 1 ); if ( data ) BsGetBit( bitstream, &data, 4 ); /* stereo mixdown present */ BsGetBit( bitstream, &data, 1 ); if ( data ) BsGetBit( bitstream, &data, 4 ); /* matrix mixdown index present */ BsGetBit( bitstream, &data, 1 ); if ( data ) { BsGetBit( bitstream, &data, 2 ); BsGetBit( bitstream, &data, 1 ); } /* we only have to parse one front channel element */ BsGetBit( bitstream, &data, 1 ); if ( !data ) adifInfo->numChannels = 1; /* single channel */ else adifInfo->numChannels = 2; /* channel pair */ /* instance tag */ BsGetBit( bitstream, &data, 4 ); adifInfo->elementTag = (int)data; /* The other channel elements should be parsed here !! */ /* byte allignment */ data = BsCurrentBit( bitstream ); tmp = ((int)data)%8; if ( tmp ) BsGetSkip( bitstream, 8 - tmp ); /* Comment field */ BsGetBit( bitstream, &data, 8 ); tmp = (int)data; for (i=0; i<tmp; i++) { BsGetBit( bitstream, &data, 8 ); adifInfo->commentField[i] = (char)data; } adifInfo->commentField[i] = '\0'; }
//--------------------------------------------------------------------------- // Return current index int NaPNTimeDepend::CurrentIndex () const { return (int)(CurrentTime() / GetSamplingRate()); }