home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Exec 3 / CD_Magazyn_EXEC_nr_3.iso / Recent / mus / play / DelfSF.lha / DelfSF / src / main.c < prev    next >
C/C++ Source or Header  |  2000-07-19  |  11KB  |  333 lines

  1. /*****************************************************************************
  2.  
  3.     DelfSF - sndfile player for Delfina DSP
  4.     Copyright (C) 2000  Michael Henke
  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  
  20. *****************************************************************************/
  21.  
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <math.h>
  26. #include <libraries/reqtools.h>
  27. #ifndef off_t
  28. #define off_t size_t
  29. #endif
  30. #include <libraries/sndfile.h>
  31. #include <proto/exec.h>
  32. #include <proto/dos.h>
  33. #include <proto/reqtools.h>
  34. #include <proto/sndfile.h>
  35.  
  36.  
  37. /* functions in delf.c */
  38. extern int StartDelfina(unsigned int rate, unsigned int channels, LONG volume);
  39. extern void StopDelfina(void);
  40.  
  41. /* number of samples per buffer */
  42. /* note: must be equal to DELFINA_SAMPLES in delf.c !!! */
  43. #define BUFFER_SAMPLES      2048
  44.  
  45. /* number of buffers (segments in ringbuffer) */
  46. #define NUM_BUFFERS         44
  47.  
  48.  
  49.  
  50.  
  51. static char version[]="$VER: DelfSF 0.2 (Wed 19-Jul-2000)";
  52. static char template[]=
  53.  "FILES/M,-N=NOPLAY/S,-NT=NOTIMER/S,-VOL=VOLUME/K/N,"
  54.  "-R=RATE/K/N,-B=BITS/K/N,-C=CHANNELS/K/N,-BS=BYTESWAP/S";
  55.  
  56. static char *format1[9]=
  57.     {"<noname>","WAV","AIFF","AU","AU_LE","RAW","PAF","SVX","NIST"};
  58. static char *format2[14]=
  59.     {"<noname>","PCM","FLOAT","ULAW","ALAW","IMA_ADPCM","MS_ADPCM",
  60.      "PCM_BE","PCM_LE","PCM_S8","PCM_U8","SVX_FIB","SVX_EXP","GSM610"};
  61.  
  62. struct loadbuf {
  63.     struct loadbuf *next;
  64.     short *data;
  65. };
  66.  
  67. struct loadbuf *buf_read, *buf_play;
  68. long buffers_filled, buffers_played, pause;
  69.     
  70.  
  71.  
  72.  
  73. struct Library *SndFileBase=NULL;
  74. struct ReqToolsBase *ReqToolsBase=NULL;
  75.  
  76. static struct loadbuf bufstruct[NUM_BUFFERS];
  77. static short bufmem[NUM_BUFFERS*BUFFER_SAMPLES*2];
  78.  
  79. static struct RDArgs *rdargs;
  80. static LONG args[8]={0,0,0,0,0,0,0,0};
  81. static LONG noplay, notimer, volume=100, raw_bits=0, raw_chan=0, raw_rate=0;
  82. static LONG raw_bs=0, ende=0, i, playraw=0, read_eof, taskpri, samples;
  83. static char **files_pt, *filename, rtfilename[128], *f1, *f2;
  84. static SNDFILE *sndfile;
  85. static SF_INFO sfi;
  86. static struct rtFileRequester *rtfilereq=NULL;
  87. static struct rtFileList *rtfilelist=NULL, *rtfilelist_curr=NULL;
  88. static BPTR lock_newdir=NULL, lock_olddir=NULL;
  89. static struct Task *mytask;
  90. static ULONG sigs, prev_print, curr_print;
  91. static double duration;
  92. static int rc=0;
  93.  
  94.  
  95.  
  96.  
  97.  
  98. /* this function is just here to make the code slightly shorter... */
  99. /* fills the current read buffer, increments buffers_filled and */
  100. /* advances the buffer pointer; sets the read_eof flag */
  101. static void fillBuffer(void)
  102. {
  103.     LONG r;
  104.     short *pt;
  105.     if((r=SF_ReadShort(sndfile,buf_read->data,(size_t)samples))>0)
  106.     {
  107.         pt=buf_read->data+r;
  108.         for(r=samples-r;r>0;r--) (*pt++)=0;
  109.         pt=buf_read->data;
  110.         if(sfi.pcmbitwidth==8) for(r=samples;r>0;r--) (*pt++)<<=8;
  111.         buffers_filled++;
  112.         buf_read=buf_read->next;
  113.     }
  114.     else read_eof++;
  115. }
  116.  
  117.  
  118.  
  119.  
  120. int main(void)
  121. {
  122.     rdargs=ReadArgs(template,args,NULL);
  123.     files_pt=(char**)args[0];
  124.     noplay=args[1];
  125.     notimer=args[2];
  126.     if(args[3]) volume=(*(LONG*)args[3]);
  127.     if(volume<0) volume=0; else if(volume>200) volume=200;
  128.     if(args[4]) {raw_rate=(*(LONG*)args[4]); playraw++;}
  129.     if(args[5]) {raw_bits=(*(LONG*)args[5]); playraw++;}
  130.     if(args[6]) {raw_chan=(*(LONG*)args[6]); playraw++;}
  131.     raw_bs=args[7]; if(raw_bs) playraw++;
  132.  
  133.     printf("\33[1m%s by Smack/Infect!\33[0m\n",&version[6]);
  134.  
  135.     if(!(SndFileBase=OpenLibrary("sndfile.library",1)))
  136.     {
  137.         printf("**unable to open sndfile.library v1\n");
  138.         rc=20;
  139.         goto exit_clean;
  140.     }
  141.  
  142.     mytask=FindTask(NULL);
  143.  
  144.     for(i=0;i<NUM_BUFFERS;i++)
  145.     {
  146.         bufstruct[i].next= &bufstruct[i+1];
  147.         bufstruct[i].data= &bufmem[i*2*BUFFER_SAMPLES];
  148.     }
  149.     bufstruct[NUM_BUFFERS-1].next= &bufstruct[0];
  150.  
  151.     if(!files_pt)
  152.     {
  153.         if((ReqToolsBase=(struct ReqToolsBase*)OpenLibrary("reqtools.library",38)))
  154.         {
  155.             if(!(rtfilereq=rtAllocRequest(RT_FILEREQ,NULL)))
  156.             {
  157.                 rc=10;
  158.                 goto exit_clean;
  159.             }
  160.         }
  161.         else
  162.         {
  163.             rc=5;
  164.             goto exit_clean;
  165.         }
  166.     }
  167. next_filereq:
  168.     if(rtfilereq)
  169.     {
  170.         rtfilelist=rtFileRequest( rtfilereq, &rtfilename[0],
  171.                                   "DelfSF: select audio files",
  172.                                   RTFI_Flags, FREQF_MULTISELECT|FREQF_PATGAD,
  173.                                   TAG_DONE );
  174.         if(rtfilelist)
  175.         {
  176.             rtfilelist_curr=rtfilelist;
  177.             if(rtfilereq->Dir)
  178.             {
  179.                 lock_newdir=Lock(rtfilereq->Dir,SHARED_LOCK);
  180.                 lock_olddir=CurrentDir(lock_newdir);
  181.             }
  182.         }
  183.         else goto exit_clean;
  184.     }
  185.  
  186.     do
  187.     {
  188.         if(rtfilelist)
  189.         {
  190.             if(rtfilelist_curr)
  191.             {
  192.                 filename=rtfilelist_curr->Name;
  193.                 rtfilelist_curr=rtfilelist_curr->Next;
  194.             }
  195.             else filename=NULL;
  196.         }
  197.         else filename=(*files_pt++);
  198.         if(!filename) break;
  199.         printf("\n  file: %s\n",filename);
  200.         sfi.samplerate=(raw_rate?raw_rate:44100);
  201.         sfi.pcmbitwidth=(raw_bits?raw_bits:16);
  202.         sfi.channels=(raw_chan?raw_chan:2);
  203.         if(raw_bits==8) i=SF_FORMAT_PCM_S8;
  204.         else if(raw_bs) i=SF_FORMAT_PCM_LE; else i=SF_FORMAT_PCM_BE;
  205.         sfi.format=i|SF_FORMAT_RAW;
  206.         if((sndfile=SF_OpenRead(filename,&sfi)))
  207.         {
  208.             i=(LONG)((sfi.format>>16)&0x7fff);
  209.             f1=format1[(i>=(sizeof(format1)/sizeof(char*)))?0:i];
  210.             i=(LONG)(sfi.format&0xffff);
  211.             f2=format2[(i>=(sizeof(format2)/sizeof(char*)))?0:i];
  212.             printf("  type: %s %s, %d Hz, %d bits, %d channel%s\n",f1,f2,
  213.                     sfi.samplerate,sfi.pcmbitwidth,sfi.channels,
  214.                     ((sfi.channels==1)?"":"s") );
  215.             duration=(double)sfi.samples/(double)sfi.samplerate;
  216.             printf("  time: %02d min %06.3f sec\n",
  217.                     (int)(duration/60.0),fmod(duration,60.0) );
  218.             if(!noplay)
  219.             {
  220.                 if(!playraw && ((sfi.format&SF_FORMAT_TYPEMASK)==SF_FORMAT_RAW))
  221.                 {
  222.                     printf("**raw file will not be played\n"
  223.                            "  (must specify RATE, BITS, CHANNELS and/or BYTESWAP options)\n");
  224.                 }
  225.                 else if(sfi.channels>2)
  226.                 {
  227.                     printf("**unsupported number of channels\n");
  228.                 }
  229.                 else
  230.                 {
  231.                     pause=0;
  232.                     read_eof=0;
  233.                     buffers_filled=buffers_played=0;
  234.                     prev_print=curr_print=0;
  235.                     buf_read=buf_play= &bufstruct[0];
  236.                     samples=BUFFER_SAMPLES*sfi.channels;
  237.                     fillBuffer();
  238.                     fillBuffer();  /* fill two buffers for StartDelfina() */
  239.                     fillBuffer();
  240.                     if(StartDelfina(sfi.samplerate,sfi.channels,volume))
  241.                     {
  242.                         printf("  playing..."); fflush(stdout);
  243.                         taskpri=SetTaskPri(mytask,9);
  244.                         while(1)
  245.                         {
  246.                             sigs=CheckSignal(SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F);
  247.                             if(sigs&SIGBREAKF_CTRL_C)
  248.                             {
  249.                                 printf(" break CTRL-C\n");
  250.                                 break;
  251.                             }
  252.                             if(sigs&SIGBREAKF_CTRL_D)
  253.                             {
  254.                                 ende=1;
  255.                                 printf(" break CTRL-D\n");
  256.                                 break;
  257.                             }
  258.                             if(sigs&SIGBREAKF_CTRL_E)
  259.                             {
  260.                                 if(pause)
  261.                                 {
  262.                                     pause=0;
  263.                                     printf("\n  playing...");
  264.                                 }
  265.                                 else
  266.                                 {
  267.                                     pause=1;
  268.                                     printf(" pause");
  269.                                 }
  270.                                 fflush(stdout);
  271.                             }
  272.                             if(sigs&SIGBREAKF_CTRL_F)
  273.                             {
  274.                                 pause++; i=10;
  275.                                 while((buffers_filled>0) && (i-- >0))
  276.                                 {
  277.                                     buf_play=buf_play->next;
  278.                                     buffers_filled--;
  279.                                     buffers_played++;
  280.                                 }
  281.                                 pause--;
  282.                             }
  283.                             if(!read_eof && (buffers_filled<NUM_BUFFERS)) fillBuffer();
  284.                             else
  285.                             {
  286.                                 if(read_eof && (buffers_filled==0)) break;
  287.                                 if(!notimer)
  288.                                 {
  289.                                     curr_print=(buffers_played*BUFFER_SAMPLES)/sfi.samplerate;
  290.                                     if(prev_print!=curr_print)
  291.                                     {
  292.                                         prev_print=curr_print;
  293.                                         printf("\r  playing... (%02d:%02d)",
  294.                                             curr_print/60, curr_print%60);
  295.                                         fflush(stdout);
  296.                                     }
  297.                                 }
  298.                                 Delay(1);
  299.                             }
  300.                         }
  301.                         SetTaskPri(mytask,taskpri);
  302.                     }
  303.                     StopDelfina();
  304.                     if(read_eof) printf(" done.\n");
  305.                 }
  306.             }
  307.             SF_Close(sndfile);
  308.         }
  309.         else
  310.         {
  311.             printf("**unable to open file\n");
  312.             SF_ErrorStr(sndfile,(char*)bufmem,4096);
  313.             printf("%s\n",bufmem);
  314.         }
  315.     } while(!ende);
  316.  
  317.     if(rtfilelist)
  318.     {
  319.         if(lock_olddir) { CurrentDir(lock_olddir); lock_olddir=NULL; }
  320.         if(lock_newdir) { UnLock(lock_newdir); lock_newdir=NULL; }
  321.         rtFreeFileList(rtfilelist); rtfilelist=NULL;
  322.         if(!ende) goto next_filereq;
  323.     }
  324.  
  325. exit_clean:
  326.     if(rdargs) FreeArgs(rdargs);
  327.     if(rtfilereq) rtFreeRequest(rtfilereq);
  328.     if(ReqToolsBase) CloseLibrary((struct Library*)ReqToolsBase);
  329.     if(SndFileBase) CloseLibrary(SndFileBase);
  330.     return(rc);
  331. }
  332.  
  333.