home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / Synthesizer Source / Synthesizer Folder / SampleTestPlay.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-01  |  9.7 KB  |  364 lines  |  [TEXT/KAHL]

  1. /* SampleTestPlay.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Synthesizer:  Digital Music Synthesis on General Purpose Computers     */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "SampleTestPlay.h"
  31. #include "SoundOutput.h"
  32. #include "Memory.h"
  33. #include "SampleWindow.h"
  34. #include "SampleConsts.h"
  35.  
  36. #define FRAMESPERBUFFER (8192)
  37. #define MAXBUFFERS (3)
  38. #define INITIALBUFFERS (MAXBUFFERS)
  39.  
  40.  
  41. typedef enum
  42.     {
  43.         eNoPlay EXECUTE(= -18481),
  44.         eLoopPlay,
  45.         eNoLoopPlay,
  46.         eWaiting
  47.     } InternalStates;
  48.  
  49. static InternalStates            State = eNoPlay;
  50.  
  51. static SampleTestErrors        ErrorOccurred;
  52. static SampleWindowRec*        Window;
  53. static char*                            Data;
  54. static long                                LoopStart;
  55. static long                                LoopEnd;
  56. static long                                CurrentIndex;
  57. static NumBitsType                NumBits;
  58. static NumChannelsType        NumChannels;
  59. static long                                EndOfChannel;
  60. static MyBoolean                    DoingLoop;
  61.  
  62.  
  63. MyBoolean                    SampleTestPlayInProgress(void)
  64.     {
  65.         return State != eNoPlay;
  66.     }
  67.  
  68.  
  69. void                            SampleTestPlayCallback(SampleWindowRec* TheWindow, MyBoolean IgnoreMe)
  70.     {
  71.         void*                        Buffer;
  72.         long                        Scan;
  73.         long                        LocalIndex;
  74.         long                        LocalEnd;
  75.         char*                        LocalData;
  76.         long                        Limit;
  77.  
  78.         if (State == eNoPlay)
  79.             {
  80.                 SoundOutputStereo        StereoRequest;
  81.                 SoundOutputNumBits    BitsRequest;
  82.  
  83.                 State = eLoopPlay;
  84.                 ErrorOccurred = eSampleTestNoError;
  85.  
  86.                 Window = TheWindow;
  87.  
  88.                 Data = SampleWindowGetRawData(TheWindow);
  89.                 if (Data == NIL)
  90.                     {
  91.                         ErrorOccurred = eSampleTestNoSample;
  92.                         return;
  93.                     }
  94.                 LoopStart = SampleWindowGetLoopStart(TheWindow);
  95.                 LoopEnd = SampleWindowGetLoopEnd(TheWindow);
  96.                 if (LoopEnd == LoopStart)
  97.                     {
  98.                         State = eNoLoopPlay;
  99.                     }
  100.                 CurrentIndex = 0;
  101.                 NumBits = SampleWindowGetNumBits(TheWindow);
  102.                 NumChannels = SampleWindowGetNumChannels(TheWindow);
  103.                 if (NumChannels == eSampleStereo)
  104.                     {
  105.                         StereoRequest = eStereo;
  106.                     }
  107.                  else
  108.                     {
  109.                         StereoRequest = eMono;
  110.                     }
  111.                 if (NumBits == eSample16bit)
  112.                     {
  113.                         BitsRequest = e16bit;
  114.                     }
  115.                  else
  116.                     {
  117.                         BitsRequest = e8bit;
  118.                     }
  119.                 if (!OpenSoundChannel(SampleWindowGetSamplingRate(TheWindow),
  120.                     StereoRequest,BitsRequest,FRAMESPERBUFFER,MAXBUFFERS,INITIALBUFFERS))
  121.                     {
  122.                         ErrorOccurred = eSampleTestCouldntOpenChannel;
  123.                         return;
  124.                     }
  125.                 DoingLoop = True;
  126.                 EndOfChannel = PtrSize(Data);
  127.                 if (NumChannels == eSampleStereo)
  128.                     {
  129.                         EndOfChannel = EndOfChannel / 2;
  130.                     }
  131.                 if (NumBits == eSample16bit)
  132.                     {
  133.                         EndOfChannel = EndOfChannel / (sizeof(short) / sizeof(char));
  134.                     }
  135.             }
  136.  
  137.         if (State == eWaiting)
  138.             {
  139.                 return;
  140.             }
  141.         if (ErrorOccurred != eSampleTestNoError)
  142.             {
  143.                 return;
  144.             }
  145.         ERROR(Window != TheWindow,PRERR(ForceAbort,
  146.             "SampleTestPlayCallback:  window pointers are different"));
  147.  
  148.         /* set up local variable values */
  149.         Buffer = CheckOutSoundBuffer();
  150.         if (Buffer == NIL)
  151.             {
  152.                 return;
  153.             }
  154.         Scan = 0;
  155.         LocalIndex = CurrentIndex;
  156.         LocalData = Data;
  157.         Limit = FRAMESPERBUFFER;
  158.  
  159.         /* use one of the 8 synthesis techniques */
  160.         if (State == eNoLoopPlay)
  161.             {
  162.                 LocalEnd = EndOfChannel; /* for no loop, the end is the real end */
  163.                 if (NumChannels == eSampleStereo)
  164.                     {
  165.                         if (NumBits == eSample16bit)
  166.                             {
  167.                                 /* stereo, 16-bit, no loop */
  168.                                 PRNGCHK(Buffer,Buffer,sizeof(short) * Limit * 2);
  169.                                 while (Scan < Limit)
  170.                                     {
  171.                                         if (LocalIndex >= LocalEnd)
  172.                                             {
  173.                                                 goto AllDonePoint;
  174.                                             }
  175.                                         ((signed short*)Buffer)[Scan * 2 + 0]
  176.                                             = ((signed short*)LocalData)[LocalIndex * 2 + 0] >> 1;
  177.                                         ((signed short*)Buffer)[Scan * 2 + 1]
  178.                                             = ((signed short*)LocalData)[LocalIndex * 2 + 1] >> 1;
  179.                                         LocalIndex += 1;
  180.                                         Scan += 1;
  181.                                     }
  182.                             }
  183.                          else
  184.                             {
  185.                                 /* stereo, 8-bit, no loop */
  186.                                 PRNGCHK(Buffer,Buffer,sizeof(char) * Limit * 2);
  187.                                 while (Scan < Limit)
  188.                                     {
  189.                                         if (LocalIndex >= LocalEnd)
  190.                                             {
  191.                                                 goto AllDonePoint;
  192.                                             }
  193.                                         ((signed char*)Buffer)[Scan * 2 + 0]
  194.                                             = ((signed char*)LocalData)[LocalIndex * 2 + 0] >> 1;
  195.                                         ((signed char*)Buffer)[Scan * 2 + 1]
  196.                                             = ((signed char*)LocalData)[LocalIndex * 2 + 1] >> 1;
  197.                                         LocalIndex += 1;
  198.                                         Scan += 1;
  199.                                     }
  200.                             }
  201.                     }
  202.                  else
  203.                     {
  204.                         if (NumBits == eSample16bit)
  205.                             {
  206.                                 /* mono, 16-bit, no loop */
  207.                                 PRNGCHK(Buffer,Buffer,sizeof(short) * Limit);
  208.                                 while (Scan < Limit)
  209.                                     {
  210.                                         if (LocalIndex >= LocalEnd)
  211.                                             {
  212.                                                 goto AllDonePoint;
  213.                                             }
  214.                                         ((signed short*)Buffer)[Scan]
  215.                                             = ((signed short*)LocalData)[LocalIndex] >> 1;
  216.                                         LocalIndex += 1;
  217.                                         Scan += 1;
  218.                                     }
  219.                             }
  220.                          else
  221.                             {
  222.                                 /* mono, 8-bit, no loop */
  223.                                 PRNGCHK(Buffer,Buffer,sizeof(char) * Limit);
  224.                                 while (Scan < Limit)
  225.                                     {
  226.                                         if (LocalIndex >= LocalEnd)
  227.                                             {
  228.                                                 goto AllDonePoint;
  229.                                             }
  230.                                         ((signed char*)Buffer)[Scan]
  231.                                             = ((signed char*)LocalData)[LocalIndex] >> 1;
  232.                                         LocalIndex += 1;
  233.                                         Scan += 1;
  234.                                     }
  235.                             }
  236.                     }
  237.                 goto SubmitPoint;
  238.                 /* skip this */
  239.              AllDonePoint:
  240.                 /* end of channel, time to stop playing */
  241.                 SubmitBuffer((char*)Buffer,Scan,NIL,NIL);
  242.                 State = eWaiting;
  243.                 return;
  244.             }
  245.          else
  246.             {
  247.                 LocalEnd = LoopEnd; /* for loop, this is what the end is */
  248.                 if (NumChannels == eSampleStereo)
  249.                     {
  250.                         if (NumBits == eSample16bit)
  251.                             {
  252.                                 /* stereo, 16-bit, yes loop */
  253.                                 PRNGCHK(Buffer,Buffer,sizeof(short) * Limit * 2);
  254.                                 while (Scan < Limit)
  255.                                     {
  256.                                         if (LocalIndex == LocalEnd)
  257.                                             {
  258.                                                 LocalIndex = LoopStart;
  259.                                             }
  260.                                         ((signed short*)Buffer)[Scan * 2 + 0]
  261.                                             = ((signed short*)LocalData)[LocalIndex * 2 + 0] >> 1;
  262.                                         ((signed short*)Buffer)[Scan * 2 + 1]
  263.                                             = ((signed short*)LocalData)[LocalIndex * 2 + 1] >> 1;
  264.                                         LocalIndex += 1;
  265.                                         Scan += 1;
  266.                                     }
  267.                             }
  268.                          else
  269.                             {
  270.                                 /* stereo, 8-bit, yes loop */
  271.                                 PRNGCHK(Buffer,Buffer,sizeof(char) * Limit * 2);
  272.                                 while (Scan < Limit)
  273.                                     {
  274.                                         if (LocalIndex == LocalEnd)
  275.                                             {
  276.                                                 LocalIndex = LoopStart;
  277.                                             }
  278.                                         ((signed char*)Buffer)[Scan * 2 + 0]
  279.                                             = ((signed char*)LocalData)[LocalIndex * 2 + 0] >> 1;
  280.                                         ((signed char*)Buffer)[Scan * 2 + 1]
  281.                                             = ((signed char*)LocalData)[LocalIndex * 2 + 1] >> 1;
  282.                                         LocalIndex += 1;
  283.                                         Scan += 1;
  284.                                     }
  285.                             }
  286.                     }
  287.                  else
  288.                     {
  289.                         if (NumBits == eSample16bit)
  290.                             {
  291.                                 /* mono, 16-bit, yes loop */
  292.                                 PRNGCHK(Buffer,Buffer,sizeof(short) * Limit);
  293.                                 while (Scan < Limit)
  294.                                     {
  295.                                         if (LocalIndex == LocalEnd)
  296.                                             {
  297.                                                 LocalIndex = LoopStart;
  298.                                             }
  299.                                         ((signed short*)Buffer)[Scan]
  300.                                             = ((signed short*)LocalData)[LocalIndex] >> 1;
  301.                                         LocalIndex += 1;
  302.                                         Scan += 1;
  303.                                     }
  304.                             }
  305.                          else
  306.                             {
  307.                                 /* mono, 8-bit, yes loop */
  308.                                 PRNGCHK(Buffer,Buffer,sizeof(char) * Limit);
  309.                                 while (Scan < Limit)
  310.                                     {
  311.                                         if (LocalIndex == LocalEnd)
  312.                                             {
  313.                                                 LocalIndex = LoopStart;
  314.                                             }
  315.                                         ((signed char*)Buffer)[Scan]
  316.                                             = ((signed char*)LocalData)[LocalIndex] >> 1;
  317.                                         LocalIndex += 1;
  318.                                         Scan += 1;
  319.                                     }
  320.                             }
  321.                     }
  322.             }
  323.  
  324.         /* play the data and write changed values out */
  325.      SubmitPoint:
  326.         SubmitBuffer((char*)Buffer,Limit,NIL,NIL);
  327.         CurrentIndex = LocalIndex;
  328.     }
  329.  
  330.  
  331. void                            SampleTestBreakLoop(void)
  332.     {
  333.         ERROR(State != eLoopPlay,PRERR(ForceAbort,
  334.             "SampleTestBreakLoop:  cancelling loop but it isn't looping"));
  335.         State = eNoLoopPlay;
  336.     }
  337.  
  338.  
  339. SampleTestErrors    SampleTestDidErrorOccur(void)
  340.     {
  341.         return ErrorOccurred;
  342.     }
  343.  
  344.  
  345. void                            SampleTestPlayCleanup(void)
  346.     {
  347.         ERROR(State == eNoPlay,PRERR(ForceAbort,
  348.             "SampleTestPlayCleanup:  nothing is playing"));
  349.         CloseSoundChannel(NIL,NIL);
  350.         State = eNoPlay;
  351.     }
  352.  
  353.  
  354. MyBoolean                    SampleTestIsItLooping(void)
  355.     {
  356.         return State == eLoopPlay;
  357.     }
  358.  
  359.  
  360. MyBoolean                    SampleTestIsWaitingForCleanup(void)
  361.     {
  362.         return State == eWaiting;
  363.     }
  364.