static void assert_no_curr_seqtrack(void){ if (g_curr_seqtrack_automation_seqtrack != NULL){ R_ASSERT_NON_RELEASE(false); g_curr_seqtrack_automation_seqtrack = NULL; } if (g_curr_seqtrack_automation_num != -1){ R_ASSERT_NON_RELEASE(false); g_curr_seqtrack_automation_num = -1; } }
// Called from Mixer.cpp after events are calculated, and before audio is created. void RT_LPB_set_beat_position(struct SeqTrack *seqtrack, int audioblocksize){ if (is_playing()==false) return; if (seqtrack->curr_seqblock==NULL) return; bool curr_num_beats_is_valid = true; // Might become false when switching block. If false, we must not set new curr_bpm value. LPB_Iterator *iterator = &seqtrack->lpb_iterator; set_new_num_beats_values(seqtrack, seqtrack->curr_seqblock, iterator, audioblocksize, &curr_num_beats_is_valid); double num_beats_till_next_time = iterator->next_num_beats - iterator->curr_num_beats; #if DEBUG_BUGS R_ASSERT_NON_RELEASE(num_beats_till_next_time > 0); #endif if (curr_num_beats_is_valid==true) { double bpm = num_beats_till_next_time * 60.0 * (double)pc->pfreq / (double)audioblocksize; //printf("bpm: %f, curr_num_beats: %f - %f (d: %f)\n", bpm,iterator->curr_num_beats,iterator->next_num_beats,num_beats_till_next_time); if (fabs(bpm-iterator->curr_bpm) > 0.001) iterator->curr_bpm = bpm; } #if DEBUG_BUGS static double last = 0.0; printf("Num_beats: %f. (diff: %f). So far: %f\n", iterator->curr_num_beats, iterator->curr_num_beats-last, iterator->num_beats_played_so_far); last = iterator->curr_num_beats; #endif }
static void reschedule_reallines_because_num_reallines_have_changed_in_wblock3(struct SeqTrack *seqtrack, struct SeqBlock *seqblock, struct WBlocks *wblock, int64_t curr_seqtrack_time){ R_ASSERT_NON_RELEASE(seqblock->block != NULL); struct Blocks *block = wblock->block; if (seqblock->block == block && curr_seqtrack_time < seqblock->t.time2) { PLAYER_lock();{ curr_seqtrack_time = seqtrack->start_time; // Get accurate seqtrack time, and also update it. if (curr_seqtrack_time >= seqblock->t.time) { if (curr_seqtrack_time < seqblock->t.time2) { STime stime = seqtime_to_blocktime(seqblock, curr_seqtrack_time - seqblock->t.time); Place place = STime2Place(block, stime); int realline=FindRealLineFor(wblock,0,&place); setit(wblock, realline); realline++; //printf(" Rescheduling block %d. Realline: %d. Place: %d + %d/%d\n", wblock->l.num, realline, place.line,place.counter,place.dividor); RT_schedule_reallines_in_block2(seqtrack, seqblock, wblock, realline); } } }PLAYER_unlock(); } }
static void set_new_num_beats_values(struct SeqTrack *seqtrack, const struct SeqBlock *seqblock, LPB_Iterator *iterator, int audioblocksize, bool *curr_num_beats_is_valid){ //double curr_num_before = iterator->num_beats_played_so_far; bool just_started_playing = iterator->has_next_num_beats==false; if (iterator->has_next_num_beats==false){ iterator->curr_num_beats = get_num_beats(seqtrack, seqblock, iterator, 0, "start1", curr_num_beats_is_valid); iterator->next_num_beats = get_num_beats(seqtrack, seqblock, iterator, audioblocksize, "start2", curr_num_beats_is_valid); iterator->has_next_num_beats=true; //fprintf(stderr, " PEQ_LPB: Set new g_curr_num_beats to %f. Place: %f - %f. curr: %f, next: %f\n", iterator->curr_num_beats,iterator->place1_f, iterator->place2_f, iterator->curr_num_beats, iterator->next_num_beats); } else { #if DEBUG_BUGS printf("Prev curr_num_beats: %f\n",iterator->curr_num_beats); #endif iterator->curr_num_beats = iterator->next_num_beats; // Since the prev value might have been calculated using previous LPB values, this value sometimtes might not be 100% correct, but it should be good enough. iterator->next_num_beats = get_num_beats(seqtrack, seqblock, iterator, audioblocksize, "nextnumbeats", curr_num_beats_is_valid); } #if DEBUG_BUGS printf("curr: %f, next: %f\n",iterator->curr_num_beats,iterator->next_num_beats); if (iterator->next_num_beats <= iterator->curr_num_beats) abort(); R_ASSERT_NON_RELEASE(iterator->next_num_beats > iterator->curr_num_beats); #endif RT_Beats_set_new_last_bar_start_value(seqtrack, iterator->curr_num_beats, just_started_playing); }
static double get_num_beats(const struct SeqTrack *seqtrack, const struct SeqBlock *seqblock, LPB_Iterator *iterator, int audioframes_to_add, const char *from_where, bool *curr_num_beats_is_valid){ struct Blocks *block = seqblock->block; double time = seqtrack->start_time - seqblock->time; #if DEBUG_BUGS R_ASSERT_NON_RELEASE(time > -(RADIUM_BLOCKSIZE*ATOMIC_DOUBLE_GET(block->reltempo))); #endif if (time < 0) // Happens when switching between two seqblocks at a non-audio block alignment (i.e. delta time > 0). To avoid this minor inaccuracy, it seems necessary to break the use of constant 64 frame audio block sizes, so it's probably not worth it. time = 0; double time_to_add = (double)audioframes_to_add * ATOMIC_DOUBLE_GET(block->reltempo); #if DEBUG_BUGS printf("Get num_beats. from_where: %s, time: %f, time_to_add: %f, pc->start_time_f: %f, stime2place: %f\n", from_where, time, time_to_add, ATOMIC_DOUBLE_GET(seqtrack->start_time_f), STime2Place_f(block, time+time_to_add) ); #endif if (time+time_to_add > getBlockSTimeLength(block)) // can happen when switching block *curr_num_beats_is_valid = false; return iterator->num_beats_played_so_far + scale_double(STime2Place_f(block, time+time_to_add), iterator->place1_f, iterator->place2_f, 0.0, iterator->num_beats_between_place1_and_place2 ); }
static float get_pitch_x(const struct WBlocks *wblock, const struct ListHeader3 *element, int *logtype){ struct Pitches *pitch = (struct Pitches*)element; *logtype = pitch->logtype; if (track_pitch_min==track_pitch_max){ R_ASSERT_NON_RELEASE(track_pitch_min==pitch->note); return (track_notearea_x1 + track_notearea_x2) / 2.0f; } return scale(pitch->note, track_pitch_min, track_pitch_max, track_notearea_x1, track_notearea_x2 ); }
static bool patch_used_in_current_editor_block(struct Patch *patch){ if(root==NULL || root->song==NULL || root->song->tracker_windows==NULL || root->song->tracker_windows->wblock==NULL || root->song->tracker_windows->wblock->block==NULL){ R_ASSERT_NON_RELEASE(false); return false; } struct Tracks *track = root->song->tracker_windows->wblock->block->tracks; while(track != NULL){ if(track->patch==patch) return true; track = NextTrack(track); } return false; }
static bool elements_are_equal(const hash_element_t *el1, const hash_element_t *el2){ R_ASSERT_NON_RELEASE(el1->i==el2->i); R_ASSERT_NON_RELEASE(!strcmp(el1->key,el2->key)); return DYN_equal(el1->a, el2->a); }
int process (const double actualRatio, const float* in, const int numIn, float* out, const int numOut, int *numConsumed ) { R_ASSERT_NON_RELEASE(numIn > 0); R_ASSERT_NON_RELEASE(numOut > 0); if (actualRatio > 0.9999 && actualRatio < 1.00001) return process_no_interpolation(in, numIn, out, numOut, numConsumed); double pos = subSamplePos; int num_produced = 0; int num_consumed = 0; if (actualRatio < 1.0) { for ( ; num_produced < numOut ; num_produced++){ if (pos >= 1.0) { if (num_consumed == numIn) goto bail_out; push(in[num_consumed]); num_consumed++; pos -= 1.0; } out[num_produced] = interpolate(pos); pos += actualRatio; } } else { for ( ; num_produced < numOut ; num_produced++){ while (pos < actualRatio) { if (num_consumed == numIn) // I've benchmarked running two different types of inner loops, depending on whether we would risk reading in[numIns]. // The point was that the test on this line was removed in one of those inner loops. // However, the increase in performance was hardly measurable for larger input arrays (i.e. numOut >= 1024), // while for smaller input arrays the performance was significantly worse. -Kjetil goto bail_out; push(in[num_consumed]); num_consumed++; pos += 1.0; } pos -= actualRatio; // I don't understand why pos handling is done differently when sampling down or up. And does it work properly if the ratio crosses 1.0 in a swipe? out[num_produced] = interpolate(1.0f - (float)pos); } } bail_out: subSamplePos = pos; *numConsumed = num_consumed; return num_produced; }
float *get_channel(int ch) const{ R_ASSERT_NON_RELEASE(_has_channels); return _channels[ch]->buffer; }