/***************************************************************************
    mmusbplay  -  A simple command line .wav file player

    begin                : July 26, 2003
    copyright            : (C) 2003 by Michael Minn
    email                : See www.michaelminn.com

    This program is free software; you can redistribute it and/or modify
    it under the terms of version 2 of the GNU General Public License as 
    published by the Free Software Foundation (see COPYING or www.gnu.org).

***************************************************************************/

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/cdrom.h> // /usr/include/linux/cdrom.h
#include <linux/soundcard.h>
#include "mmusbaudio.h"
#include "mmuwave_file_header.h"

int main(int argc, char **argv)
{
	const char *device_name = "/dev/dsp";

	if ((argc < 2) || (argc > 3))
		return fprintf(stderr, "SYNTAX: mmusbplay <wav_file> [dsp_device]\n");

	if (argc >= 3)
		device_name = argv[2];

	int descriptor = open(argv[1], O_RDONLY);
	if (descriptor <= 0)
		return fprintf(stderr, "Failure opening %s: %s\n", argv[1], strerror(errno));

	mmuwave_file_header header;
	if (read(descriptor, &header, sizeof(header)) < (int) sizeof(header))
		return fprintf(stderr, "Failure reading .wav file header from %s: %s\n", argv[1], strerror(errno));

	if (!header.is_valid_header())
		return fprintf(stderr, "%s is not a valid .wav file\n", argv[1]);

	int device = open(device_name, O_WRONLY);
	if (device <= 0)
		return fprintf(stderr, "Failure opening sound device %s: %s\n", device_name, strerror(errno));

	int audio_format = AFMT_S16_LE;
	if (header.bits_per_sample == 8)
		audio_format = AFMT_U8;
	else if (header.bits_per_sample == 24)
		audio_format = AFMT_S24_LE;
	else if (header.bits_per_sample != 16)
		return fprintf(stderr, "%d bits per sample unsupported\n", header.bits_per_sample);
	
	if (ioctl(device, SNDCTL_DSP_SETFMT, &audio_format) < 0)
		return fprintf(stderr, "Failure setting device %s to %d bits per sample: %s", 
			device_name, header.bits_per_sample, strerror(errno));

	int channels = header.channel_numbers;
	if (ioctl(device, SNDCTL_DSP_CHANNELS, &channels) < 0)
		return fprintf(stderr, "Failure setting device %s to %d channels: %s", 
			device_name, channels, strerror(errno));

	if (ioctl(device, SNDCTL_DSP_SPEED, &header.sample_rate) < 0)
		return fprintf(stderr, "Failure setting device %s to %d samples/sec: %s", 
			device_name, header.sample_rate, strerror(errno));

	int status = 0;
	char buffer[1024 * 3];
	while ((status = read(descriptor, buffer, sizeof(buffer))) > 0)
		if ((status = write(device, buffer, status)) < 0)
		{
			fprintf(stderr, "Failure writing to device %s: %s\n", device_name, strerror(errno));
			//usleep(250000);
			return -1;
		}

	//sleep(2);

	close(device);

	return 0;
};
