예제 #1
0
파일: memory.c 프로젝트: onukore/radium
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



}
예제 #2
0
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, &note->l);
  }

  if (start!=NULL && start!=&note->l.p)
    note->l.p = *start;

  if (end!=NULL && end!=&note->end)
    note->end = *end;

  if (track!=NULL){
    ListAddElement3(&track->notes, &note->l);
    if (has_lock==false)
      PLAYER_unlock();
  }
}
예제 #3
0
파일: scheduler.c 프로젝트: onukore/radium
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];
}
예제 #4
0
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;
}
예제 #5
0
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();
}
예제 #6
0
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, &note->end)){
    RError("Illegal argument for CutNoteAt 1. %f >= %f\n",GetfloatFromPlacement(place),GetfloatFromPlacement(&note->end));
    return;
  }
  
  if (PlaceLessOrEqual(place, &note->l.p)){
    RError("Illegal argument for CutNoteAt 2. %f <= %f\n",GetfloatFromPlacement(place),GetfloatFromPlacement(&note->l.p));
    return;
  }
  
  CutListAt(&note->velocities,place);
  CutListAt(&note->pitches,place);
  PlaceCopy(&note->end,place);

}
예제 #7
0
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(&note->l.p);
  ValidatePlace(&note->end);
}
예제 #8
0
/**************************************************************
  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);
	}
}