Ejemplo n.º 1
0
mad_fixed_t random_value(void)
{
	mad_fixed_t result;
	float tmp = (rand()/(RAND_MAX+1.0))-0.5;
	result = mad_f_tofixed(tmp);

	return result;
}
Ejemplo n.º 2
0
int main(int argc, char* argv[])
{
	FILE *fp1;
	FILE *fp2;
	FILE *fp3;
	mad_fixed_t X[num_inp], T[num_out], H[num_hid], Y[num_out];
	mad_fixed_t W_xh[num_inp][num_hid], W_hy[num_hid][num_out];
	mad_fixed_t dW_xh[num_inp][num_hid], dW_hy[num_hid][num_out];
	mad_fixed_t Q_h[num_hid], Q_y[num_out];
	mad_fixed_t dQ_h[num_hid], dQ_y[num_out];
	mad_fixed_t delta_h[num_hid], delta_y[num_out];
	mad_fixed_t sum, mse;
	int Icycle, Itrain;
	int i, j, h;

	fp1 = fopen(train_file, "r");
	fp2 = fopen(weight_file, "w");
	fp3 = fopen(mse_file, "w");
	if (fp1 == NULL) {
		puts("File not exist !!");
		getchar();
		exit(1);
	}

	srand((int)time(0));

	for (h = 0; h < num_hid; h++) {
		for (i = 0; i < num_inp; i++) {
			W_xh[i][h] = random_value();
			dW_xh[i][h] = F_ZERO;
		}
	}

	for (j = 0; j <= num_out; j++) {
		for (h = 0; h < num_hid; h++) {
			W_hy[h][j] = random_value();
			dW_hy[h][j] = F_ZERO;
		}
	}

	for (h = 0; h < num_hid; h++) {
		Q_h[h] = F_ZERO;
		dQ_h[h] = F_ZERO;
		delta_h[h] = F_ZERO;
	}

	for (j = 0; j < num_out; j++) {
		Q_y[j] = random_value();
		dQ_y[j] = F_ZERO;
		delta_y[j] = F_ZERO;
	}

	/*start learning */
	float tmp;
	for (Icycle = 0; Icycle < num_cycle; Icycle++) {
		mse = F_ZERO;

		fseek(fp1, 0, 0);
		for (Itrain = 0; Itrain < num_train; Itrain++) {
			for (i = 0; i < num_inp; i++) {
				tmp = parser(fp1);
				X[i] = mad_f_tofixed(tmp);
			}


			for (j = 0; j < num_out; j++) {
				tmp = parser(fp1);
				T[j]= mad_f_tofixed(tmp);
			}

			for (h = 0; h < num_hid; h++) {
				sum = F_ZERO;
				for (i = 0; i < num_inp; i++) {
					sum = mad_f_add(sum, mad_f_mul(X[i], W_xh[i][h]));
				}
				/* H[h] = (float)1.0 / (1.0 + exp(-(sum - Q_h[h]))); */
				tmp = exp(-1.0 * mad_f_todouble(mad_f_sub(sum, Q_h[h])));
				mad_fixed_t exp_result = mad_f_tofixed(tmp);
				H[h] = mad_f_div(F_POS_ONE, mad_f_add(F_POS_ONE, exp_result));
			}

			for (j = 0; j < num_out; j++) {
				sum = F_ZERO;
				for (h = 0; h < num_hid; h++) {
					sum = mad_f_add(sum, mad_f_mul(H[h], W_hy[h][j]));
				}
				/* Y[j] = (float)1.0 / (1.0 + exp(-(sum - Q_y[j]))); */
				tmp = exp(-1.0 * mad_f_todouble(mad_f_sub(sum, Q_y[j])));
				mad_fixed_t exp_result = mad_f_tofixed(tmp);
				Y[j] = mad_f_div(F_POS_ONE, mad_f_add(F_POS_ONE, exp_result));
			}

			for (j = 0; j < num_out; j++) {
				/* delta_y[j] = Y[j] * (1.0 - Y[j]) * (T[j] - Y[j]); */
				mad_fixed_t first, second, third;
				first = Y[j];
				second = mad_f_sub(F_POS_ONE, Y[j]);
				third = mad_f_sub(T[j], Y[j]);
				delta_y[j] = mad_f_mul(mad_f_mul(first, second), third);
			}

			for (h = 0; h < num_hid; h++) {
				sum = F_ZERO;
				for (j = 0; j < num_out; j++) {
					/* sum = sum + W_hy[h][j] * delta_y[j]; */
					sum = mad_f_add(sum, mad_f_mul(W_hy[h][j], delta_y[j]));
				}
				/* delta_h[h] = H[h] * (1.0 - H[h]) * sum; */
				mad_fixed_t first, second, third;
				first = H[h];
				second = mad_f_sub(F_POS_ONE, H[h]);
				third = sum;
				delta_h[h] = mad_f_mul(mad_f_mul(first, second), sum);
			}

			for (j = 0; j < num_out; j++) {
				for (h = 0; h < num_hid; h++) {
					/* dW_hy[h][j] = eta * delta_y[j] * H[h] + alpha * dW_hy[h][j]; */
					mad_fixed_t first, second;
					first = mad_f_mul(mad_f_mul(F_ETA, delta_y[j]), H[h]);
					second = mad_f_mul(F_ALPHA, dW_hy[h][j]);
					dW_hy[h][j] = mad_f_add(first, second);
				}
			}

			for (j = 0; j < num_out; j++) {
				/* dQ_y[j] = -eta * delta_y[j] + alpha * dQ_y[j]; */
				mad_fixed_t first, second;
				first = mad_f_mul(F_NEG_ETA, delta_y[j]);
				second = mad_f_mul(F_ALPHA, dQ_y[j]);
				dQ_y[j] = mad_f_add(first, second);
			}
			for (h = 0; h < num_hid; h++) {
				for (i = 0; i < num_inp; i++) {
					/* dW_xh[i][h] = eta * delta_h[h] * X[i] + alpha * dW_xh[i][h]; */
					mad_fixed_t first, second;
					first = mad_f_mul(X[i], mad_f_mul(F_ETA, delta_h[h]));
					second = mad_f_mul(F_ALPHA, dW_xh[i][h]);
					dW_xh[i][h] = mad_f_add(first, second);
				}
			}

			for (h = 0; h < num_hid; h++) {
				/* dQ_h[h] = -eta * delta_h[h] + alpha * dQ_h[h]; */
				mad_fixed_t first, second;
				first = mad_f_mul(F_NEG_ETA, delta_h[h]);
				second = mad_f_mul(F_ALPHA, dQ_h[h]);
				dQ_h[h] = mad_f_add(first, second);
			}

			for (j = 0; j < num_out; j++) {
				for (h = 0; h < num_hid; h++) {
					/* W_hy[h][j] = W_hy[h][j] + dW_hy[h][j]; */
					tmp = mad_f_todouble(W_hy[h][j]);
					W_hy[h][j] = mad_f_add(W_hy[h][j], dW_hy[h][j]);
				}
			}

			for (j = 0; j < num_out; j++) {
				/* Q_y[j] = Q_y[j] + dQ_y[j]; */
				Q_y[j] = mad_f_add(Q_y[j], dQ_y[j]);
			}

			for (h = 0; h < num_hid; h++) {
				for (i = 0; i < num_inp; i++) {
					/* W_xh[i][h] = W_xh[i][h] + dW_xh[i][h]; */
					W_xh[i][h] = mad_f_add(W_xh[i][h], dW_xh[i][h]);
				}
			}

			for (h = 0; h < num_hid; h++) {
				/* Q_h[h] = Q_h[h] + dQ_h[h]; */
				Q_h[h] = mad_f_add(Q_h[h], dQ_h[h]);
			}

			for (j = 0; j < num_out; j++) {
				/* mse += (T[j] - Y[j]) * (T[j] - Y[j]); */
				mad_fixed_t first, second;
				first = mad_f_sub(T[j], Y[j]);
				second = mad_f_sub(T[j], Y[j]);
				mse = mad_f_add(mse, mad_f_mul(first, second));
			}
		}

		/* mse = mse / num_train; */
		mse = mad_f_div(mse, mad_f_tofixed(num_train));
		if ((Icycle % 10) == 9) {
			printf("\nIcycle=%3d \nmse=%-8.6f\n", Icycle, mad_f_todouble(mse));
			fprintf(fp3,"%3d \n%-8.6f\n", Icycle, mad_f_todouble(mse));
		}
	}

	printf("\n");
	for (h = 0; h < num_hid; h++) {
		for (i = 0; i < num_inp; i++) {
			printf("W_xh[%2d][%2d]=%-8.4f\t", i, h, mad_f_todouble(W_xh[i][h]));
			fprintf(fp2,"%-8.4f\t", mad_f_todouble(W_xh[i][h]));
		}
		printf("\n");
		fprintf(fp2,"\n");
	}
	printf("\n");
	fprintf(fp2,"\n");
	for (j = 0; j < num_out; j++) {
		for (h = 0; h < num_hid; h++) {
			printf("W_hy[%2d][%2d]=%-8.4f\t", h, j, mad_f_todouble(W_hy[h][j]));
			fprintf(fp2,"%-8.4f\t", mad_f_todouble(W_hy[h][j]));
		}
		printf("\n");
		fprintf(fp2,"\n");
	}
	printf("\n");
	fprintf(fp2,"\n");

	for (h = 0; h < num_hid; h++) {
		printf("Q_h[%2d]=%-8.4f\t", h, mad_f_todouble(Q_h[h]));
		fprintf(fp2,"%-8.4f\t", mad_f_todouble(Q_h[h]));
	}
	printf("\n\n");
	fprintf(fp2,"\n\n");
	for (j = 0; j < num_out; j++) {
		printf("Q_y[%2d]=%-8.4f\t", j, mad_f_todouble(Q_y[j]));
		fprintf(fp2,"%-8.4f\t", mad_f_todouble(Q_y[j]));
	}
	printf("\n\n");
	fprintf(fp2,"\n\n");

	fclose(fp1);
	fclose(fp2);
	fclose(fp3);
	return 0;
}
Ejemplo n.º 3
0
#include <math.h>
#include <time.h>
#include <mad.h>

#define		num_cycle		3000
#define		num_train  		1500
#define		num_inp			2
#define		num_hid    		4
#define		num_out    		1
#define		eta     		0.5
#define		alpha   		0.2
#define		train_file		"test.txt"
#define		weight_file		"pwm.wei"
#define		mse_file		"pwm.mes"

const mad_fixed_t F_POS_ONE  	 = mad_f_tofixed((float)1.0);
const mad_fixed_t F_POS_TWO  	 = mad_f_tofixed((float)2.0);
const mad_fixed_t F_NEG_ONE  	 = mad_f_tofixed((float)-1.0);
const mad_fixed_t F_ZERO	 	 = mad_f_tofixed((float)0.0);
const mad_fixed_t F_POS_RDDO 	 = mad_f_tofixed((float)0.5);
const mad_fixed_t F_NEG_RDDO 	 = mad_f_tofixed((float)-0.5);
const mad_fixed_t F_ALPHA	 	 = mad_f_tofixed((float)alpha);
const mad_fixed_t F_ETA		 	 = mad_f_tofixed((float)eta);
const mad_fixed_t F_NEG_ETA	 	 = mad_f_tofixed((float)-eta);

float parser(FILE *fp)
{
	char c;
	char str[50], *p;
	float res;
Ejemplo n.º 4
0
int main(int argc, char *argv[])
{
    int fd = 0;
    char *currentfile, old_dir[PATH_MAX];
    playlist *pl = NULL;
    struct id3_file *id3struct = NULL;
    struct id3_tag *id3tag = NULL;
    int retval;

    buffer playbuf;
    
    struct mad_decoder decoder;
    pthread_t keyb_thread;

    key_t sem_key;
    key_t mem_key;
    key_t frames_key;

    union semun sem_ops;
    int shm_id;
    int frames_id;
    mad_decoder_position = 0;
    output_buffer_position = 0;
    
    old_dir[0] = '\0';

    playbuf.pl = pl = new_playlist();

    if (!pl)
    {
        fprintf(stderr, "malloc failed at startup!\n");
        exit(1);
    }

    loop_remaining = 1;

    options.volume = MAD_F_ONE;

    status = MPG321_PLAYING;
    
    /* Get the command line options */
    parse_options(argc, argv, pl);

    if(options.opt & MPG321_PRINT_FFT)
	    if(!(options.opt & MPG321_REMOTE_PLAY))
	    {
		    /* printf("FFT analysis can only be used in Remote mode play.\n\n"); */
		    usage(argv[0]);			
		    exit(0);
	    }


    /* If there were no files and no playlist specified just print the usage */
    if (!playlist_file && optind == argc)
    {
        usage(argv[0]);
        exit(0);
    }

    if (playlist_file)
        load_playlist(pl, playlist_file);

    if(options.opt & MPG321_RECURSIVE_DIR)
	    add_cmdline_files_recursive_dir(pl, argv);
    else
	    add_cmdline_files(pl, argv);

    if (shuffle_play)
        shuffle_files(pl);

    if(options.opt & MPG321_ENABLE_BUFFER)
    {
	    /* Initialize semaphore and shared memeory */
	    if(access(argv[0],X_OK) == 0)
		    sem_key = ftok(argv[0],0);
	    else
		    sem_key = ftok(MPG321_PATH,0);
	    if(sem_key == -1)
	    {
		    perror("Cannot obtain resources for semaphores");
		    exit(EXIT_FAILURE);
	    }
	    semarray = semget(sem_key,3,IPC_CREAT | IPC_EXCL | S_IRWXU);
	    if(semarray == -1)
	    {
		    perror("Cannot initialize semaphores");
		    exit(EXIT_FAILURE);
	    }
	    sem_ops.val = buffer_size-1;
	    if(semctl(semarray,0,SETVAL,sem_ops) == -1)
	    {
		    perror("Error while initializing mad_decoder semaphore");
		    if(semctl(semarray,0,IPC_RMID) == -1)
			    perror("Error while destroying semaphores");
		    goto out;
		    //exit(EXIT_FAILURE);
	    }
	    sem_ops.val = 0;
	    if(semctl(semarray,1,SETVAL,sem_ops) == -1)
	    {
		    perror("Error while initializing mad_decoder semaphore");
		    if(semctl(semarray,0,IPC_RMID) == -1)
			    perror("Error while destroying semaphores");
		    goto out;
		    //exit(EXIT_FAILURE);
	    }
	    sem_ops.val = 0;
	    if(semctl(semarray,2,SETVAL,sem_ops) == -1)
	    {
		    perror("Error while initializing mad_decoder semaphore");
		    if(semctl(semarray,0,IPC_RMID) == -1)
			    perror("Error while destroying semaphores");
		    goto out;
		    //exit(EXIT_FAILURE);
	    }

	    /* Shared Memory */
	    mem_key = ftok(argv[0],1);
	    shm_id = shmget(mem_key,buffer_size * sizeof(output_frame), IPC_CREAT | S_IREAD | S_IWRITE);
	    if(shm_id == -1)
	    {
		    perror("Cannot initialize shared buffer");
		    goto out;
		    //exit(EXIT_FAILURE);
	    }
	    Output_Queue = shmat(shm_id,NULL,0);
	    if(*(int *)Output_Queue == -1)
	    {
		    perror("Error while attaching shared buffer to mad_decoder");
		    if(shmctl(shm_id,IPC_RMID,NULL))
			    perror("Cannot destroy shared buffer");
		    goto out;
		    //exit(EXIT_FAILURE);
	    }
	    static int n;
	    for(n=0;n<buffer_size;n++)
	    {
		    memset((Output_Queue+n)->data,'\0',4608);
		    memset((Output_Queue+n)->time,'\0',80);
		    (Output_Queue+n)->length = 0;
		    (Output_Queue+n)->seconds = 0;
		    (Output_Queue+n)->num_frames = 0;
	    }
	    
	    frames_key = ftok(argv[0],2);
	    frames_id = shmget(frames_key,buffer_size * sizeof(decoded_frames), IPC_CREAT | S_IREAD | S_IWRITE);
	    if(frames_id == -1)
	    {
		    perror("Cannot initialize shared frames counter");
		    goto out;
		    //exit(EXIT_FAILURE);
	    }
	    Decoded_Frames = shmat(frames_id,NULL,0);
	    if(*(int *)Decoded_Frames == -1)
	    {
		    perror("Error while attaching shared frames counter to mad_decoder");
		    if(shmctl(frames_id,IPC_RMID,NULL))
			    perror("Cannot destroy shared frames counter");
		    goto out;
		    //exit(EXIT_FAILURE);
	    }
	    	
	    Decoded_Frames->is_http = 0;
	    Decoded_Frames->is_file = 0;

    }
    else {
	    ao_initialize();
	    check_default_play_device();
    }
    
    if (!(options.opt & MPG321_REMOTE_PLAY))
    {
        handle_signals(-1); /* initialize signal handler */
        remote_input_buf[0] = '\0';
    }
    
    if (!(options.opt & MPG321_QUIET_PLAY)) 
        mpg123_boilerplate();
    
    if (options.opt & MPG321_REMOTE_PLAY)
    {
        printf ("@R MPG123\n");
	if(options.opt & MPG321_ENABLE_BUFFER)
	{
#ifdef HAVE_ALSA
		init_alsa_volume_control("default"); /* For the moment use "default", it works on most of the systems. Tested in Debian,Fedora,Ubuntu,RedHat,CentOS,Gentoo */
		if(options.volume != MAD_F_ONE)
			mpg321_alsa_set_volume((long)options.volume*volume_max/100);
#endif
	}
    }

    /* Fork here. */
    if(options.opt & MPG321_ENABLE_BUFFER)
    {
	    output_pid = fork();
	    if(output_pid == -1)
	    {
		    perror("Error while forking output process");
		    goto out; /* Release shared memeory and semaphores */
		//    exit(EXIT_FAILURE);
	    }

	    if(output_pid == 0)
	    {
		    frame_buffer_p();
		    exit(EXIT_SUCCESS);
	    }
	    signal(SIGUSR1,handle_signals);
	    if(!(options.opt & MPG321_REMOTE_PLAY))
	    {
#ifdef HAVE_ALSA
		    init_alsa_volume_control("default");
		    if(options.volume != MAD_F_ONE)
			    mpg321_alsa_set_volume((long)options.volume*volume_max/100);
#endif
	    }
    }

    if( (options.volume != MAD_F_ONE) && !(options.opt & MPG321_ENABLE_BUFFER))
    {
	    options.volume = mad_f_tofixed((long)options.volume/100.0);
    }
    else{
	    options.volume = MAD_F_ONE; /* When using the buffer options.volume when decoding each frame should be equal to MAD_F_ONE */
//	    options.volume = mad_f_tofixed((long)100.0/100.0);
    }

    if (!(options.opt & MPG321_REMOTE_PLAY))
    {
	     if(options.opt & MPG321_ENABLE_BASIC)
	     {
	 	     /* Now create and detach the basic controls thread */
		     sem_init(&main_lock,0,0);
	 	     pthread_create(&keyb_thread,NULL,read_keyb,NULL);
		     pthread_detach(keyb_thread);
	     }
     }
    if(set_xterm)
    {
	    tty_control();
	    get_term_title(title);
    }else
    {
     	
	    if (!(options.opt & MPG321_REMOTE_PLAY))
	    {
	    	    if (tcgetattr(0, &terminal_settings) < 0)
	    		    perror("tcgetattr()");
	    	    memcpy(&old_terminal_settings, &terminal_settings, sizeof(struct termios));
		    /* Early thread start */
		    sem_post(&main_lock);
	    }
    }
    /* Play the mpeg files or zip it! */
    while((currentfile = get_next_file(pl, &playbuf)))
    {
        //printf("Current File: %s\n",currentfile);
	   if (quit_now) 
            break;
        
        signal(SIGINT, SIG_DFL);
        
        playbuf.buf = NULL;
        playbuf.fd = -1;
        playbuf.length = 0;
        playbuf.done = 0;
        playbuf.num_frames = 0;
        current_frame = 0;
        playbuf.max_frames = -1;
        strncpy(playbuf.filename,currentfile, PATH_MAX);
        playbuf.filename[PATH_MAX-1] = '\0';
        
        if (status == MPG321_PLAYING || status == MPG321_STOPPED) 
            file_change = 1;

        mad_timer_reset(&playbuf.duration);
        
        mad_timer_reset(&current_time);

	id3struct = NULL;

        if (!(options.opt & MPG321_QUIET_PLAY) && file_change)
        {
           /* id3struct = id3_file_open (currentfile, ID3_FILE_MODE_READONLY);*/

            if (id3struct == NULL)
		    get_id3_info(currentfile, &id3struct, &id3tag);
	    if(id3tag)
		    show_id3(id3tag);
	}

	scrobbler_time = -1;
	if(options.opt & MPG321_USE_SCROBBLER)
	{
		if(id3struct == NULL)
			get_id3_info(currentfile,&id3struct,&id3tag);
                
	    if (id3tag)
	    {
		    char emptystring[31], emptyyear[5] = "    ";
		    int i;

		    if(parse_id3(scrobbler_args, id3tag))
		    {
			    memset(emptystring, ' ', 30);
			    emptystring[30] = '\0';
	    		    if((options.opt & MPG321_VERBOSE_PLAY) && (options.opt & MPG321_USE_SCROBBLER))
			    {
				    fprintf(stderr, "\nPreparing for the AudioScrobbler:\n");
				    for(i = 0; i < 6; i++)
				    {
					    if(scrobbler_args[i] == NULL)
						    scrobbler_args[i] =
							    ( i == 3 ? emptyyear: emptystring);
					    fprintf(stderr, "- %s\n", scrobbler_args[i]);
				    }
			    }
		    }
	    }
	}
      

        if (options.opt & MPG321_REMOTE_PLAY && file_change)
        {
		if(id3struct == NULL)
			get_id3_info(currentfile, &id3struct, &id3tag);
		if(id3tag)
                {
                    if (!show_id3(id3tag))
                    {
                        /* This shouldn't be necessary, but it appears that
                           libid3tag doesn't necessarily know if there are no
                           id3 tags on a given mp3 */
                        char * basec = strdup(currentfile);
                        char * basen = basename(basec);
                        
                        char * dot = strrchr(basen, '.');
                        
                        if (dot)
                            *dot = '\0';
                        
                        printf("@I %s\n", basen);

                        free(basec);
                    }
                }
            else
            {
                char * basec = strdup(currentfile);
                char * basen = basename(basec);
                
                char * dot = strrchr(basen, '.');
                
                if (dot)
                    *dot = '\0';
                
                printf("@I %s\n", basen);

                free(basec);
            }
        }

	if(id3struct != NULL)
		id3_file_close(id3struct);

        /* Create the MPEG stream */
        /* Check if source is on the network */
        if((fd = raw_open(currentfile)) != 0 || (fd = http_open(currentfile)) != 0
            || (fd = ftp_open(currentfile)) != 0)
        {
            playbuf.fd = fd;
            playbuf.buf = malloc(BUF_SIZE);
            playbuf.length = BUF_SIZE;
	    if(options.opt & MPG321_ENABLE_BUFFER)
	    {
		    Decoded_Frames->is_http = 1;
		    Decoded_Frames->is_file = 0;
	    }
	    calc_http_length(&playbuf);

            mad_decoder_init(&decoder, &playbuf, read_from_fd, read_header, /*filter*/0,
                            output, handle_error, /* message */ 0);
        }

        /* Check if we are to use stdin for input */
        else if(strcmp(currentfile, "-") == 0)
        {
            playbuf.fd = fileno(stdin);
            playbuf.buf = malloc(BUF_SIZE);
            playbuf.length = BUF_SIZE;

            mad_decoder_init(&decoder, &playbuf, read_from_fd, read_header, /*filter*/0,
                            output, handle_error, /* message */ 0);
        }
            
        /* currentfile is a local file (presumably.) mmap() it */
        else
        {
            struct stat stat;
            
            if((fd = open(currentfile, O_RDONLY)) == -1)
            {
	    
                mpg321_error(currentfile);
		/* Restore TTY from keyboard reader thread */
	        if(options.opt & MPG321_ENABLE_BASIC)
			if (tcsetattr(0, TCSANOW, &old_terminal_settings) < 0)
				perror("tcsetattr ICANON");
		if(set_xterm)
	    	{
			set_tty_restore();
	    		osc_print(0,0,title);
	    		if (ctty)
	    			fclose(ctty);
	    	}
		if( options.opt & MPG321_REMOTE_PLAY)
			if(remote_restart)
			{	
				clear_remote_file(pl); /* If restart is enabled, restart remote shell when file doesn't exist*/
				continue;
			}
		if(options.opt & MPG321_ENABLE_BUFFER)
			goto out;
		else
			exit(1);
                /* mpg123 stops immediately if it can't open a file */
		/* If sth goes wrong break!!!*/
                break;
            }

	    if(options.opt & MPG321_ENABLE_BUFFER)
	    {
		    Decoded_Frames->is_http = 0;
		    Decoded_Frames->is_file = 1;
	    }
            
            if(fstat(fd, &stat) == -1)
            {
                mpg321_error(currentfile);
		close(fd);
                continue;
            }
            
            if (!S_ISREG(stat.st_mode))
            {
		    if(S_ISFIFO(stat.st_mode))
		    {
			    fallback = 1;
			    goto fall_back_to_read_from_fd;
		    }

		close(fd);    
                continue;
            }
            
            retval = calc_length(currentfile, &playbuf); //FIXME Check also if it is an mp3 file. If not break and go to the next file possible
	    if(retval < 0)
	    {
		    if(options.opt & MPG321_REMOTE_PLAY)
		    {
			    fprintf(stderr,"@E Corrupted file: %s\n",currentfile);
			    close(fd);
			    if(remote_restart)
			    {
				    clear_remote_file(pl); /* If restart is enabled, restart remote shell when file is corrupted */
				    continue;
			    }
			    break;
		    }
		    mpg321_error(currentfile);
		    close(fd);
//		    break; //FIXME Break and stop OR continue the playlist ????
		    continue;
	    }

	    if((options.opt & MPG321_VERBOSE_PLAY) && (options.opt & MPG321_USE_SCROBBLER))
		    fprintf(stderr, "Track duration: %ld seconds\n",playbuf.duration.seconds);

	    if(options.opt & MPG321_USE_SCROBBLER)
		    scrobbler_set_time(playbuf.duration.seconds);

            if ((options.maxframes != -1) && (options.maxframes <= playbuf.num_frames))
            { 
                playbuf.max_frames = options.maxframes;
            }
            
            playbuf.frames = malloc((playbuf.num_frames + 1) * sizeof(void*));
            playbuf.times = malloc((playbuf.num_frames + 1) * sizeof(mad_timer_t));
#ifdef __uClinux__
	    if((playbuf.buf = mmap(0, playbuf.length, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
#else       
 	    if((playbuf.buf = mmap(0, playbuf.length, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED)
#endif		    
            {
                mpg321_error(currentfile);
                continue;
            }
            
            playbuf.frames[0] = playbuf.buf;
		    
	    mad_decoder_init(&decoder, &playbuf, read_from_mmap, read_header, /*filter*/0,
            
	    		    output, handle_error, /* message */ 0);
fall_back_to_read_from_fd:	//FIXME. Reported that on some embedded systems with low memory, less than 16MB doesn't work properly.
	    if(fallback)
	    {
	    
		    playbuf.fd = fd;
		    playbuf.buf = malloc(BUF_SIZE);
		    playbuf.length = BUF_SIZE;
		    mad_decoder_init(&decoder, &playbuf, read_from_fd, read_header, /*filter*/0,
				    output, handle_error, /* message */ 0);
		    fallback = 1;
	    }
        }

        if(!(options.opt & MPG321_QUIET_PLAY))/*zip it!!!*/
        {
            /* Because dirname might modify the argument */
            char * dirc = strdup(currentfile);
            char * basec = strdup(currentfile);

            char * basen = basename(basec);
            char * dirn = dirname(dirc);
            
            /* make sure that the file has a pathname; otherwise don't print out
               a Directory: listing */
            if(strchr(currentfile, '/') && strncmp(old_dir, dirn, PATH_MAX) != 0)
            {
                /* Print information about the file */
                fprintf(stderr, "\n");
                fprintf(stderr,"Directory: %s\n", dirn);
                
                strncpy(old_dir, dirn, PATH_MAX);
                old_dir[PATH_MAX-1] = '\0';
            }
            
            /* print a newline between different songs only, not after
               Directory: listing */
            else
            {
                fprintf(stderr, "\n");
            }

            fprintf(stderr,"Playing MPEG stream from %s ...\n", basen);
            
	    /* Printing xterm title */
	    if(set_xterm)
	    {
		    osc_print(0,0,basen);
	    }
	    
            free(dirc);
            free(basec);
        }    

        signal(SIGINT, handle_signals);
	signal(SIGCHLD, handle_sigchld);
        /*Give control back so that we can implement SIG's*/
	if(set_xterm)
	{
		set_tty_restore();
		if (tcgetattr(0, &terminal_settings) < 0)
			perror("tcgetattr()");
		memcpy(&old_terminal_settings, &terminal_settings, sizeof(struct termios));
		/* disable canonical mode processing in the line discipline driver */
		terminal_settings.c_lflag &= ~(ICANON | ECHO);
		/* apply our new settings */
		if (tcsetattr(0, TCSANOW, &terminal_settings) < 0)
			perror("tcsetattr ICANON");
		if(options.opt & MPG321_ENABLE_BASIC)
		{
			/* Late thread start */
			sem_post(&main_lock);
		}
	}
        /* Every time the user gets us to rewind, we exit decoding,
           reinitialize it, and re-start it */
	    
	if(options.opt & MPG321_ENABLE_BUFFER)
    	{
		Decoded_Frames->total_decoded_frames = 0;
		Decoded_Frames->done = 0;
	}
      
        while (1)
        {
            decoder.options |= MAD_OPTION_IGNORECRC;
            mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);
	    if(options.opt & MPG321_ENABLE_BUFFER)
	    {
		    static struct sembuf start_sops = {2,-1,0};
		    semop(semarray,&start_sops,1);
		    mad_decoder_position = 0;
		    output_buffer_position = 0;
		    union semun sem_ops;
		    sem_ops.val = 0;
		    semctl(semarray,2,SETVAL,sem_ops);
		    Decoded_Frames->total_decoded_frames = 0;
		    Decoded_Frames->done = 0;
		    Decoded_Frames->is_http = 0;
		    Decoded_Frames->is_file = 0;
	    }
            /* if we're rewinding on an mmap()ed stream */
            if(status == MPG321_REWINDING && playbuf.fd == -1) 
            {
                mad_decoder_init(&decoder, &playbuf, read_from_mmap, read_header, /*filter*/0,
                    output, /*error*/0, /* message */ 0);
            }    
            else
                break;
        } 

        if (!(options.opt & MPG321_QUIET_PLAY))
        {
            char time_formatted[11];
            mad_timer_string(current_time, time_formatted, "%.1u:%.2u", MAD_UNITS_MINUTES,
                       MAD_UNITS_SECONDS, 0);
	    fprintf(stderr,"                                                                            \r");
	    fprintf(stderr, "\n[%s] Decoding of %s finished.\n",time_formatted, basename(currentfile)); /* Report total decoded seconds. Maybe for the frame buffer report only total played time?? */
        }
        
        if (options.opt & MPG321_REMOTE_PLAY && status == MPG321_STOPPED)
        {
            clear_remote_file(pl);
        }

        mad_decoder_finish(&decoder);

        if (playbuf.frames)
             free(playbuf.frames);

        if (playbuf.times)
            free(playbuf.times);
            
        if (playbuf.fd == -1)
        {
            munmap(playbuf.buf, playbuf.length);
            close(fd);
        }

        else
        {
            free(playbuf.buf);
            if (playbuf.fd != fileno(stdin)) 
                close(playbuf.fd);
        }
    }

    if(!(options.opt & MPG321_ENABLE_BUFFER))
    {
  	     if(playdevice)
		     ao_close(playdevice);
	     ao_shutdown();
     }

     if (!(options.opt & MPG321_REMOTE_PLAY))
     {
	     if(options.opt & MPG321_ENABLE_BASIC)
	     {
	 	     pflag = 1;
		     /* Restore TTY from keyboard reader thread */
	 	     if (tcsetattr(0, TCSANOW, &old_terminal_settings) < 0)
		 	     perror("tcsetattr ICANON");
	     }
     }
    /*Restoring TTY*/
    if(set_xterm)
    {
	    set_tty_restore();
	    osc_print(0,0,title);
	    if (ctty)
		    fclose(ctty);
    }

out:
    if(options.opt & MPG321_ENABLE_BUFFER)
    {
	    if(kill(output_pid,SIGUSR1) == -1)
		    perror("Error while stopping output process");
	    static int wstatus;
	    wait(&wstatus);
	    if(wstatus == -1)
		    perror("Error while waiting for output process to exit");
	    if(semctl(semarray,0,IPC_RMID) == -1)
		    perror("Error while destroying semaphores");
	    if(shmdt(Output_Queue) == -1)
		    perror("Error while detaching shared buffer");
	    if(shmctl(shm_id,IPC_RMID,NULL))
		    perror("Cannot destroy shared buffer");
	    if(shmctl(frames_id,IPC_RMID,NULL))
		    perror("Cannot destroy shared buffer");
    }
    return(0);
}
Ejemplo n.º 5
0
/* Basic control keys thread */
void *read_keyb(void *ptr)
{
	int ch;
	long bvolume = 0;
	sem_wait(&main_lock);
	/* Get the current terminal settings for the first time*/
	if (tcgetattr(0, &terminal_settings) < 0)
		perror("tcgetattr()");
	
	memcpy(&old_terminal_settings, &terminal_settings, sizeof(struct termios));
	terminal_settings.c_lflag &= ~(ICANON | ECHO);
	if (tcsetattr(0, TCSANOW, &terminal_settings) < 0)
		perror("tcsetattr ICANON");
	if(options.opt & MPG321_ENABLE_BUFFER)
	{
//		init_alsa_volume_control("default");
#ifdef HAVE_ALSA
		bvolume = mpg321_alsa_get_volume();
#endif
		Decoded_Frames->timer = -1;
	}
	else
		volume = (int)((double)options.volume / (1 << MAD_F_FRACBITS) * 100.0);
	while(!pflag)
	{
		ch = getchar();
		if(ch == KEY_CTRL_VOLUME_DOWN)
		{
			if(options.opt & MPG321_ENABLE_BUFFER)
			{
#ifdef HAVE_ALSA
				bvolume = mpg321_alsa_get_volume();
				bvolume = bvolume - round(0.02*volume_max); /* 1dB decrement ? */
#endif
				Decoded_Frames->timer = 1;
			}
			else
			{
				count = 1;
				volume -= 3;
			}
			if(options.opt & MPG321_ENABLE_BUFFER)
			{
#ifdef HAVE_ALSA
				if(bvolume < volume_min)
					bvolume = volume_min;
				Decoded_Frames->bvolume = 100*bvolume/volume_max;
#endif
			
			}
			else
			{
				if(volume < 0)
					volume = 0;
			}
			if(options.opt & MPG321_ENABLE_BUFFER)
			{	
#ifdef HAVE_ALSA
				mpg321_alsa_set_volume(bvolume);
#endif
			}
			else
				options.volume = mad_f_tofixed(volume / 100.0);
			if(!(options.opt & MPG321_VERBOSE_PLAY))
			{
#ifdef HAVE_ALSA
				if(options.opt & MPG321_ENABLE_BUFFER)
					fprintf(stderr,"Volume: %lu%%      \r",100*bvolume/volume_max);
				else{
#endif					
					if(!(options.opt & MPG321_ENABLE_BUFFER))
						fprintf(stderr,"Volume: %ld%%      \r",volume);
#ifdef HAVE_ALSA
				}
#endif
			}
		}
		if(ch == KEY_CTRL_VOLUME_UP)
		{
			if(options.opt & MPG321_ENABLE_BUFFER)
			{
#ifdef HAVE_ALSA
				bvolume = mpg321_alsa_get_volume();
				bvolume = bvolume + round(0.02*volume_max); /* 1dB increment? */
#endif
				Decoded_Frames->timer = 1;
			}
			else
			{
				count = 1;
				volume += 3;
			}
			if(options.opt & MPG321_ENABLE_BUFFER)
			{
#ifdef HAVE_ALSA
				if(bvolume > volume_max)
					bvolume = volume_max;
				Decoded_Frames->bvolume = 100*bvolume/volume_max;
#endif
			}
			else
			{
				if(volume > 100)
					volume = 100;
			}
			if(options.opt & MPG321_ENABLE_BUFFER)
			{
#ifdef HAVE_ALSA
				mpg321_alsa_set_volume(bvolume);
#endif
			}
			else
				options.volume = mad_f_tofixed(volume / 100.0);
			if(!(options.opt & MPG321_VERBOSE_PLAY))
			{
#ifdef HAVE_ALSA
				if(options.opt & MPG321_ENABLE_BUFFER)
					fprintf(stderr,"Volume: %lu%%      \r",100*bvolume/volume_max);
				else{
#endif
					if(!(options.opt & MPG321_ENABLE_BUFFER))
						fprintf(stderr,"Volume: %ld%%      \r",volume);
#ifdef HAVE_ALSA
				}
#endif
			}
		}
		if(ch == KEY_CTRL_NEXT_SONG)
		{
			kill(getpid(),SIGINT);
		}
		if(ch == KEY_CTRL_MUTE)
		{
			if(!muted)
			{
				muted = 1;
#ifdef HAVE_ALSA
				if(options.opt & MPG321_ENABLE_BUFFER)
					mpg321_alsa_set_volume((long)0.0);
				else
#endif
					options.volume = mad_f_tofixed(0.0);
			}
			else
			{
				muted = 0;
#ifdef HAVE_ALSA
				if(options.opt & MPG321_ENABLE_BUFFER)
					mpg321_alsa_set_volume(bvolume);
				else
#endif
					options.volume = mad_f_tofixed(volume / 100.0);
			}
		}
	}
	if (tcsetattr(0, TCSANOW, &old_terminal_settings) < 0)
		perror("tcsetattr ICANON");
	return (void *)0;
}
Ejemplo n.º 6
0
/****************************************************************************
 * Command-line arguments parsing. We use two methods and two command-line	*
 * formats depending on the system type. On unix system we apply the good	*
 * old getopt() method, other system are offered a really primitive options	*
 * interface.																*
 ****************************************************************************/
static int ParseArgs(int argc, char * const argv[])
{
	int				DoPhoneFilter=0,
					i;
	double			AmpFactor;
	mad_fixed_t		Amp=MAD_F_ONE;

#ifdef HAVE_GETOPT /* This version is for Unix systems. */
	int				Option;

	/* Parse the command line. */
	while((Option=getopt(argc,argv,"a:p"))!=-1)
		switch(Option)
		{
			/* {5} Set the amplification/attenuation factor, expressed
			 * in dB.
			 */
			case 'a':
				/* If the current linear amplification factor is not
				 * one (MAD_F_ONE) then is was already set. Setting it
				 * again is not permitted.
				 */
				if(Amp!=MAD_F_ONE)
				{
					fprintf(stderr,"%s: the amplification/attenuation factor "
							"was set several times.\n",ProgName);
					return(1);
				}

				/* The decibel value is converted to a linear factor.
				 * That factor is checked against the maximum value
				 * that can be stored in a mad_fixed_t. The upper
				 * bound is MAD_F_MAX, it is converted to a double
				 * value with mad_f_todouble() for comparison.
				 */
				AmpFactor=pow(10.,atof(optarg)/20);
				if(AmpFactor>mad_f_todouble(MAD_F_MAX))
				{
					fprintf(stderr,"%s: amplification out of range.\n",
							ProgName);
					return(1);
				}

				/* Eventually the amplification factor is converted
				 * from double to fixed point with mad_f_tofixed().
				 */
				Amp=mad_f_tofixed(AmpFactor);
				break;

			/* {6} The output is filtered through a telephone wire. */
			case 'p':
				/* Only one occurrence of the option is permitted. */
				if(DoPhoneFilter)
				{
					fprintf(stderr,"%s: the phone-line simulation option "
							"was already set.\n",ProgName);
					return(1);
				}

				/* The output will be filtered through a band-pass
				 * filter simulating a phone line transmission.
				 */
				DoPhoneFilter=1;
				break;

			/* Print usage guide for invalid options. */
			case '?':
			default:
				PrintUsage();
				return(1);
		}
#else /* HAVE_GETOPT */ /* This other version is for non-Unix systems. */
	/* Scan all command-line arguments. */
	for(i=1;i<argc;i++)
	{
		/* Set the amplification factor if the current argument looks
		 * like a number. Look at the comment of the case marked {5}
		 * in the Unix section for details.
		 */
		if(*argv[i]=='+' || *argv[i]=='-' || isdigit(*argv[i]))
		{
			if(Amp!=MAD_F_ONE)
			{
				fprintf(stderr,"%s: the amplification/attenuation factor "
						"was set several times.\n",ProgName);
				return(1);
			}

			AmpFactor=pow(10.,atof(argv[i])/20);
			if(AmpFactor>mad_f_todouble(MAD_F_MAX))
			{
				fprintf(stderr,"%s: amplification out of range.\n",
						ProgName);
				return(1);
			}

			Amp=mad_f_tofixed(AmpFactor);
		}
		else
			/* Use the phone-like filter if the argument is the *
			 * 'phone' string. Look at the comment of the case marked
			 * {6} in the Unix section for details.
			 */
			if(strcmp(argv[i],"phone")==0)
			{
				if(DoPhoneFilter)
				{
					fprintf(stderr,"%s: the phone-line simulation option "
							"was already set.\n",ProgName);
					return(1);
				}
				DoPhoneFilter=1;
			}
			else
			{
				/* The argument is not a recognized one. Print the
				 * usage guidelines and stop there.
				 */
				PrintUsage();
				return(1);
			}
	}
#endif /* HAVE_GETOPT */

	/* Initialize the subband-domain filter coefficients to one if
	 * filtering is requested.
	 */
	if(Amp!=MAD_F_ONE || DoPhoneFilter)
		for(i=0;i<32;i++)
			Filter[i]=MAD_F_ONE;

	/* The amplification/attenuation is applied to the subband-domain
     * filter definition.
	 */
	if(Amp!=MAD_F_ONE)
	{
		DoFilter=1;
		for(i=0;i<32;i++)
			Filter[i]=Amp;
	}

	/* The telephone-like filter is applied to the subband-domain
	 * filter definition. All subbands are set to zero except bands 2
	 * to 6. This programs author has no access to the MPEG audio
	 * specification, he does not know the frequencies bands covered
	 * by the MPEG subbands.
	 */
	if(DoPhoneFilter)
	{
		DoFilter=1;
		Filter[0]=MAD_F(0);
		for(i=5;i<32;i++)
			Filter[i]=MAD_F(0);
	}

	/* Command-line arguments are okay. */
	return(0);
}