⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 instrum.c

📁 SDL_mixer 是一个基于 SDL 的混音器
💻 C
📖 第 1 页 / 共 2 页
字号:
      else	sp->panning=(uint8)(panning & 0x7F);      sp->resonance=0;      sp->cutoff_freq=0;      sp->reverberation=0;      sp->chorusdepth=0;      sp->exclusiveClass=0;      sp->keyToModEnvHold=0;      sp->keyToModEnvDecay=0;      sp->keyToVolEnvHold=0;      sp->keyToVolEnvDecay=0;      if (cfg_tuning)	{	  double tune_factor = (double)(cfg_tuning)/1200.0;	  tune_factor = pow(2.0, tune_factor);	  sp->root_freq = (uint32)( tune_factor * (double)sp->root_freq );	}      /* envelope, tremolo, and vibrato */      if (18 != fread(tmp, 1, 18, fp)) goto fail;       if (!tmp[13] || !tmp[14])	{	  sp->tremolo_sweep_increment=	    sp->tremolo_phase_increment=sp->tremolo_depth=0;	  ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no tremolo");	}      else	{	  sp->tremolo_sweep_increment=convert_tremolo_sweep(tmp[12]);	  sp->tremolo_phase_increment=convert_tremolo_rate(tmp[13]);	  sp->tremolo_depth=tmp[14];	  ctl->cmsg(CMSG_INFO, VERB_DEBUG,	       " * tremolo: sweep %d, phase %d, depth %d",	       sp->tremolo_sweep_increment, sp->tremolo_phase_increment,	       sp->tremolo_depth);	}      if (!tmp[16] || !tmp[17])	{	  sp->vibrato_sweep_increment=	    sp->vibrato_control_ratio=sp->vibrato_depth=0;	  ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no vibrato");	}      else	{	  sp->vibrato_control_ratio=convert_vibrato_rate(tmp[16]);	  sp->vibrato_sweep_increment=	    convert_vibrato_sweep(tmp[15], sp->vibrato_control_ratio);	  sp->vibrato_depth=tmp[17];	  ctl->cmsg(CMSG_INFO, VERB_DEBUG,	       " * vibrato: sweep %d, ctl %d, depth %d",	       sp->vibrato_sweep_increment, sp->vibrato_control_ratio,	       sp->vibrato_depth);	}      READ_CHAR(sp->modes);      READ_SHORT(sp->freq_center);      READ_SHORT(sp->freq_scale);      if (sf2flag)        {          READ_SHORT(sample_volume);	  READ_CHAR(sf2delay);          READ_CHAR(sp->exclusiveClass);          skip(fp, 32);	}      else        {          skip(fp, 36);        }      /* Mark this as a fixed-pitch instrument if such a deed is desired. */      if (note_to_use!=-1)	sp->note_to_use=(uint8)(note_to_use);      else	sp->note_to_use=0;            /* seashore.pat in the Midia patch set has no Sustain. I don't         understand why, and fixing it by adding the Sustain flag to         all looped patches probably breaks something else. We do it         anyway. */	       if (sp->modes & MODES_LOOPING) 	sp->modes |= MODES_SUSTAIN;      /* Strip any loops and envelopes we're permitted to */      if ((strip_loop==1) && 	  (sp->modes & (MODES_SUSTAIN | MODES_LOOPING | 			MODES_PINGPONG | MODES_REVERSE)))	{	  ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing loop and/or sustain");	  sp->modes &=~(MODES_SUSTAIN | MODES_LOOPING | 			MODES_PINGPONG | MODES_REVERSE);	}      if (strip_envelope==1)	{	  if (sp->modes & MODES_ENVELOPE)	    ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing envelope");	  sp->modes &= ~MODES_ENVELOPE;	}      else if (strip_envelope != 0)	{	  /* Have to make a guess. */	  if (!(sp->modes & (MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE)))	    {	      /* No loop? Then what's there to sustain? No envelope needed		 either... */	      sp->modes &= ~(MODES_SUSTAIN|MODES_ENVELOPE);	      ctl->cmsg(CMSG_INFO, VERB_DEBUG, 			" - No loop, removing sustain and envelope");	    }	  else if (!memcmp(tmp, "??????", 6) || tmp[11] >= 100) 	    {	      /* Envelope rates all maxed out? Envelope end at a high "offset"?		 That's a weird envelope. Take it out. */	      sp->modes &= ~MODES_ENVELOPE;	      ctl->cmsg(CMSG_INFO, VERB_DEBUG, 			" - Weirdness, removing envelope");	    }	  else if (!(sp->modes & MODES_SUSTAIN))	    {	      /* No sustain? Then no envelope.  I don't know if this is		 justified, but patches without sustain usually don't need the		 envelope either... at least the Gravis ones. They're mostly		 drums.  I think. */	      sp->modes &= ~MODES_ENVELOPE;	      ctl->cmsg(CMSG_INFO, VERB_DEBUG, 			" - No sustain, removing envelope");	    }	}      sp->attenuation = 0;      for (j=ATTACK; j<DELAY; j++)	{	  sp->envelope_rate[j]=	    (j<3)? convert_envelope_rate_attack(tmp[j], 11) : convert_envelope_rate(tmp[j]);	  sp->envelope_offset[j]= 	    convert_envelope_offset(tmp[6+j]);	}      if (sf2flag)	{	  if (sf2delay > 5) sf2delay = 5;	  sp->envelope_rate[DELAY] = (int32)( (sf2delay*play_mode->rate) / 1000 );	}      else	{          sp->envelope_rate[DELAY]=0;	}      sp->envelope_offset[DELAY]=0;      for (j=ATTACK; j<DELAY; j++)	{	  sp->modulation_rate[j]=sp->envelope_rate[j];	  sp->modulation_offset[j]=sp->envelope_offset[j];	}      sp->modulation_rate[DELAY] = sp->modulation_offset[DELAY] = 0;      sp->modEnvToFilterFc=0;      sp->modEnvToPitch=0;      sp->lfo_sweep_increment = 0;      sp->lfo_phase_increment = 0;      sp->modLfoToFilterFc = 0;      sp->vibrato_delay = 0;      /* Then read the sample data */      if (sp->data_length/2 > MAX_SAMPLE_SIZE)        {	  goto fail;	}      sp->data = safe_malloc(sp->data_length + 1);      lp->size += sp->data_length + 1;      if (1 != fread(sp->data, sp->data_length, 1, fp))	goto fail;            if (!(sp->modes & MODES_16BIT)) /* convert to 16-bit data */	{	  int32 i=sp->data_length;	  uint8 *cp=(uint8 *)(sp->data);	  uint16 *tmp,*newdta;	  tmp=newdta=safe_malloc(sp->data_length*2 + 2);	  while (i--)	    *tmp++ = (uint16)(*cp++) << 8;	  cp=(uint8 *)(sp->data);	  sp->data = (sample_t *)newdta;	  free(cp);	  sp->data_length *= 2;	  sp->loop_start *= 2;	  sp->loop_end *= 2;	}#if SDL_BYTEORDER == SDL_BIG_ENDIAN      else	/* convert to machine byte order */	{	  int32 i=sp->data_length/2;	  int16 *tmp=(int16 *)sp->data,s;	  while (i--)	    { 	      s=LE_SHORT(*tmp);	      *tmp++=s;	    }	}#endif            if (sp->modes & MODES_UNSIGNED) /* convert to signed data */	{	  int32 i=sp->data_length/2;	  int16 *tmp=(int16 *)sp->data;	  while (i--)	    *tmp++ ^= 0x8000;	}      /* Reverse reverse loops and pass them off as normal loops */      if (sp->modes & MODES_REVERSE)	{	  int32 t;	  /* The GUS apparently plays reverse loops by reversing the	     whole sample. We do the same because the GUS does not SUCK. */	  ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "Reverse loop in %s", name);	  reverse_data((int16 *)sp->data, 0, sp->data_length/2);	  t=sp->loop_start;	  sp->loop_start=sp->data_length - sp->loop_end;	  sp->loop_end=sp->data_length - t;	  sp->modes &= ~MODES_REVERSE;	  sp->modes |= MODES_LOOPING; /* just in case */	}      /* If necessary do some anti-aliasing filtering  */      if (antialiasing_allowed)	  antialiasing(sp,play_mode->rate);#ifdef ADJUST_SAMPLE_VOLUMES      if (amp!=-1)	sp->volume=(FLOAT_T)((amp) / 100.0);      else if (sf2flag)	sp->volume=(FLOAT_T)((sample_volume) / 255.0);      else	{	  /* Try to determine a volume scaling factor for the sample.	     This is a very crude adjustment, but things sound more	     balanced with it. Still, this should be a runtime option. */	  uint32 i, numsamps=sp->data_length/2;	  uint32 higher=0, highcount=0;	  int16 maxamp=0,a;	  int16 *tmp=(int16 *)sp->data;	  i = numsamps;	  while (i--)	    {	      a=*tmp++;	      if (a<0) a=-a;	      if (a>maxamp)		maxamp=a;	    }	  tmp=(int16 *)sp->data;	  i = numsamps;	  while (i--)	    {	      a=*tmp++;	      if (a<0) a=-a;	      if (a > 3*maxamp/4)		{		   higher += a;		   highcount++;		}	    }	  if (highcount) higher /= highcount;	  else higher = 10000;	  sp->volume = (32768.0 * 0.875) /  (double)higher ;	  ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * volume comp: %f", sp->volume);	}#else      if (amp!=-1)	sp->volume=(double)(amp) / 100.0;      else	sp->volume=1.0;#endif      sp->data_length /= 2; /* These are in bytes. Convert into samples. */      sp->loop_start /= 2;      sp->loop_end /= 2;      sp->data[sp->data_length] = sp->data[sp->data_length-1];      /* Then fractional samples */      sp->data_length <<= FRACTION_BITS;      sp->loop_start <<= FRACTION_BITS;      sp->loop_end <<= FRACTION_BITS;    /* trim off zero data at end */    {	int ls = sp->loop_start>>FRACTION_BITS;	int le = sp->loop_end>>FRACTION_BITS;	int se = sp->data_length>>FRACTION_BITS;	while (se > 1 && !sp->data[se-1]) se--;	if (le > se) le = se;	if (ls >= le) sp->modes &= ~MODES_LOOPING;	sp->loop_end = le<<FRACTION_BITS;	sp->data_length = se<<FRACTION_BITS;    }      /* Adjust for fractional loop points. This is a guess. Does anyone	 know what "fractions" really stands for? */      sp->loop_start |=	(fractions & 0x0F) << (FRACTION_BITS-4);      sp->loop_end |=	((fractions>>4) & 0x0F) << (FRACTION_BITS-4);      /* If this instrument will always be played on the same note,	 and it's not looped, we can resample it now. */      if (sp->note_to_use && !(sp->modes & MODES_LOOPING))	pre_resample(sp);#ifdef LOOKUP_HACK      /* Squash the 16-bit data into 8 bits. */      {	uint8 *gulp,*ulp;	int16 *swp;	int l=sp->data_length >> FRACTION_BITS;	gulp=ulp=safe_malloc(l+1);	swp=(int16 *)sp->data;	while(l--)	  *ulp++ = (*swp++ >> 8) & 0xFF;	free(sp->data);	sp->data=(sample_t *)gulp;      }#endif            if (strip_tail==1)	{	  /* Let's not really, just say we did. */	  ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Stripping tail");	  sp->data_length = sp->loop_end;	}    } /* end of sample loop */ } /* end of stereo layer loop */ } /* end of vlayer loop */  close_file(fp);  return headlp;}static int fill_bank(int dr, int b){  int i, errors=0;  ToneBank *bank=((dr) ? drumset[b] : tonebank[b]);  if (!bank)    {      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 	   "Huh. Tried to load instruments in non-existent %s %d",	   (dr) ? "drumset" : "tone bank", b);      return 0;    }  for (i=0; i<MAXPROG; i++)    {      if (bank->tone[i].layer==MAGIC_LOAD_INSTRUMENT)	{	  if (!(bank->tone[i].name))	    {	      ctl->cmsg(CMSG_WARNING, (b!=0) ? VERB_VERBOSE : VERB_NORMAL,		   "No instrument mapped to %s %d, program %d%s",		   (dr)? "drum set" : "tone bank", b, i, 		   (b!=0) ? "" : " - this instrument will not be heard");	      if (b!=0)		{		  /* Mark the corresponding instrument in the default		     bank / drumset for loading (if it isn't already) */		  if (!dr)		    {		      if (!(standard_tonebank.tone[i].layer))			standard_tonebank.tone[i].layer=			  MAGIC_LOAD_INSTRUMENT;		    }		  else		    {		      if (!(standard_drumset.tone[i].layer))			standard_drumset.tone[i].layer=			  MAGIC_LOAD_INSTRUMENT;		    }		}	      bank->tone[i].layer=0;	      errors++;	    }	  else if (!(bank->tone[i].layer=		     load_instrument(bank->tone[i].name, 			     	     bank->tone[i].font_type,				     (dr) ? 1 : 0,				     bank->tone[i].pan,				     bank->tone[i].amp,				     bank->tone[i].tuning,				     (bank->tone[i].note!=-1) ? 				       bank->tone[i].note :				       ((dr) ? i : -1),				     (bank->tone[i].strip_loop!=-1) ?				     bank->tone[i].strip_loop :				     ((dr) ? 1 : -1),				     (bank->tone[i].strip_envelope != -1) ? 				     bank->tone[i].strip_envelope :				     ((dr) ? 1 : -1),				     bank->tone[i].strip_tail,				     b,				     ((dr) ? i + 128 : i),				     bank->tone[i].sf_ix			    			 )))	    {	      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 		   "Couldn't load instrument %s (%s %d, program %d)",		   bank->tone[i].name,		   (dr)? "drum set" : "tone bank", b, i);	      errors++;	    }	  else	    { /* it's loaded now */		bank->tone[i].last_used = current_tune_number;		current_patch_memory += bank->tone[i].layer->size;		purge_as_required();		if (current_patch_memory > max_patch_memory) {	      		ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 		   		"Not enough memory to load instrument %s (%s %d, program %d)",		   		bank->tone[i].name,		   		(dr)? "drum set" : "tone bank", b, i);	      		errors++;	    		free_layer(bank->tone[i].layer);	    		bank->tone[i].layer=0;	    		bank->tone[i].last_used=-1;		}#if 0  	        if (check_for_rc()) {	    		free_layer(bank->tone[i].layer);	    		bank->tone[i].layer=0;	    		bank->tone[i].last_used=-1;			return 0;		}#endif	    }	}    }  return errors;}static void free_old_instruments(int how_old){  int i=MAXBANK;  while(i--)    {      if (tonebank[i])	free_old_bank(0, i, how_old);      if (drumset[i])	free_old_bank(1, i, how_old);    }}static void purge_as_required(void){  if (!max_patch_memory) return;  while (last_tune_purged < current_tune_number	&& current_patch_memory > max_patch_memory)    {	last_tune_purged++;	free_old_instruments(last_tune_purged);    }}int load_missing_instruments(void){  int i=MAXBANK,errors=0;  while (i--)    {      if (tonebank[i])	errors+=fill_bank(0,i);      if (drumset[i])	errors+=fill_bank(1,i);    }  current_tune_number++;  return errors;}void free_instruments(void){  int i=128;  while(i--)    {      if (tonebank[i])	free_bank(0,i);      if (drumset[i])	free_bank(1,i);    }}int set_default_instrument(char *name){  InstrumentLayer *lp;/*  if (!(lp=load_instrument(name, 0, -1, -1, -1, 0, 0, 0))) */  if (!(lp=load_instrument(name, FONT_NORMAL, 0, -1, -1, 0, -1, -1, -1, -1, 0, -1, -1)))    return -1;  if (default_instrument)    free_layer(default_instrument);  default_instrument=lp;  default_program=SPECIAL_PROGRAM;  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -