Save This Page
Home » openjdk-7 » com.sun.media » sound » [javadoc | source]
    1   /*
    2    * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   package com.sun.media.sound;
   26   
   27   import java.io.UnsupportedEncodingException;
   28   import java.util.Arrays;
   29   
   30   import javax.sound.midi.Patch;
   31   
   32   /**
   33    * A tuning program container, for use with MIDI Tuning.
   34    * See: http://www.midi.org
   35    *
   36    * @author Karl Helgason
   37    */
   38   public class SoftTuning {
   39   
   40       private String name = null;
   41       private double[] tuning = new double[128];
   42       private Patch patch = null;
   43   
   44       public SoftTuning() {
   45           name = "12-TET";
   46           for (int i = 0; i < tuning.length; i++)
   47               tuning[i] = i * 100;
   48       }
   49   
   50       public SoftTuning(byte[] data) {
   51           for (int i = 0; i < tuning.length; i++)
   52               tuning[i] = i * 100;
   53           load(data);
   54       }
   55   
   56       public SoftTuning(Patch patch) {
   57           this.patch = patch;
   58           name = "12-TET";
   59           for (int i = 0; i < tuning.length; i++)
   60               tuning[i] = i * 100;
   61       }
   62   
   63       public SoftTuning(Patch patch, byte[] data) {
   64           this.patch = patch;
   65           for (int i = 0; i < tuning.length; i++)
   66               tuning[i] = i * 100;
   67           load(data);
   68       }
   69   
   70       private boolean checksumOK(byte[] data) {
   71           int x = data[1] & 0xFF;
   72           for (int i = 2; i < data.length - 2; i++)
   73               x = x ^ (data[i] & 0xFF);
   74           return (data[data.length - 2] & 0xFF) == (x & 127);
   75       }
   76   
   77       /*
   78       private boolean checksumOK2(byte[] data) {
   79           int x = data[1] & 0xFF; // 7E
   80           x = x ^ (data[2] & 0xFF); // <device ID>
   81           x = x ^ (data[4] & 0xFF); // nn
   82           x = x ^ (data[5] & 0xFF); // tt
   83           for (int i = 22; i < data.length - 2; i++)
   84               x = x ^ (data[i] & 0xFF);
   85           return (data[data.length - 2] & 0xFF) == (x & 127);
   86       }
   87        */
   88       public void load(byte[] data) {
   89           // Universal Non-Real-Time / Real-Time SysEx
   90           if ((data[1] & 0xFF) == 0x7E || (data[1] & 0xFF) == 0x7F) {
   91               int subid1 = data[3] & 0xFF;
   92               switch (subid1) {
   93               case 0x08: // MIDI Tuning Standard
   94                   int subid2 = data[4] & 0xFF;
   95                   switch (subid2) {
   96                   case 0x01: // BULK TUNING DUMP (NON-REAL-TIME)
   97                   {
   98                       // http://www.midi.org/about-midi/tuning.shtml
   99                       //if (!checksumOK2(data))
  100                       //    break;
  101                       try {
  102                           name = new String(data, 6, 16, "ascii");
  103                       } catch (UnsupportedEncodingException e) {
  104                           name = null;
  105                       }
  106                       int r = 22;
  107                       for (int i = 0; i < 128; i++) {
  108                           int xx = data[r++] & 0xFF;
  109                           int yy = data[r++] & 0xFF;
  110                           int zz = data[r++] & 0xFF;
  111                           if (!(xx == 127 && yy == 127 && zz == 127))
  112                               tuning[i] = 100.0 *
  113                                       (((xx * 16384) + (yy * 128) + zz) / 16384.0);
  114                       }
  115                       break;
  116                   }
  117                   case 0x02: // SINGLE NOTE TUNING CHANGE (REAL-TIME)
  118                   {
  119                       // http://www.midi.org/about-midi/tuning.shtml
  120                       int ll = data[6] & 0xFF;
  121                       int r = 7;
  122                       for (int i = 0; i < ll; i++) {
  123                           int kk = data[r++] & 0xFF;
  124                           int xx = data[r++] & 0xFF;
  125                           int yy = data[r++] & 0xFF;
  126                           int zz = data[r++] & 0xFF;
  127                           if (!(xx == 127 && yy == 127 && zz == 127))
  128                               tuning[kk] = 100.0*(((xx*16384) + (yy*128) + zz)/16384.0);
  129                       }
  130                       break;
  131                   }
  132                   case 0x04: // KEY-BASED TUNING DUMP (NON-REAL-TIME)
  133                   {
  134                       // http://www.midi.org/about-midi/tuning_extens.shtml
  135                       if (!checksumOK(data))
  136                           break;
  137                       try {
  138                           name = new String(data, 7, 16, "ascii");
  139                       } catch (UnsupportedEncodingException e) {
  140                           name = null;
  141                       }
  142                       int r = 23;
  143                       for (int i = 0; i < 128; i++) {
  144                           int xx = data[r++] & 0xFF;
  145                           int yy = data[r++] & 0xFF;
  146                           int zz = data[r++] & 0xFF;
  147                           if (!(xx == 127 && yy == 127 && zz == 127))
  148                               tuning[i] = 100.0*(((xx*16384) + (yy*128) + zz)/16384.0);
  149                       }
  150                       break;
  151                   }
  152                   case 0x05: // SCALE/OCTAVE TUNING DUMP, 1 byte format
  153                              // (NON-REAL-TIME)
  154                   {
  155                       // http://www.midi.org/about-midi/tuning_extens.shtml
  156                       if (!checksumOK(data))
  157                           break;
  158                       try {
  159                           name = new String(data, 7, 16, "ascii");
  160                       } catch (UnsupportedEncodingException e) {
  161                           name = null;
  162                       }
  163                       int[] octave_tuning = new int[12];
  164                       for (int i = 0; i < 12; i++)
  165                           octave_tuning[i] = (data[i + 23] & 0xFF) - 64;
  166                       for (int i = 0; i < tuning.length; i++)
  167                           tuning[i] = i * 100 + octave_tuning[i % 12];
  168                       break;
  169                   }
  170                   case 0x06: // SCALE/OCTAVE TUNING DUMP, 2 byte format
  171                              // (NON-REAL-TIME)
  172                   {
  173                       // http://www.midi.org/about-midi/tuning_extens.shtml
  174                       if (!checksumOK(data))
  175                           break;
  176                       try {
  177                           name = new String(data, 7, 16, "ascii");
  178                       } catch (UnsupportedEncodingException e) {
  179                           name = null;
  180                       }
  181                       double[] octave_tuning = new double[12];
  182                       for (int i = 0; i < 12; i++) {
  183                           int v = (data[i * 2 + 23] & 0xFF) * 128
  184                                   + (data[i * 2 + 24] & 0xFF);
  185                           octave_tuning[i] = (v / 8192.0 - 1) * 100.0;
  186                       }
  187                       for (int i = 0; i < tuning.length; i++)
  188                           tuning[i] = i * 100 + octave_tuning[i % 12];
  189                       break;
  190                   }
  191                   case 0x07: // SINGLE NOTE TUNING CHANGE (NON
  192                              // REAL-TIME/REAL-TIME) (BANK)
  193                       // http://www.midi.org/about-midi/tuning_extens.shtml
  194                       int ll = data[7] & 0xFF;
  195                       int r = 8;
  196                       for (int i = 0; i < ll; i++) {
  197                           int kk = data[r++] & 0xFF;
  198                           int xx = data[r++] & 0xFF;
  199                           int yy = data[r++] & 0xFF;
  200                           int zz = data[r++] & 0xFF;
  201                           if (!(xx == 127 && yy == 127 && zz == 127))
  202                               tuning[kk] = 100.0
  203                                       * (((xx*16384) + (yy*128) + zz) / 16384.0);
  204                       }
  205                       break;
  206                   case 0x08: // scale/octave tuning 1-byte form (Non
  207                              // Real-Time/REAL-TIME)
  208                   {
  209                       // http://www.midi.org/about-midi/tuning-scale.shtml
  210                       int[] octave_tuning = new int[12];
  211                       for (int i = 0; i < 12; i++)
  212                           octave_tuning[i] = (data[i + 8] & 0xFF) - 64;
  213                       for (int i = 0; i < tuning.length; i++)
  214                           tuning[i] = i * 100 + octave_tuning[i % 12];
  215                       break;
  216                   }
  217                   case 0x09: // scale/octave tuning 2-byte form (Non
  218                              // Real-Time/REAL-TIME)
  219                   {
  220                       // http://www.midi.org/about-midi/tuning-scale.shtml
  221                       double[] octave_tuning = new double[12];
  222                       for (int i = 0; i < 12; i++) {
  223                           int v = (data[i * 2 + 8] & 0xFF) * 128
  224                                   + (data[i * 2 + 9] & 0xFF);
  225                           octave_tuning[i] = (v / 8192.0 - 1) * 100.0;
  226                       }
  227                       for (int i = 0; i < tuning.length; i++)
  228                           tuning[i] = i * 100 + octave_tuning[i % 12];
  229                       break;
  230                   }
  231                   default:
  232                       break;
  233                   }
  234               }
  235           }
  236       }
  237   
  238       // am: getTuning(int) is more effective.
  239       // currently getTuning() is used only by tests
  240       public double[] getTuning() {
  241           return Arrays.copyOf(tuning, tuning.length);
  242       }
  243   
  244       public double getTuning(int noteNumber) {
  245           return tuning[noteNumber];
  246       }
  247   
  248       public Patch getPatch() {
  249           return patch;
  250       }
  251   
  252       public String getName() {
  253           return name;
  254       }
  255   
  256       public void setName(String name) {
  257           this.name = name;
  258       }
  259   }

Save This Page
Home » openjdk-7 » com.sun.media » sound » [javadoc | source]