#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>

#include "drv.h"

#define AD_BUFFER_SIZE  8192	// 512 * 16
#define DA_BUFFER_SIZE  500000
#define DEVICE_NAME	"/dev/kt"

static int   ad_data[AD_BUFFER_SIZE];
static short da_data[DA_BUFFER_SIZE];

static int main_end_flag;

typedef struct
{
	char		riff[4];	// = "RIFF"
	unsigned long	total_size;	// 全体サイズ
	char		fmt[8];		// "WAVEfmt "
	unsigned long	fmt_size;	// fmt チャンクサイズ
	unsigned short	format;		// フォーマットの種類
	unsigned short	channel;	// チャンネル
	unsigned long	rate;		// サンプリングレート
	unsigned long	avgbyte;	// rate * block
	unsigned short	block;		// channels * bit / 8
	unsigned short	bit;		// ビット数
	char		data[4];	// = "data"
	unsigned long	data_size;	// データサイズ
} WAVEFORMAT;

void sigint_action(int signum, siginfo_t *info, void *ctx)
{
//    printf("sigint_handler(%d): signo(%d) code(0x%x)\n",
//           signum, info->si_signo, info->si_code);
    
    main_end_flag = 1;
}


int main(int argc, char **argv)
{
    struct sigaction sa_sigint;
    
    int fd;
    int stat;
    
    int    ret_val;
    struct timeval time_out;
    fd_set rfds, wfds;
    
    int rbyte;
    int wbyte;
    
    char filename[64];

    int i, j, rdcnt, def = 0, ret, smpl;

    FILE *fp;
    fpos_t pos;
    WAVEFORMAT header;

    char *ptr;
    int ptr_size;

    memset( &header, 0, sizeof(header) );

    if(argc == 2)
    {
        strcpy(filename, argv[1]);
    }
    else
    {
        strcpy(filename, "/root/sin_data.dat");
        def = 1;
    }
    fd = open( DEVICE_NAME, O_RDWR, 0666 );
    if(fd < 0)
    {
        printf("%s open error.\n", DEVICE_NAME);
        return -1;
    }
    
    memset( &header, 0, sizeof(header) );

    /* Open file */
    if ((fp = fopen( filename, "rb")) == NULL ) {
        printf("file open error! (%s)\n", filename );
        close( fd );
        return -1;
    }

    /* Header Read */
    if( fread( &header, sizeof( header ), 1, fp ) < 1 )
    {
        printf("file read error!\n");
        close( fd );
        fclose( fp );
        return -1;
    }
    if( def )
    {
        header.channel = 1;
        header.rate = 8000;
        header.bit = 16;
    }
    printf(" channel = %d\n", header.channel);
    printf("    rate = %d\n", header.rate);
    printf("     bit = %d\n", header.bit);

    /* File Read */
    smpl = fread( da_data, 1, sizeof(da_data), fp );
    if( smpl < 1 )
    {
        printf("file read error!\n");
        close( fd );
        fclose( fp );
        return -1;
    }
    printf("filesize = %d\n", smpl );
    printf("  sample = %d\n", smpl / (header.bit / 8) / header.channel );

    /* File Close */
    fclose( fp );
    
    memset(&sa_sigint, 0, sizeof(sa_sigint));
    sa_sigint.sa_sigaction = sigint_action;
    sa_sigint.sa_flags = SA_RESTART | SA_SIGINFO;
    
    if (sigaction(SIGINT, &sa_sigint, NULL) < 0)
    {
        printf("sigaction error.\n");
    }

    ptr_size = 0;
    while(!main_end_flag)
    {
        do
        {
            FD_ZERO(&rfds);
            FD_ZERO(&wfds);
            FD_SET(fd, &rfds);
            FD_SET(fd, &wfds);
            
            time_out.tv_sec  = 0;
            time_out.tv_usec = 10 * 1000;
            ret_val = select(fd+1, &rfds, &wfds, NULL, &time_out);
        }while(ret_val == 0);
        
        if(ret_val < 0)
        {
            printf("ret_val = %d\n", ret_val);
            main_end_flag = 1;
            break;
        }

        /* データ書き込み処理 */
        if(FD_ISSET(fd, &wfds))
        {
            if( ptr_size == 0 )
            {
                ptr = (char *)da_data;
                ptr_size = smpl;
            }
            wbyte = write( fd, ptr, ptr_size );
            ptr += wbyte;
            ptr_size -= wbyte;
        }
    }
    
    /* Close device */
    close( fd );
    
    return 0;
}

/* EOF */

