Logo Search packages:      
Sourcecode: fenix-plugins version File versions  Download package

wav.c

#include <stdlib.h>
#include <string.h>
#include <codec.h>
#include <vorbisfile.h>
#include <dumb.h>
#include <fenix/fxdll.h>
#include "mixer.h"

typedef struct WAV_SIGNAL WAV_SIGNAL;
typedef struct WAV_SAMPINFO WAV_SAMPINFO;


#define CONVERT16(src, pos, signconv)                        \
{                                                                              \
      signed int f = src;                                                \
      f = MID(-32768, f, 32767);                                   \
      ((short *)dst)[pos] = (short)(f ^ signconv);     \
}


struct WAV_SAMPINFO
{
      char *stream;
      unsigned short bitstream;
      unsigned short n_channels;
      long pos;
      long length;
};



struct WAV_SIGNAL
{
      char *filename;
      long length;
      unsigned long  average_bitrate;
      unsigned short channels;
      unsigned long  frequency;

};



static long wav_render_samples(void *sampinfo, float volume, float delta, long size, sample_t **samples);
static void *wav_start_samples(DUH *duh, void *signal, int n_channels, long pos);
static void wav_end_samples(void *sampinfo);
static void wav_unload_signal(void *signal);



static DUH_SIGTYPE_DESC sigtype_wav = {
      NULL,
      NULL,                   /* entheh says I don't need you */
      &wav_start_samples,
      NULL,                   /* don't need this either */
      &wav_render_samples,
      &wav_end_samples,
      &wav_unload_signal
};


long z=1;


DUH *dumb_load_wav(const char *filename) {


    file *fp;
      WAV_SIGNAL *signal;

      DUH_SIGTYPE_DESC *descptr = &sigtype_wav;

      signal = malloc(sizeof(WAV_SIGNAL));
      signal->filename = malloc((strlen(filename) + 1));
      strcpy(signal->filename,filename);



      fp = file_open_mixer(filename);
    if (fp)
    {

        char id[4], *sound_buffer; //four bytes to hold 'RIFF'
        long size; //32 bit value to hold file size
            long           chunkSize;
        short          wFormatTag;
            unsigned short wChannels;
            unsigned long  dwSamplesPerSec;
            unsigned long  dwAvgBytesPerSec;
            unsigned short wBlockAlign;
            unsigned short wBitsPerSample;
            unsigned long  data_size;


            file_getnc_mixer(id,4,fp);                                              //RIFF



        if ((id[0]=='R') && (id[1]=='I') && (id[2]=='F') && (id[3]=='F')) {



                  file_getnc_mixer(&size,4,fp);                               //SIZE
                  file_getnc_mixer(id,4,fp);                                        //WAVE

                  if ((id[0]=='W') && (id[1]=='A') && (id[2]=='V') && (id[3]=='E')) {



                              //Es un wav, por lo tanto vamos a leerlo.
                              file_getnc_mixer(id,4,fp);                            //format

                              file_getnc_mixer(&chunkSize,4,fp);

                              file_getnc_mixer(&wFormatTag,2,fp);
                              file_getnc_mixer(&wChannels,2,fp);              //channels
                              file_getnc_mixer(&dwSamplesPerSec,4,fp);  //frequency
                              file_getnc_mixer(&dwAvgBytesPerSec,4,fp);   //bytes per second
                              file_getnc_mixer(&wBlockAlign,2,fp);          //bloq alignment
                              file_getnc_mixer(&wBitsPerSample,2,fp);     //bits per sample


                              file_getnc_mixer(id,4,fp);                            //data



                              file_getnc_mixer(&data_size,4,fp);              //data written;



                              if (wFormatTag!=1) {
                                    file_close_mixer(fp);
                                    return NULL;
                              }


                              signal->length= data_size;
                              signal->average_bitrate = wBitsPerSample;
                              signal->channels = wChannels;
                              signal->frequency = dwSamplesPerSec;

                              file_close_mixer (fp);

                              return make_duh(((WAV_SIGNAL*)signal)->length-8, 0, NULL, 1, &descptr, &signal);


                  } else {
                        file_close_mixer (fp);
                        return NULL;
                  }

            } else {

                  file_close_mixer (fp);
                  return NULL;

            }
    }

}


static long wav_render_samples(void *sampinfo, float volume, float delta, long size, sample_t **samples) {

      long total_samples_read=0;
      WAV_SAMPINFO *wavsampinfo;
      sample_t *dst = samples[0];


      wavsampinfo=sampinfo;



            {
                  int i, j;
                  float mul = 1.0f * volume;
                  for (j = 0; j < size; j++) {



                        if (wavsampinfo->bitstream==16) {

                                    dst[j]= (wavsampinfo->stream[(long)wavsampinfo->pos+1]<<8);
                                    dst[j]=dst[j]|(unsigned char)(wavsampinfo->stream[(long)wavsampinfo->pos]);
                                    dst[j]=dst[j]*mul;
                                          wavsampinfo->pos=wavsampinfo->pos+2;
                                    if (get_mixer_channels()==2) {
                                          if (wavsampinfo->n_channels==2) {
                                                      dst[j+size]= wavsampinfo->stream[(long)wavsampinfo->pos+1]<<8;
                                                      dst[j+size]=dst[j+size]| (unsigned char) (wavsampinfo->stream[(long)wavsampinfo->pos]);
                                                      dst[j+size]=dst[j+size]*mul;
                                                      wavsampinfo->pos=wavsampinfo->pos+2;
                                          } else {
                                                      dst[j+size]=dst[j];
                                          }
                                    }

                        } else {

                                    dst[j]=(unsigned char) (wavsampinfo->stream[(long)wavsampinfo->pos]);
                                    dst[j]=dst[j]*mul*100;
                                    wavsampinfo->pos=wavsampinfo->pos+1;

                                    if (get_mixer_channels()==2) {

                                          if (wavsampinfo->n_channels==2) {
                                                      dst[j+size]=(unsigned char) (wavsampinfo->stream[(long)wavsampinfo->pos]);
                                                      dst[j+size]=dst[j+size]*mul*100;
                                                      wavsampinfo->pos=wavsampinfo->pos+1;
                                          } else {
                                                      dst[j+size]=dst[j];
                                          }
                                    }


                        }


                        total_samples_read++;
                        if (wavsampinfo->pos==wavsampinfo->length)
                               return total_samples_read;

                  }
            }


            return total_samples_read;
}


static void *wav_start_samples(DUH *duh, void *signal, int n_channels, long pos)
{

      FILE *file;
      WAV_SAMPINFO *sampinfo;
      WAV_SIGNAL *signalx;
      unsigned short wChannels;

      (void)duh;
      signalx=signal;


      file = file_open_mixer  (signalx->filename);

      if (!file)
            return NULL;



      sampinfo = malloc(sizeof(WAV_SAMPINFO));
      if(!sampinfo) {
            fclose(file);
            return NULL;
      }


      file_skip_mixer (file, 22);

      file_getnc_mixer(&wChannels,2,file);

      file_skip_mixer (file, 20);



      sampinfo->stream=(char *) malloc (signalx->length);

      file_getnc_mixer(sampinfo->stream,signalx->length,file);



      ((WAV_SAMPINFO*)sampinfo)->n_channels = wChannels;
      ((WAV_SAMPINFO*)sampinfo)->pos = pos;
      ((WAV_SAMPINFO*)sampinfo)->length=signalx->length;
      ((WAV_SAMPINFO*)sampinfo)->bitstream=signalx->average_bitrate;

      file_close_mixer (file);

      return sampinfo;
}


static void wav_end_samples(void *sampinfo) {



      if(sampinfo)
      {
            free ( ((WAV_SAMPINFO*)sampinfo)->stream);
            free(sampinfo);
      }

      return;

}


static void wav_unload_signal(void *signal) {

      if(signal)
      {
            free(signal);
      }
}

Generated by  Doxygen 1.6.0   Back to index