home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / maestro / source / videbjct / pnsncptd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-15  |  22.5 KB  |  691 lines

  1. /*
  2.  * Copyright (c) 1990, 1991, 1992 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and 
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name
  8.  * Stanford may not be used in any advertising or publicity relating to
  9.  * the software without the specific, prior written permission of
  10.  * Stanford.
  11.  * 
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  13.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  14.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  15.  *
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  17.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
  18.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
  19.  * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
  20.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21.  * SOFTWARE.
  22.  */
  23.  
  24. /* $Header: /Source/Media/collab/VideoObject/RCS/PanasonicOptDriver.c,v 0.26 92/09/28 12:39:41 drapeau Exp $ */
  25. /* $Log:    PanasonicOptDriver.c,v $
  26.  * Revision 0.26  92/09/28  12:39:41  drapeau
  27.  * PlayFromTo() was modified to reflect the new semantics of the VideoObject
  28.  * library.
  29.  * 
  30.  * Revision 0.25  92/09/12  14:06:24  drapeau
  31.  * Removed the function PanasonicOptReadResponse() since it was not being used.
  32.  * Because of this, also removed references to XView toolkit header files.
  33.  * 
  34.  * Revision 0.24  92/07/30  15:21:58  drapeau
  35.  * Several changes:
  36.  * * Re-formatted all function declarations to conform to ANSI function
  37.  *   prototype standards.
  38.  * * Replaced hard-coded references to 30 frame-per-second frame rates with
  39.  *   new definition "FrameRate".  All math is based on this definition now,
  40.  *   allowing the driver to be used in places where the frame rate is not
  41.  *   30 fps.
  42.  * * Improved diagnostic messages.  Diagnostics now report the serial port
  43.  *   being used for the command when possible.
  44.  * 
  45.  * Revision 0.23  92/06/16  23:40:57  drapeau
  46.  * Changed the way asynchronous calls are handled, to remove XView-dependent
  47.  * code from the driver.  This might have to be changed yet again, when the
  48.  * new toolkit-independent asynchronous reading scheme is implemented for
  49.  * all appropriate drivers.
  50.  * 
  51.  * Revision 0.22  92/01/03  16:51:17  drapeau
  52.  * Modified PanasonicOptReadResponse() to return the more proper
  53.  * XView return value "NOTIFY_DONE" rather than NULL.
  54.  * 
  55.  * Revision 0.21  91/09/30  17:05:55  lim
  56.  * Implemented PanasonicOptPing.
  57.  * 
  58.  * Revision 0.20  91/08/24  17:49:54  lim
  59.  * Implemented PrintDiagnostics.
  60.  * 
  61.  * Revision 0.19  91/08/24  13:37:59  lim
  62.  * 1. Updated to use status codes in new PlayerStatus.h
  63.  * 2. Clear Marker() removed as part of video object.
  64.  * 
  65.  * Revision 0.18  91/08/17  20:38:37  lim
  66.  * 1. Removed 'stopped'. Video mute is turned off whenever a command
  67.  * requiring video output is issued.
  68.  * 2. Pause After Search is now implemented.
  69.  * 3. Scan has been fixed to scan forward 250 frames at each call.
  70.  * 4. Stop and Pause implemented with interrupt capability.
  71.  * 5. Clear Marker implemented to do as specs in videoObj.h require.
  72.  * 
  73.  * Revision 0.17  91/08/15  12:52:05  lim
  74.  * Changed interrupt command to use "AC" which clears buffer and puts player
  75.  * in still playback mode.
  76.  * 
  77.  * Revision 0.16  91/08/13  22:57:18  lim
  78.  * Changed PlayAtSpeedDir to perform playback when speed is 30 frames/sec and
  79.  * direction is forward
  80.  * 
  81.  * Revision 0.15  91/08/08  17:13:43  lim
  82.  * 1. PlayAtSpeedDir() - try to input device-dependent speed rather than an arbitrary speed.
  83.  *    ie use CalcSpeed before calling PlayAtSpeedDir()
  84.  * 2. CalcSpeed() - one parameter added, 'playMode'. If playMode is 1, it is used to calculate
  85.  *    device speed for segment play. If playMode is 0, it is used to calculate device speed for
  86.  *    normal play.
  87.  * 3. QueryMedium() - one parameter added, 'result'. Used to return non-integer results.
  88.  * 
  89.  * Revision 0.14  91/08/07  13:01:37  lim
  90.  * 1. Made as part of VideoLib.a. Removed references to vEdit application.
  91.  * 2. Added instance pointer, "theObject" to all public functions. 
  92.  * 3. ErrorDecode() is now a private function. It calls DisplayError() 
  93.  * (in 'videoObjects.c') to display the error message. 
  94.  * 4. notify_set_input_func uses a PanasonicClient as first argument. The
  95.  * value is set in 'PanasonicOptDriver.h'.
  96.  * 
  97.  * Revision 0.13  91/08/02  12:48:17  lim
  98.  * 1. SetDefault function changed to take in 4 parameters:
  99.  * audio, addressingMode, addressDisplayOnOff and DisplayMode
  100.  * 2. xv_set is no longer called within driver code. Called
  101.  *    within vEdit instead.
  102.  * 3. Pause is removed and replaced by Still.
  103.  * 4. SetAddressDisplay now has 2 parameters, so as to be consistent
  104.  * with the default function.
  105.  * 
  106.  * Revision 0.12  91/07/27  22:26:23  lim
  107.  * Changed all code regarding speed settings to deal with int rather than double.
  108.  * Rounding macro, "MyRound" has been changed.
  109.  * 
  110.  * Revision 0.11  91/07/24  11:00:39  lim
  111.  * Ran through xsaber, and fixed warnings.
  112.  * 
  113.  * Revision 0.10  91/07/23  16:13:09  lim
  114.  * Initial revision.
  115.  *  */
  116.  
  117. #include "PanasonicOptDriver.h"
  118.  
  119. static char panasonicRcsid[] = "$Header: /Source/Media/collab/VideoObject/RCS/PanasonicOptDriver.c,v 0.26 92/09/28 12:39:41 drapeau Exp $";
  120.  
  121. static int    endFrame = 0;                        /* marks the end of segment to be played */
  122. int        waitConsumeResponse = 0;                /* Set to 1 if we do not wait to consume end response for the
  123.                                      command immediately after issuing it */
  124. static char    diagMsg[64];
  125.  
  126.  
  127. int 
  128.   PanasonicOptSendCode(VideoObject*    theObject,
  129.                char*        code,
  130.                int        param1,                /* Negative => no parameters */
  131.                int        param2,                /* Negative => only one param */
  132.                int        respMode)            /* 0 means read execution end, 1 means return so ...
  133.                                        ... that the app is not waiting for command to ...
  134.                                        ... finish execution */
  135. {
  136.   int    charRead1;
  137.   int    charRead2;
  138.   int    error;
  139.   int    data;
  140.   char    command[20];
  141.   char    response1[20];
  142.   char    response2[20];
  143.   char    errorMsg[50];
  144.   
  145.   command[0] = Stx;
  146.   
  147.   if ((param1 >= 0) && (param2 >= 0))                    /* 2 params */
  148.     sprintf(&command[1], "%s%d:%d:", code, param1, param2);
  149.   else if (param1 >= 0)                            /* 1 param */
  150.     sprintf(&command[1], "%s%d:", code, param1);
  151.   else                                    /* 0 params */
  152.     sprintf(&command[1], "%s", code);
  153.   
  154.   sprintf(diagMsg, "%s :\tCommand's length = %d.\n",
  155.       theObject->DevConfig->serialPort,
  156.       strlen(command));
  157.   PrintDiagnostics(diagMsg);
  158.   
  159.   command[strlen(command)] = Etx;
  160.   command[strlen(command) + 1] = '\r';
  161.   
  162.   sprintf(diagMsg, "%s :\tSending %s.\n",
  163.       theObject->DevConfig->serialPort,
  164.       &command[1]);
  165.   PrintDiagnostics(diagMsg);
  166.   write(theObject->DevConfig->fd, command, strlen(command));
  167.   
  168.   if (waitConsumeResponse)                        /* If response from previous command is not consumed... */
  169.   {                                    /* ... consume it here first */
  170.     if (strcmp(command, "AC") != 0)
  171.     {
  172.       sprintf(diagMsg, "%s :\tConsumed asynch end response.\n",
  173.           theObject->DevConfig->serialPort);
  174.       PrintDiagnostics(diagMsg);
  175.       charRead1 = read(theObject->DevConfig->fd, response1, 20);
  176.     }
  177.     waitConsumeResponse = 0;
  178.   }
  179.   
  180.   charRead1 = read(theObject->DevConfig->fd, response1, 20);
  181.   response1[charRead1 - 2] = '\0';
  182.   
  183.   if (response1[0] == Ack)                        /* ACK is received - 1st response*/
  184.   {
  185.     sprintf(diagMsg, "%s :\tRead an ACK.\n",
  186.         theObject->DevConfig->serialPort);
  187.     PrintDiagnostics(diagMsg);
  188.     if (respMode == 1)
  189.       return PlayerOk;
  190.     else
  191.     {
  192.       charRead2 = read(theObject->DevConfig->fd, response2, 20);    /* Read 2nd response */
  193.       response2[charRead2 - 1] = '\0';
  194.       
  195.       if (response2[1] == 'E')                        /* Error in execution */
  196.       {
  197.     sscanf(&response2[2], "%d", &error);
  198.     sprintf(diagMsg, "%s :\t2nd read - error: %d.\n",
  199.         theObject->DevConfig->serialPort,
  200.         error);
  201.     PrintDiagnostics(diagMsg);
  202.     PanasonicOptErrorDecode(theObject, -error, errorMsg);
  203.     return(-error);
  204.       }
  205.       else if (response2[1] == 'N')                    /* Returning frame address */
  206.       {
  207.     sscanf(&response2[3], "%d", &data);
  208.     sprintf(diagMsg, "%s :\t2nd read - address: %d.\n",
  209.         theObject->DevConfig->serialPort,
  210.         data);
  211.     PrintDiagnostics(diagMsg);
  212.     return (data);
  213.       }
  214.       else if (response2[1] == 'Z')                    /* Returning player status */
  215.       {
  216.     sprintf(diagMsg, "%s :\t2nd read - status: %s.\n",
  217.         theObject->DevConfig->serialPort,
  218.         &response2[2]);
  219.     PrintDiagnostics(diagMsg);
  220.     if (strncmp(&response2[2], "PF", 2) == 0)
  221.       return PlayerForwardPlay;
  222.     else if (strncmp(&response2[2], "PR", 2) == 0)
  223.       return PlayerReversePlay;
  224.     else if (strncmp(&response2[2], "TF", 2) == 0)
  225.       return PlayerForwardStep;
  226.     else if (strncmp(&response2[2], "TR", 2) == 0)
  227.       return PlayerReverseStep;
  228.     else if (strncmp(&response2[2], "LF", 2) == 0)
  229.       return PlayerForwardSlow;
  230.     else if (strncmp(&response2[2], "LR", 2) == 0)
  231.       return PlayerReverseSlow;
  232.     else if (strncmp(&response2[2], "FF", 2) == 0)
  233.       return PlayerForwardFast;
  234.     else if (strncmp(&response2[2], "FR", 2) == 0)
  235.       return PlayerReverseFast;
  236.     else if (strncmp(&response2[2], "RA", 2) == 0)
  237.       return PlayerRecording;
  238.     else if (strncmp(&response2[2], "RM", 2) == 0)
  239.       return PlayerRecording;
  240.     else if (strncmp(&response2[2], "GS", 2) == 0)
  241.       return PlayerRecording;
  242.     else if (strncmp(&response2[2], "RE", 2) == 0)
  243.       return PlayerRecording;
  244.     else if (strncmp(&response2[2], "AE", 2) == 0)
  245.       return PlayerRecording;
  246.     else if (strncmp(&response2[2], "SR", 2) == 0)
  247.       return PlayerSearch;
  248.     else if (strncmp(&response2[2], "LD", 2) == 0)
  249.       return PlayerLoad;
  250.     else if (strncmp(&response2[2], "EJ", 2) == 0)
  251.       return PlayerEject;
  252.     else if (strncmp(&response2[2], "HT", 2) == 0)
  253.       return PlayerStop;
  254.     else if (strncmp(&response2[2], "WT", 2) == 0)
  255.       return PlayerWait;
  256.     else if (strncmp(&response2[2], "SD", 2) == 0)
  257.       return PlayerSystemDown;
  258.       }
  259.       else if (response2[0] == Stx)                    /* Normal execution end response */
  260.       {
  261.     sprintf(diagMsg, "%s :\t2nd read - end execution %s.\n",
  262.         theObject->DevConfig->serialPort,
  263.         &response2[1]);
  264.     PrintDiagnostics(diagMsg);
  265.     return PlayerOk;
  266.       }
  267.     }
  268.   }                                   /* end of ACK 2nd response handling */
  269.   else
  270.   {
  271.     if (response1[0] == Nak)                        /* NAK is received - 1st response */
  272.     {
  273.       sprintf(diagMsg, "%s :\tRead a NAK.\n",
  274.           theObject->DevConfig->serialPort);
  275.       PrintDiagnostics(diagMsg);
  276.       sscanf(&response1[1], "%d", &error);
  277.       PanasonicOptErrorDecode(theObject, -error, errorMsg);
  278.       return (-error);
  279.     }
  280.     else if ((response1[1] == 'E') && (response1[2] != 'J'))        /* Error in instruction */
  281.     {
  282.       sscanf(&response1[2], "%d", &error);
  283.       sprintf(diagMsg, "%s :\tRead error : %d.\n",
  284.           theObject->DevConfig->serialPort,
  285.           error);
  286.       PrintDiagnostics(diagMsg);
  287.       PanasonicOptErrorDecode(theObject, -error, errorMsg);
  288.       return (-error);
  289.     }
  290.   }                                    /* end of NAK 1st response */
  291. }                                    /* end function PanasonicOptSendCode */
  292.  
  293.  
  294. int 
  295.   PanasonicOptSetDefaults(VideoObject*    theObject,
  296.               int        audio,
  297.               int        addressingMode,            /* Unused */
  298.               int        addressDisplayOnOff,
  299.               int        displayMode)            /* Unused */
  300. {
  301.   PanasonicOptSendCode(theObject, "ON", 0, -1, 0);            /* set player OnLine */
  302.   PanasonicOptPlay(theObject);                        /* Put player in ready state */
  303.   PanasonicOptStill(theObject);
  304.   PanasonicOptSetAudio(theObject, audio);                /* Set audio */
  305.   PanasonicOptSetAddressDisplay(theObject, 
  306.                 addressDisplayOnOff, displayMode);  /* Set address display */
  307. }                                    /* end function PanasonicOptSetDefaults */
  308.  
  309.  
  310. int 
  311.   PanasonicOptPlay(VideoObject* theObject)
  312. {
  313.   PanasonicOptSetVideo(theObject, 1);                    /* get rid of video mute */
  314.   return(PanasonicOptSendCode(theObject, "PF", -1, -1, 0));
  315. }                                    /* end function PanasonicOptPlay */
  316.  
  317.  
  318. int 
  319.   PanasonicOptPlayFromTo(VideoObject*    theObject,
  320.              int        from,
  321.              int        to,
  322.              int        speed)
  323. {
  324.   int status;
  325.   int deviceSpeed;
  326.   
  327.   PanasonicOptSetVideo(theObject, 1);                    /* get rid of video mute */
  328.   if ((from == to) || ((from > 0) && (to == 0)))            /* Case a & b: search to "from" and still (non-blocking... */
  329.   {                                    /* ...search doesn't apply here since search time is quick) */
  330.     PanasonicOptSendCode(theObject, "SR", from,  -1, 0);        /* Search to address "from" */
  331.     if (status != PlayerOk)
  332.       return (status);
  333.     return (PanasonicOptSendCode(theObject, "AC", -1,  -1, 0));        /* Stills */
  334.   }    
  335.   if ((from == 0) && (to > 0))                        /* Case c: play from current position until address... */
  336.   {                                    /* ..."to" has been reached. */
  337.     endFrame = to;
  338.     deviceSpeed = PanasonicOptCalcSpeed(theObject, speed, 0);
  339.     status = PanasonicOptPlayAtSpeedDir(theObject, deviceSpeed,        /* This function examines "endFrame" to determine when... */
  340.                     Forward);            /* ...to stop playback. */
  341.     endFrame = 0;                            /* reset endFrame back to 0 */
  342.     return (status);
  343.   }
  344.   if ((from > 0) && (to > 0) && (from < to))                /* Case d: play from "from" to "to" */
  345.   {
  346.     PanasonicOptSendCode(theObject, "SR", from,  -1, 0);        /* Search to address "from" */
  347.     if (status != PlayerOk)
  348.       return (status);
  349.     PanasonicOptSendCode(theObject, "AC", -1,  -1, 0);            /* Stills */
  350.     endFrame = to;
  351.     deviceSpeed = PanasonicOptCalcSpeed(theObject, speed, 0);
  352.     status = PanasonicOptPlayAtSpeedDir(theObject, deviceSpeed,        /* This function examines "endFrame" to determine when... */
  353.                     Forward);            /* ...to stop playback. */
  354.     endFrame = 0;                            /* reset endFrame back to 0 */
  355.     return (status);
  356.   }
  357.   return(PlayerReturnError);                        /* If this code is reached, incorrect from & to were requested */
  358. }                                    /* end function PanasonicOptPlayFromTo */
  359.  
  360.  
  361. int 
  362.   PanasonicOptFastForward(VideoObject* theObject)
  363. {
  364.   return(PanasonicOptSendCode(theObject, "CF", 0, -1, 0));
  365. }                                    /* end function PanasonicOptFastForward */
  366.  
  367.  
  368. int 
  369.   PanasonicOptReverse(VideoObject* theObject)
  370.   return(PanasonicOptSendCode(theObject, "CR", 0, -1, 0));
  371. }                                    /* end function PanasonicOptReverse */
  372.  
  373.  
  374. /* Returns number of frames per second (device-capable) */
  375. int
  376.   PanasonicOptCalcSpeed(VideoObject*    theObject,
  377.             int        sliderValue,
  378.             int        playMode)            /* unused */
  379. {
  380.   int denom;
  381.   int deviceSpeed;                            /* in frames per second */
  382.   
  383.   if (sliderValue == 0)
  384.     return (0);
  385.   
  386.   if (MyAbs(sliderValue) < FrameRate)
  387.   {
  388.     denom = MyRound(FrameRate, sliderValue);                /* Bring to the nearest rounded denom */
  389.     deviceSpeed = (FrameRate / denom);
  390.   }
  391.   else
  392.   {
  393.     deviceSpeed = MyRound(sliderValue, FrameRate) * FrameRate;        /* Bring to nearest whole number */
  394.     if (deviceSpeed > (10 * FrameRate))
  395.       deviceSpeed = 10 * FrameRate;
  396.   }
  397.   sprintf(diagMsg, "%s :\tDevice speed : %d.\n",
  398.       theObject->DevConfig->serialPort,
  399.       deviceSpeed);
  400.   PrintDiagnostics(diagMsg);
  401.   return (deviceSpeed);
  402. }                                    /* end function PanasonicOptCalcSpeed */
  403.  
  404.  
  405. int 
  406.   PanasonicOptPlayAtSpeedDir(VideoObject*    theObject,
  407.                  int        inputSpeed,
  408.                  enum Direction    dir)
  409. {
  410.   int        denom;
  411.   int        speedTimes;
  412.   int        sendStatus;
  413.   static int    lastSpeed = 0;
  414.   
  415.   if (inputSpeed == lastSpeed)                        /* Was a new speed requested? */
  416.     return(PlayerOk);                            /* No, don't bother sending a new command to the player */
  417.   
  418.   lastSpeed = inputSpeed;                        /* Update last speed requested */
  419.   PanasonicOptSetVideo(theObject, 1);                    /* get rid of video mute */
  420.   
  421.   if ((inputSpeed == FrameRate) && (dir == Forward))
  422.     if (endFrame)
  423.       sendStatus = PanasonicOptSendCode(theObject, "PF", endFrame, -1, 1);
  424.     else
  425.       sendStatus = PanasonicOptSendCode(theObject, "PF", -1, -1, 0);
  426.   
  427.   if (inputSpeed < FrameRate)
  428.   {
  429.     denom = MyRound(FrameRate, inputSpeed);
  430.     if (dir == Forward)
  431.     {
  432.       if (endFrame)
  433.     sendStatus = PanasonicOptSendCode(theObject, "LF", denom, endFrame, 1);
  434.       else
  435.     sendStatus = PanasonicOptSendCode(theObject, "LF", denom, -1, 0);
  436.     }
  437.     else
  438.     {
  439.       if (endFrame)
  440.     sendStatus = PanasonicOptSendCode(theObject, "LR", denom, endFrame, 1);
  441.       else
  442.     sendStatus = PanasonicOptSendCode(theObject, "LR", denom, -1, 0);
  443.     }
  444.   }
  445.   else
  446.   {
  447.     speedTimes = MyRound(inputSpeed, FrameRate);
  448.     if (speedTimes > 10)
  449.       speedTimes = 10;
  450.     if (dir == Forward)
  451.     {
  452.       if (endFrame)
  453.     sendStatus = PanasonicOptSendCode(theObject, "FF", speedTimes, 
  454.                       endFrame, 1);
  455.       else
  456.     sendStatus = PanasonicOptSendCode(theObject, "FF", speedTimes, -1, 0);
  457.     }
  458.     else
  459.     {
  460.       if (endFrame)
  461.     sendStatus = PanasonicOptSendCode(theObject, "FR", speedTimes, 
  462.                       endFrame, 1);
  463.       else
  464.     sendStatus = PanasonicOptSendCode(theObject, "FR", speedTimes, 
  465.                       -1, 0);
  466.     }
  467.   }  
  468.   
  469.   if ((sendStatus >= 0) && (endFrame))                    /* No errors in sending */
  470.     waitConsumeResponse = 1;                        /* Set flag because end response is not consumed here */
  471.   return sendStatus;
  472. }                                    /* end function PanasonicOptPlayAtSpeedDir */
  473.  
  474.  
  475.  
  476. int 
  477.   PanasonicOptStep(VideoObject*        theObject,
  478.            enum Direction    dir)
  479. {
  480.   PanasonicOptSetVideo(theObject, 1);                    /* get rid of video mute */
  481.   if (dir == Forward)
  482.     return (PanasonicOptSendCode(theObject, "TF", -1, -1, 0));
  483.   else
  484.     return (PanasonicOptSendCode(theObject, "TR", -1, -1, 0));
  485. }                                    /* end function PanasonicOptStep */
  486.  
  487.  
  488. int 
  489.   PanasonicOptStill(VideoObject* theObject)
  490. {
  491.   PanasonicOptSetVideo(theObject, 1);                    /* get rid of video mute */
  492.   return(PanasonicOptSendCode(theObject, "AC", -1, -1, 0));        /* Interrupts play and stills */
  493.   
  494. }                                    /* end function PanasonicOptStill */
  495.  
  496.  
  497. int 
  498.   PanasonicOptStop(VideoObject*    theObject)
  499. {
  500.   PanasonicOptSendCode(theObject, "AC", -1, -1, 0);            /* Interrupts play and stills */
  501.   return(PanasonicOptSetVideo(theObject, 0));                /* Set video off */
  502. }                                    /* end function PanasonicOptStop */
  503.  
  504.  
  505. int 
  506.   PanasonicOptSetAudio(VideoObject*    theObject,
  507.                int        mode)
  508. {
  509.   switch (mode)
  510.   {
  511.    case PlayerAudioMute:
  512.     PanasonicOptSendCode(theObject, "A1", 0, -1, 0);
  513.     return(PanasonicOptSendCode(theObject, "A2", 0, -1, 0));
  514.    case PlayerAudioLeft:
  515.     PanasonicOptSendCode(theObject, "A1", 34, -1, 0);
  516.     return(PanasonicOptSendCode(theObject, "A2", 0, -1, 0));
  517.    case PlayerAudioRight:
  518.     PanasonicOptSendCode(theObject, "A2", 34, -1, 0);
  519.     return(PanasonicOptSendCode(theObject, "A1", 0, -1, 0));
  520.    case PlayerAudioStereo:
  521.     PanasonicOptSendCode(theObject, "A1", 34, -1, 0);
  522.     return(PanasonicOptSendCode(theObject, "A2", 34, -1, 0));
  523.   }
  524. }                                    /* end function PanasonicOptSetAudio */
  525.  
  526.  
  527. int 
  528.   PanasonicOptSetVideo(VideoObject*    theObject,
  529.                int        mode)                /* 0 for mute, 1 for on */
  530. {
  531.   if (mode)
  532.     return(PanasonicOptSendCode(theObject, "VS", -1, -1, 0));
  533.   else
  534.     return(PanasonicOptSendCode(theObject, "VR", -1, -1, 0));
  535. }                                    /* end function PanasonicOptSetVideo */
  536.  
  537.  
  538. int 
  539.   PanasonicOptSetAddressDisplay(VideoObject*    theObject,
  540.                 int        onOff,            /* 0 for off, 1 for on */
  541.                 int        mode)            /* Unused */
  542. {
  543.   if (onOff)
  544.     return(PanasonicOptSendCode(theObject, "DS", -1, -1, 0));
  545.   else
  546.     return(PanasonicOptSendCode(theObject, "DR", -1, -1, 0));
  547.   
  548. }                                    /* end function PanasonicOptSetAddressDisplay */
  549.  
  550.  
  551.  
  552. int 
  553.   PanasonicOptEject(VideoObject* theObject)
  554. {
  555.   return (PanasonicOptSendCode(theObject, "EJ", -1, -1, 0));
  556. }                                    /* end function PanasonicOptEject */
  557.  
  558.  
  559. int 
  560.   PanasonicOptQueryFrame(VideoObject* theObject)
  561. {
  562.   return(PanasonicOptSendCode(theObject, "NO", -1, -1, 0));
  563. }                                    /* end function PanasonicOptQueryFrame */
  564.  
  565.  
  566. int                                    /* right now, don't know if can be used */
  567.   PanasonicOptQueryMedium(VideoObject*    theObject,
  568.               char*        result)
  569. {
  570.   return;
  571. }                                    /* end function PanasonicOptQueryMedium */
  572.  
  573.  
  574. int 
  575.   PanasonicOptQueryStatus(VideoObject* theObject)
  576. {
  577.   return(PanasonicOptSendCode(theObject, "PS", -1, -1, 0));
  578. }                                    /* end function PanasonicOptQueryStatus */
  579.  
  580.  
  581. int 
  582.   PanasonicOptPing(VideoObject* theObject)
  583. {
  584.   int    charRead;
  585.   char    command[5];
  586.   char    response[7];
  587.   
  588.   command[0] = Stx;
  589.   strcpy(&command[1], "PS");                        /* Player status command */
  590.   command[3] = Etx;
  591.   command[4] = '\r';
  592.   sprintf(diagMsg, "%s :\tSent ping.\n",
  593.       theObject->DevConfig->serialPort);
  594.   PrintDiagnostics(diagMsg);
  595.   
  596.   write(theObject->DevConfig->fd, command, 5);
  597.   
  598.   charRead = read(theObject->DevConfig->fd, response, 1);
  599.   if (charRead)
  600.   {
  601.     sprintf(diagMsg, "%s :\tSuccessful ping.\n",
  602.         theObject->DevConfig->serialPort);
  603.     PrintDiagnostics(diagMsg);
  604.   }
  605.   else
  606.   {
  607.     sprintf(diagMsg, "%s :\tPing unsuccessful.\n",
  608.         theObject->DevConfig->serialPort);
  609.     PrintDiagnostics(diagMsg);
  610.   }  
  611.   return charRead;
  612. }                                    /* end function PanasonicOptPing */
  613.  
  614.  
  615.  
  616. void 
  617.   PanasonicOptErrorDecode(VideoObject*    theObject,
  618.               int        errorCode,
  619.               char*        errorMsg)
  620. {
  621.   switch (errorCode)
  622.   {
  623.    case InvalidInstruction:
  624.     strcpy(errorMsg, "Invalid instruction");
  625.     break;
  626.    case DiskCheck:
  627.     strcpy(errorMsg, "Please check disc");
  628.     break;
  629.    case NoDisk:
  630.     strcpy(errorMsg, "There is no disc loaded");
  631.     break;
  632.    case CantFindAddress:
  633.     strcpy(errorMsg, "Can't find address");
  634.     break;
  635.    case OutOfFocus:
  636.     strcpy(errorMsg, "Focus is off");
  637.     break;
  638.    case DiscMotorSyncNG:
  639.     strcpy(errorMsg, "Disk motor out of sync/speed low");
  640.     break;
  641.    case OptHeadOffEnd:
  642.     strcpy(errorMsg, "Optical head is off start/end of disc");
  643.     break;
  644.    case RecordError:
  645.     strcpy(errorMsg, "Attempting to set recording area from recorded track");
  646.     break;
  647.    case ExtVideoError:
  648.     strcpy(errorMsg, "Video signal not correct/ not input");
  649.     break;
  650.    case LoadError:
  651.     strcpy(errorMsg, "Load error. Perform inverting operation");
  652.     break;
  653.    case Moisture:
  654.     strcpy(errorMsg, "Moisture : Optical system is dewed");
  655.     break;
  656.    case RcvBuffOverflow:
  657.     strcpy(errorMsg, "Receiver buffer overflow");
  658.     break;
  659.    case CommError:
  660.     strcpy(errorMsg, "Communication error");
  661.     break;
  662.    case InvalidCmdFormat:
  663.     strcpy(errorMsg, "Inaccurate format of command");
  664.     break;
  665.    case ConcentricDisc:
  666.     strcpy(errorMsg, "Cannot proceed with concentric disk");
  667.     break;
  668.    case Battery:
  669.     strcpy(errorMsg, "Stored program cannot be protected.");
  670.     break;
  671.    case NestingErr:
  672.     strcpy(errorMsg, "Subroutine depth > level 15");
  673.     break;
  674.    case NoProgram:
  675.     strcpy(errorMsg, "Program not loaded/stored program cannot be protected");
  676.     break;
  677.    case ProgramExceedMem:
  678.     strcpy(errorMsg, "Program exceeds memory");
  679.     break;
  680.    case NoiseInUnit:
  681.     strcpy(errorMsg, "Noise detected by unit");
  682.     break;
  683.    default:
  684.     strcpy(errorMsg, "Unknown error code");
  685.     break;
  686.   }
  687.   DisplayError(errorMsg, " ");
  688.   return;
  689. }                                    /* end function PanasonicOptErrorDecode */
  690.