Team Ai
Datasetpublic

hschumann2/TempleOS-Source-Code

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes832downloads
SndMath.txt250 linesDownload Raw Back to Snd
1 2#help_index "Snd/Math;Math"3public F64 Saw(F64 t,F64 period)4{//Sawtooth. 0.0 - 1.0 think "(Sin+1)/2"5  if (period) {6    if (t>=0.0)7      return t%period/period;8    else9      return 1.0+t%period/period;10  } else11    return 0.0;12}13 14public F64 FullSaw(F64 t,F64 period)15{//Plus&Minus Sawtooth. 1.0 - -1.0 think "Sin"16  if (period) {17    if (t>=0.0)18      return 2.0*(t%period/period)-1.0;19    else20      return 2.0*(t%period/period)+1.0;21  } else22    return 0.0;23}24 25public F64 Caw(F64 t,F64 period)26{//Cawtooth. 1.0 - 0.0 think "(Cos+1)/2"27  if (period) {28    if (t>=0.0)29      return 1.0-t%period/period;30    else31      return -(t%period)/period;32  } else33    return 1.0;34}35 36public F64 FullCaw(F64 t,F64 period)37{//Plus&Minus Cawtooth. 1.0 - -1.0 think "Cos"38  if (period) {39    if (t>=0.0)40      return -2.0*(t%period/period)+1.0;41    else42      return -2.0*(t%period/period)-1.0;43  } else44    return 1.0;45}46 47public F64 Tri(F64 t,F64 period)48{//Triangle waveform. 0.0 - 1.0 - 0.049  if (period) {50    t=2.0*(Abs(t)%period)/period;51    if (t<=1.0)52      return t;53    else54      return 2.0-t;55  } else56    return 0.0;57}58 59public F64 FullTri(F64 t,F64 period)60{//Plus&Minus Triangle waveform. 0.0 - 1.0 - 0.0 - -1.0 -0.061  if (period) {62    t=4.0*(t%period)/period;63    if (t<=-1.0) {64      if (t<=-3.0)65        return t+4.0;66      else67        return -2.0-t;68    } else {69      if (t<=1.0)70        return t;71      else if (t<=3.0)72        return 2.0-t;73      else74        return t-4.0;75    }76  } else77    return 0.0;78}79 80#help_index "Snd/Math"81 82public I8 Note2Ona(I64 note,I64 octave=4)83{//Note to ona. Mid C is ona=51, note=3 and octave=4.84  if (note<3)85    return (octave+1)*12+note;86  else87    return octave*12+note;88}89 90public I8 Ona2Note(I8 ona)91{//Ona to note in octave. Mid C is ona=51, note=3 and octave=4.92  return ona%12;93}94 95public I8 Ona2Octave(I8 ona)96{//Ona to octave. Mid C is ona=51, note=3 and octave=4.97  I64 note=ona%12,octave=ona/12;98  if (note<3)99    return octave-1;100  else101    return octave;102}103 104F64 SinPhaseCont(F64 last_y,F64 last_dydt,105                    F64 current_amp,F64 phase_offset)106{//Next sample of sin waveform.107  F64 phase;108  phase=last_y/current_amp;109  if (phase>1.0) phase=1.0;110  if (phase<-1.0) phase=-1.0;111  if (last_dydt<0)112    phase=pi-ASin(phase);113  else114    phase=ASin(phase);115  return phase-phase_offset;116}117 118public CSndWaveCtrl *SndWaveCtrlNew(I64 sample_rate=8000,I64 sample_bits=24,119  I64 channels=2,CTask *mem_task=NULL)120{//MAlloc ctrl struct for generating waveforms.121  CSndWaveCtrl *swc=CAlloc(sizeof(CSndWaveCtrl),mem_task);122  swc->freq_multiplier=1.0;123  swc->amp_multiplier=1.0;124  swc->sample_rate=sample_rate;125  swc->sample_bits=sample_bits;126  swc->channels=channels;127  swc->last_dydt=1.0;128  return swc;129}130 131public U0 SndWaveCtrlDel(CSndWaveCtrl *swc)132{//Free waveform ctrl.133  Free(swc);134}135 136#define WF_NULL                 0137#define WF_SQUARE               1138#define WF_SINE                 2139#define WF_TRI                  3140#define WF_SAWTOOTH             4141#define WF_NOISE                5142#define WF_WAVEFORMS_NUM        6143 144public U0 SndWaveAddBuf(CSndWaveCtrl *swc,U8 *buf,I64 num_samples,145  F64 _freq,I64 _waveform=WF_SQUARE,F64 _amp=1.0,F64 _left=1.0, F64 _right=1.0)146{//Add waveform to buffer.147//num_samples is multiplied by channels to get buf_len.148  //left,right range from 0.0-1.0149  //Supports 16,24 and 32 bits150  I64 reg i,reg j,reg k;151  F64 a,f,amp,reg phase;152  if (!swc) return;153  _freq*=swc->freq_multiplier;154  _amp*=swc->amp_multiplier;155  if (!_freq||!_amp) {156    swc->last_y=swc->phase=0;157    swc->last_dydt=1.0;158  } else {159    phase=swc->phase;160    i=0;161    amp=Min(I32_MAX,I32_MAX*_amp);162    f=2*pi/swc->sample_rate*_freq;163    switch (_waveform) {164      case WF_NOISE:165        a=2.0/pi*amp;166        break;167      case WF_SAWTOOTH:168        a=amp/pi;169        break;170      case WF_SINE:171        phase=SinPhaseCont(swc->last_y,swc->last_dydt,amp,0.0);172        break;173    }174    while (phase<0)175      phase+=2*pi;176    while (phase>=2*pi)177      phase-=2*pi;178    num_samples*=swc->channels;179    while (i<num_samples) {180      switch (_waveform) {181        case WF_SQUARE:182          if (phase>=pi)183            j=-amp;184          else185            j=amp;186          break;187        case WF_SINE:188          j=amp*Sin(phase);189          break;190        case WF_TRI:191          if (phase>=pi) {192            swc->last_y=swc->next_y;193            swc->next_y=-amp*Sign(swc->last_y)+.00001;194            phase-=pi;195          }196          j=(swc->last_y*(pi-phase)+swc->next_y*phase)/pi;197          break;198        case WF_SAWTOOTH:199          j=a*(phase-pi);200          break;201        case WF_NOISE:202          if (phase<pi) {203            if (phase<f) {204              swc->last_y=swc->next_y;205              swc->next_y=a*RandI16/U16_MAX;206            }207            j=swc->last_y*(pi-phase)+swc->next_y*phase;208          } else {209            if (phase-pi<f) {210              swc->last_y=swc->next_y;211              swc->next_y=a*RandI16/U16_MAX;212            }213            j=swc->last_y*(2.0*pi-phase)+swc->next_y*(phase-pi);214          }215          break;216      }217//left channel218      k=j*_left;219      if (swc->sample_bits==16) {220        k>>=16;221        buf(I16 *)[i++]+=k;222      } else {223        if (swc->sample_bits==24)224          k&=0xFFFFFF00;225        buf(I32 *)[i++]+=k;226      }227//right channel228      if (swc->channels==2) {229        k=j*_right;230        if (swc->sample_bits==16) {231          k>>=16;232          buf(I16 *)[i++]+=k;233        } else {234          if (swc->sample_bits==24)235            k&=0xFFFFFF00;236          buf(I32 *)[i++]+=k;237        }238      }239      phase+=f;240      while (phase>=2*pi)241        phase-=2*pi;242    }243    if (_waveform==WF_SINE) {244      swc->last_y=amp*Sin(phase);245      swc->last_dydt=Cos(phase);246    }247    swc->phase=phase;248  }249}250