timidity/timidity.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 04 Oct 2009 02:54:48 +0000
changeset 421 de784f36729a
parent 416 67aaecd0610d
child 437 cd21b80e524f
permissions -rw-r--r--
Fixed bug #825

O.Sezer 2009-10-03 15:22:34 PDT

The following compiler warning

./timidity/timidity.c: In function 'Timidity_Init':
./timidity/timidity.c:298: warning: passing argument 1 of 'read_config_file'
discards qualifiers from pointer target type

.. showed that timidity needed some constification. Minor grunt work attached.
     1 /*
     2 
     3     TiMidity -- Experimental MIDI to WAVE converter
     4     Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
     5 
     6 	 This program is free software; you can redistribute it and/or modify
     7 	 it under the terms of the GNU General Public License as published by
     8     the Free Software Foundation; either version 2 of the License, or
     9 	 (at your option) any later version.
    10 
    11     This program is distributed in the hope that it will be useful,
    12     but WITHOUT ANY WARRANTY; without even the implied warranty of
    13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14 	 GNU General Public License for more details.
    15 
    16     You should have received a copy of the GNU General Public License
    17     along with this program; if not, write to the Free Software
    18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    19 
    20 */
    21 #include <stdio.h>
    22 #include <stdlib.h>
    23 #include <string.h>
    24 
    25 #include "SDL.h"
    26 #include "config.h"
    27 #include "common.h"
    28 #include "instrum.h"
    29 #include "playmidi.h"
    30 #include "readmidi.h"
    31 #include "output.h"
    32 #include "ctrlmode.h"
    33 #include "timidity.h"
    34 
    35 #include "tables.h"
    36 
    37 void (*s32tobuf)(void *dp, int32 *lp, int32 c);
    38 int free_instruments_afterwards=0;
    39 static char def_instr_name[256]="";
    40 
    41 int AUDIO_BUFFER_SIZE;
    42 resample_t *resample_buffer=NULL;
    43 int32 *common_buffer=NULL;
    44 int num_ochannels;
    45 
    46 #define MAXWORDS 10
    47 
    48 static int read_config_file(const char *name)
    49 {
    50   FILE *fp;
    51   char tmp[1024], *w[MAXWORDS], *cp;
    52   ToneBank *bank=0;
    53   int i, j, k, line=0, words;
    54   static int rcf_count=0;
    55 
    56   if (rcf_count>50)
    57    {
    58     ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
    59       "Probable source loop in configuration files");
    60     return (-1);
    61    }
    62 
    63   if (!(fp=open_file(name, 1, OF_VERBOSE)))
    64    return -1;
    65 
    66   while (fgets(tmp, sizeof(tmp), fp))
    67   {
    68     line++;
    69     w[words=0]=strtok(tmp, " \t\r\n\240");
    70     if (!w[0] || (*w[0]=='#')) continue;
    71     while (w[words] && (words < MAXWORDS))
    72       {
    73         w[++words]=strtok(0," \t\r\n\240");
    74         if (w[words] && w[words][0]=='#') break;
    75       }
    76     if (!strcmp(w[0], "map")) continue;
    77     if (!strcmp(w[0], "dir"))
    78     {
    79       if (words < 2)
    80        {
    81         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
    82           "%s: line %d: No directory given\n", name, line);
    83         return -2;
    84        }
    85       for (i=1; i<words; i++)
    86         add_to_pathlist(w[i]);
    87     }
    88   else if (!strcmp(w[0], "source"))
    89   {
    90     if (words < 2)
    91       {
    92         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
    93           "%s: line %d: No file name given\n", name, line);
    94         return -2;
    95      }
    96     for (i=1; i<words; i++)
    97       {
    98         rcf_count++;
    99       read_config_file(w[i]);
   100         rcf_count--;
   101       }
   102   }
   103       else if (!strcmp(w[0], "default"))
   104   {
   105     if (words != 2)
   106       {
   107         ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
   108         "%s: line %d: Must specify exactly one patch name\n",
   109           name, line);
   110         return -2;
   111       }
   112     strncpy(def_instr_name, w[1], 255);
   113     def_instr_name[255]='\0';
   114   }
   115     else if (!strcmp(w[0], "drumset"))
   116   {
   117     if (words < 2)
   118       {
   119         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
   120           "%s: line %d: No drum set number given\n", 
   121           name, line);
   122       return -2;
   123       }
   124     i=atoi(w[1]);
   125     if (i<0 || i>127)
   126      {
   127         ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
   128           "%s: line %d: Drum set must be between 0 and 127\n",
   129         name, line);
   130         return -2;
   131      }
   132     if (!drumset[i])
   133       {
   134         drumset[i]=safe_malloc(sizeof(ToneBank));
   135       memset(drumset[i], 0, sizeof(ToneBank));
   136      }
   137     bank=drumset[i];
   138   }
   139     else if (!strcmp(w[0], "bank"))
   140   {
   141     if (words < 2)
   142      {
   143         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
   144           "%s: line %d: No bank number given\n", 
   145         name, line);
   146         return -2;
   147      }
   148     i=atoi(w[1]);
   149     if (i<0 || i>127)
   150       {
   151         ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
   152           "%s: line %d: Tone bank must be between 0 and 127\n",
   153         name, line);
   154         return -2;
   155       }
   156     if (!tonebank[i])
   157      {
   158       tonebank[i]=safe_malloc(sizeof(ToneBank));
   159         memset(tonebank[i], 0, sizeof(ToneBank));
   160       }
   161     bank=tonebank[i];
   162   }
   163       else {
   164   if ((words < 2) || (*w[0] < '0' || *w[0] > '9'))
   165     {
   166      ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
   167         "%s: line %d: syntax error\n", name, line);
   168      return -2;
   169     }
   170   i=atoi(w[0]);
   171   if (i<0 || i>127)
   172     {
   173       ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
   174         "%s: line %d: Program must be between 0 and 127\n",
   175         name, line);
   176       return -2;
   177     }
   178   if (!bank)
   179     {
   180       ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
   181        "%s: line %d: Must specify tone bank or drum set "
   182         "before assignment\n",
   183         name, line);
   184      return -2;
   185     }
   186   if (bank->tone[i].name)
   187     free(bank->tone[i].name);
   188   strcpy((bank->tone[i].name=safe_malloc(strlen(w[1])+1)),w[1]);
   189   bank->tone[i].note=bank->tone[i].amp=bank->tone[i].pan=
   190     bank->tone[i].strip_loop=bank->tone[i].strip_envelope=
   191       bank->tone[i].strip_tail=-1;
   192 
   193   for (j=2; j<words; j++)
   194     {
   195       if (!(cp=strchr(w[j], '=')))
   196         {
   197     ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: bad patch option %s\n",
   198       name, line, w[j]);
   199     return -2;
   200         }
   201       *cp++=0;
   202       if (!strcmp(w[j], "amp"))
   203       {
   204     k=atoi(cp);
   205     if ((k<0 || k>MAX_AMPLIFICATION) || (*cp < '0' || *cp > '9'))
   206       {
   207        ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
   208           "%s: line %d: amplification must be between "
   209          "0 and %d\n", name, line, MAX_AMPLIFICATION);
   210        return -2;
   211       }
   212     bank->tone[i].amp=k;
   213         }
   214       else if (!strcmp(w[j], "note"))
   215         {
   216     k=atoi(cp);
   217     if ((k<0 || k>127) || (*cp < '0' || *cp > '9'))
   218       {
   219        ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
   220          "%s: line %d: note must be between 0 and 127\n",
   221           name, line);
   222         return -2;
   223       }
   224     bank->tone[i].note=k;
   225       }
   226      else if (!strcmp(w[j], "pan"))
   227       {
   228     if (!strcmp(cp, "center"))
   229       k=64;
   230     else if (!strcmp(cp, "left"))
   231       k=0;
   232     else if (!strcmp(cp, "right"))
   233       k=127;
   234     else
   235       k=((atoi(cp)+100) * 100) / 157;
   236     if ((k<0 || k>127) ||
   237        (k==0 && *cp!='-' && (*cp < '0' || *cp > '9')))
   238       {
   239        ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
   240          "%s: line %d: panning must be left, right, "
   241          "center, or between -100 and 100\n",
   242          name, line);
   243        return -2;
   244       }
   245     bank->tone[i].pan=k;
   246       }
   247      else if (!strcmp(w[j], "keep"))
   248       {
   249     if (!strcmp(cp, "env"))
   250       bank->tone[i].strip_envelope=0;
   251     else if (!strcmp(cp, "loop"))
   252       bank->tone[i].strip_loop=0;
   253     else
   254       {
   255         ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
   256           "%s: line %d: keep must be env or loop\n", name, line);
   257        return -2;
   258       }
   259       }
   260      else if (!strcmp(w[j], "strip"))
   261       {
   262     if (!strcmp(cp, "env"))
   263       bank->tone[i].strip_envelope=1;
   264     else if (!strcmp(cp, "loop"))
   265       bank->tone[i].strip_loop=1;
   266     else if (!strcmp(cp, "tail"))
   267       bank->tone[i].strip_tail=1;
   268     else
   269       {
   270        ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
   271          "%s: line %d: strip must be env, loop, or tail\n",
   272          name, line);
   273        return -2;
   274       }
   275       }
   276      else
   277       {
   278     ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: line %d: bad patch option %s\n",
   279       name, line, w[j]);
   280     return -2;
   281       }
   282     }
   283     }
   284    }
   285   if (ferror(fp))
   286    {
   287     ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't read from %s\n", name);
   288     close_file(fp);
   289     return -2;
   290    }
   291   close_file(fp);
   292   return 0;
   293 }
   294 
   295 int Timidity_Init(int rate, int format, int channels, int samples)
   296 {
   297   const char *env = getenv("TIMIDITY_CFG");
   298   if (!env || read_config_file(env)<0) {
   299     if (read_config_file(CONFIG_FILE)<0) {
   300       if (read_config_file(CONFIG_FILE_ETC)<0) {
   301         if (read_config_file(CONFIG_FILE_ETC_TIMIDITY)<0) {
   302           return(-1);
   303         }
   304       }
   305     }
   306   }
   307 
   308   if (channels < 1 || channels == 3 || channels == 5 || channels > 6) return(-1);
   309 
   310   num_ochannels = channels;
   311 
   312   /* Set play mode parameters */
   313   play_mode->rate = rate;
   314   play_mode->encoding = 0;
   315   if ( (format&0xFF) == 16 ) {
   316     play_mode->encoding |= PE_16BIT;
   317   }
   318   if ( (format&0x8000) ) {
   319     play_mode->encoding |= PE_SIGNED;
   320   }
   321   if ( channels == 1 ) {
   322     play_mode->encoding |= PE_MONO;
   323   } 
   324   switch (format) {
   325     case AUDIO_S8:
   326       s32tobuf = s32tos8;
   327       break;
   328     case AUDIO_U8:
   329       s32tobuf = s32tou8;
   330       break;
   331     case AUDIO_S16LSB:
   332       s32tobuf = s32tos16l;
   333       break;
   334     case AUDIO_S16MSB:
   335       s32tobuf = s32tos16b;
   336       break;
   337     case AUDIO_U16LSB:
   338       s32tobuf = s32tou16l;
   339       break;
   340     case AUDIO_U16MSB:
   341       s32tobuf = s32tou16b;
   342       break;
   343     default:
   344       ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Unsupported audio format");
   345       return(-1);
   346   }
   347   AUDIO_BUFFER_SIZE = samples;
   348 
   349   /* Allocate memory for mixing (WARNING:  Memory leak!) */
   350   resample_buffer = safe_malloc(AUDIO_BUFFER_SIZE*sizeof(resample_t)+100);
   351   common_buffer = safe_malloc(AUDIO_BUFFER_SIZE*num_ochannels*sizeof(int32));
   352 
   353   init_tables();
   354 
   355   if (ctl->open(0, 0)) {
   356     ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Couldn't open %s\n", ctl->id_name);
   357     return(-1);
   358   }
   359 
   360   if (!control_ratio) {
   361     control_ratio = play_mode->rate / CONTROLS_PER_SECOND;
   362     if(control_ratio<1)
   363       control_ratio=1;
   364     else if (control_ratio > MAX_CONTROL_RATIO)
   365       control_ratio=MAX_CONTROL_RATIO;
   366   }
   367   if (*def_instr_name)
   368     set_default_instrument(def_instr_name);
   369   return(0);
   370 }
   371 
   372 char timidity_error[1024] = "";
   373 const char *Timidity_Error(void)
   374 {
   375   return(timidity_error);
   376 }