static Audio_instrument_widget *create_audio_instrument_widget(struct Patch *patch, bool set_as_current){ EditorWidget *editor = static_cast<EditorWidget*>(root->song->tracker_windows->os_visual.widget); Audio_instrument_widget *instrument = new Audio_instrument_widget(editor->main_window,patch); R_ASSERT_RETURN_IF_FALSE2(instrument!=NULL, NULL); instrument->_patch_widget->name_widget->setText(patch->name); //instruments_widget->tabs->insertTab(instrument, QString::fromLatin1(patch->name), instruments_widget->tabs->count()); g_instruments_widget->tabs->insertWidget(g_instruments_widget->tabs->count(),instrument); // (forgot to take copy) if (set_as_current){ IsAlive is_alive(instrument); // Schedule this happen a little bit later since setCurrentWidget triggers an eventEvent, which might not work properly before the instrument is finished initializing. QTimer::singleShot(g_set_current_delay,[is_alive, instrument]{ if (!is_alive) return; g_instruments_widget->tabs->setCurrentWidget(instrument); MW_update_all_chips(); }); } instrument->updateWidgets(); return instrument; }
static bool co_CB_PasteTrackFX( struct WBlocks *wblock, struct WTracks *wtrack, struct WTracks *towtrack ){ struct Tracks *totrack; struct Tracks *track; Place *p1,p2; R_ASSERT_RETURN_IF_FALSE2(towtrack!=NULL, false); totrack=towtrack->track; track=wtrack->track; make_patches_usable(track); if (totrack->patch == NULL) totrack->patch = track->patch; if(track->midi_instrumentdata!=NULL){ totrack->midi_instrumentdata=MIDI_CopyInstrumentData(track); } VECTOR_clean(&totrack->fxs); p1=PlaceGetFirstPos(); PlaceSetLastPos(wblock->block,&p2); CopyRange_fxs(&totrack->fxs,&track->fxs,p1,&p2); LegalizeFXlines(wblock->block,totrack); return true; }
int dec_users(void){ R_ASSERT_RETURN_IF_FALSE2(_num_seqblock_users>0, 0); _num_seqblock_users--; if (_num_seqblock_users==0) _time_when_num_seqblock_users_decreased_to_0 = TIME_get_ms(); return _num_seqblock_users; }
int CursorLeft(struct Tracker_Windows *window,struct WBlocks *wblock){ if(window->curr_track>0 || (0==window->curr_track && window->curr_track_sub>=0)){ window->curr_track_sub--; if(window->curr_track_sub==-2){ do{ ATOMIC_INC(window->curr_track, -1); R_ASSERT_RETURN_IF_FALSE2(window->curr_track >= 0, 0); ATOMIC_WRITE(wblock->wtrack, ListFindElement1(&wblock->wtracks->l,window->curr_track)); }while(wblock->wtrack==NULL); int num_subtracks = GetNumSubtracks(wblock->wtrack); window->curr_track_sub=num_subtracks-1; } if( window->curr_track<wblock->left_track || (window->curr_track==wblock->left_track && window->curr_track_sub<wblock->left_subtrack) ){ wblock->left_subtrack=-1;//window->curr_track_sub; wblock->left_track=window->curr_track; printf(" left_track: %d, left_subtrack: %d. curr_track: %d\n",wblock->left_track, wblock->left_subtrack,window->curr_track); //UpdateAllWTracksCoordinates(window,wblock); UpdateWBlockCoordinates(window,wblock); return 2; }else{ printf(" left_track: %d, left_subtrack: %d, curr_track: %d\n",wblock->left_track, wblock->left_subtrack,window->curr_track); return 1; } }else{ if (window->curr_track==TEMPOTRACK) return 0; ATOMIC_INC(window->curr_track, -1); if (window->curr_track==TEMPONODETRACK && window->show_reltempo_track==false) ATOMIC_INC(window->curr_track, -1); if (window->curr_track==LINENUMBTRACK) ATOMIC_INC(window->curr_track, -1); if (window->curr_track==SIGNATURETRACK && window->show_signature_track==false) ATOMIC_INC(window->curr_track, -1); if (window->curr_track==LPBTRACK && window->show_lpb_track==false) ATOMIC_INC(window->curr_track, -1); if (window->curr_track==TEMPOTRACK && window->show_bpm_track==false) set_curr_track_to_leftmost_legal_track(window); return 1; } }
int ListPosition3(struct ListHeader3 *list, struct ListHeader3 *element ) { int ret = 0; while(list!=element) { ret++; R_ASSERT_RETURN_IF_FALSE2(list!=NULL, 0); list = list->next; } return ret; }
static bool econnect(QGraphicsScene *scene, Chip *from, Chip *to){ if (SP_add_elink(to->_sound_producer, from->_sound_producer) == false) return false; SoundPlugin *plugin1 = SP_get_plugin(from->_sound_producer); volatile struct Patch *patch1 = plugin1->patch; R_ASSERT_RETURN_IF_FALSE2(patch1!=NULL, false); SoundPlugin *plugin2 = SP_get_plugin(to->_sound_producer); volatile struct Patch *patch2 = plugin2->patch; R_ASSERT_RETURN_IF_FALSE2(patch2!=NULL, false); if (PATCH_add_event_receiver((struct Patch*)patch1, (struct Patch*)patch2) == false ) { RError("Impossible situation: PATCH_add_event_receiver()==true and SP_add_elink()==false"); return false; } return true; }
/****************************************************************************** FUNCTION Returns the previos element in a list. (slow). ******************************************************************************/ void *ListPrevElement1( struct ListHeader1 *list, struct ListHeader1 *element ){ struct ListHeader1 *prev=NULL; while(list!=element){ R_ASSERT_RETURN_IF_FALSE2(list!=NULL, element); prev=list; list=list->next; } return prev; }
NInt ListFindElementPos1( struct ListHeader1 *list, struct ListHeader1 *element ){ NInt pos=0; while(list!=element){ R_ASSERT_RETURN_IF_FALSE2(list!=NULL, 0); list=list->next; pos++; if (list==NULL) { RError("element not in list"); return pos-1; } } return pos; }
int get_subID_from_scancode(int scancode_code){ static bool scancodes_inited = false; if (scancodes_inited==false){ init_scancodes(); scancodes_inited=true; } R_ASSERT_RETURN_IF_FALSE2(scancode_code >= 0, EVENT_NO); if (scancode_code >= 0x100) return EVENT_NO; int subID = scancode[scancode_code]; //printf(" SCANCODE: %x, subID: %d\n", scancode_code, subID); return subID; }
static bool tab_name_has_changed(QWidget *tab, QString new_name) { R_ASSERT_RETURN_IF_FALSE2(g_currpatch != NULL, false); if (g_currpatch->name_is_edited) return false; if(new_name==""){ //name_widget->setText("pip"); new_name = "pip"; } { printf(" tab_name_has_changed -%s-\n", new_name.toUtf8().constData()); PATCH_set_name(g_currpatch, new_name.toUtf8().constData()); struct Tracker_Windows *window = root->song->tracker_windows; window->must_redraw = true; // update track headers to the new name } return true; }
static struct Notes *sort_notes_by_pitch_a_little_bit(struct Notes *notes){ struct Notes *ret = notes; struct Notes *note_to_place_after = NULL; while(notes != NULL){ struct Notes *next = NextNote(notes); R_ASSERT_RETURN_IF_FALSE2(next!=NULL, NULL); if (PlaceEqual(¬es->l.p, &next->l.p)) if (notes->note > next->note) { note_to_place_after = notes; break; } notes = next; } ListRemoveElement3(&ret, ¬e_to_place_after->l); ListAddElement3_a(&ret, ¬e_to_place_after->l); return ret; }
static VoiceOp RT_play_voice(const Data *data, const Voice *voice, const int num_frames, float *destination){ int start_writing_pos = 0; int end_writing_pos = num_frames; const int delta_pos_at_start = voice->delta_pos_at_start; const int delta_pos_at_end = voice->delta_pos_at_end; VoiceOp ret = VOICE_KEEP; if (delta_pos_at_start==0 && delta_pos_at_end==-1){ // 1. continue playing; int num_consumed_frames = RT_get_resampled_data(voice, destination, num_frames); if (num_consumed_frames < num_frames) { end_writing_pos = num_consumed_frames; ret = VOICE_REMOVE; } }else if (delta_pos_at_start>0 && delta_pos_at_end==-1){ // 2. start playing (without end playing) start_writing_pos = delta_pos_at_start; int new_num_frames = num_frames - delta_pos_at_start; int num_consumed_frames = RT_get_resampled_data(voice, destination, new_num_frames); if (num_consumed_frames < new_num_frames){ end_writing_pos = start_writing_pos + num_consumed_frames; ret = VOICE_REMOVE; } }else{ // 3. end playing R_ASSERT_RETURN_IF_FALSE2(delta_pos_at_end>=0, VOICE_REMOVE); R_ASSERT_RETURN_IF_FALSE2(delta_pos_at_end>=delta_pos_at_start, VOICE_REMOVE); int new_num_frames = delta_pos_at_end - delta_pos_at_start; int num_consumed_frames = RT_get_resampled_data(voice, destination+delta_pos_at_start, new_num_frames); start_writing_pos = delta_pos_at_start; end_writing_pos = delta_pos_at_start+num_consumed_frames; ret = VOICE_REMOVE; } if (start_writing_pos > 0) memset(destination, 0, start_writing_pos*sizeof(float)); if (end_writing_pos < num_frames) memset(destination+end_writing_pos, 0, (num_frames-end_writing_pos)*sizeof(float)); return ret; }
static const struct NodeLine *create_nodelines( const struct Tracker_Windows *window, const struct WBlocks *wblock, const struct ListHeader3 *list, float (*get_x)(const struct WBlocks *wblock, const struct ListHeader3 *element, int *logtype), // should return a value between 0 and 1. const struct ListHeader3 *last_element // may be null. may also contain more than one element. ) { struct NodeLine *nodelines = NULL; R_ASSERT(list != NULL); R_ASSERT(list->next != NULL || last_element!=NULL); if (last_element!=NULL){ const Place *start = &list->p; const Place *end = &last_element->p; R_ASSERT(PlaceGreaterThan(end, start)); } // 1. Create straight forward nodelines from the list { float reallineF = 0.0f; struct NodeLine *nodelines_last = NULL; while(list != NULL){ struct NodeLine *nodeline = (struct NodeLine *)talloc(sizeof(struct NodeLine)); nodeline->x1 = get_x(wblock, list, &nodeline->logtype); reallineF = FindReallineForF(wblock, reallineF, &list->p); nodeline->y1 = get_realline_y(window, reallineF); nodeline->element1 = list; nodeline->is_node = true; if(nodelines_last==NULL) nodelines = nodelines_last = nodeline; else { nodelines_last->next = nodeline; nodelines_last = nodeline; } list = list->next; if (list==NULL) { list = last_element; last_element = NULL; } } } // 2. Insert x2, y2 and element2 attributes, and remove last element. { R_ASSERT_RETURN_IF_FALSE2(nodelines!=NULL, NULL); // shouldn't be possible, but I got a crash report that indicates that this might have happened. R_ASSERT_RETURN_IF_FALSE2(nodelines->next!=NULL, NULL); // shouldn't be possible either, but more likely than the line above. struct NodeLine *ns = nodelines; struct NodeLine *next = ns->next; for(;;){ ns->x2 = ns->logtype==LOGTYPE_HOLD ? ns->x1 : next->x1; ns->y2 = next->y1; if (ns->y2 < ns->y1) { RWarning("y2 < y1: %f < %f",ns->y2,ns->y1); ns->y2 = ns->y1; } ns->element2 = next->element1; if(next->next==NULL) break; ns = next; next = next->next; } ns->next = NULL; // Cut the last element } // 3. Insert all non-node break-points. (caused by realline level changes) { struct LocalZooms **reallines=wblock->reallines; int curr_level = reallines[0]->level; int realline; float reallineF = 0.0f; for(realline = 1; realline < wblock->num_reallines ; realline++) { struct LocalZooms *localzoom = reallines[realline]; if (localzoom->level != curr_level){ reallineF = FindReallineForF(wblock, reallineF, &localzoom->l.p); insert_nonnode_nodeline(nodelines, &localzoom->l, get_realline_y(window, reallineF)); curr_level = localzoom->level; } } } return nodelines; }
static StretchspeedTimeConversionTable get_time_conversion_table(struct SeqBlock *seqblock, const struct SeqblockAutomation *stretch, const struct SeqblockAutomation *speed) { StretchspeedTimeConversionTable table = default_table; const bool do_stretch = RT_seqblock_automation_is_enabled(stretch); const bool do_speed = RT_seqblock_automation_is_enabled(speed); R_ASSERT_RETURN_IF_FALSE2(do_stretch||do_speed, table); const double total_time = seqblock->t.num_samples; //default_duration / resample_ratio; //2.0;//(s2-s1); int num_elements = get_num_elements(seqblock); //total_time / RADIUM_BLOCKSIZE; int64_t *array = (int64_t*)V_calloc(sizeof(int64_t), (num_elements+1)); //_automation.print(); double time_inc = (double)seqblock->t.default_duration / (double)num_elements; double total_stretch = total_time; double total_speed = total_time; radium::SeqAutomationIterator<radium::AutomationNode> stretch_iterator(SEQBLOCK_AUTOMATION_get_SeqAutomation(stretch)); radium::SeqAutomationIterator<radium::AutomationNode> speed_iterator(SEQBLOCK_AUTOMATION_get_SeqAutomation(speed)); if (do_stretch && do_speed) apply_to_time_conversion_table_double(num_elements, array, stretch_iterator, speed_iterator, time_inc, total_stretch, total_speed); else if (do_stretch) apply_to_time_conversion_table_single(num_elements, array, stretch_iterator, SAT_STRETCH, time_inc, total_stretch); else if (do_speed) apply_to_time_conversion_table_single(num_elements, array, speed_iterator, SAT_SPEED, time_inc, total_speed); else R_ASSERT(false); table.stretch_automation_compensation = total_stretch / total_time; table.speed_automation_compensation = total_speed / total_time; table.num_elements = num_elements; table.array = array; //printf("1. stretch c: %f. speed c: %f. total c: %f. total time: %f\n", table.stretch_automation_compensation, table.speed_automation_compensation, g_total, total_time); if (do_stretch){ table.stretch_automation_compensation = total_stretch / total_time; table.stretchspeed_automation_compensation = table.stretch_automation_compensation; } else { table.stretch_automation_compensation = 1.0; } //printf("2. stretch c: %f. speed c: %f. total c: %f. total time: %f\n", table.stretch_automation_compensation, table.speed_automation_compensation, g_total, total_time); if (do_speed){ table.speed_automation_compensation = total_speed / total_time; table.stretchspeed_automation_compensation = table.speed_automation_compensation; } else { table.speed_automation_compensation = 1.0; } //printf("3. stretch c: %f. speed c: %f. total c: %f. total time: %f\n", table.stretch_automation_compensation, table.speed_automation_compensation, g_total, total_time); if (do_stretch && do_speed){ double uncompensated_duration = array[num_elements]; table.stretchspeed_automation_compensation = uncompensated_duration / total_time; table.speed_automation_compensation = uncompensated_duration / total_stretch; //printf("4. stretch c: %f. speed c: %f. total c: %f. uncompensated duration: %f. total_stretch: %f. total_speed: %f. total time: %f\n", table.stretch_automation_compensation, table.speed_automation_compensation, g_total, uncompensated_duration, total_stretch, total_speed, total_time); } return table; }
static int get_peaks(struct SoundPlugin *plugin, float note_num, int ch, float das_pan, int64_t start_time, int64_t end_time, float *min_value, float *max_value ) { Data *data = (Data*)plugin->data; if(ch==-1){ int i; for(i=0;i<MAX_NUM_SAMPLES;i++){ Sample *sample=(Sample*)&data->samples[i]; if(sample->sound!=NULL){ if(sample->ch==1) return 2; } } return 1; } R_ASSERT_RETURN_IF_FALSE2(note_num >= 0.0f, 2); const Note *note=&data->notes[(int)note_num]; if (!note_has_sample(note)){ *min_value = 0.0f; *max_value = 0.0f; return 2; } int start_frame = time_to_frame(data, start_time, note_num); int end_frame = time_to_frame(data, end_time, note_num); { float min=0.0f; float max=0.0f; int samplenum; for(samplenum=0;samplenum<note->num_samples;samplenum++){ const Sample *sample=note->samples[samplenum]; Panvals pan = get_pan_vals_vector(das_pan, sample->ch==-1 ? 1 : 2); int input_channel = sample->ch==-1 ? 0 : sample->ch; float panval = pan.vals[input_channel][ch]; if(panval>0.0f){ float min2; float max2; get_peaks_from_sample(sample, start_frame, end_frame, &min2, &max2); min2 *= panval; max2 *= panval; if(min2<min) min=min2; if(max2>max) max=max2; } } *min_value = min; *max_value = max; } apply_adsr_to_peak(data, (start_time+end_time)/2, min_value, max_value); return 2; }