Logo Search packages:      
Sourcecode: xabacus version File versions  Download package

vms_mmov.c

#include <stdio.h>
#include <signal.h>
#include <mme/mme_api.h>
#include "mmc_buffers.h"
#include "mmc_cmdlin.h"
#include "mmc_memory.h"
#include "mmc_wave_format.h"
#include "mmc_wave_file.h"
#include "mmc_wave.h"

#define BUFFER_PAD 4

#define DEFAULT_NCHANNELS           1
#define DEFAULT_ENCODING      WAVE_FORMAT_MULAW
#define DEFAULT_SAMPLESIZE          8
#define DEFAULT_SAMPLERATE    8000

#define DIV_ROUND_UP_(n,d) ((n + d - 1) / d)
#define ROUND_UP_(n,d) (DIV_ROUND_UP_(n,d) * d)

enum mmov_state
{
  MMOV_START,
  MMOV_PLAY,
  MMOV_WAITING,
  MMOV_CLOSE
};

#define NUM_DATA 32
struct mmov_soundformat
{
   WAVEFORMATEX wave;
   char extra_data[ NUM_DATA ];
};

static int Verbose;
static mmcWaveFileState_t wavefilestatus = mmcWaveFileStateInitialValue;
static mmcBufferList_t mmov_buffer = mmcBufferListInitialValue;
static enum mmov_state play_state;

static void mmov_cleanup( )
{
   if (mmov_buffer.b)
     {
      mmcBuffersFree (&mmov_buffer);
     }
   mmcFreeAll ();
    {
       mmcWaveInFileClose (&wavefilestatus);
    }
    return;
}

static void mmov_driver (HANDLE hWaveOut,
                       UINT wMsg,
                       DWORD dwInstance,
                       LPARAM lParam1,
                       LPARAM lParam2)
{
    switch (wMsg)
    {
      case WOM_OPEN:
      play_state = MMOV_PLAY;
      break;
      case WOM_CLOSE:
      play_state = MMOV_CLOSE;
      break;

      case WOM_DONE:
      {
        int buffer_index = mmcWaveOutGotData (&mmov_buffer, lParam1);
        mmcBuffer_p bp = &mmov_buffer.b[buffer_index];
        mmcBufferSetStatus (&mmov_buffer, buffer_index, Empty,
                        mmov_buffer.nbytes);
      }
      break;
      default:
      mmcVerboseDisplay(Verbose, "Unknown index %d", wMsg);
      break;
    }
}

void play_sound_mmov( char* FileName , int verbose )
{
    HWAVEOUT hwaveout;
    MMRESULT status;
    int mask1;
    int allDone;

    static int uDeviceId = WAVE_MAPPER;
    static int AdpcmBitsPerSample = 16;
    static int AdpcmSamplesPerBlock = 0;
    static int sizeBuffers = 0;
    static int msBuffers = 0;
    static int numBuffers = 4;
    static struct mmov_soundformat sound_format =
    {
      {
          DEFAULT_ENCODING,
          DEFAULT_NCHANNELS,
          DEFAULT_SAMPLERATE,
          0,
          0,
          DEFAULT_SAMPLESIZE,
          NUM_DATA
      }, {
          0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0
      }
    };

   Verbose = verbose;
   play_state = MMOV_START;

    /* Open the Wave In file */
    if (mmcWaveInFileOpen (FileName, &sound_format.wave, &wavefilestatus) != 0)
    {
      mmcVerboseDisplay(Verbose,"Error opening input file");
      mmov_cleanup();
       return;
    }

    if ( sound_format.wave.wFormatTag == WAVE_FORMAT_PCM)
      mmcVerboseDisplay(Verbose,"PCM file");
    else if ( sound_format.wave.wFormatTag == WAVE_FORMAT_MULAW)
      mmcVerboseDisplay(Verbose,"mu-law file");
    else if ( sound_format.wave.wFormatTag == WAVE_FORMAT_IMA_ADPCM)
      mmcVerboseDisplay(Verbose,"IMA file");
    else
      mmcVerboseDisplay(Verbose,"Unknown sound format %d",
                        sound_format.wave.wFormatTag);
    mmcVerboseDisplay(Verbose,"Channels = %d ",  sound_format.wave.nChannels );
    mmcVerboseDisplay(Verbose,"Sample rate = %d",
                  sound_format.wave.nSamplesPerSec);
    mmcVerboseDisplay(Verbose,
                  "Sample size = %d", sound_format.wave.wBitsPerSample );

    if( sound_format.wave.nChannels == 0)
      sound_format.wave.nChannels = DEFAULT_NCHANNELS;
    if( sound_format.wave.nSamplesPerSec == 0)
      sound_format.wave.nSamplesPerSec = DEFAULT_SAMPLERATE;
    if( sound_format.wave.wBitsPerSample == 0)
      sound_format.wave.wBitsPerSample = DEFAULT_SAMPLESIZE;

    if ( sound_format.wave.wFormatTag == WAVE_FORMAT_IMA_ADPCM ) {
      AdpcmSamplesPerBlock = *(Uint16 *)(&sound_format.extra_data[0]);
    }

    if ( ( sound_format.wave.wFormatTag == WAVE_FORMAT_PCM) ||
      ( sound_format.wave.wFormatTag == WAVE_FORMAT_MULAW) ) {
      mask1 = WAVE_FORMAT_FIX_BLOCK_ALIGN | WAVE_FORMAT_FIX_AVG_BPS;
      mmcWaveFormatFix((LPPCMWAVEFORMAT)(&sound_format), mask1 );
    }

    if ( sound_format.wave.wFormatTag == WAVE_FORMAT_IMA_ADPCM) {
      sizeBuffers = sound_format.wave.nBlockAlign;
      msBuffers = sizeBuffers * 1000 /
        (DIV_ROUND_UP_(AdpcmBitsPerSample,8) *
         sound_format.wave.nSamplesPerSec *
         sound_format.wave.nChannels);


    } else {
      if (!msBuffers && !sizeBuffers)
      msBuffers = 1000/numBuffers;

      if (msBuffers)
      sizeBuffers =
        ROUND_UP_(DIV_ROUND_UP_(msBuffers *
                        DIV_ROUND_UP_( sound_format.wave.wBitsPerSample,
                                    8) *
                        sound_format.wave.nSamplesPerSec *
                        sound_format.wave.nChannels,1000), BUFFER_PAD);
      else
      {
        sizeBuffers = ROUND_UP_(sizeBuffers, BUFFER_PAD);
        msBuffers = sizeBuffers * 1000 /
          (DIV_ROUND_UP_( sound_format.wave.wBitsPerSample,8) *
           sound_format.wave.nSamplesPerSec *
           sound_format.wave.nChannels);
      }
    }


    mmcVerboseDisplay(Verbose, "Buffer size = %d bytes or %d milliseconds",
                  sizeBuffers, msBuffers);

    hwaveout = NULL;

    status = mmcWaveOutOpen(&sound_format.wave, uDeviceId, &mmov_driver ,
                      WAVE_OPEN_SHAREABLE, &hwaveout);

    if (status != MMSYSERR_NOERROR)
     {
      mmov_cleanup();
      return;
     }

   if (mmcBuffersCreate (&mmov_buffer, numBuffers, sizeBuffers, BUFFER_PAD)
      != MMSYSERR_NOERROR)
     {
      mmov_cleanup();
      return;
     }

    while (1)
    {
      switch ( play_state )
      {
        case MMOV_START:
          break;

        case MMOV_PLAY:
          status = mmcWaveOutQueueBufferAll (hwaveout, &mmov_buffer, Verbose,
                                     &wavefilestatus, &allDone);
          if (allDone)
            play_state = MMOV_WAITING;
          else
           {
            if (status != MMSYSERR_NOERROR)
              {
                 mmov_cleanup();
                 return;
              }
           }
          break;

        case MMOV_WAITING:
          if ((mmcBufferFind(&mmov_buffer,Filling) != mmcBufferNone) ||
            (mmcBufferFind(&mmov_buffer,Full) != mmcBufferNone) ||
            (mmcBufferFind(&mmov_buffer,Playing) != mmcBufferNone))
            break;
          play_state = MMOV_CLOSE;

        case MMOV_CLOSE:
         status = mmcWaveOutClose (hwaveout, &mmov_buffer);
         if (status != MMSYSERR_NOERROR)
              {
                 mmov_cleanup();
                 return;
              }
          mmov_cleanup();
         return;

        default:
          mmcVerboseDisplay(Verbose,"Unknown play_state %d", play_state);
          mmov_cleanup();
         return;
      }

      mmeWaitForCallbacks (); /* block so we don't hog 100% of the CPU */
      mmeProcessCallbacks ();
    }
}

Generated by  Doxygen 1.6.0   Back to index