home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1990, 1991 Stanford University
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the name
- * Stanford may not be used in any advertising or publicity relating to
- * the software without the specific, prior written permission of
- * Stanford.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
- * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
- /* $Header: /Source/Media/collab/DTR/RCS/play.c,v 1.10 92/01/09 12:42:42 drapeau Exp Locker: derek $ */
- /* $Log: play.c,v $
- * Revision 1.10 92/01/09 12:42:42 drapeau
- * Slight modifications to the code to make it ANSI-compliant.
- *
- * Revision 1.0 92/01/07 14:16:55 drapeau
- * Made a number of cosmetic changes to make code easier to read and
- * to conform to programming specifications.
- * Also, changed an alert message in Play(); alert message is now owned
- * by the main window, no longer by the editing status message that has
- * been removed.
- *
- * Revision 0.21 91/09/18 22:47:34 derek
- * The following things are done:
- * 1. The Makefile is changed corresponding to the changes in collab/.
- * 2. Copyright messages included.
- * 3. Some minor bugs fixed.
- *
- * Revision 0.20 91/08/21 11:34:28 derek
- * The following changes are made:
- * 1. Now the duration and size of the recorded sound will be displayed
- * during recording.
- * 2. I have changed GetSelection() corresponding to the request of Tek joo
- * 3. Info Panel is added to the application.
- * 4. Fixed SizeToFitHandler() so that when no file or buffer is currently
- * loaded, it would not do anything (except giving a warning
- * notice_prompt).
- * 5. Inplemented the `Close' Menu option in the document menu.
- * 6. Fixed the bug in which after ClearAll and I press PreviewEdit,
- * the edit wont be played.
- * 7. I have made the changes corresponding to the change in OpenPanel's
- * name. (from OpenPanel to Browse).
- * 8. Incorporated BrowseCheck to check command line arg.
- * 9. Changed most EditingStatusMessages to NoticePrompts.
- * 10. SoundFileSaveAsPopUp and EditListSaveAsPopUp are removed
- * from the application.
- *
- * Revision 0.19 91/08/16 18:10:48 derek
- *
- * The following things are done:
- * 1. I have fixed an openpanel bug in my code in which I
- * made the app return the wrong values to OpenHandler and
- * the SaveHandler.
- * 2. The flashing color of the play button has been changed from
- * Red to Green.
- * 3. Fixed a quantization bug: Buffer.play.end, when converted
- * from endingTimeInSec, should not exceed Buffer_hdr_data_size - 1.
- *
- * Revision 0.18 91/08/13 20:38:36 derek
- * The buttons (play, pause, record) will now flash after they are pressed.
- * This only applies to times when audio files (not edit-lists) are
- * played.
- *
- * Revision 0.17 91/08/07 16:24:38 derek
- * The Edit list part of DTR is done. OpenPanel is also incorporated.
- *
- * Revision 0.16 91/07/29 15:10:26 derek
- * The playing w/o stopping error is fixed.
- *
- * Revision 0.15 91/07/23 21:25:23 derek
- * This version is not ready for release. Disk space editing is half-done:
- * the application can play an infinite sound and the canvases can handle
- * infinite sound files. The app is pretty bug free too, I think. The
- * weakness is that it cannot record sond infinitely.
- *
- * Revision 0.14 91/06/26 15:55:24 derek
- * I have reformatted the code to conform coding specs.
- *
- * Revision 0.13 91/06/25 16:27:35 derek
- * The displaying of wrong pause message is fixed.
- *
- * Revision 0.12 91/06/20 20:01:16 derek
- * The network part should be working. Also fixed a number of bugs involving
- * canvases and display.
- *
- * Revision 0.10 1991/04/25 01:50:53 derek
- * This version is checked in on 4/24/91
- * */
- static char rcsid[] = "$Header: /Source/Media/collab/DTR/RCS/play.c,v 1.10 92/01/09 12:42:42 drapeau Exp Locker: derek $";
-
- #include "dtr.h"
- #include "dtr_ui.h"
-
- extern dtr_editListPanelPopUp_objects* dtr_editListPanelPopUp;
-
-
- void
- StopPlay()
- {
- unsigned u;
-
- EVENT("Stop_Play");
-
- ActiveFlag &= ~PLAY;
-
- if (WaitFlag & PLAY) /* If waiting for device open, quit waiting now. */
- {
- WaitFlag &= ~PLAY;
- return;
- }
-
- Buffer.draining = FALSE;
-
- (void) audio_get_play_error(Audio_fd, &u); /* Get latest error count. */
-
- Audio_state.play.error = u;
- if (!ActiveFlag)
- {
- AudioFlushClose();
- CancelVUMeterTimer();
- CancelButtonGlowTimer();
- }
-
- UpdateMessageDisplay(); /* Update Message display. */
- ClearVUMeterCanvas(); /* Clear VU Meter Canvas. */
- CancelButtonGlow();
-
- xv_set(dtr_editListPanelPopUp->addButton,
- PANEL_INACTIVE, FALSE, NULL);
- xv_set(dtr_editListPanelPopUp->modifyButton,
- PANEL_INACTIVE, FALSE, NULL);
- xv_set(dtr_editListPanelPopUp->deleteButton,
- PANEL_INACTIVE, FALSE, NULL);
- xv_set(dtr_editListPanelPopUp->deleteAllButton,
- PANEL_INACTIVE, FALSE, NULL);
- xv_set(dtr_editListPanelPopUp->editListScrollList, /* Enable the scroll-list. */
- PANEL_INACTIVE, FALSE, NULL);
- } /* end function StopPlay */
-
-
- /*
- * This routine is called when the buffer markers are changed.
- */
- void
- PlayUpdateCursor()
- {
- Audio_info tmpinfo;
-
- EVENT("Play_Update_Cursor");
- if (!(ActiveFlag & PLAY)) /* No need to take action if not actually playing. */
- return;
- if (Buffer.play.end <= Buffer.play.start) /* If start and end points are the same, catch... */
- { /* ...it here. */
- StopPlay();
- return;
- }
- ActiveFlag &= ~PLAY; /* Turn off the SIGPOLL handler for now. */
-
- (void) audio_flush_play(Audio_fd); /* Flush queue and start over. */
- Buffer.draining = FALSE;
- Buffer.play.io_position = Buffer.play.start;
- ActiveFlag |= PLAY;
-
- AUDIO_INITINFO(&tmpinfo); /* Reset sample, error, and eof counts. SIGPOLL.. */
- tmpinfo.play.eof = 0; /* ...will kick play. */
- tmpinfo.play.error = 0;
- tmpinfo.play.samples = 0;
- (void) audio_setinfo(Audio_fd, &tmpinfo);
- } /* end function PlayUpdateCursor */
-
-
- void
- StartPlay()
- {
- EVENT("Start_Play");
-
- /** if (SelectCheck() <= 0) {
- StopPlay();
- return;
- }
- ***/
- Buffer.play.io_position = Buffer.play.start;
- Buffer.display.last = -1;
- Buffer.draining = FALSE;
-
- ActiveFlag |= PLAY; /* Set the play flag here. */
-
- ResetVUMeter(); /* Reset VU Meter parameters. */
-
- xv_set(dtr_editListPanelPopUp->addButton,
- PANEL_INACTIVE, TRUE, NULL);
- xv_set(dtr_editListPanelPopUp->modifyButton,
- PANEL_INACTIVE, TRUE, NULL);
- xv_set(dtr_editListPanelPopUp->deleteButton,
- PANEL_INACTIVE, TRUE, NULL);
- xv_set(dtr_editListPanelPopUp->deleteAllButton,
- PANEL_INACTIVE, TRUE, NULL);
- SetButtonGlowTimer(GLOW_INTERVAL);
- SetVUMeterTimer((double)SCOPE_WIDTH/
- (double)Buffer.hdr.sample_rate); /* Set a Timer to go off, probably painting the */
- /* screen once per Scope width. */
- (void) kill(getpid(), SIGPOLL); /* This sends a signal SIGPOLL to the server,... */
- /* ...which then notifies SigpollAsyncHandler(). */
- /* ...This procedure later triggers PlayService(). */
- }
-
-
- /*
- * This is the routine that is called from the main loop that writes
- * sound to the device.
- *
- * It needs the following state data:
- * - cursor start and end (calculate in proc)
- * - current position in the buffer
- */
- void
- PlayService()
- {
- int start;
- int end;
- int outcnt;
- int rtn;
- int cnt;
-
- EVENT("Play_Service");
- if (Buffer.draining)
- return;
- start = Buffer.play.io_position;
- end = Buffer.play.end;
- outcnt = end - start + 1;
- if (FileReady)
- {
- soundfd = open(Buffer.filename, O_RDONLY); /* ...buffer mode. */
- lseek(soundfd, Buffer.hdr_size + start, L_SET);
- }
- while (outcnt > 0)
- {
- if (FileReady)
- {
- cnt = read(soundfd, (char *)SndBuf, (outcnt > 1024 ? 1024 : outcnt));
- rtn = write(Audio_fd, (char *)SndBuf, cnt);
- }
- else
- {
- rtn = write(Audio_fd, (char *)&Buffer.data[start], outcnt);
- }
- if (rtn > 0)
- {
- outcnt -= rtn;
- start += rtn;
- Buffer.play.io_position = start;
- }
- else
- {
- break;
- }
- }
- if (FileReady)
- {
- close(soundfd);
- if (outcnt <= 0)
- {
- if (!Buffer.draining)
- {
- Buffer.draining = TRUE;
- (void) write(Audio_fd, (char *)&Buffer.data[0], 0);
- }
- }
- }
- else
- {
- if (outcnt == 0) /* Check for end of sound condition. */
- {
- if (!Buffer.draining)
- {
- Buffer.draining = TRUE;
- (void) write(Audio_fd, (char *)&Buffer.data[0], 0); /* Write EOF marker. */
- }
- }
- }
- } /* end function PlayService*/
-
-
-
- /*
- * This procedure Play() is called by PlayButtonHandler() and is run
- * when the play button is pressed. Before executing this procedure,
- * the audio file is already loaded into memory.
- */
- void
- Play(ip)
- dtr_mainWindow_objects *ip;
- {
- EVENT("Play");
-
- if ((ActiveFlag & RECORD) || (WaitFlag & RECORD)) /* Play stops in-progress Record. */
- StopRecord();
-
- switch (AudioOpen(PLAY))
- {
- case 0: /* Open succeeded. */
- break;
- case 1: /* Open returned EBUSY. */
- WaitFlag |= PLAY; /* SIGPOLL is sent on close(). */
- return;
- case -1: /* Open error. */
- default:
- AlertByNoticePrompt(ip->mainWindow,
- "Could not open the audio device.");
- return;
- }
- StartPlay();
- } /* end function Play */
-