int audio_init(const struct uade_config *uc) { int driver; if (uade_no_audio_output) return 1; process_config_options(uc); ao_initialize(); if (uade_output_file_name[0]) { driver = ao_driver_id(uade_output_file_format[0] ? uade_output_file_format : "wav"); if (driver < 0) { __android_log_print(ANDROID_LOG_VERBOSE, "UADE", "Invalid libao driver\n"); return 0; } libao_device = ao_open_file(driver, uade_output_file_name, 1, &format, NULL); } else { driver = ao_default_driver_id(); libao_device = ao_open_live(driver, &format, options); } if (libao_device == NULL) { __android_log_print(ANDROID_LOG_VERBOSE, "UADE", "Can not open ao device: %d\n", errno); return 0; } return 1; }
/* Opens the audio device with the appropriate parameters */ static int set_sample_format(VGMSTREAM *vgms) { ao_sample_format format; memset(&format, 0, sizeof(format)); format.bits = 8 * sizeof(sample); format.channels = vgms->channels; format.rate = vgms->sample_rate; format.byte_format = #ifdef LITTLE_ENDIAN_OUTPUT AO_FMT_LITTLE #else AO_FMT_BIG #endif ; if (memcmp(&format, ¤t_sample_format, sizeof(format))) { /* Sample format has changed, so (re-)open audio device */ ao_info *info = ao_driver_info(driver_id); if (!info) return -1; if ((info->type == AO_TYPE_FILE) != !!out_filename) { if (out_filename) fprintf(stderr, "Live output driver \"%s\" does not take an output file\n", info->short_name); else fprintf(stderr, "File output driver \"%s\" requires an output filename\n", info->short_name); return -1; } if (device) ao_close(device); memcpy(¤t_sample_format, &format, sizeof(format)); if (out_filename) device = ao_open_file(driver_id, out_filename, 1, &format, device_options); else device = ao_open_live(driver_id, &format, device_options); if (!device) { fprintf(stderr, "Error opening \"%s\" audio device\n", info->short_name); return -1; } } return 0; }
int main(int argc, char** argv) { int d,x; char *samps; //initialise AO ao_device *ao; ao_sample_format form; ao_initialize(); d=ao_default_driver_id(); form.bits=8; form.rate=DDS_FREQ; form.channels=1; form.byte_format=AO_FMT_NATIVE; #ifdef TO_FILE ao=ao_open_file(ao_driver_id("wav"),"music.wav",1,&form,NULL); #else ao=ao_open_live(d,&form,NULL); if (ao==NULL) { printf("Error opening device %d\n"); exit(0); } #endif //Libao is opened and initialised now. //allocate sample buffer samps=malloc(AO_BUFF); d=0; //reset player player_reset(); while(1) { //generate AO_BUFF samples, advance the player 60 times per second for (x=0; x<AO_BUFF; x++) { d++; if (d>(DDS_FREQ/PLAYER_FREQ)) { d=0; player_tick(); } samps[x]=dds_get_next_sample()<<5; } //let libao play the samples ao_play(ao,samps,AO_BUFF); } //never happens because the while() above ao_close(ao); ao_shutdown(); }
/* Actually create a new AudioDevice object */ static PyObject* py_ao_new(PyObject *self, PyObject *args, PyObject *kwargs) { uint_32 overwrite, driver_id; const char *filename = NULL; PyObject *py_options = NULL; ao_option *c_options = NULL; ao_device *dev; ao_sample_format sample_format; ao_Object *retobj; if (!parse_args(args, kwargs, &sample_format, &py_options, &filename, &driver_id, &overwrite)) return NULL; if (py_options && PyDict_Size(py_options) > 0) { /* dict_to_options returns NULL on error, so you can't pass an empty dictionary. We can skip this then anyway. */ c_options = dict_to_options(py_options); if (!c_options) { return NULL; } } if (filename == NULL) { dev = ao_open_live(driver_id, &sample_format, c_options); } else { dev = ao_open_file(driver_id, filename, overwrite, &sample_format, c_options); } ao_free_options(c_options); if (dev == NULL) { PyErr_SetString(Py_aoError, "Error opening device."); return NULL; } retobj = (ao_Object *) PyObject_NEW(ao_Object, &ao_Type); retobj->dev = dev; retobj->driver_id = driver_id; return (PyObject *) retobj; }
int main(int argc, char* argv[]) { long size; char *filedata; term_size terminal; ModPlugFile *f2; int mlen; struct timeval tvstart; struct timeval tv; struct timeval tvpause, tvunpause; struct timeval tvptotal; char status[161]; char songname[41]; char notpaus[4]; int loop=0; // kontest int songsplayed = 0; int nFiles = 0, fnOffset[100]; int i; ModPlug_Settings settings; ModPlug_GetSettings(&settings); ao_device *device; ao_sample_format format = {0}; int default_driver; ao_initialize(); default_driver = ao_default_driver_id(); for (i=1; i<argc; i++) { /* check if arguments need to be parsed */ if (argv[i][0] == '-') { if (strstr(argv[i],"-h")) { printf("\n"); help(argv[0],0); } else if (strstr(argv[i],"-v")) { versioninfo(); exit(0); } else if (strstr(argv[i],"-l")) { loop=1; continue; } else if (strstr(argv[i],"-ao")) { default_driver = ao_driver_id(argv[++i]); continue; } if (argv[i][1] == '-') { // not a song if (strstr(argv[i],"--help")) { help(argv[0],0); } else if (strstr(argv[i],"--version")) { versioninfo(); exit(0); } continue; } } /* "valid" filename - store it */ fnOffset[nFiles++] = i; } format.bits = 16; format.channels = 2; format.rate = 44100; format.byte_format = AO_FMT_LITTLE; // printf("Default driver = %i\n", default_driver); char buffer[128]; int result, nread; struct pollfd pollfds; int timeout = 1; /* Timeout in msec. */ int pause=0; int mono=0; int bits=0; int song; // [rev--dly--] [sur--dly--] [bas--rng--] int rev=0; // a int revdly=0; // s int sur=0; // d int surdly=0; // y int bas=0; // x int basrng=0; // c /* Initialize pollfds; we're looking at input, stdin */ pollfds.fd = 0; /* stdin */ pollfds.events = POLLIN; /* Wait for input */ if (argc==1) { help(argv[0],1); } if (!get_term_size(STDIN_FILENO,&terminal)) { fprintf(stderr,"warning: failed to get terminal size\n"); } srand(time(NULL)); for (song=0; song<nFiles; song++) { char *filename = argv[fnOffset[song]]; /* -- Open driver -- */ if (default_driver == ao_driver_id("wav")) { device = ao_open_file(default_driver, "output.wav", 1, &format, NULL /*no options*/); } else { device = ao_open_live(default_driver, &format, NULL /* no options */); } if (device == NULL) { fprintf(stderr, "Error opening device. (%s)\n", filename); fprintf(stderr, "ERROR: %i\n", errno); return 1; } printf("%s ",filename); printf("[%d/%d]",song+1,nFiles); filedata = getFileData(filename, &size); if (filedata == NULL) continue; printf(" [%ld]\n",size); // Note: All "Basic Settings" must be set before ModPlug_Load. settings.mResamplingMode = MODPLUG_RESAMPLE_FIR; /* RESAMP */ settings.mChannels = 2; settings.mBits = 16; settings.mFrequency = 44100; settings.mStereoSeparation = 128; settings.mMaxMixChannels = 256; /* insert more setting changes here */ ModPlug_SetSettings(&settings); f2 = ModPlug_Load(filedata, size); if (!f2) { printf("could not load %s\n", filename); close(audio_fd); free(filedata); /* ? */ } else { songsplayed++; /* settings.mFlags=MODPLUG_ENABLE_OVERSAMPLING | \ MODPLUG_ENABLE_NOISE_REDUCTION | \ MODPLUG_ENABLE_REVERB | \ MODPLUG_ENABLE_MEGABASS | \ MODPLUG_ENABLE_SURROUND;*/ // settings.mReverbDepth = 100; /* 0 - 100 */ * [REV--DLY--] // settings.mReverbDelay = 200; /* 40 - 200 ms 00-FF */ // settings.mSurroundDepth = 100; /* 0 - 100 */ [SUR--DLY--] // settings.mSurroundDelay = 40; /* 5 - 40 ms */ // settings.mBassAmount = 100; /* 0 - 100 */ [BAS--RNG--] // settings.mBassRange = 100; /* 10 - 100 hz */ // [REV--DLY--] [SUR--DLY--] [BAS--RNG--] // [rev--dly--] [sur--dly--] [bas--rng--] set_keypress(); strcpy(songname, ModPlug_GetName(f2)); /* if no modplug "name" - use last 41 characters of filename */ if (strlen(songname)==0) { int l = strlen(filename); char *st = filename; if (l >= 41) st = filename + l - 41; strncpy(songname,st,41); songname[40] = 0; } sprintf(status,"[1Gplaying %s (%%d.%%d/%d\") (%%d/%%d/%%d) \b\b\b\b",songname,ModPlug_GetLength(f2)/1000); if (loop) sprintf(status,"[1Glooping %s (%%d.%%d/%d\") (%%d/%%d/%%d) \b\b\b\b",songname,ModPlug_GetLength(f2)/1000); gettimeofday(&tvstart,NULL); tvptotal.tv_sec=tvptotal.tv_usec=0; mlen=1; while(mlen!=0) { if (mlen==0) { break; } if (!pause) { gettimeofday(&tv,NULL); mlen = ModPlug_Read(f2,audio_buffer,BUF_SIZE); if (mlen > 0 && ao_play(device, audio_buffer, mlen) == 0) { perror("audio write"); exit(1); } } printf(status,tv.tv_sec-tvstart.tv_sec-tvptotal.tv_sec,tv.tv_usec/100000,format.rate,format.channels,settings.mBits/*,rev,revdly,sur,surdly,bas,basrng*/); fflush(stdout); if ((mlen==0) && (loop==1)) { /*printf("LOOPING NOW\n");*/ ModPlug_Seek(f2,0); gettimeofday(&tvstart,NULL); mlen=ModPlug_Read(f2,audio_buffer,BUF_SIZE); tvptotal.tv_sec=tvptotal.tv_usec=0; } result = poll(&pollfds, 1, timeout); switch (result) { case 0: /*printf(".");*/ break; case -1: perror("select"); exit(1); default: if (pollfds.revents && POLLIN) { nread = read(0, buffer, 1); /* s/nread/1/2 */ if (nread == 0) { printf("keyboard done\n"); exit(0); } else { buffer[nread] = 0; /* printf("%s", buffer); */ if (buffer[0]=='q') { mlen=0; song=nFiles; } /* quit */ if (buffer[0]=='f') { if ((tv.tv_sec-tvstart.tv_sec-tvptotal.tv_sec+10) < (ModPlug_GetLength(f2)/1000)) { ModPlug_Seek(f2,(tv.tv_sec-tvstart.tv_sec-tvptotal.tv_sec)*1000+10000); tvstart.tv_sec-=10; } } /* forward 10" */ if (buffer[0]=='b') { if ((tv.tv_sec-tvstart.tv_sec-tvptotal.tv_sec-10) > 0) { ModPlug_Seek(f2,(tv.tv_sec-tvstart.tv_sec-tvptotal.tv_sec)*1000-10000); tvstart.tv_sec+=10; } } /* backward 10" */ /* if (buffer[0]=='i') { printf("\n"); } */ /* if (buffer[0]=='a') { rev++; settings.mReverbDepth=rev; ModPlug_SetSettings(&settings); } if (buffer[0]=='A') { rev--; settings.mReverbDepth=rev; ModPlug_SetSettings(&settings); } if (buffer[0]=='s') { revdly++; settings.mReverbDelay=revdly; ModPlug_SetSettings(&settings); } if (buffer[0]=='S') { revdly--; settings.mReverbDelay=revdly; ModPlug_SetSettings(&settings); } if (buffer[0]=='d') { sur++; settings.mSurroundDepth=sur; ModPlug_SetSettings(&settings); } if (buffer[0]=='D') { sur--; settings.mSurroundDepth=sur; ModPlug_SetSettings(&settings); } if (buffer[0]=='y') { surdly++; settings.mSurroundDelay=surdly; ModPlug_SetSettings(&settings); } if (buffer[0]=='Y') { surdly--; settings.mSurroundDelay=surdly; ModPlug_SetSettings(&settings); } if (buffer[0]=='x') { bas++; settings.mBassAmount=bas; ModPlug_SetSettings(&settings); } if (buffer[0]=='X') { bas--; settings.mBassAmount=bas; ModPlug_SetSettings(&settings); } if (buffer[0]=='c') { basrng++; settings.mBassRange=basrng; ModPlug_SetSettings(&settings); } if (buffer[0]=='C') { basrng--; settings.mBassRange=basrng; ModPlug_SetSettings(&settings); } */ if (buffer[0]=='n') { if (song<argc) { mlen=0; pause=0; } } if (buffer[0]=='N') { if (song>1) { song-=2; mlen=0; pause=0; } } if (buffer[0]=='r') { song=(int) ((float)(argc-1)*rand()/(RAND_MAX+1.0)); mlen=0; pause=0; // ioctl(audio_fd,SNDCTL_DSP_RESET,0); /* printf("\n[%d?]\n",song+1); */ } /*if (buffer[0]=='R') { song=(int) ((float)(argc-1)*rand()/(RAND_MAX+1.0)); mlen=0; pause=0; }*/ /* if (buffer[0]=='m') { // mono/stereo mono^=1; if (mono) format.channels=1; else format.channels=2; ioctl(audio_fd,SNDCTL_DSP_RESET,0); if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels) == -1) { perror("SNDCTL_DSP_CHANNELS"); exit(1); } if (mono) settings.mChannels=1; else settings.mChannels=2; ModPlug_SetSettings(&settings); f2=ModPlug_Load(d,size); ModPlug_Seek(f2,(tv.tv_sec-tvstart.tv_sec-tvptotal.tv_sec)*1000+10000); } */ if (buffer[0]=='l') { loop^=1; if (loop) { memcpy(status+4,"loop",4); } else { memcpy(status+4,"play",4); } } /* loop */ if (buffer[0]=='p') { pause^=1; if (pause) { gettimeofday(&tvpause,NULL); memcpy(notpaus,status+4,4); memcpy(status+4,"paus",4); } else { gettimeofday(&tvunpause,NULL); memcpy(status+4,notpaus,4); tvptotal.tv_sec+=tvunpause.tv_sec-tvpause.tv_sec; tvptotal.tv_usec+=tvunpause.tv_usec-tvpause.tv_usec; /* printf(status,tv.tv_sec-tvstart.tv_sec,tv.tv_usec/100000); */ } } /* pause */ } } } } printf("\n"); reset_keypress(); ModPlug_Unload(f2); ao_close(device); fprintf(stderr, "Closing audio device.\n"); free(filedata); } /* valid module */ } /* for */ ao_shutdown(); return 0; }
ao_device *open_ao_playdevice_buffer(struct mad_header const *header) { ao_sample_format format; ao_device *pldev = NULL; /* Because these can sometimes block, we stop our custom signal handler, and restore it afterwards */ signal(SIGINT, SIG_DFL); format.bits = 16; format.rate = header->samplerate; format.channels = (options.opt & MPG321_FORCE_STEREO) ? 2 : MAD_NCHANNELS(header); /* Add this element as an option to mpg321 */ format.matrix = "L,R"; /* mad gives us little-endian data; we swap it on big-endian targets, to big-endian format, because that's what most drivers expect. */ format.byte_format = AO_FMT_NATIVE; if(options.opt & MPG321_USE_AU) { int driver_id = ao_driver_id("au"); ao_option *ao_options = NULL; /* Don't have to check options.device here: we only define MPG321_USE_AU when --au <aufile> is defined, and <aufile> is pointd to by options.device */ if((pldev=ao_open_file(driver_id, options.device, 1 /*overwrite*/, &format, ao_options))==NULL) { fprintf(stderr, "Error opening libao file output driver to write AU data.\n"); return NULL; } } else if (options.opt & MPG321_USE_CDR) { ao_option * ao_options = NULL; int driver_id = ao_driver_id("raw"); /* because CDR is a special format, i.e. headerless PCM, big endian, this is a special case. */ ao_append_option(&ao_options, "byteorder", "big"); if((pldev=ao_open_file(driver_id, options.device, 1 /*overwrite*/, &format, ao_options))==NULL) { fprintf(stderr, "Error opening libao file output driver to write CDR data.\n"); return NULL; } } /* if the user specifies both au and wave, wav will be prefered, so testing * later */ else if(options.opt & MPG321_USE_WAV) { int driver_id = ao_driver_id("wav"); ao_option *ao_options = NULL; /* Don't have to check options.device here: we only define MPG321_USE_WAV when -w <wavfile> is defined, and <wavfile> is pointd to by options.device */ if((pldev=ao_open_file(driver_id, options.device, 1 /*overwrite*/, &format, ao_options))==NULL) { fprintf(stderr, "Error opening libao wav file driver. (Do you have write permissions?)\n"); return NULL; } } else if(options.opt & MPG321_USE_NULL) { int driver_id = ao_driver_id("null"); /* null is dirty, create a proper options struct later */ if((pldev = ao_open_live(driver_id, &format, NULL)) == NULL) { fprintf(stderr, "Error opening libao null driver. (This shouldn't have happened.)\n"); return NULL; } } else if (options.opt & MPG321_USE_STDOUT) { ao_option * ao_options = NULL; int driver_id = ao_driver_id("raw"); /* stdout output is expected to be little-endian generally */ ao_append_option(&ao_options, "byteorder", "little"); if((pldev=ao_open_file(driver_id, "-", 1 /*overwrite*/, &format, ao_options))==NULL) { fprintf(stderr, "Error opening libao raw output driver.\n"); return NULL; } } else if (options.opt & MPG321_USE_USERDEF) { ao_option *ao_options = NULL; int driver_id = ao_driver_id(options.devicetype); if (driver_id < 0) { fprintf(stderr, "Can't open unknown ao driver %s\n", options.devicetype); exit(1); } if (playdevice_is_live()) { if (options.device) { fprintf(stderr, "Can't set output device to %s for unknown ao plugin %s", options.device, options.devicetype); } if((pldev=ao_open_live(driver_id, &format, ao_options))==NULL) { fprintf(stderr, "Error opening unknown libao %s driver. (Is device in use?)\n", options.devicetype); return NULL; } } else { if (options.device) { /* Just assume that options.device is a filename. The user can shoot themselves in the foot all they like... */ if((pldev=ao_open_file(driver_id, options.device, 1 /*overwrite*/, &format, ao_options))==NULL) { fprintf(stderr, "Error opening unknown libao %s file driver for file %s. (Do you have write permissions?)\n", options.devicetype, options.device); return NULL; } } else { fprintf(stderr, "Filename must be specified (with -a filename) for unknown ao driver %s\n", options.devicetype); } } } else { /* Hack-tacular. This code tries to the device as specified; if it can't, it'll fall through to the other devices, trying each in turn. If the user specified a device to use, though, it won't fall through: principle of least surprise */ int opened = 0; if(!opened && options.opt & MPG321_USE_ALSA) { ao_option *ao_options = NULL; int driver_id = ao_driver_id("alsa"); char *c; char *card=(char *)malloc((int)16); memset(card,0,16); strncat(card,"alsa:\0",6); if (options.device) { strcat(card,options.device); //if ((c = strchr(options.device, ':')) == NULL || strlen(c+1) < 1) if ((c = strchr(card, ':')) == NULL || strlen(c+1) < 1) { fprintf(stderr, "Poorly formed ALSA card:device specification %s", options.device); exit(1); } *(c++) = '\0'; /* change the : to a null to create two separate strings */ //ao_append_option(&ao_options, "card", options.device); ao_append_option(&ao_options, "card", card); ao_append_option(&ao_options, "dev", c); } if((pldev=ao_open_live(driver_id, &format, ao_options))==NULL) { if (options.device) { fprintf(stderr, "Can't open libao driver with device %s (is device in use?)\n", options.device); return NULL; } else options.opt |= MPG321_USE_ALSA09; } else opened++; } if(!opened && options.opt & MPG321_USE_ALSA09) { ao_option *ao_options = NULL; int driver_id = ao_driver_id("alsa09"); if(options.device) ao_append_option(&ao_options, "dev", options.device); if((pldev=ao_open_live(driver_id, &format, ao_options))==NULL) { if (options.device) { fprintf(stderr, "Can't open libao driver with device %s (is device in use?)\n", options.device); return NULL; } else options.opt |= MPG321_USE_OSS; } else opened++; } if(!opened && options.opt & MPG321_USE_OSS) { ao_option *ao_options = NULL; int driver_id = ao_driver_id("oss"); if(options.device) ao_append_option(&ao_options, "dsp", options.device); if((pldev=ao_open_live(driver_id, &format, ao_options))==NULL) { if (options.device) { fprintf(stderr, "Can't open libao driver with device %s (is device in use?)\n", options.device); return NULL; } else options.opt |= MPG321_USE_SUN; } else opened++; } if(!opened && options.opt & MPG321_USE_SUN) { ao_option *ao_options = NULL; int driver_id = ao_driver_id("sun"); if(options.device) ao_append_option(&ao_options, "dev", options.device); if((pldev=ao_open_live(driver_id, &format, ao_options))==NULL) { if (options.device) { fprintf(stderr, "Can't open libao driver with device %s (is device in use?)\n", options.device); return NULL; } else options.opt |= MPG321_USE_ESD; } } if(!opened && options.opt & MPG321_USE_ESD) { ao_option *ao_options = NULL; int driver_id = ao_driver_id("esd"); if(options.device) ao_append_option(&ao_options, "host", options.device); if((pldev=ao_open_live(driver_id, &format, ao_options))==NULL) { if (options.device) { fprintf(stderr, "Can't open libao driver with device %s (is device in use?)\n", options.device); return NULL; } else options.opt |= MPG321_USE_ARTS; } else opened++; } if(!opened && options.opt & MPG321_USE_ARTS) { ao_option *ao_options = NULL; int driver_id = ao_driver_id("arts"); if((pldev=ao_open_live(driver_id, &format, ao_options))==NULL) { fprintf(stderr, "Can't find a suitable libao driver. (Is device in use?)\n"); return NULL; } } } /* Restore signal handler */ signal(SIGINT, handle_signals); return pldev; }
// Initialize the libPOLY global state. Return 0 on success, 1 on error. int poly_init(int bitdepth, int channels, int bitrate, int max_generators, const char *filename) { // Make sure arguments are valid: if(!((bitdepth == 8) || (bitdepth == 16) || (bitdepth == 24))) { DEBUG_MSG("bitdepth not one of 8, 16, 26"); errno = EINVAL; return 1; } if(!((channels == 1) || (channels == 2))) { DEBUG_MSG("channels not one of 1, 2"); errno = EINVAL; return 1; } if(!((bitrate == 44100) || (bitrate == 48000) || (bitrate == 96000))) { DEBUG_MSG("bitrate not one of 44100, 48000, 96000"); errno = EINVAL; return 1; } if(max_generators <= 0) { DEBUG_MSG("max_generators <= 0"); errno = EINVAL; return 1; } // Initialize libao: ao_initialize(); poly_ao_init = 1; poly_playback = 0; poly_max_generators = max_generators; poly_time = 0; int driver; // Populate the format struct: poly_format = calloc(1, sizeof(*poly_format)); if(poly_format == NULL) { DEBUG_MSG("calloc for *poly_format failed"); errno = ENOMEM; return 1; } poly_format->bits = bitdepth; poly_format->channels = channels; poly_format->rate = bitrate; poly_format->byte_format = AO_FMT_NATIVE; // Are we using a sound card? if(filename == NULL) { #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) || defined(WIN64) || defined(_WIN64) || defined(__WIN64) || defined(__WIN32__) || defined(__WIN64__) || defined(__WINDOWS__) driver = ao_default_driver_id(); if(driver == -1) { DEBUG_MSG("ao_default_driver_id() failed"); errno = ENODEV; free(poly_format); return 1; } #else driver = ao_driver_id("alsa"); if(driver == -1) { DEBUG_MSG("ao_driver_id() failed"); errno = ENODEV; free(poly_format); return 1; } #endif poly_card = ao_open_live(driver, poly_format, NULL); if(poly_card == NULL) { switch(errno) { case AO_ENODRIVER: DEBUG_MSG("invalid driver"); break; case AO_ENOTLIVE: DEBUG_MSG("file driver passed, live driver expected"); break; case AO_EBADOPTION: DEBUG_MSG("invalid libao option, check local libao config"); break; case AO_EOPENDEVICE: DEBUG_MSG("can't open device"); break; default: DEBUG_MSG("unknown libao error"); break; } free(poly_format); return 1; } } // We're using an output file: else { driver = ao_driver_id("wav"); if(driver == -1) { DEBUG_MSG("libao error, can't open WAV driver"); errno = ENODEV; free(poly_format); return 1; } poly_card = ao_open_file(driver, filename, 1, poly_format, NULL); if(poly_card == NULL) { switch(errno) { case AO_ENODRIVER: DEBUG_MSG("invalid driver"); break; case AO_ENOTFILE: DEBUG_MSG("non-file driver passed"); break; case AO_EBADOPTION: DEBUG_MSG("invalid libao option, check local libao config"); break; case AO_EOPENFILE: DEBUG_MSG("can't open file"); break; default: DEBUG_MSG("unknown libao error"); break; } free(poly_format); return 1; } } poly_generators = calloc(poly_max_generators, sizeof(*poly_generators)); return 0; }
int main(int argc, char **argv) { int r, tmp, fi, random=0; char Buffer[1024]; char length_str[256], fade_str[256], volume[256], title_str[256]; char tmp_str[256]; char *tag; soundLowPass = 0; soundEcho = 0; soundQuality = 0; DetectSilence=1; silencelength=5; IgnoreTrackLength=0; DefaultLength=150000; TrailingSilence=1000; playforever=0; while((r=getopt(argc, argv, "hlsrieWL:t:"))>=0) { char *e; switch(r) { case 'h': printf("playgsf version %s (based on Highly Advanced version %s)\n\n", VERSION_STR, HA_VERSION_STR); printf("Usage: ./playgsf [options] files...\n\n"); printf(" -l Enable low pass filer\n"); printf(" -s Detect silence\n"); printf(" -L Set silence length in seconds (for detection). Default 5\n"); printf(" -t Set default track length in milliseconds. Default 150000 ms\n"); printf(" -i Ignore track length (use default length)\n"); printf(" -e Endless play\n"); printf(" -r Play files in random order\n"); printf(" -W output to 'output.wav' rather than soundcard\n"); printf(" -h Displays what you are reading right now\n"); return 0; break; case 'i': IgnoreTrackLength = 1; break; case 'l': soundLowPass = 1; break; case 's': DetectSilence = 1; break; case 'L': silencelength = strtol(optarg, &e, 0); if (e==optarg) { fprintf(stderr, "Bad value\n"); return 1; } break; case 'e': playforever = 1; break; case 't': DefaultLength = strtol(optarg, &e, 0); if (e==optarg) { fprintf(stderr, "Bad value\n"); return 1; } break; case 'r': random = 1; break; case 'W': fileoutput = 1; break; case '?': fprintf(stderr, "Unknown argument. try -h\n"); return 1; break; } } if (argc-optind<=0) { printf("No files specified! For help, try -h\n"); return 1; } if (random) { shuffle_list(&argv[optind], argc-optind); } printf("playgsf version %s (based on Highly Advanced version %s)\n\n", VERSION_STR, HA_VERSION_STR); signal(SIGINT, signal_handler); tag = (char*)malloc(50001); fi = optind; while (!g_must_exit && fi < argc) { decode_pos_ms = 0; seek_needed = -1; TrailingSilence=1000; r = GSFRun(argv[fi]); if (!r) { fi++; continue; } g_playing = 1; psftag_readfromfile((void*)tag, argv[fi]); BOLD(); printf("Filename: "); NORMAL(); printf("%s\n", basename(argv[fi])); BOLD(); printf("Channels: "); NORMAL(); printf("%d\n", sndNumChannels); BOLD(); printf("Sample rate: "); NORMAL(); printf("%d\n", sndSamplesPerSec); if (!psftag_getvar(tag, "title", title_str, sizeof(title_str)-1)) { BOLD(); printf("Title: "); NORMAL(); printf("%s\n", title_str); } if (!psftag_getvar(tag, "artist", tmp_str, sizeof(tmp_str)-1)) { BOLD(); printf("Artist: "); NORMAL(); printf("%s\n", tmp_str); } if (!psftag_getvar(tag, "game", tmp_str, sizeof(tmp_str)-1)) { BOLD(); printf("Game: "); NORMAL(); printf("%s\n", tmp_str); } if (!psftag_getvar(tag, "year", tmp_str, sizeof(tmp_str)-1)) { BOLD(); printf("Year: "); NORMAL(); printf("%s\n", tmp_str); } if (!psftag_getvar(tag, "copyright", tmp_str, sizeof(tmp_str)-1)) { BOLD(); printf("Copyright: "); NORMAL(); printf("%s\n", tmp_str); } if (!psftag_getvar(tag, "gsfby", tmp_str, sizeof(tmp_str)-1)) { BOLD(); printf("GSF By: "); NORMAL(); printf("%s\n", tmp_str); } if (!psftag_getvar(tag, "tagger", tmp_str, sizeof(tmp_str)-1)) { BOLD(); printf("Tagger: "); NORMAL(); printf("%s\n", tmp_str); } if (!psftag_getvar(tag, "comment", tmp_str, sizeof(tmp_str)-1)) { BOLD(); printf("Comment: "); NORMAL(); printf("%s\n", tmp_str); } if (!psftag_getvar(tag, "fade", fade_str, sizeof(fade_str)-1)) { FadeLength = LengthFromString(fade_str); BOLD(); printf("Fade: "); NORMAL(); printf("%s (%d ms)\n", fade_str, FadeLength); } if (!psftag_raw_getvar(tag, "length", length_str, sizeof(length_str)-1)) { TrackLength = LengthFromString(length_str) + FadeLength; BOLD(); printf("Length: "); NORMAL(); printf("%s (%d ms) ", length_str, TrackLength); if (IgnoreTrackLength) { printf("(ignored)"); TrackLength = DefaultLength; } printf("\n"); } else { TrackLength = DefaultLength; } /* Must be done after GSFrun so sndNumchannels and * sndSamplesPerSec are set to valid values */ ao_initialize(); ao_sample_format format_ao = { 16, sndSamplesPerSec, sndNumChannels, AO_FMT_LITTLE }; if(fileoutput) { snd_ao = ao_open_file(ao_driver_id("wav"), "output.wav", 1, &format_ao, NULL); } else { snd_ao = ao_open_live(ao_default_driver_id(), &format_ao, NULL); } while(g_playing) { int remaining = TrackLength - (int)decode_pos_ms; if (remaining<0) { // this happens during silence period remaining = 0; } EmulationLoop(); BOLD(); printf("Time: "); NORMAL(); printf("%02d:%02d.%02d ", (int)(decode_pos_ms/1000.0)/60, (int)(decode_pos_ms/1000.0)%60, (int)(decode_pos_ms/10.0)%100); if (!playforever) { /*BOLD();*/ printf("["); /*NORMAL();*/ printf("%02d:%02d.%02d", remaining/1000/60, (remaining/1000)%60, (remaining/10%100) ); /*BOLD();*/ printf("] of "); /*NORMAL();*/ printf("%02d:%02d.%02d ", TrackLength/1000/60, (TrackLength/1000)%60, (TrackLength/10%100)); } BOLD(); printf(" GBA Cpu: "); NORMAL(); printf("%02d%% ", cpupercent); printf(" \r"); fflush(stdout); } printf("\n--\n"); ao_close(snd_ao); fi++; } ao_shutdown(); return 0; }
int sound_lowlevel_init( const char *device, int *freqptr, int *stereoptr ) { ao_option *options = NULL; ao_info *driver_info = NULL; int driver_id = -1; static ao_sample_format format = { .bits = 0 }; /* To prevent recursive errors */ static int sound_lowlevel_init_in_progress = 0; int error; if( sound_lowlevel_init_in_progress ) return 0; sound_lowlevel_init_in_progress = 1; ao_initialize(); error = parse_driver_options( device, &driver_id, &options ); if( error ) { settings_current.sound = 0; sound_lowlevel_init_in_progress = 0; return error; } if( driver_id == -1 ) driver_id = ao_default_driver_id(); if( driver_id == -1 ) { ui_error( UI_ERROR_ERROR, "ao: driver '%s' unknown", device ); settings_current.sound = 0; sound_lowlevel_init_in_progress = 0; return 1; } driver_info = ao_driver_info( driver_id ); if( driver_info->type == AO_TYPE_FILE && format.bits != 0 ) { /* OK. We not want to trunc the file :-) */ ui_error( UI_ERROR_WARNING, "ao: must truncate audio file '%s'", filename ); } format.channels = *stereoptr ? 2 : 1; format.rate = *freqptr; format.bits = settings_current.sound_force_8bit ? 8 : 16; format.byte_format = AO_FMT_LITTLE; sixteenbit = settings_current.sound_force_8bit ? 0 : 1; if( driver_info->type == AO_TYPE_LIVE ) { dev_for_ao = ao_open_live( driver_id, &format, options); } else { if( !filename ) filename = (char *)default_filename; dev_for_ao = ao_open_file( driver_id, filename, 1, &format, options); } if( !dev_for_ao ) { driver_error(); settings_current.sound = 0; sound_lowlevel_init_in_progress = 0; return 1; } ao_free_options( options ); sound_lowlevel_init_in_progress = 0; first_init = 0; return 0; } void sound_lowlevel_end( void ) { if( filename != default_filename ) free( filename ); ao_close(dev_for_ao); ao_shutdown(); } void sound_lowlevel_frame( libspectrum_signed_word *data, int len ) { static signed char buf8[4096]; void *data8 = data; len <<= 1; /* now in bytes */ if( !sixteenbit ) { libspectrum_signed_word *src; signed char *dst; int f; src = data; dst = buf8; len >>= 1; for( f = 0; f < len; f++) *dst++ = ( int )( ( *src++ ) / 256 ); data8 = buf8; } ao_play( dev_for_ao, data8, len ); }