Blame libao/audio_out_aif.c

Packit 64f477
/*
Packit 64f477
 * audio_out_aif.c
Packit 64f477
 * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
Packit 64f477
 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
Packit 64f477
 *
Packit 64f477
 * This file is part of a52dec, a free ATSC A-52 stream decoder.
Packit 64f477
 * See http://liba52.sourceforge.net/ for updates.
Packit 64f477
 *
Packit 64f477
 * a52dec is free software; you can redistribute it and/or modify
Packit 64f477
 * it under the terms of the GNU General Public License as published by
Packit 64f477
 * the Free Software Foundation; either version 2 of the License, or
Packit 64f477
 * (at your option) any later version.
Packit 64f477
 *
Packit 64f477
 * a52dec is distributed in the hope that it will be useful,
Packit 64f477
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 64f477
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 64f477
 * GNU General Public License for more details.
Packit 64f477
 *
Packit 64f477
 * You should have received a copy of the GNU General Public License
Packit 64f477
 * along with this program; if not, write to the Free Software
Packit 64f477
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit 64f477
 */
Packit 64f477
Packit 64f477
#include "config.h"
Packit 64f477
Packit 64f477
#include <stdio.h>
Packit 64f477
#include <stdlib.h>
Packit 64f477
#include <errno.h>
Packit 64f477
#include <inttypes.h>
Packit 64f477
Packit 64f477
#include "a52.h"
Packit 64f477
#include "audio_out.h"
Packit 64f477
#include "audio_out_internal.h"
Packit 64f477
Packit 64f477
typedef struct aif_instance_s {
Packit 64f477
    ao_instance_t ao;
Packit 64f477
    int sample_rate;
Packit 64f477
    int set_params;
Packit 64f477
    int flags;
Packit 64f477
    int size;
Packit 64f477
} aif_instance_t;
Packit 64f477
Packit 64f477
static uint8_t aif_header[] = {
Packit 64f477
    'F', 'O', 'R', 'M', 0xff, 0xff, 0xff, 0xfe, 'A', 'I', 'F', 'F',
Packit 64f477
    'C', 'O', 'M', 'M', 0, 0, 0, 18,
Packit 64f477
    0, 2, 0x3f, 0xff, 0xff, 0xf4, 0, 16, 0x40, 0x0e, -1, -1, 0, 0, 0, 0, 0, 0,
Packit 64f477
    'S', 'S', 'N', 'D', 0xff, 0xff, 0xff, 0xd8, 0, 0, 0, 0, 0, 0, 0, 0
Packit 64f477
};
Packit 64f477
Packit 64f477
static int aif_setup (ao_instance_t * _instance, int sample_rate, int * flags,
Packit 64f477
		      sample_t * level, sample_t * bias)
Packit 64f477
{
Packit 64f477
    aif_instance_t * instance = (aif_instance_t *) _instance;
Packit 64f477
Packit 64f477
    if ((instance->set_params == 0) && (instance->sample_rate != sample_rate))
Packit 64f477
	return 1;
Packit 64f477
    instance->sample_rate = sample_rate;
Packit 64f477
Packit 64f477
    *flags = instance->flags;
Packit 64f477
    *level = 1;
Packit 64f477
    *bias = 384;
Packit 64f477
Packit 64f477
    return 0;
Packit 64f477
}
Packit 64f477
Packit 64f477
static void store4 (uint8_t * buf, int value)
Packit 64f477
{
Packit 64f477
    buf[0] = value >> 24;
Packit 64f477
    buf[1] = value >> 16;
Packit 64f477
    buf[2] = value >> 8;
Packit 64f477
    buf[3] = value;
Packit 64f477
}
Packit 64f477
Packit 64f477
static void store2 (uint8_t * buf, int16_t value)
Packit 64f477
{
Packit 64f477
    buf[0] = value >> 8;
Packit 64f477
    buf[1] = value;
Packit 64f477
}
Packit 64f477
Packit 64f477
static int aif_play (ao_instance_t * _instance, int flags, sample_t * _samples)
Packit 64f477
{
Packit 64f477
    aif_instance_t * instance = (aif_instance_t *) _instance;
Packit 64f477
    int16_t int16_samples[256*2];
Packit 64f477
Packit 64f477
#ifdef LIBA52_DOUBLE
Packit 64f477
    float samples[256 * 2];
Packit 64f477
    int i;
Packit 64f477
Packit 64f477
    for (i = 0; i < 256 * 2; i++)
Packit 64f477
	samples[i] = _samples[i];
Packit 64f477
#else
Packit 64f477
    float * samples = _samples;
Packit 64f477
#endif
Packit 64f477
Packit 64f477
    if (instance->set_params) {
Packit 64f477
	instance->set_params = 0;
Packit 64f477
	store2 (aif_header + 30, instance->sample_rate);
Packit 64f477
	fwrite (aif_header, sizeof (aif_header), 1, stdout);
Packit 64f477
    }
Packit 64f477
Packit 64f477
    float2s16_2 (samples, int16_samples);
Packit 64f477
    s16_BE (int16_samples, 2);
Packit 64f477
    fwrite (int16_samples, 256 * sizeof (int16_t) * 2, 1, stdout);
Packit 64f477
Packit 64f477
    instance->size += 256 * sizeof (int16_t) * 2;
Packit 64f477
Packit 64f477
    return 0;
Packit 64f477
}
Packit 64f477
Packit 64f477
static void aif_close (ao_instance_t * _instance)
Packit 64f477
{
Packit 64f477
    aif_instance_t * instance = (aif_instance_t *) _instance;
Packit 64f477
Packit 64f477
    if (fseek (stdout, 0, SEEK_SET) < 0)
Packit 64f477
	return;
Packit 64f477
Packit 64f477
    store4 (aif_header + 4, instance->size + 46);
Packit 64f477
    store4 (aif_header + 22, instance->size / 4);
Packit 64f477
    store4 (aif_header + 42, instance->size + 8);
Packit 64f477
    fwrite (aif_header, sizeof (aif_header), 1, stdout);
Packit 64f477
}
Packit 64f477
Packit 64f477
static ao_instance_t * aif_open (int flags)
Packit 64f477
{
Packit 64f477
    aif_instance_t * instance;
Packit 64f477
Packit 64f477
    instance = malloc (sizeof (aif_instance_t));
Packit 64f477
    if (instance == NULL)
Packit 64f477
	return NULL;
Packit 64f477
Packit 64f477
    instance->ao.setup = aif_setup;
Packit 64f477
    instance->ao.play = aif_play;
Packit 64f477
    instance->ao.close = aif_close;
Packit 64f477
Packit 64f477
    instance->sample_rate = 0;
Packit 64f477
    instance->set_params = 1;
Packit 64f477
    instance->flags = flags;
Packit 64f477
    instance->size = 0;
Packit 64f477
Packit 64f477
    return (ao_instance_t *) instance;
Packit 64f477
}
Packit 64f477
Packit 64f477
ao_instance_t * ao_aif_open (void)
Packit 64f477
{
Packit 64f477
    return aif_open (A52_STEREO);
Packit 64f477
}
Packit 64f477
Packit 64f477
ao_instance_t * ao_aifdolby_open (void)
Packit 64f477
{
Packit 64f477
    return aif_open (A52_DOLBY);
Packit 64f477
}