Movie   movieToPlay = mMovie;
nsresult rv;  mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv); if (NS_FAILED(rv)) { Cleanup(); return rv; }  OSErr err = ::SndPlay(mSndChannel, (SndListHandle)mSoundHandle, true ); if (err != noErr) { Cleanup(); return NS_ERROR_FAILURE; }    SndCommand    theCmd = { callBackCmd, 0, 0 }; theCmd.param2 = (long)this;
nsSoundRequest::PlaySound(){  nsresult rv;  // we'll have a timer already if the sound is still playing from a previous  // request. In that case, we cloen the movie into a new one, so we can play it  // again from the start.  if (!mTimer)  {      mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);    // release previous timer, if any    if (NS_FAILED(rv)) {      Cleanup();      return rv;    }        const PRInt32   kMovieTimerInterval = 250;      // 250 milliseconds    rv = mTimer->Init(NS_STATIC_CAST(nsITimerCallback*, this), kMovieTimerInterval,            NS_PRIORITY_NORMAL, NS_TYPE_REPEATING_PRECISE);    if (NS_FAILED(rv)) {      Cleanup();      return rv;    }  }    Movie   movieToPlay = mMovie;    if (!::IsMovieDone(mMovie))     // if the current movie is still playing, clone it  {    Movie   newMovie = ::NewMovie(0);    if (!newMovie) return NS_ERROR_FAILURE;        // note that this copies refs, not all the data. So it should be fast    OSErr err = ::InsertMovieSegment(mMovie, newMovie, 0, ::GetMovieDuration(mMovie), 0);    if (err != noErr)    {      ::DisposeMovie(newMovie);      return NS_ERROR_FAILURE;    }        // append it to the array    PRBool  appended = mMovies.AppendElement((void *)newMovie);    if (!appended)     {      ::DisposeMovie(newMovie);      return NS_ERROR_FAILURE;    }    movieToPlay = newMovie;  }    ::SetMovieVolume(movieToPlay, kFullVolume);  ::GoToBeginningOfMovie(movieToPlay);  ::StartMovie(movieToPlay);  ::MoviesTask(movieToPlay, 0);  #ifdef SOUND_DEBUG  printf("Starting movie playback\n");#endif  return NS_OK;}