bool SpiralLoopPlugin::GetOutput(Sample &data) { if (!m_Recording && !m_Playing) { return false; } if (!m_Recording && m_StoreBuffer.GetLength()==0) { return false; } if (m_FixedRecord && m_DubBuffer.GetLength()!=m_StoreBuffer.GetLength()) { cerr<<"eek! dub and store buffers don't match!"<<endl; } if (m_Recording) { RecordBuf(m_Pos, data.GetLength()); if (!m_StoreBuffer.GetLength()) { return false; } } int Pos; bool ret=false; for (int n=0; n<data.GetLength(); n++) { Pos=static_cast<int>(m_Pos); // brute force fix if (Pos>0 && Pos<m_LoopPoint) { data.Set(n,(m_StoreBuffer[m_Pos]+m_DubBuffer[m_Pos])*m_Volume); } else data.Set(n,0); m_Pos+=m_Speed; if (static_cast<int>(m_Pos)>=m_LoopPoint) { ret=true; m_Pos=0; } } m_IntPos=static_cast<int>(m_Pos); return ret; }
ATHENAError Track::GetKeyLength(const SLong & k_id, ULong & length) { Float f_lgt(0.0F); SLong s_id; Sample * sample; if (ULong(k_id) >= key_c) return ATHENA_ERROR_HANDLE; s_id = GetSampleID(s_id); if (_sample.IsNotValid(s_id)) { length = 0; return ATHENA_OK; } sample = _sample[s_id]; TrackKey * key = &key_l[k_id]; if (key->pitch.interval) { Float min, max, cur; Float size; length = sample->length; size = Float(length) * (key->loop + 1); min = key->pitch.min * sample->format.frequency * key->pitch.interval * 0.001F; max = key->pitch.max * sample->format.frequency * key->pitch.interval * 0.001F; cur = max; while (size > 0.0F) { f_lgt += key->pitch.interval; size -= cur = cur == min ? max : min; } if (size < 0.0F) f_lgt += key->pitch.interval * (size / cur); f_lgt *= 0.5F; } else { ULong size, loop; sample->GetLength(size); loop = (key->loop + 1) / 2; f_lgt = (size * loop) * (1.0F / key->pitch.max); loop = (key->loop + 1) - loop; f_lgt += (size * loop) * (1.0F / key->pitch.min); } length = key->start + (key->loop + 1) * key->delay_max; length += ULong(f_lgt); return ATHENA_OK; }
void Filter::GetOutput(int V, Sample &data) { float Cutoff; float Resonance; if (m_FilterBypass || fc<0) return; for (int n=0; n<data.GetLength(); n++) { coef = iir[V].coef + 1; /* Skip k, or gain */ k=0.25; Cutoff = fc; Resonance = Q; Cutoff/=2; if (Resonance>MAX_RES) Resonance=MAX_RES; if (Cutoff>MAX_CUTOFF) Cutoff=MAX_CUTOFF; if (Resonance<MIN_RES) Resonance=MIN_RES; if (Cutoff<MIN_CUTOFF) Cutoff=MIN_CUTOFF; if (n%10==0) { // if different from last time //if (m_LastQ!=Q || m_LastFC!=fc) { for (nInd = 0; nInd < iir[V].length; nInd++) { a2 = ProtoCoef[nInd].a2; a0 = ProtoCoef[nInd].a0; a1 = ProtoCoef[nInd].a1; b0 = ProtoCoef[nInd].b0; b1 = ProtoCoef[nInd].b1 / Resonance; b2 = ProtoCoef[nInd].b2; szxform(&a0, &a1, &a2, &b0, &b1, &b2, Cutoff*(Cutoff/1000.0f), fs, &k, coef); coef += 4; } iir[V].coef[0] = k; m_LastQ=Q; m_LastFC=fc; } } data.Set(n,iir_filter(data[n],&iir[V])); } }
void Sample::Insert(const Sample &S, int Pos) { // do some checking assert(Pos<=GetLength()); int NewLen = GetLength()+S.GetLength(); AudioType *NewBuf = (AudioType*) m_Allocator->New(NewLen*sizeof(AudioType)); int FromPos=0, ToPos=0, TempBufPos=0; while (FromPos<=GetLength()) { if (FromPos==Pos) { for (TempBufPos=0; TempBufPos<S.GetLength(); TempBufPos++) { NewBuf[ToPos]=S[TempBufPos]; ToPos++; } } else { // this test is needed so the loop can deal // with samples being "inserted" on to the // very end of the buffer if (FromPos<GetLength()) { NewBuf[ToPos]=m_Data[FromPos]; } } FromPos++; ToPos++; } Clear(); m_Data=NewBuf; m_Length=NewLen; }
void Sample::Mix(const Sample &S, int Pos) { // do some checking assert(Pos<GetLength()); int ToPos=Pos; for (int FromPos=0; FromPos<S.GetLength(); FromPos++) { m_Data[ToPos]=m_Data[ToPos]+S[FromPos]; if (ToPos>GetLength()) ToPos=0; ToPos++; } }
ATHENAError Track::GetKeyLoopLength(const SLong & k_id, const ULong & loop_i, ULong & length) { Float f_lgt(0.0F); if (ULong(k_id) >= key_c || loop_i > key_l[k_id].loop) return ATHENA_ERROR_HANDLE; SLong s_id(GetSampleID(s_id)); if (_sample.IsNotValid(s_id)) { length = 0; return ATHENA_OK; } Sample * sample = _sample[s_id]; TrackKey * key = &key_l[k_id]; if (key->pitch.interval) { Float min, max, cur; Float size; length = sample->length; //length in bytes size = Float(length) * (key->loop + 1); min = key->pitch.min * sample->format.frequency * key->pitch.interval * 0.001F; max = key->pitch.max * sample->format.frequency * key->pitch.interval * 0.001F; cur = max; while (size > 0.0F) { f_lgt += key->pitch.interval; size -= cur = cur == min ? max : min; } if (size < 0.0F) f_lgt += key->pitch.interval * (size / cur); } else { sample->GetLength(length); length = ULong((loop_i & 0x00000001 ? key->pitch.max : key->pitch.min) * length); } return ATHENA_OK; }