void *tracker_alloc__(size_t size,void *(*AllocFunction)(size_t size2), const char *filename, int linenumber){ allocated+=size; R_ASSERT(THREADING_is_main_thread()); R_ASSERT(!PLAYER_current_thread_has_lock()); #ifndef DISABLE_BDWGC # ifdef _AMIGA return (*GC_amiga_allocwrapper_do)(size,AllocFunction); # else # if !defined(VALIDATE_MEM) void *ret = AllocFunction(size); # else void *ret = V_alloc(AllocFunction,size,filename,linenumber); void *actual_mem_start = V_allocated_mem_real_start(ret); #if defined(RELEASE) #error "oh no" #endif GC_register_finalizer_ignore_self(actual_mem_start, gcfinalizer, NULL, NULL, NULL); # endif # endif return ret; #else return OS_getmem(size); // For debugging. (wrong use of GC_malloced memory could be very difficult to trace) #endif }
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(); } }
void SCHEDULER_add_event(int64_t seq_time, SchedulerCallback callback, const union SuperType *args, int num_args, enum SchedulerPriority priority){ R_ASSERT(PLAYER_current_thread_has_lock()); // An event created by an RT_process function needs to run right away. // If not it won't be run until the next audio block since SCHEDULER_called_per_block // has already been called for this audio block. // (Q: why not do this for events genereated by the editor too? // A: Because then effects could be run after notes, "note on" events could be run before "note off" events, and so forth) if (false==pc->is_treating_editor_events && seq_time < pc->end_time) { callback(seq_time, args); return; } int64_t time = seq_to_scheduler_time(seq_time); //args=NULL; // test crashreporter #if 0 printf("|||||||||| Adding event at seq_time %d, scheduler_time %d. g_current_time: %d, pc->start_time: %d\n", (int)seq_time,(int)time, (int)g_current_time,(int)pc->start_time); #endif if(g_queue_size > QUEUE_SIZE-2){ printf("SCHEDULER: queue full. Skipping.\n"); return; } if(num_args>MAX_ARGS){ printf("Max %d args allowed for scheduler...\n",MAX_ARGS); return; } // Add priority bit. time = time << SCHEDULER_NUM_PRIORITY_BITS; time = time + priority; event_t *event = get_free_event(); event->callback=callback; event->time = time; g_queue_size++; int i = g_queue_size; int new_i = i >> 1; while(time <= g_queue[new_i]->time){ // '<=' (instead of '<') means that the event will be inserted after events with the same time. g_queue[i] = g_queue[new_i]; i = new_i; new_i = new_i >> 1; } g_queue[i] = event; int argnum; for(argnum=0;argnum<num_args;argnum++) event->args[argnum] = args[argnum]; }
static void MIDI_handle_fx_when_theres_a_new_patch_for_track(struct Tracks *track, struct Patch *old_patch, struct Patch *new_patch){ R_ASSERT(PLAYER_current_thread_has_lock()); VECTOR_FOR_EACH(struct FXs *fxs, &track->fxs){ struct FX *fx = fxs->fx; fx->patch = new_patch; // Only need to change patch. All patches use the same fx system. }END_VECTOR_FOR_EACH; return; }
static void PlayStopReally(bool doit){ pc->isplaying=false; pc->initplaying=false; pc->playertask_has_been_called = false; pc->is_playing_range = false; printf("PlayStopReally called: %s\n",doit==true?"true":"false"); if (PLAYER_current_thread_has_lock()){ RError("Potential deadlock detected: Calling PlayStopReally while holding player lock."); return; } if (PLAYER_is_running()) while(pc->peq!=NULL) OS_WaitForAShortTime(20); StopAllInstruments(); #if !USE_OPENGL if(doit) (*Ptask2MtaskCallBack)(); #endif pc->end_time=0; pc->end_time_f=0; pc->play_id++; struct Tracker_Windows *window = root->song->tracker_windows; struct WBlocks *wblock = window->wblock; ScrollEditorToRealLine(window,wblock,wblock->curr_realline); #if !USE_OPENGL DrawWBlockSpesific(window,wblock,wblock->curr_realline,wblock->curr_realline); // clear cursor shade. UpdateAllWTracks(window,wblock,wblock->curr_realline,wblock->curr_realline); // same here. #endif printf("[hb gakkgakk: %d\n",GC_dont_gc); PATCH_reset_time(); //while(GC_is_disabled()) while(GC_dont_gc>0) GC_enable(); MIDI_insert_recorded_midi_events(); }
void CutNoteAt(struct Blocks *block, struct Tracks *track,struct Notes *note, Place *place){ R_ASSERT(PLAYER_current_thread_has_lock() || is_playing()==false); if (PlaceGreaterOrEqual(place, ¬e->end)){ RError("Illegal argument for CutNoteAt 1. %f >= %f\n",GetfloatFromPlacement(place),GetfloatFromPlacement(¬e->end)); return; } if (PlaceLessOrEqual(place, ¬e->l.p)){ RError("Illegal argument for CutNoteAt 2. %f <= %f\n",GetfloatFromPlacement(place),GetfloatFromPlacement(¬e->l.p)); return; } CutListAt(¬e->velocities,place); CutListAt(¬e->pitches,place); PlaceCopy(¬e->end,place); }
void NOTE_validate(const struct Blocks *block, struct Tracks *track, struct Notes *note){ R_ASSERT_RETURN_IF_FALSE(block!=NULL); R_ASSERT_RETURN_IF_FALSE(note!=NULL); R_ASSERT(track==NULL || PLAYER_current_thread_has_lock() || is_playing()==false); if (note->note<=0.0f){ RError("notenum<=0.0f: %f. Setting to 0.01",note->note); note->note=0.01f; } if(note->note>=128.0f){ RError("notenum>=128.0f: %f. Setting to 127.99",note->note); note->note=127.99; } set_legal_start_and_end_pos(block, track, note); ValidatePlace(¬e->l.p); ValidatePlace(¬e->end); }
/************************************************************** FUNCTION Stops all notes before line+(counter/dividor) at line+(counter/dividor, if they last that long. **************************************************************/ void StopAllNotesAtPlace( struct Blocks *block, struct Tracks *track, Place *placement ){ if (PLAYER_current_thread_has_lock()==false && is_playing()==true){ RError("StopAllNotesAtPlace. PLAYER_current_thread_has_lock(): %d, is_playing(): %d", PLAYER_current_thread_has_lock()==false, is_playing()==true); } struct Notes *temp; temp=track->notes; while(temp!=NULL && PlaceLessThan(&temp->l.p,placement)){ if(PlaceGreaterThan(&temp->end,placement)){ CutListAt(&temp->velocities,placement); CutListAt(&temp->pitches,placement); PlaceCopy(&temp->end,placement); NOTE_validate(block, track, temp); } temp=NextNote(temp); } }