This version of this document is no longer maintained. For the latest documentation, see http://www.qnx.com/developers/docs. |
Soundfile Player
The Soundfile Player plugins play simple audio files. They can be used to playback various simple audio and wave file formats such as:
The soundfile_noph.so player is launched by typing playsound_noph at the command line.
Calling MvInit() sets the value of MvPluginCtrl_t.MvPluginFlags_t pflags to 0.
See the Resource Profile Estimates and Library Dependencies appendix.
The soundfile plugin is a single track plugin and supports the following commands:
CMD_PLUGIN_CLOSE
CMD_PLUGIN_DIRECT_AUDIO
CMD_PLUGIN_GET_STATUS
CMD_PLUGIN_MUTE
CMD_PLUGIN_OPEN_URLS
CMD_PLUGIN_PAUSE
CMD_PLUGIN_SEEK_TO
CMD_PLUGIN_SET_PARAMETER
CMD_PLUGIN_START
CMD_PLUGIN_STOP
See the playsound_noph.c example in the Appendix.
The following sample callback handler is used by phplay to analyze state changes and status information. After verifying that the plugin handle is still valid, the value of the MvEventFlags_t change variable is examined to determine which field of the MvPluginStatus_t const *pst structure is valid.
Values that may be used for MvEventFlags_t change include:
MVS_DURATION
MVS_ERRORMSG
MVS_FLAGS
MVS_MEDIA
MVS_PLUGIN_STATE
MVS_POSITION
MVS_VPSIZE
void soundfile_vcb( MvPluginCtrl_t *ctrl, MvEventFlags_t change, MvPluginStatus_t const *pst ) { PtArg_t args[2]; const char *status = "No plugin"; if( mplayer.pctrl == NULL ) { //this plugin has been closed if( pst->state == MV_DEAD ) { // plugin is ready for destruction UnloadDll( ctrl ); free( ctrl ); // reset plugin count mplayer.pluginIsLoaded = FALSE; } // show the correct pause/play button SetPlayPauseButton( TRUE ); return; } /* CHECK IF PLUGIN STATE HAS CHANGE */ if( change & MVS_PLUGIN_STATE ) { //plugin state has change MvCommandData_t cmdData = {0}; switch( pst->state ) { case MV_DEAD: status ="Dead"; mplayer.pluginIsLoaded = FALSE; SetStopEjectButton( FALSE ); cbBaseClose( 0, 0, 0 ); return; case MV_CLOSED: status = ( mplayer.pctrl->lastst == MV_OPENING ) ? "Open failed" : "No Clip"; break; case MV_OPENING: status = "Opening"; break; case MV_STOPPED: status = ( mplayer.pctrl->lastst == MV_OPENING ) ? "Opened" : "Stopped"; PtSetArg( &args[0], Pt_ARG_GAUGE_VALUE, 0, 0 ); PtSetResources( ABW_curpos, 1, args ); SoundFileUpdatePosition( 0, mplayer.pctrl->duration ); if( !mplayer.bPluginError ) { cmdData.pluginCtrl = &mplayer.pctrl->mv; cmdData.cmdType = CMD_PLUGIN_SEEK_TO; cmdData.which = MVP_DELTA | MVP_POSITION; cmdData.param = &mplayer.playback_parms; mplayer.playback_parms.delta = 0; mplayer.playback_parms.position = 0; mplayer.pctrl->mv.calls->command( &cmdData ); if( mplayer.playIsSet ) { if( mplayer.pctrl->lastst == MV_OPENING && !mplayer.played) { PtTimerArm( ABW_pausePlayButton, 200 ); } } } break; case MV_PAUSED: status = "Paused"; break; case MV_PREFETCHING: status = "Prefetching"; break; case MV_PLAYING: status = "Playing"; mplayer.played = 1; // arm the timer with the right frequency for mplayer get_status() call to the plugin PtSetArg( &args[0], Pt_ARG_TIMER_INITIAL, mplayer.playback_parms.status_frequency, 0 ); PtSetArg( &args[1], Pt_ARG_TIMER_REPEAT, mplayer.playback_parms.status_frequency, 0 ); PtSetResources( ABW_timer, 2, args ); break; default: status = "Unknown"; break; } // reset the timer for mplayer get_status() call to the plugin // only if it has been arm and the plugin state has change if( pst->state != MV_PLAYING) { PtSetArg( &args[0], Pt_ARG_TIMER_INITIAL,0, 0 ); PtSetArg( &args[1], Pt_ARG_TIMER_REPEAT,0, 0 ); PtSetResources( ABW_timer, 2, args ); } // show the correct play /pause button setbuttons( pst->state); // update mplayer state flag mplayer.pctrl->lastst = pst->state; //update GUI status label with new state PtSetArg( &args[0], Pt_ARG_TEXT_STRING, status, 0 ); PtSetResources( ABW_status, 1, args ); } /* CHECK IF PLUGIN STATUS FLAG HAS CHANGE */ if( change & MVS_FLAGS ) {// flags is valid. the only one supported is MVP_FULLSCREEN = 0x01 mplayer.pctrl->psflags = pst->flags; } /* CHECK IF PLUGIN WANT TO ADJUST PHPLAY VOLUME SETTING */ if( change & MVS_MEDIA ) { if( pst->media_info && (pst->media_info->which & MV_MEDIA_AUDIO_INFO) ) { //fprintf(stderr,"Ang in %s plugin was volume change to %d\n",__FILE__,pst->media_info->audio->volume); PtSetArg( &args[0], Pt_ARG_GAUGE_VALUE, pst->media_info->audio->volume, 0 ); PtSetResources( ABW_PtSlider_volume, 1, args ); return; } } /* CHECK IF PLUGIN MEDIA INFO IS VALID */ if( change & MVS_MEDIA ) // media_info is valid and points to new media { if( mplayer.pctrl->lastst >= MV_STOPPED ) {// last state was MV_STOPPED or MV_PAUSED or MV_PREFETCHING or MV_PLAYING const char* title = pst->media_info->title; if( title == NULL ) { title = ( title = strrchr( pst->media_info->url, '/' ) ) ? ++title : pst->media_info->url; } PtSetArg( &args[0], Pt_ARG_TEXT_STRING, title, 0 ); PtSetResources( ABW_cliptitle, 1, args ); PtSetArg( &args[0], Pt_ARG_TEXT_STRING, pst->media_info->moreinfo, 0 ); PtSetResources( ABW_clipinfo, 1, args ); mplayer.pctrl->mediaType = pst->media_info->type; mplayer.pctrl->duration = pst->media_info->duration; if( mplayer.pctrl->mediaType & MV_MEDIA_SEEKABLE && mplayer.pctrl->duration ) { PtSetArg( &args[0], Pt_ARG_FLAGS, 0, Pt_BLOCKED | Pt_GHOST ); PtSetResources( ABW_curpos, 1, args ); } if( pst->media_info->type & MV_MEDIA_PLAYLIST ) { // media info playlist parameter is valid int track = ControllerGetPluginList(); ControllerOpenIndex( NULL, track ); } else { int track; MvCommandData_t cmdData = {0}; // the plugin doesn't have the playlist info //track = ControllerAddUrl( pst->media_info->url, pst->media_info->title ); //ControllerSetActiveTrack( track ); if( pst->media_info->duration ) { // adjust the maximum range of the progress bar widget PtSetArg( &args[0], Pt_ARG_GAUGE_MAXIMUM, pst->media_info->duration, 0 ); PtSetResources( ABW_curpos, 1, args ); } // repositioning of the widget to show beginning of time frame PtSetArg( &args[0], Pt_ARG_GAUGE_VALUE, 0, 0 ); PtSetResources( ABW_curpos, 1, args ); if(( mplayer.playback_parms.status_frequency = mplayer.pctrl->duration / POS_SLIDER_WIDTH ) > 1000 ) { mplayer.playback_parms.status_frequency = 1000; } cmdData.pluginCtrl = &mplayer.pctrl->mv; cmdData.cmdType = CMD_PLUGIN_SET_PARAMETER; cmdData.which = MVP_STATUS_FREQ | MVP_AUDIO; cmdData.param = &mplayer.playback_parms; mplayer.pctrl->mv.calls->command( &cmdData ); } } else {// last state was MV_DEAD or MV_CLOSED or MV_OPENING // reset GUI cursor position PtSetArg( &args[0], Pt_ARG_GAUGE_VALUE, 0, 0 ); PtSetResources( ABW_curpos, 1, args ); // make it impossible to move the cursor from the GUI PtSetArg( &args[0], Pt_ARG_FLAGS, ~0, Pt_BLOCKED | Pt_GHOST ); PtSetResources( ABW_curpos, 1, args ); // reset clip title label PtSetArg( &args[0], Pt_ARG_TEXT_STRING, "", 0 ); PtSetResources( ABW_cliptitle, 1, args ); // reset clip info label PtSetArg( &args[0], Pt_ARG_TEXT_STRING, "", 0 ); PtSetResources( ABW_clipinfo, 1, args ); PtSetArg( &args[0], Pt_ARG_TEXT_STRING, "", 0 ); PtSetResources( ABW_postxt, 1, args ); } } /* CHECK IF PLUGIN POSITION IS VALID */ if( change & MVS_POSITION ) { // position is valid plassert( mplayer.pctrl->duration != 0, "MVS_POSITION is set even though duration is zero" ); if( !mplayer.cursorIsDrag && (mplayer.pctrl->lastst == MV_PLAYING) ) { mplayer.pctrl->lastpos = pst->position; // update cursor position PtSetArg( &args[0], Pt_ARG_GAUGE_VALUE, pst->position, 0 ); PtSetResources( ABW_curpos, 1, args ); if( ( pst->position / 100 ) != mplayer.pctrl->lrpos ) { //update GUI text display only if change is visible mplayer.pctrl->lrpos = pst->position / 100; SoundFileUpdatePosition( pst->position, mplayer.pctrl->duration ); } } } /* CHECK IF PLUGIN HAS AN ERROR MESSAGE */ if( change & MVS_ERRORMSG ) { // there's an error message in errmsg mplayer.bPluginError = TRUE; popup_error( pst->errormsg ); } /* CHECK IF PLUGIN IS WAITING FOR NEXT COMMAND */ if( mplayer.pctrl->lastst == MV_STOPPED && mplayer.played ) { mplayer.played = 0; PtTimerArm( ABW_ControlGroup, 200 ); } }