view libao2/ao_pcm.c @ 6643:01eaf5358176

Changed the way that the streams are requested. Now the streams are requested depending on the bandwidth option. If the option is not set, the higher bitrate stream is chose. Moved the asf_http_streaming_ctrl_t struct to asf.h
author bertrand
date Fri, 05 Jul 2002 02:46:03 +0000
parents 827f08ddf044
children 8411ea0d9078
line wrap: on
line source

#include "config.h"

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

#include "bswap.h"
#include "afmt.h"
#include "audio_out.h"
#include "audio_out_internal.h"

static ao_info_t info = 
{
	"RAW PCM/WAVE file writer audio output",
	"pcm",
	"Atmosfear",
	""
};

LIBAO_EXTERN(pcm)

extern int vo_pts;

char *ao_outputfilename = NULL;
int ao_pcm_waveheader = 1;

#define WAV_ID_RIFF 0x46464952 /* "RIFF" */
#define WAV_ID_WAVE 0x45564157 /* "WAVE" */
#define WAV_ID_FMT  0x20746d66 /* "fmt " */
#define WAV_ID_DATA 0x61746164 /* "data" */
#define WAV_ID_PCM  0x0001

struct WaveHeader
{
	unsigned long riff;
	unsigned long file_length;
	unsigned long wave;
	unsigned long fmt;
	unsigned long fmt_length;
	short fmt_tag;
	short channels;
	unsigned long sample_rate;
	unsigned long bytes_per_second;
	short block_align;
	short bits;
	unsigned long data;
	unsigned long data_length;
};

/* init with default values */
static struct WaveHeader wavhdr = {
	le2me_32(WAV_ID_RIFF),
	le2me_32(0x00000000),
	le2me_32(WAV_ID_WAVE),
	le2me_32(WAV_ID_FMT),
	le2me_32(16),
	le2me_16(WAV_ID_PCM),
	le2me_16(2),
	le2me_32(44100),
	le2me_32(192000),
	le2me_16(4),
	le2me_16(16),
	le2me_32(WAV_ID_DATA),
	le2me_32(0x00000000)
};

static FILE *fp = NULL;

// to set/get/query special features/parameters
static int control(int cmd,int arg){
    return -1;
}

// open & setup audio device
// return: 1=success 0=fail
static int init(int rate,int channels,int format,int flags){
	int bits;
	if(!ao_outputfilename) {
		ao_outputfilename = (char *) malloc(sizeof(char) * 14);
		strcpy(ao_outputfilename,
		       (ao_pcm_waveheader ? "audiodump.wav" : "audiodump.pcm"));
	}
	
	/* bits is only equal to format if (format == 8) or (format == 16);
	   this means that the following "if" is a kludge and should
	   really be a switch to be correct in all cases */
	if (format == AFMT_S16_BE) { bits = 16;	}
	else { bits = format; }

	wavhdr.channels = le2me_16(channels);
	wavhdr.sample_rate = le2me_32(rate);
	wavhdr.bytes_per_second = rate * (bits / 8) * channels;
	wavhdr.bytes_per_second = le2me_32(wavhdr.bytes_per_second);
	wavhdr.bits = le2me_16(bits);

	printf("PCM: File: %s (%s)\n"
	       "PCM: Samplerate: %iHz Channels: %s Format %s\n",
	       ao_outputfilename, (ao_pcm_waveheader?"WAVE":"RAW PCM"), rate,
	       (channels > 1) ? "Stereo" : "Mono", audio_out_format_name(format));
	printf("PCM: Info: fastest dumping is achieved with -vo null "
	       "-hardframedrop.\n"
	       "PCM: Info: to write WAVE files use -waveheader (default); "
	       "for RAW PCM -nowaveheader.\n");

	fp = fopen(ao_outputfilename, "wb");

	ao_data.outburst = 65536;


	if(fp) {
		if(ao_pcm_waveheader) /* Reserve space for wave header */
			fwrite(&wavhdr,sizeof(wavhdr),1,fp);
		return 1;
	}
	printf("PCM: Failed to open %s for writing!\n", ao_outputfilename);
	return 0;
}

// close audio device
static void uninit(){
	
	if(ao_pcm_waveheader && fseek(fp, 0, SEEK_SET) == 0){ /* Write wave header */
		wavhdr.file_length = wavhdr.data_length + sizeof(wavhdr) - 8;
		wavhdr.file_length = le2me_32(wavhdr.file_length);
		fwrite(&wavhdr,sizeof(wavhdr),1,fp);
	}
	fclose(fp);
	free(ao_outputfilename);
}

// stop playing and empty buffers (for seeking/pause)
static void reset(){

}

// stop playing, keep buffers (for pause)
static void audio_pause()
{
    // for now, just call reset();
    reset();
}

// resume playing, after audio_pause()
static void audio_resume()
{
}

// return: how many bytes can be played without blocking
static int get_space(){

    if(vo_pts)
      return ao_data.pts < vo_pts ? ao_data.outburst : 0;
    return ao_data.outburst;
}

// plays 'len' bytes of 'data'
// it should round it down to outburst*n
// return: number of bytes played
static int play(void* data,int len,int flags){

#ifdef WORDS_BIGENDIAN
	register int i;
	unsigned short *buffer = (unsigned short *) data;

	if (wavhdr.bits == le2me_16(16)) {
	  for(i = 0; i < len/2; ++i) {
	    buffer[i] = le2me_16(buffer[i]);
	  }
	}
	/* FIXME: take care of cases with more than 8 bits here? */
#endif 
	
	//printf("PCM: Writing chunk!\n");
	fwrite(data,len,1,fp);

	if(ao_pcm_waveheader)
		wavhdr.data_length += len;
	
	return len;
}

// return: delay in seconds between first and last sample in buffer
static float get_delay(){

    return 0.0;
}