예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
 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;
 }
예제 #4
0
파일: cursor.c 프로젝트: onukore/radium
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;
	}
}
예제 #5
0
파일: list.c 프로젝트: jakobvonrotz/radium
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;
}
예제 #6
0
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;
}
예제 #7
0
파일: list.c 프로젝트: jakobvonrotz/radium
/******************************************************************************
  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;

}
예제 #8
0
파일: list.c 프로젝트: jakobvonrotz/radium
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;
}
예제 #9
0
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;
}
예제 #10
0
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;
}
예제 #11
0
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(&notes->l.p, &next->l.p))
      if (notes->note > next->note) {
        note_to_place_after = notes;
        break;
      }
    
    notes = next;
  }

  ListRemoveElement3(&ret, &note_to_place_after->l);
  ListAddElement3_a(&ret, &note_to_place_after->l);
  
  return ret;
}
예제 #12
0
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;
}
예제 #13
0
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;
}
예제 #14
0
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;
}
예제 #15
0
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;
}