/* > arsnd.c

 *  SJ Middleton, 1994

 */

#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "arutils.h"
#include "utils.h"

double arsnd_realsamplerate(const armovie_soundstr *sp)
{
    return sp->rate < 256 ? 1000000/sp->rate : sp->rate;
}

/*
 * These 3 functions are only valid if armovie_Seekable is set
 */

int arsnd_bytes_per_sec(const armovie_soundstr *sp)
{
    return (int) ceil(arsnd_realsamplerate(sp)*sp->precision/8*sp->channels);
}

int arsnd_s2b(const armovie_soundstr *sp, int nsamples)
{
    return nsamples * sp->channels * sp->precision/8;
}

int arsnd_b2s(const armovie_soundstr *sp, int nbytes)
{
    return nbytes * 8 / (sp->channels * sp->precision);
}

int arsnd_chunksize(armovie_hdr *hdr)
{
    return hdr->sound->format ? (int) (hdr->frames_per_chunk/hdr->fps*arsnd_bytes_per_sec(hdr->sound)) : 0;
}

static char armovie__prefix[16] = "ARPlayer";

void arsnd_setprefix(const char *prefix)
{
    strncpy(armovie__prefix, prefix, sizeof(armovie__prefix));
    armovie__prefix[sizeof(armovie__prefix)-1] = '\0';
}

char *arsnd_varval(const char *suffix)
{
    char buffer[64];
    sprintf(buffer, "%s$%s", armovie__prefix, suffix);
    return getenv(buffer);
}

BOOL arsnd_opt(int c)
{
    char *var = arsnd_varval("Options");
    BOOL r = var == NULL ? FALSE : strchr(var, tolower(c)) != NULL || strchr(var, toupper(c)) != NULL;
    return r;
}

os_error *arsnd_readinfo_path(const char *path, const char *name, arsnd_info *info, BOOL read_names)
{
    char        buffer[256];
    os_error    *e;
    filehandle  f;
    sprintf(buffer, "%s.%s.Info", path, name);
    if ((e = file_open(fopt_Read, buffer, &f)) == NULL)
    {
/* read text lines */
        file_readlinebuffer(f, buffer, sizeof(buffer));
        if (read_names)
            info->description = strdup(buffer);

        file_readlinebuffer(f, buffer, sizeof(buffer));
        if (read_names)
            info->author = strdup(buffer);

/* read information lines */
        file_readlinebuffer(f, buffer, sizeof(buffer));
        if (strtoul(buffer, NULL, 10) != 0)
            info->flags |= arsnd_Seekable;

        file_readlinebuffer(f, buffer, sizeof(buffer));
        info->nbits = (int) strtoul(buffer, NULL, 10);

        file_readlinebuffer(f, buffer, sizeof(buffer));
        if (strtoul(buffer, NULL, 10) != 0)
            info->flags |= arsnd_VariableSize;

        file_readlinebuffer(f, buffer, sizeof(buffer));
        info->max_size = strtod(buffer, NULL);

        file_readlinebuffer(f, buffer, sizeof(buffer));
        info->channel_overhead = (int) strtoul(buffer, NULL, 10);

        file_close(f);
    }

/* check whether conversion code is available */
    sprintf(buffer, "%s.%s.From16", path, name);
    if (file_size(buffer, NULL) > 0)
        info->flags |= arsnd_FromCode;

    sprintf(buffer, "%s.%s.To16", path, name);
    if (file_size(buffer, NULL) > 0)
        info->flags |= arsnd_ToCode;

    return e;
}

os_error *arsnd_readinfo(const char *name, arsnd_info *info, BOOL read_names)
{
    return arsnd_readinfo_path("<ARMovie$SoundDir>", name, info, read_names);
}

void arsnd_freeinfo(arsnd_info *info)
{
    free(info->description);
    free(info->author);
    info->description = info->author = NULL;
}

/* eof arsnd.c */
