#include #include #include #include #include #include #include #include #include #include #include #include #include static int InitAudio(AFfilehandle, ALport *); static int PlaySamples(AFfilehandle , ALport); static void GetPathTail(char *, char **); static void DefaultAFerror(long, const char *); static char *filename; /* input file name */ static char *filenametail; /* input file name tail */ static long filefmt; /* input file format */ static int fd; /* input file descriptor */ static char *myname; /* name of this program */ static int rude, quiet; /* global flags */ static int bytes_per_samp; /* sample width */ static long bits_per_samp; /* sample resolution */ static int samps_per_frame; /* frame size */ static int frames_per_sec; /* sample rate */ static int bytes_per_buf; /* bytes / sample buffer */ static int samps_per_buf; /* samples / sample buffer */ static int frames_per_buf; /* frames / sample buffer */ static double secs_per_frame; /* time to play one audio frame */ static double secs_per_buf; /* time to play one sample buffer */ static char *sampbuf; /* sample buffer */ static long compression; /* audio data compression type */ static double file_rate; /* audio file sample rate */ int GetOutputRate(); main(int argc, char **argv){ AFfilehandle audio_file; ALport audio_port; int errseen, result, c, i; extern char *optarg; extern int optind; setreuid(geteuid(), getuid()); setregid(getegid(), getgid()); GetPathTail(argv[0], &myname); rude = 0; quiet = 0; ALseterrorhandler(0); AFseterrorhandler(DefaultAFerror); errseen = 0; if (argc - optind < 1){ printf("\nTarget File Name is not found (;_;)\n"); exit(1); } while (optind < argc){ filename = argv[optind]; GetPathTail(filename, &filenametail); if ((fd = open(filename, O_RDONLY)) < 0){ fprintf(stderr, "%s: failed to open file '%s' %s\n", myname, filename, strerror(errno)); errseen = 1; } else if (AFidentifyfd(fd) < 0) { fprintf(stderr,"%s: '%s' not an AIFF-C or AIFF file\n", myname, filename); errseen = 1; } else if ((audio_file = AFopenfd(fd, "r", AF_NULL_FILESETUP)) == AF_NULL_FILEHANDLE){ fprintf(stderr, "%s: failed to open file '%s'\n", myname, filename); errseen = 1; } else { result = InitAudio(audio_file, &audio_port); if (result != -1) PlaySamples(audio_file, audio_port); else errseen++; AFclosefile(audio_file); if (result != -1) ALcloseport(audio_port); free(sampbuf); } optind++; } if (errseen) exit(1); exit(0); } static int InitAudio(AFfilehandle audio_file, ALport *audio_port){ ALconfig audio_port_config; long pvbuf[4], audio_rate, output_rate, samp_type, samp_wordsize, vers; int err; samps_per_frame = AFgetchannels(audio_file, AF_DEFAULT_TRACK); file_rate = AFgetrate(audio_file, AF_DEFAULT_TRACK); compression = AFgetcompression(audio_file, AF_DEFAULT_TRACK); filefmt = AFgetfilefmt(audio_file, &vers); AFgetsampfmt(audio_file, AF_DEFAULT_TRACK, &samp_type, &bits_per_samp); pvbuf[0] = AL_OUTPUT_COUNT; pvbuf[2] = AL_MONITOR_CTL; if (ALgetparams(AL_DEFAULT_DEVICE, pvbuf, 4) < 0) { if (oserror() == AL_BAD_DEVICE_ACCESS) { fprintf(stderr,"%s: Can't play -- could not access audio hardware.\n",myname); return -1; } } if ((pvbuf[1] == 0) && (pvbuf[3] == AL_MONITOR_OFF)) rude = 1; audio_rate = frames_per_sec = (long) file_rate; output_rate = GetOutputRate(); if (output_rate != audio_rate){ if (rude){ output_rate = audio_rate; pvbuf[0] = AL_OUTPUT_RATE; pvbuf[1] = output_rate; ALsetparams(AL_DEFAULT_DEVICE, pvbuf, 2); } else { if (output_rate < 0) fprintf(stderr, "%s: '%s': Adjust output rate [currently set to an undetermined Digital rate]\n", myname, filenametail); else fprintf(stderr, "%s: '%s': Adjust output rate [currently %d Hz]\n", myname, filenametail, output_rate); } } if (bits_per_samp <= 8){ bytes_per_samp = 1; samp_wordsize = AL_SAMPLE_8; } else if (bits_per_samp <= 16){ bytes_per_samp = 2; samp_wordsize = AL_SAMPLE_16; } else if (bits_per_samp <= 24){ bytes_per_samp = 4; samp_wordsize = AL_SAMPLE_24; } else{ fprintf(stderr, "%s: %s: error can't play %d bit samples\n", myname, filenametail, bits_per_samp); return(-1); } if ((samps_per_frame != 1)&&(samps_per_frame!= 2)&&(samps_per_frame!=4)){ fprintf(stderr, "%s: %s: error can't play %d channel sample data\n", myname, filenametail, samps_per_frame); return(-1); } secs_per_frame = 1.0 / ((double)frames_per_sec); frames_per_buf = (frames_per_sec+1)/2; samps_per_buf = frames_per_buf * samps_per_frame; bytes_per_buf = samps_per_buf * bytes_per_samp; secs_per_buf = secs_per_frame * frames_per_buf; sampbuf = malloc(bytes_per_buf); audio_port_config = ALnewconfig(); ALsetwidth(audio_port_config, samp_wordsize); ALsetchannels(audio_port_config, samps_per_frame); ALsetqueuesize(audio_port_config, samps_per_buf*2); *audio_port = ALopenport(myname, "w", audio_port_config); if (*audio_port == 0) { err = oserror(); if (err == AL_BAD_NO_PORTS) { fprintf(stderr,"%s: Can't play -- no audio ports available at the moment\n",myname); } else if (err == AL_BAD_OUT_OF_MEM) { fprintf(stderr,"%s: Can't play -- not enough memory to open audio port\n",myname); } return -1; } } static int PlaySamples(AFfilehandle audio_file, ALport audio_port){ int num_bufs, leftover_bytes, leftover_samps, leftover_frames, samp_count, frame_count; double sec_count; int i, bytes_read, samples_read, frames_read, done, total_frames, total_samps, total_samp_bytes; float file_playingtime; float fileplayingtime; sec_count = 0.0; total_frames = AFgetframecnt(audio_file, AF_DEFAULT_TRACK); if (total_frames > 0) { total_samps = total_frames * samps_per_frame; total_samp_bytes = total_samps * bytes_per_samp; num_bufs = total_samp_bytes / bytes_per_buf; leftover_bytes = total_samp_bytes % bytes_per_buf; leftover_samps = leftover_bytes / bytes_per_samp; leftover_frames = leftover_samps / samps_per_frame; } else num_bufs = -1; GetPathTail(filename, &filenametail); fileplayingtime = (float)total_frames / (float)frames_per_sec; printf("Start: '%s' %6.3fsec %2.1fKHz %s %dbit\n", filenametail, fileplayingtime, file_rate/1000.0, samps_per_frame == 1 ? "mono" : (samps_per_frame == 2 ? "stereo" : "4-channel"), bits_per_samp ); setreuid(geteuid(), getuid()); setregid(getegid(), getgid()); #ifdef THIS_IS_BROKEN_REVISIT_AFTER_5_1 if (schedctl(NDPRI, 0, NDPNORMMAX)!=-1) schedctl(SLICE, 0, CLK_TCK); else{ for (i = NDPLOMAX+1; schedctl(NDPRI, 0, i) != -1; i--) ; } #else if (schedctl(NDPRI, 0, NDPNORMMAX)< 0) fprintf(stderr, "%s: Run as root for higher process priority\n", myname); #endif setreuid(geteuid(), getuid()); setregid(getegid(), getgid()); AFseekframe(audio_file, AF_DEFAULT_TRACK, 0); done = 0; samp_count = 0; frame_count = 0; sec_count = 0.0; for (i=0; num_bufs<0 || i 0){ fprintf(stderr, "%s: warning short read for %s: expected %d frames, got %d frames\n",myname, filenametail, frames_per_buf, frames_read); } done++; } samples_read = frames_read * samps_per_frame; ALwritesamps(audio_port, sampbuf, samples_read); if (done){ while(ALgetfilled(audio_port) > 0) { sginap(1); } sginap(10); return(0); } } samp_count += leftover_samps; frame_count += leftover_frames; sec_count += ((double)leftover_frames) * secs_per_frame; if (leftover_samps>0) { /* printf("Finish: '%s' %dframes %6.3fsec (^_^)\n", filenametail, frame_count, sec_count); */ } if ((frames_read = AFreadframes(audio_file, AF_DEFAULT_TRACK, sampbuf, leftover_frames)) < leftover_frames){ if (!quiet){ fprintf(stderr, "%s: warning short read for %s: expected %d frames, got %d frames\n",myname, filenametail, leftover_frames, frames_read); } } samples_read = frames_read * samps_per_frame; ALwritesamps(audio_port, sampbuf, samples_read); while(ALgetfilled(audio_port) > 0) { sginap(1); } sginap(10); return(0); } static void GetPathTail(char *thepath, char **thetail){ char *p; p = strrchr(thepath, '/'); if(p) p++; else p = thepath; *thetail = (char *)malloc(strlen(p) + 1); strcpy(*thetail, p); } static void DefaultAFerror(long code, const char *desc){ switch (code){ #if 0 case AF_BAD_CODEC_LICENSE: fprintf(stderr, "%s: license unavailable for Aware %s decoder\n",myname, compression==AF_COMPRESSION_AWARE_MULTIRATE?"MultiRate":"MPEG"); break; #endif default: fprintf(stderr, "%s (Audio File Library error %d): %s\n",myname, code, desc); break; } } int GetInputRate(){ long buf[6]; buf[0] = AL_INPUT_RATE; buf[2] = AL_INPUT_SOURCE; buf[4] = AL_DIGITAL_INPUT_RATE; ALgetparams(AL_DEFAULT_DEVICE, buf, 6); if((buf[1] == AL_RATE_AES_1)||(buf[3] == AL_INPUT_DIGITAL)) { if (ALgetdefault(AL_DEFAULT_DEVICE, AL_DIGITAL_INPUT_RATE) >= 0) return (buf[5]); } else if (buf[1] > 0) return (buf[1]); return (AL_RATE_UNDEFINED); } int GetOutputRate(){ long buf[4]; buf[0] = AL_OUTPUT_RATE; buf[2] = AL_DIGITAL_INPUT_RATE; ALgetparams(AL_DEFAULT_DEVICE, buf, 4); if (buf[1] > 0) return (buf[1]); else { if(buf[1] == AL_RATE_AES_1) { if (ALgetdefault(AL_DEFAULT_DEVICE,AL_DIGITAL_INPUT_RATE) >= 0) return (buf[3]); } else if (buf[1] == AL_RATE_INPUTRATE) return (GetInputRate()); return (AL_RATE_UNDEFINED); } }