void MediaObject::setSource(const Phonon::MediaSource &source)
        {
            if (m_state == Phonon::PlayingState)
            {
                setError(Phonon::NormalError, QLatin1String("source changed while playing"));
                stop();
            }

            m_source = source;
            m_hasSource = true;
            m_sourceIsValid = false;

            emit currentSourceChanged(source);

            if (source.type() == Phonon::MediaSource::LocalFile) {
                if (!openWaveFile(source.fileName())) {
                  setError(Phonon::FatalError, QLatin1String("cannot open media file"));
                  return ;
                }
            } else if (source.type() == Phonon::MediaSource::Stream) {
                if (m_stream)
                   delete m_stream;
                m_stream = new IOWrapper(this, source);
                m_mediaSize = m_stream->size();
            } else if (source.type() == Phonon::MediaSource::Url) {
                if (!openWaveFile(source.url().toLocalFile())) {
                    setError(Phonon::FatalError, QLatin1String("cannot open media file"));
                    return ;
                }
            } else {
                setError(Phonon::FatalError, QLatin1String("type of source not supported"));
                return ;
            }
            setState(Phonon::LoadingState);

            if (!readHeader())
                setError(Phonon::FatalError, QLatin1String("invalid header"));
            else if (!getWaveOutDevice())
                setError(Phonon::FatalError, QLatin1String("No waveOut device available"));
            else if (!fillBuffers())
                setError(Phonon::FatalError, QLatin1String("no data for buffering"));
            else if (!prepareBuffers())
                setError(Phonon::FatalError, QLatin1String("cannot prepare buffers"));
            else
                m_sourceIsValid = true;

            if (m_sourceIsValid)
                setState(Phonon::StoppedState);
        }
/* Note that this procedure leaks memory like mad. */
static void
applyPlugin(const char               * pcInputFilename,
	    const char               * pcOutputFilename,
	    const LADSPA_Data          fExtraSeconds,
	    const unsigned long        lPluginCount,
	    const LADSPA_Descriptor ** ppsPluginDescriptors,
	    LADSPA_Data             ** ppfPluginControlValues) {

  LADSPA_PortDescriptor iPortDescriptor;
  LADSPA_Handle * ppsPlugins;
  LADSPA_Data ** ppfBuffers;
  long lFrameSize;
  unsigned long lAudioInputCount;
  unsigned long lAudioOutputCount;
  unsigned long lPreviousAudioOutputCount;
  unsigned long lBufferCount;
  unsigned long lBufferIndex;
  unsigned long lControlIndex;
  unsigned long lInputFileChannelCount;
  unsigned long lInputFileLength;
  unsigned long lOutputFileChannelCount;
  unsigned long lOutputFileLength;
  unsigned long lPluginIndex;
  unsigned long lPortIndex;
  unsigned long lSampleRate;
  unsigned long lTimeAt;
  LADSPA_Data fDummyControlOutput;

  /* Open input file and output file: 
     -------------------------------- */

  lOutputFileChannelCount
    = getPortCountByType(ppsPluginDescriptors[lPluginCount - 1],
			 LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT);
  if (lOutputFileChannelCount == 0) {
    fprintf(stderr,
	    "The last plugin in the chain has no audio outputs.\n");
    exit(1);
  }

  openWaveFile(pcInputFilename, 
	       &lInputFileChannelCount, 
	       &lSampleRate,
	       &lInputFileLength);
  if (lInputFileChannelCount
      != getPortCountByType(ppsPluginDescriptors[0],
			    LADSPA_PORT_AUDIO | LADSPA_PORT_INPUT)) {
    fprintf(stderr,
	    "Mismatch between channel count in input file and audio inputs "
	    "on first plugin in chain.\n");
    exit(1);
  }

  lOutputFileLength 
    = lInputFileLength + (unsigned long)(fExtraSeconds * lSampleRate);

  createWaveFile(pcOutputFilename,
		 lOutputFileChannelCount,
		 lSampleRate,
		 lOutputFileLength);

  /* Count buffers and sanity-check the flow graph:
     ---------------------------------------------- */

  lBufferCount = 0;
  lPreviousAudioOutputCount = 0;
  for (lPluginIndex = 0; lPluginIndex < lPluginCount; lPluginIndex++) {

    lAudioInputCount
      = getPortCountByType(ppsPluginDescriptors[lPluginIndex],
			   LADSPA_PORT_AUDIO | LADSPA_PORT_INPUT);
    lAudioOutputCount
      = getPortCountByType(ppsPluginDescriptors[lPluginIndex],
			   LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT);

    if (lBufferCount < lAudioInputCount)
      lBufferCount = lAudioInputCount;

    if (lPluginIndex > 0) 
      if (lAudioInputCount != lPreviousAudioOutputCount) {
	fprintf(stderr,
		"There is a mismatch between the number of output channels "
		"on plugin \"%s\" (%ld) and the number of input channels on "
		"plugin \"%s\" (%ld).\n",
		ppsPluginDescriptors[lPluginIndex - 1]->Name,
		lPreviousAudioOutputCount,
		ppsPluginDescriptors[lPluginIndex]->Name,
		lAudioInputCount);
	exit(1);
      }

    lPreviousAudioOutputCount = lAudioOutputCount;

    if (lBufferCount < lAudioOutputCount)
      lBufferCount = lAudioOutputCount;
  }

  /* Create the buffers, create instances, wire them up:
     --------------------------------------------------- */

  ppsPlugins = (LADSPA_Handle *)calloc(lPluginCount, sizeof(LADSPA_Handle));
  ppfBuffers = (LADSPA_Data **)calloc(lBufferCount, sizeof(LADSPA_Data *));
  for (lBufferIndex = 0; lBufferIndex < lBufferCount; lBufferIndex++)
    ppfBuffers[lBufferIndex] 
      = (LADSPA_Data *)calloc(BUFFER_SIZE, sizeof(LADSPA_Data));

  for (lPluginIndex = 0; lPluginIndex < lPluginCount; lPluginIndex++) {

    ppsPlugins[lPluginIndex]
      = ppsPluginDescriptors[lPluginIndex]
      ->instantiate(ppsPluginDescriptors[lPluginIndex],
		    lSampleRate);
    if (!ppsPlugins[lPluginIndex]) {
      fprintf(stderr,
	      "Failed to instantiate plugin of type \"%s\".\n",
	      ppsPluginDescriptors[lPluginIndex]->Name);
      exit(1);
    }

    /* Controls:
       --------- */

    lControlIndex = 0;
    for (lPortIndex = 0;
	 lPortIndex < ppsPluginDescriptors[lPluginIndex]->PortCount; 
	 lPortIndex++) {

      iPortDescriptor 
	= ppsPluginDescriptors[lPluginIndex]->PortDescriptors[lPortIndex];
      
      if (LADSPA_IS_PORT_CONTROL(iPortDescriptor)) {
	if (LADSPA_IS_PORT_INPUT(iPortDescriptor))
	  ppsPluginDescriptors[lPluginIndex]->connect_port
	    (ppsPlugins[lPluginIndex],
	     lPortIndex,
	     ppfPluginControlValues[lPluginIndex] + (lControlIndex++));
	if (LADSPA_IS_PORT_OUTPUT(iPortDescriptor))
	  ppsPluginDescriptors[lPluginIndex]->connect_port
	    (ppsPlugins[lPluginIndex],
	     lPortIndex,
	     &fDummyControlOutput);
      }
    }

    /* Input Buffers:
       -------------- */

    lBufferIndex = 0;
    for (lPortIndex = 0;
	 lPortIndex < ppsPluginDescriptors[lPluginIndex]->PortCount; 
	 lPortIndex++) {
      iPortDescriptor 
	= ppsPluginDescriptors[lPluginIndex]->PortDescriptors[lPortIndex];
      if (LADSPA_IS_PORT_INPUT(iPortDescriptor) 
	  && LADSPA_IS_PORT_AUDIO(iPortDescriptor))
	ppsPluginDescriptors[lPluginIndex]->connect_port
	  (ppsPlugins[lPluginIndex],
	   lPortIndex,
	   ppfBuffers[lBufferIndex++]);
    }
    

    /* Output Buffers:
       --------------- */

    lBufferIndex = 0;
    for (lPortIndex = 0;
	 lPortIndex < ppsPluginDescriptors[lPluginIndex]->PortCount; 
	 lPortIndex++) {
      iPortDescriptor 
	= ppsPluginDescriptors[lPluginIndex]->PortDescriptors[lPortIndex];
      if (LADSPA_IS_PORT_OUTPUT(iPortDescriptor) 
	  && LADSPA_IS_PORT_AUDIO(iPortDescriptor))
	ppsPluginDescriptors[lPluginIndex]->connect_port
	  (ppsPlugins[lPluginIndex],
	   lPortIndex,
	   ppfBuffers[lBufferIndex++]);
    }
  }

  /* Activate:
     --------- */

  for (lPluginIndex = 0; lPluginIndex < lPluginCount; lPluginIndex++) 
    if (ppsPluginDescriptors[lPluginIndex]->activate != NULL)
      ppsPluginDescriptors[lPluginIndex]->activate(ppsPlugins[lPluginIndex]);

  /* Run:
     ---- */

  lTimeAt = 0;
  while (lTimeAt < lOutputFileLength) {

    lFrameSize = lInputFileLength - lTimeAt;
    if (lFrameSize > BUFFER_SIZE)
      lFrameSize = BUFFER_SIZE;
    else {
      /* We've reached or are reaching the end of the file. We're not
         going to fill the buffer from file. Could just memset the end
         part, but there's only one frame where this is worth the
         effort. */
      for (lBufferIndex = 0; lBufferIndex < lBufferCount; lBufferIndex++)
	memset(ppfBuffers[lBufferIndex], 0, sizeof(LADSPA_Data) * BUFFER_SIZE);
    }

    if (lFrameSize > 0) {
      /* Read from disk. */
      readIntoBuffers(ppfBuffers, lFrameSize);
    }

    /* Run the plugins: */
    lFrameSize = lOutputFileLength - lTimeAt;
    if (lFrameSize > BUFFER_SIZE)
      lFrameSize = BUFFER_SIZE;

    for (lPluginIndex = 0; lPluginIndex < lPluginCount; lPluginIndex++) 
      ppsPluginDescriptors[lPluginIndex]
	->run(ppsPlugins[lPluginIndex],
	      lFrameSize);
    
    /* Write the output to disk. */
    writeFromBuffers(ppfBuffers, lFrameSize);

    lTimeAt += lFrameSize;
  }

  /* Deactivate:
     ----------- */

  for (lPluginIndex = 0; lPluginIndex < lPluginCount; lPluginIndex++) 
    if (ppsPluginDescriptors[lPluginIndex]->deactivate != NULL)
      ppsPluginDescriptors[lPluginIndex]->deactivate(ppsPlugins[lPluginIndex]);

  /* Cleanup:
     -------- */

  for (lPluginIndex = 0; lPluginIndex < lPluginCount; lPluginIndex++) 
    ppsPluginDescriptors[lPluginIndex]->cleanup(ppsPlugins[lPluginIndex]);

  /* Close the input and output files:
     --------------------------------- */

  closeFiles();

}