int play_read_filelist( char *dir_path) { struct WAVE *_wave; DIR *dir; struct dirent *dp; char *file_path; char *temp = dir_path; file_path = (char*)malloc(sizeof(char)*BUFFER_MAX*2); /* support "PATH/" and "PATH" */ while(*(++temp) != '\0'); if(*(temp-1)!='/'){ *(temp) = '/'; *(temp+1) = '\0'; } /* list up the wav*/ dir = opendir(dir_path); if(!dir){ fprintf(stderr,"[PLAY]: Not such directory\n"); exit(1); } /* search wav file */ for(dp=readdir(dir);dp!=NULL;dp=readdir(dir)){ temp = dp->d_name; while(*(temp++)!='.' && *(temp)!='\0'); if(!strcmp("wav", temp)){ _wave = (struct WAVE *)malloc(sizeof(struct WAVE)); memset(_wave, 0, sizeof(struct WAVE)); if(!head){ head = _wave; head->next=_wave; head->prev=_wave; }else{ _wave->prev=head->prev; _wave->next=head; head->prev->next=_wave; head->prev=_wave; } memset(file_path, 0, sizeof(*file_path)); strcat(file_path,dir_path); strcat(file_path,dp->d_name); wave_read_file(file_path,_wave); sprintf(_wave->file_name,"%s",strtok(dp->d_name,".")); list_count++; } } closedir(dir); if(!list_count){ fprintf(stderr,"Not such wav sound file\n"); exit(1); } printf("<<<< Read WAV file >>>>>\n"); for(_wave=head;list_count!=0;_wave=_wave->next){ printf("%s%s.wav\n",dir_path,_wave->file_name); if(head->prev == _wave)break; } printf("\n"); return 0; }
void* play_thread(void *argv) { char *__file_name = argv; struct WAVE *_wave; #ifdef SOLO _wave = (struct WAVE*)malloc(sizeof(struct WAVE)); memset(&_wave, 0, sizeof(struct _wave)); if(!wave_read_file(argv, &_wave )){ goto ERR; } #else if(!list_count){ fprintf(stderr,"[PLAY]: Not such wav sound file.\nPlease call \'play_read_filelist(DIR_PATH)\'\n"); exit(1); } for(_wave=head;;_wave=_wave->next){ if(!strcmp(_wave->file_name, __file_name))break; if(head->prev == _wave){ fprintf(stderr,"[PLAY]: Invalid file_name...\n"); return NULL; } } #endif if(DISP) fprintf(stderr,"[PLAY]: Player will be playing \"%s\".\n",__file_name); snd_pcm_t *handle; // handle for sound_device snd_pcm_hw_params_t *params; // params for sound_device int result_func = 0; // result for function return unsigned int sampling_rate = _wave->rate; // sampling rate int dir; // sub unit direction snd_pcm_uframes_t frames = 32; // size of frame unsigned int buffer_size; // buffer_size for frame int16_t *frameBuffer=NULL; // buffer for frame unsigned int approximate_period; // period[us] {// open the pcm device // open pcm device result_func = snd_pcm_open( &handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if ( result_func < 0 ) { fprintf(stderr, "[PLAY]: unable to open pcm device :%s\n", snd_strerror(result_func)); goto ERR; } } {// set parameter to device // allocate device params snd_pcm_hw_params_alloca(¶ms); // get default param snd_pcm_hw_params_any(handle, params); // set parameter Interleaved mode snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); // set format parameter : monoral 1ch 16bit LittleEndian snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); // set output_device parameter stereo 2ch snd_pcm_hw_params_set_channels(handle, params, _wave->channel); // approximates to a specified sampling rate // pcm PCM handle // params Configuration space // val approximate target rate / returned approximate set rate // dir Sub unit direction snd_pcm_hw_params_set_rate_near( handle, params, &sampling_rate, &dir); // set parameter size of frame snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); // set parameter to hardware_device result_func = snd_pcm_hw_params(handle, params); // err check if (result_func < 0) { fprintf(stderr, "[PLAY]: unable to set hw parameters: %s\n", snd_strerror(result_func)); goto ERR; } // get bufferSize / frame snd_pcm_hw_params_get_period_size(params, &frames, &dir); // calculate buffer_size buffer_size = frames * 2; /*????????? 48000,monoral ver */ // allocate buffer frameBuffer = (int16_t *)malloc(buffer_size); memset(frameBuffer, 0, sizeof(*frameBuffer)); // get playback period // params Configuration space // val Returned approximate period duration in us // dir Sub unit direction snd_pcm_hw_params_get_period_time(params, &approximate_period, &dir); } { // playback process // playback time unsigned int ptime = approximate_period * 2 * 10; // playback while ( ptime-- ) { result_func = fread( frameBuffer, sizeof(unsigned char), buffer_size, _wave->fp); // data is ended if ( result_func == 0 ) { //fprintf(stdout, "[PLAY]: end of input devce\n"); break; } // buffer_size is not correct if ( result_func != buffer_size ) { /* fprintf(stderr, "short read: read %d bytes\n", result_func); */ break; } // playback result_func = snd_pcm_writei( handle, frameBuffer, frames); } } // for unplayed frame,wait sound finish snd_pcm_drain(handle); if(DISP) fprintf(stderr,"[PLAY]: Finished playing %s.\n",__file_name); ERR : { // release if ( frameBuffer != NULL ){ free(frameBuffer); } if ( handle != NULL ) { snd_pcm_close(handle); } } return NULL; }
int main( int argc, char** argv ) { WAVE wave; char buf[ BUFSIZE ]; int dsp; int len; int processed = 0; if ( argc != 2 ) { fprintf( stderr, "usage : wave filename\n" ); return 1; } /* WAVE ファイルヘッダ読み込み */ if ( wave_read_file( argv[1], &wave ) != 0 ) { fprintf( stderr, "Failed to read specified WAVE file" ": %s\n", argv[1] ); return 1; } printf( "\n" ); printf( "WAVE file format :\n" ); printf( " rate = %d\n", wave.rate ); printf( " channel = %d\n", wave.channel ); printf( " bits = %d\n", wave.bits ); printf( " offsets = %ld\n", wave.offset ); printf( " length = %d\n", wave.len ); printf( "\n" ); /* /dev/dsp の設定 */ if ( wave_setup_dsp( &dsp, &wave ) != 0 ) { fprintf( stderr, "Setup /dev/dsp failed.\n" ); fclose( wave.fp ); return 1; } printf( "Now playing specified wave file %s ...\n", argv[1] ); fflush( stdout ); fseek( wave.fp, wave.offset, SEEK_SET ); wave_progress( &processed, 0, &wave ); while ( 1 ) { len = fread( buf, 1, BUFSIZE, wave.fp ); if ( len < BUFSIZE ) { if ( feof( wave.fp ) ) { if ( write( dsp, buf, len ) == -1 ) { perror( "write()" ); } else { wave_progress( &processed, len, &wave ); } } else { perror( "fread()" ); } break; } if ( write( dsp, buf, len ) == -1 ) { perror( "write()" ); break; } wave_progress( &processed, len, &wave ); } fclose( wave.fp ); close( dsp ); printf( "\ndone.\n" ); return 0; }