void RemoveNoteCurrPos(struct Tracker_Windows *window){ struct WBlocks *wblock = window->wblock; struct WTracks *wtrack = wblock->wtrack; struct Tracks *track = wtrack->track; struct LocalZooms *realline = wblock->reallines[wblock->curr_realline]; int curr_realline = wblock->curr_realline; const Trs &trs = TRS_get(wblock, wtrack, curr_realline); ADD_UNDO(Notes_CurrPos(window)); if (trs.size()==0) { InsertStop(window,wblock,wtrack,&realline->l.p); maybe_scroll_down(window); return; } const TrackRealline2 &tr2 = trs[0]; if (tr2.pitch != NULL) { DeletePitch(track, tr2.note, tr2.pitch); if (trs.size()==1) maybe_scroll_down(window); return; } if (tr2.is_end_pitch) { struct Pitches *pitch = (struct Pitches*)ListLast3(&tr2.note->pitches->l); if (pitch!=NULL) tr2.note->pitch_end = pitch->note; else tr2.note->pitch_end = 0; return; } if (tr2.note != NULL) { PLAYER_lock();{ ListRemoveElement3(&track->notes,&tr2.note->l); LengthenNotesTo(wblock->block,track,&realline->l.p); }PLAYER_unlock(); SetNotePolyphonyAttributes(wtrack->track); ValidateCursorPos(window); if (trs.size()==1) maybe_scroll_down(window); return; } const struct Stops *stop = tr2.stop; PLAYER_lock();{ ListRemoveElement3(&track->stops, &stop->l); LengthenNotesTo(wblock->block,track,&realline->l.p); }PLAYER_unlock(); if (trs.size()==1) maybe_scroll_down(window); }
void *Undo_Do_TrackHeader( struct Tracker_Windows *window, struct WBlocks *wblock, struct WTracks *wtrack, int realline, void *pointer ){ struct Undo_TrackHeader *u_th=(struct Undo_TrackHeader *)pointer; int volume=wtrack->track->volume; int pan=wtrack->track->pan; bool volumeonoff=wtrack->track->volumeonoff; bool panonoff=wtrack->track->panonoff; wtrack->track->volume=u_th->volume; wtrack->track->pan=u_th->pan; wtrack->track->volumeonoff=u_th->volumeonoff; wtrack->track->panonoff=u_th->panonoff; if(wtrack->track->panonoff && wtrack->track->patch!=NULL){ PLAYER_lock(); (*wtrack->track->patch->changeTrackPan)(wtrack->track->pan,wtrack->track); PLAYER_unlock(); } u_th->volume=volume; u_th->pan=pan; u_th->panonoff=panonoff; u_th->volumeonoff=volumeonoff; return u_th; }
static void faust_gui_zone_callback(float val, void* arg){ MyUI::Controller *controller = (MyUI::Controller*)arg; float min = controller->min_value; float max = controller->max_value; SoundPlugin *plugin = controller->plugin; int effect_num = controller->effect_num; Data *data = GET_DATA_FROM_PLUGIN(plugin); if (fabs(val - data->automation_values[effect_num]) < fabs((max-min)/100.0)) // approx. return; //printf(" Callback called %f. controller: %p\n val/auto: %f %f", val, controller, val, data->automation_values[effect_num]); float stored_value; stored_value = PLUGIN_get_effect_value(plugin, effect_num, VALUE_FROM_STORAGE); if (val==stored_value) return; // We are now pretty certain that this update was caused by a user interaction in the faust gui, and not a roundtrip from radium. PLAYER_lock();{ PLUGIN_set_native_effect_value(plugin, -1, effect_num, val, PLUGIN_STORED_TYPE, PLUGIN_STORE_VALUE, FX_single); }PLAYER_unlock(); volatile struct Patch *patch = plugin->patch; ATOMIC_SET(patch->widget_needs_to_be_updated, true); }
static void set_new_position(struct Tracks *track, struct Notes *note, Place *start, Place *end){ bool has_lock = PLAYER_current_thread_has_lock(); if (track==NULL && has_lock) RError("track==NULL && has_lock"); if (track!=NULL) { if (has_lock==false) PLAYER_lock(); ListRemoveElement3(&track->notes, ¬e->l); } if (start!=NULL && start!=¬e->l.p) note->l.p = *start; if (end!=NULL && end!=¬e->end) note->end = *end; if (track!=NULL){ ListAddElement3(&track->notes, ¬e->l); if (has_lock==false) PLAYER_unlock(); } }
static void *Undo_Do_PatchVoice( struct Tracker_Windows *window, struct WBlocks *wblock, struct WTracks *wtrack, int realline, void *pointer ){ struct Undo_PatchVoice *undo_ae=pointer; struct Patch *patch = undo_ae->patch; int voicenum = undo_ae->voicenum; struct PatchVoice new_patch_voice = patch->voices[voicenum]; printf("Calling Undo_do for %d. Old value: %d. Setting it to %d\n", voicenum,new_patch_voice.is_on,undo_ae->voice.is_on); //if(new_patch_voice.is_on==undo_ae->voice.is_on) // abort(); PLAYER_lock(); { patch->voices[voicenum] = undo_ae->voice; } PLAYER_unlock(); GFX_update_instrument_widget(undo_ae->patch); undo_ae->voice = new_patch_voice; return undo_ae; }
static struct Velocities *add_velocity( int velocityvelocity, const Place *placement, struct Notes *note, int *pos ) { *pos = -1; if(PlaceLessOrEqual(placement, ¬e->l.p)) return NULL; if(PlaceGreaterOrEqual(placement, ¬e->end)) return NULL; struct Velocities *velocity=(struct Velocities*)talloc(sizeof(struct Velocities)); PlaceCopy(&velocity->l.p,placement); velocity->velocity=R_BOUNDARIES(0,velocityvelocity,MAX_VELOCITY); /* ListAddElement3_ns returns -1 (and doesnt do anything else) if there allready is an element with the same placement. */ PLAYER_lock();{ *pos = ListAddElement3_ns(¬e->velocities,&velocity->l); }PLAYER_unlock(); if (*pos==-1) return NULL; else return velocity; }
static void *Undo_Do_AudioEffect( struct Tracker_Windows *window, struct WBlocks *wblock, struct WTracks *wtrack, int realline, void *pointer ){ struct Undo_AudioEffect *undo_ae=pointer; SoundPlugin *plugin = undo_ae->patch->patchdata; float new_value = plugin->savable_effect_values[undo_ae->effect_num]; printf("Calling Undo_do for %d. Current value: %f. Now setting it back to %f\n",undo_ae->effect_num,new_value,undo_ae->value); PLAYER_lock();{ PLUGIN_set_effect_value(plugin, -1, undo_ae->effect_num, undo_ae->value, PLUGIN_STORED_TYPE, PLUGIN_STORE_VALUE, FX_single ); }PLAYER_unlock(); GFX_update_instrument_widget(undo_ae->patch); undo_ae->value = new_value; return undo_ae; }
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(); } }
void InsertNoteCurrPos(struct Tracker_Windows *window, float notenum, bool polyphonic, float velocity){ if(notenum<0.001 || notenum>127.9) return; ADD_UNDO(Notes_CurrPos(window)); struct WBlocks *wblock = window->wblock; struct WTracks *wtrack = wblock->wtrack; struct Tracks *track = wtrack->track; int curr_realline = wblock->curr_realline; const Trs &trs = TRS_get(wblock, wtrack, curr_realline); if (polyphonic==false && trs.size() > 0) { const TrackRealline2 &tr2 = trs[0]; if (tr2.pitch != NULL) { tr2.pitch->note = notenum; // lock not necessary maybe_scroll_down(window); return; } if (tr2.note != NULL) { // lock not necessary if (tr2.is_end_pitch) tr2.note->pitch_end = notenum; else tr2.note->note = notenum; maybe_scroll_down(window); return; } const struct Stops *stop = tr2.stop; PLAYER_lock();{ ListRemoveElement3(&track->stops, &stop->l); }PLAYER_unlock(); } struct LocalZooms *realline = wblock->reallines[curr_realline]; InsertNote( wblock,wtrack,&realline->l.p,NULL,notenum, velocity < 0.0 ? NOTE_get_velocity(wtrack->track) : velocity*MAX_VELOCITY, polyphonic ); if(wtrack->l.num==wblock->right_track && polyphonic) UpdateAllWTracksCoordinates(window,wblock); if (!polyphonic) maybe_scroll_down(window); }
void TRACK_make_monophonic_destructively(struct Tracks *track){ struct Tracker_Windows *window = root->song->tracker_windows; struct WBlocks *wblock = window->wblock; struct Notes *note = track->notes; bool have_made_undo = false; while(note!=NULL){ struct Notes *next = NextNote(note); if (next==NULL) break; if (PlaceGreaterThan(¬e->end, &next->l.p)){ PLAYER_lock();{ if (PlaceEqual(¬e->l.p, &next->l.p)) { ListRemoveElement3(&track->notes, &next->l); } else { PlaceCopy(¬e->end, &next->l.p); note = next; } }PLAYER_unlock(); if (have_made_undo==false){ ADD_UNDO(Notes(window, wblock->block, track, wblock->curr_realline ) ); have_made_undo = true; } } else { note = next; } } if (have_made_undo==false) GFX_Message(NULL, "Track is already monophonic"); else window->must_redraw = true; }
static bool set_new_sample(struct SoundPlugin *plugin, const wchar_t *filename, int instrument_number, int resampler_type){ bool success=false; Data *data = NULL; Data *old_data = plugin->data; filename = OS_loading_get_resolved_file_path(filename); if (filename==NULL) goto exit; data = create_data(old_data->samplerate, plugin->data, filename, instrument_number, resampler_type); if(load_sample(data,filename,instrument_number)==false) goto exit; // Put loop_onoff into storage. PLUGIN_set_effect_value2(plugin, -1, EFF_LOOP_ONOFF, data->loop_onoff==true?1.0f:0.0f, PLUGIN_STORED_TYPE, PLUGIN_STORE_VALUE, FX_single, PLAYERLOCK_NOT_REQUIRED); if(SP_is_plugin_running(plugin)){ PLAYER_lock();{ old_data->new_data = data; }PLAYER_unlock(); if (PLAYER_is_running()) RSEMAPHORE_wait(old_data->signal_from_RT,1); } else { plugin->data = data; } delete_data(old_data); update_peaks(plugin); volatile struct Patch *patch = plugin->patch; if(patch!=NULL) GFX_update_instrument_widget((struct Patch*)patch); // Update "loop" button. success = true; exit: if(success==false) free(data); return success; }
static void InsertStop( struct Tracker_Windows *window, struct WBlocks *wblock, struct WTracks *wtrack, Place *placement ){ struct Stops *stop; stop = (struct Stops*)talloc(sizeof(struct Stops)); PlaceCopy(&stop->l.p,placement); PLAYER_lock();{ StopAllNotesAtPlace(wblock->block,wtrack->track,placement); ListAddElement3_ns(&wtrack->track->stops,&stop->l); }PLAYER_unlock(); }
static bool FAUST_handle_fff_reply(struct SoundPlugin *plugin, const FFF_Reply &reply, bool is_initializing){ struct Patch *patch = (struct Patch*)plugin->patch; Devdata *devdata = (Devdata*)plugin->data; if (reply.data==NULL){ fprintf(stderr,"Error-message: -%s-\n", devdata->reply.error_message.toUtf8().constData()); devdata->reply.error_message = reply.error_message; return false; } FFF_Reply old_reply = devdata->reply; // handle gui { if (devdata->qtgui_parent == NULL) devdata->qtgui_parent = FAUST_create_qdialog(); if (old_reply.data != NULL && old_reply.data->qtgui!=NULL){ old_reply.data->qtgui->stop(); devdata->qtgui_parent->layout()->removeWidget(old_reply.data->qtgui); } create_gui(devdata->qtgui_parent, reply.data, plugin); if (devdata->qtgui_parent->isVisible()) reply.data->qtgui->run(); } hash_t *effects_state = is_initializing ? NULL : PLUGIN_get_effects_state(plugin); PLAYER_lock();{ devdata->reply = reply; }PLAYER_unlock(); if (effects_state != NULL) PLUGIN_set_effects_from_state(plugin, effects_state); if (old_reply.data != NULL) PATCH_handle_fxs_when_fx_names_have_changed(patch); FFF_request_free(devdata->id, old_reply); return true; }
struct Notes *InsertNote( struct WBlocks *wblock, struct WTracks *wtrack, Place *placement, Place *end_placement, float notenum, int velocity, bool polyphonic ){ struct Blocks *block=wblock->block; struct Tracks *track=wtrack->track; struct Notes *note=NewNote(); //((char*)note)[-5] = 'b'; // test memory validator PlaceCopy(¬e->l.p,placement); note->note=notenum; note->velocity=velocity; // note->velocity=(*wtrack->track->instrument->getStandardVelocity)(wtrack->track); note->velocity_end=note->velocity; PLAYER_lock(); { ListAddElement3(&track->notes,¬e->l); if(polyphonic==false) StopAllNotesAtPlace(block,track,placement); if (end_placement==NULL) SetEndAttributes(block,track,note); else PlaceCopy(¬e->end, end_placement); track->notes = NOTES_sort_by_pitch(track->notes); } PLAYER_unlock(); NOTE_validate(block, NULL, note); return note; }
void DeleteFxNodeLine(struct WTracks *wtrack, struct FXs *fxs, struct FXNodeLines *fxnodeline){ R_ASSERT(ListFindNumElements3(&fxs->fxnodelines->l)>1); PLAYER_lock();{ ListRemoveElement3(&fxs->fxnodelines,&fxnodeline->l); }PLAYER_unlock(); if (ListFindNumElements3(&fxs->fxnodelines->l) <= 1 ){ PlayStop(); struct FX *fx = fxs->fx; struct Tracks *track = wtrack->track; OS_SLIDER_release_automation_pointers(track->patch,fx->effect_num); (*fx->closeFX)(fx,track); ListRemoveElement1(&track->fxs,&fxs->l); } }
int AddFXNodeLine( struct Tracker_Windows *window, struct WBlocks *wblock, struct WTracks *wtrack, int fxnum, int val, const Place *p1 ){ struct FXs *fxs=ListFindElement1_r0(&wtrack->track->fxs->l,fxnum); struct FXNodeLines *fxnodeline=talloc(sizeof(struct FXNodeLines)); int ret; PLAYER_lock();{ fxnodeline->val=R_BOUNDARIES(fxs->fx->min, val, fxs->fx->max); PlaceCopy(&fxnodeline->l.p,p1); ret = ListAddElement3_ns(&fxs->fxnodelines,&fxnodeline->l); }PLAYER_unlock(); return ret; }
bool FLUIDSYNTH_set_new_preset(SoundPlugin *plugin, const wchar_t *sf2_file, int bank_num, int preset_num){ Data *data = plugin->data; if(!STRING_equals2(sf2_file, data->filename)){ Data *new_data = create_data(sf2_file, data->samplerate); if(new_data==NULL) return false; if(SP_is_plugin_running(plugin)){ PLAYER_lock();{ // Hmm. lock for setting a variable type that is atomic on all target platforms? data->new_data = new_data; }PLAYER_unlock(); RSEMAPHORE_wait(data->signal_from_RT,1); } else{ plugin->data = new_data; } delete_data(data); data = new_data; } data->bank_num = bank_num; data->preset_num = preset_num; fluid_synth_bank_select(data->synth,0,bank_num); fluid_synth_program_change(data->synth,0,preset_num); if(plugin->patch != NULL) GFX_update_instrument_widget(plugin->patch); return true; }
void StopVelocityCurrPos(struct Tracker_Windows *window,int noend){ struct WBlocks *wblock; struct WTracks *wtrack; int reallinerealline; struct LocalZooms *realline; struct Notes *note; int subtrack; wblock=window->wblock; wtrack=wblock->wtrack; reallinerealline=wblock->curr_realline; realline=wblock->reallines[reallinerealline]; subtrack=window->curr_track_sub; note=FindNoteOnSubTrack(wtrack,subtrack,&realline->l.p); if(note==NULL) return; ADD_UNDO(Notes_CurrPos(window)); PLAYER_lock();{ if(PlaceGreaterOrEqual(¬e->l.p,&realline->l.p)){ RemoveNote(wblock->block,wtrack->track,note); SetNotePolyphonyAttributes(wtrack->track); ValidateCursorPos(window); }else{ CutNoteAt(wblock->block, wtrack->track, note, &realline->l.p); } note->noend=noend; }PLAYER_unlock(); window->must_redraw=true; }
void DeletePitch(struct Tracks *track, struct Notes *note, struct Pitches *pitch){ PLAYER_lock();{ ListRemoveElement3(¬e->pitches, &pitch->l); }PLAYER_unlock(); }
static bool Load(const wchar_t *filename){ struct Root *newroot; dc.success=true; curr_disk_line = 0; dc.file=DISK_open_for_reading(filename); if(dc.file==NULL){ GFX_Message(NULL,"Could not open \"%s\" for loading\n",STRING_get_chars(filename)); return false; } DC_fgets(); if (dc.success==false) return false; if(strcmp("RADIUM SONG",dc.ls)){ GFX_Message(NULL,"First line in song was not 'RADIUM SONG', but '%s'. Last: %d\n",dc.ls,dc.ls[strlen(dc.ls)-1]); DISK_close_and_delete(dc.file); return false; } disk_load_version=DC_LoadF(); if (dc.success==false) return false; if(disk_load_version>0.4201 && disk_load_version<0.50){ disk_load_version=0.51; dc.colorize=true; dc.startcolor=5; }else{ dc.colorize=false; } #if 0 if (disk_load_version < 0.75){ GFX_Message(NULL, "<p>Note! The portamento behavior for polyphonic tracks changed in Radium V3.4.9" "</p>" "<p>" "Before Radium V3.4.9, the default final portamento value was the pitch value of the next note after the <i>start</i> of the note. " "Now, the default final portamento value is the pitch value of the next note after the <i>end</i> of the note." "</p>" "<p>" "Old songs with portamento in polyphonic tracks might not sound the same." "</p>" ); } #endif if(disk_load_version>DISKVERSION+0.0001){ GFX_Message(NULL,"Need a newer version of Radium to load this song. The song version is %f, while this program only supports %f.\n",disk_load_version,DISKVERSION); return false; }else{ printf("Song diskVersion: %f\n",disk_load_version); } dc.filename=filename; dc.playlist=NULL; DC_Next(); if (dc.success==false) return false; if(strcmp(dc.ls,"OSSTUFF")){ GFX_Message(NULL, "OSSTUFF not found, but: '%s'. File: '%s'\n",dc.ls,STRING_get_chars(filename)); DISK_close_and_delete(dc.file); EndProgram(); exit(4); } LoadOsStuff(); printf("dc.ls: -%s-\n",dc.ls); if(strcmp(dc.ls,"ROOT")){ GFX_Message(NULL, "ROOT not found. Found '%s' instead.\n", dc.ls); DISK_close_and_delete(dc.file); EndProgram(); exit(5); } newroot=LoadRoot(); DISK_close_and_delete(dc.file); if(!dc.success){ GFX_Message(NULL, "Loading failed.\n"); EndProgram(); exit(6); } ResetUndo(); #ifdef _AMIGA CloseHelpWindow(); CloseCPPWindowWindow(); CloseBlockSelectWindow(); #endif CloseAllTrackerWindows(); GL_lock();{ GL_pause_gl_thread_a_short_while(); }GL_unlock(); //GL_draw_lock();{ PLAYER_lock();{ //<-- Locks within locks are dangerous. But it doesn't matter since the player isn't playing now anyway. root=newroot; //BANG! }PLAYER_unlock(); //}GL_draw_unlock(); Undo_start_ignoring_undo_operations();{ DLoadRoot(newroot); }Undo_stop_ignoring_undo_operations(); GL_create_all(root->song->tracker_windows); if(COMMENT_show_after_loading()) COMMENTDIALOG_open(); #ifdef _AMIGA currpatch=-1; #endif ResetUndo(); return true; }