konsumer/Protracker

View on GitHub
formats/xm.js

Summary

Maintainability
F
1 wk
Test Coverage
module.exports = function(Protracker){
  Protracker.prototype.parseXM = function()
  {
    console.log('Parse FT2 file');
    console.log('unfinished');
    this.stop();
    var i,j,d;

    if (!this.buffer) return false;
    //this.buffer=new Uint8Array(this.response);
    //console.debug(this.buffer);

    /*
     0 17 char ID text 'Extended module: '
     17 20 char Module name 'Bellissima 99 (mix) '
     37 1 byte 0x1A 1A
     38 20 char Tracker name 'FastTracker v2.00 '
     58 2 word Version number 04 01
     60 4 dword Header size 14 01 00 00
     64 2 word Song length 3E 00 (1..256)
     66 2 word Restart position 00 00
     68 2 word Number of channels 20 00 (0..32/64)
     70 2 word Number of patterns 37 00 (1..256)
     72 2 word Number of instruments 12 00 (0..128)
     74 2 word Flags 01 00
     76 2 word Default tempo 05 00
     78 2 word Default BPM 98 00
     80 ? byte Pattern order table 00 01 02 03 ...
     */
    var data = {
      id:            {start:0,length:16,decode:true}
      ,name:          {start:17,length:20,decode:true}
      //,'0x1A':        {start:37,length:1,decode:true}
      ,tracker:       {start:38,length:17,decode:true}
      ,version:       {start:58,length:1}
      ,songlen:       {start:64,length:1}
      ,channels:      {start:68,length:1}
      ,nbInstruments: {start:70,length:1}
      ,nbPatterns:    {start:72,length:1}
      ,tempo:         {start:76,length:1}
      ,bpm:           {start:78,length:1}
      ,patternOrder:  {start:80,lengthData:'songlen'}
    };

    for(d in data)
    {
      var s   = data[d];
      var r   = '';
      var a   = new Array();
      var len = s.lengthData ? parseInt(data[s.lengthData]) : s.length;

      for(i=0;i<len;i++)
      {
        var val = this.buffer[s.start+i];
        if(s.decode){
          r+=String.fromCharCode(val);
        }else if(s.lengthData)
        {
          a.push(val);
          r = a;
        }else{
          r+=parseInt(val);
        }
      }
      data[d]=r;
    }
    var o = 80+parseInt(data.songlen);
    data.restart = this.buffer[o];

    console.debug(data);
    this.stop();
    return true;

    this.channels   = data.channels;
    this.songlen    = data.patternOrder.length;
    this.title      = data.name;
    this.samples    = data.nbInstruments;
    this.vu         = new Array();

    for(i=0;i<this.channels;i++) this.vu[i]=0.0;

    for(i=0;i<this.samples;i++) {
      var st=20+i*30;
      j=0;
      while(this.buffer[st+j] && j<22) {
        this.sample[i].name+=
          ((this.buffer[st+j]>0x1f) && (this.buffer[st+j]<0x7f)) ?
            (String.fromCharCode(this.buffer[st+j])) :
            (" ");
        j++;
      }


      console.log(i,this.sample[i].name);

      this.sample[i].length=2*(this.buffer[st+22]*256 + this.buffer[st+23]);
      this.sample[i].finetune=this.buffer[st+24];
      if (this.sample[i].finetune > 7) this.sample[i].finetune=this.sample[i].finetune-16;
      this.sample[i].volume=this.buffer[st+25];
      this.sample[i].loopstart=2*(this.buffer[st+26]*256 + this.buffer[st+27]);
      this.sample[i].looplength=2*(this.buffer[st+28]*256 + this.buffer[st+29]);
      if (this.sample[i].looplength==2) this.sample[i].looplength=0;
      if (this.sample[i].loopstart>this.sample[i].length) {
        this.sample[i].loopstart=0;
        this.sample[i].looplength=0;
      }
    }

    return true;


    if (this.buffer[951] != 127) this.repeatpos=this.buffer[951];
    for(i=0;i<128;i++) {
      this.patterntable[i]=this.buffer[952+i];
      if (this.patterntable[i] > this.patterns) this.patterns=this.patterntable[i];
    }
    this.patterns+=1;
    var patlen=4*64*this.channels;

    this.pattern=new Array();
    this.note=new Array();
    this.patterns=parseInt(this.buffer[72]+this.buffer[72]);
    for(i=0;i<this.patterns;i++) {
      this.pattern[i]=new Uint8Array(patlen);
      this.note[i]=new Uint8Array(this.channels*64);
      for(j=0;j<patlen;j++) this.pattern[i][j]=this.buffer[1084+i*patlen+j];
      for(j=0;j<64;j++) for(c=0;c<this.channels;c++) {
        this.note[i][j*this.channels+c]=0;
        var n=(this.pattern[i][j*4*this.channels+c*4]&0x0f)<<8 | this.pattern[i][j*4*this.channels+c*4+1];
        for(var np=0; np<this.baseperiodtable.length; np++)
          if (n==this.baseperiodtable[np]) this.note[i][j*this.channels+c]=np;
      }
    }

    console.debug(this)

    return true;
    var sst=1084+this.patterns*patlen;
    for(i=0;i<this.samples;i++) {
      this.sample[i].data=new Float32Array(this.sample[i].length);
      for(j=0;j<this.sample[i].length;j++) {
        var q=this.buffer[sst+j];
        if (q<128) {
          q=q/128.0;
        } else {
          q=((q-128)/128.0)-1.0;
        }

        this.sample[i].data[j]=q;
      }
      sst+=this.sample[i].length;
    }

    this.ready=true;
    this.loading=false;
    this.buffer=0;

    if (this.context) this.lowpassNode.frequency.value=28867;

    this.onReady();
    return true;
  };
};