/*

 --> Sample Loaders and Sample Processing

Name: Samples.c

Description:
Routines for loading samples and converting them - dithering sample quality
(16 to 8 bit, etc) and other functions.

Portability:
All systems - all compilers

*/


#include "mikmod.h"

static SAMPLOAD *samplelist = NULL;

static SAMPLOAD *RegisterSample(SAMPLE *s, FILE *fp)
{
}


static void FreeSampleList(void)
{
    SAMPLOAD *s = samplelist, *old;

    while(s!=NULL)
    {   old = s;
        s = s->next;
        free(old);
    }
    samplelist = NULL;
}


static ULONG SampleTotal(void)
// Returns the total amount of memory required by the samplelist queue.
{
    int       total = 0;
    SAMPLOAD  *s = samplelist;

    while(s!=NULL)
    {   s->sample->flags = (s->sample->flags&~15) | s->outfmt;
        total += MD_SampleLength(MD_MUSIC,s->sample);
        s = s->next;
    }

    return total;
}


static ULONG RealSpeed(SAMPLOAD *s)
{
    return(s->sample->c2spd / ((s->scalefactor==0) ? 1 : s->scalefactor));
}    


static BOOL LoadComplex(void)     // Returns 1 on error!
{
    SAMPLOAD  *c2smp;
    ULONG     maxsize, c2spd;
    SAMPLOAD  *s;

    // make sure the samples will fit inside availible RAM
    if((maxsize = MD_SampleSpace(MD_MUSIC)*1024) != 0)
    {   while(SampleTotal() > maxsize)
        {   // First Pass - check for any 16 bit samples
            s = samplelist;
            while(s!=NULL)
            {   if(s->outfmt & SF_16BITS)
                {   SL_Sample16to8(s);
                    break;
                }
                s = s->next;
            }
    
            // Second pass (if no 16bits found above) is to take the sample
            // with the highest c2spd and dither it by half.
            if(s==NULL)
            {   s = samplelist;
                c2spd = 0;
                while(s!=NULL)
                {   if((s->sample->length) && (RealSpeed(s) > c2spd))
                    {   c2spd = RealSpeed(s);
                        c2smp = s;
                    }
                    s = s->next;
                }
                SL_HalveSample(c2smp);
            }
        }
    }

    s = samplelist;
    while(s!=NULL)
    {   // sample has to be loaded ? -> increase number of
        // samples, allocate memory and load sample.

        if(s->sample->length)
        {   if(s->sample->seekpos)
               _mm_fseek(s->fp,s->sample->seekpos,SEEK_SET);

            // Call the sample load routine of the driver module.
            // It has to return a 'handle' (>=0) that identifies
            // the sample.

            s->sample->handle = MD_SampleLoad(s, s->fp);
            s->sample->flags  = (s->sample->flags&~15) | s->outfmt;
            if(s->sample->handle<0) return 1;
        }
        s = s->next;
    }

    FreeSampleList();
    return 0;
}


SAMPLELOADER  sload_complex =
{   RegisterSample,
    LoadComplex
};

