ad_rec_t *ad_open ( void ) { ad_rec_t *r; if ((r = (ad_rec_t *) calloc (1, sizeof(ad_rec_t))) == NULL) return NULL; r->audio_fd = audioOpen (16000); r->recording = 0; return r; }
ad_rec_t *ad_open_sps (int32 sps) { ad_rec_t *r; if ((r = (ad_rec_t *) calloc (1, sizeof(ad_rec_t))) == NULL) return NULL; r->audio_fd = audioOpen ((int)sps); r->recording = 0; return r; }
/* TODO: there must be a check here to see if the audio device has been opened * successfuly. This is a bitch because it requires all 6 or 7 OS-specific functions * to be changed. Is anyone willing to do this at all??? */ int setup_audio(struct AUDIO_HEADER *header) { if (A_AUDIO_PLAY) { if (AUDIO_BUFFER_SIZE==0) audioOpen(t_sampling_frequency[header->ID][header->sampling_frequency], (header->mode!=3 && !A_DOWNMIX),A_SET_VOLUME); else bufferpid = audioBufferOpen(t_sampling_frequency[header->ID][header->sampling_frequency], (header->mode!=3 && !A_DOWNMIX),A_SET_VOLUME); } return 0; }
int audioBufferOpen(int frequency, int stereo, int volume) { struct ringBuffer audioBuffer; int inFd,outFd,ctlFd,cnt,pid; int inputFinished=FALSE; int percentFull; fd_set inFdSet,outFdSet; fd_set *outFdPtr; struct timeval timeout; int filedes[2]; int controldes[2]; if (pipe(filedes) || pipe(controldes)) { perror("pipe"); exit(-1); } if ((pid=fork())!=0) { /* if we are the parent */ control_fd=controldes[1]; close(filedes[0]); buffer_fd=filedes[1]; close(controldes[0]); return(pid); /* return the pid */ } /* we are the child */ close(filedes[1]); inFd=filedes[0]; close(controldes[1]); ctlFd=controldes[0]; audioOpen(frequency,stereo,volume); outFd=getAudioFd(); initBuffer(&audioBuffer); while(1) { timeout.tv_sec=0; timeout.tv_usec=0; FD_ZERO(&inFdSet); FD_ZERO(&outFdSet); FD_SET(ctlFd,&inFdSet); FD_SET(outFd,&outFdSet); if (bufferSize(&audioBuffer)<AUSIZ) { /* is the buffer too empty */ outFdPtr = NULL; /* yes, don't try to write */ if (inputFinished) /* no more input, buffer exhausted -> exit */ break; } else outFdPtr=&outFdSet; /* no, select on write */ /* check we have at least AUSIZ bytes left (don't want <1k bits) */ if ((bufferFree(&audioBuffer)>=AUSIZ) && !inputFinished) FD_SET(inFd,&inFdSet); /* The following selects() are basically all that is left of the system dependent code outside the audioIO_*&c files. These selects really need to be moved into the audioIO_*.c files and replaced with a function like audioIOReady(inFd, &checkIn, &checkAudio, wait) where it checks the status of the input or audio output if checkIn or checkAudio are set and returns with checkIn or checkAudio set to TRUE or FALSE depending on whether or not data is available. If wait is FALSE the function should return immediately, if wait is TRUE the process should BLOCK until the required condition is met. NB: The process MUST relinquish the CPU during this check or it will gobble up all the available CPU which sort of defeats the purpose of the buffer. This is tricky for people who don't have file descriptors (and select) to do the job. In that case a buffer implemented using threads should work. The way things are set up now a threaded version shouldn't be to hard to implement. When I get some time... */ /* check if we can read or write */ if (select(MAX3(inFd,outFd,ctlFd)+1,&inFdSet,outFdPtr,NULL,NULL) > -1) { if (outFdPtr && FD_ISSET(outFd,outFdPtr)) { /* need to write */ int bytesToEnd = AUDIO_BUFFER_SIZE - audioBuffer.outPos; percentFull=100*bufferSize(&audioBuffer)/AUDIO_BUFFER_SIZE; if (AUSIZ>bytesToEnd) { cnt = audioWrite(audioBuffer.bufferPtr + audioBuffer.outPos, bytesToEnd); cnt += audioWrite(audioBuffer.bufferPtr, AUSIZ - bytesToEnd); audioBuffer.outPos = AUSIZ - bytesToEnd; } else { cnt = audioWrite(audioBuffer.bufferPtr + audioBuffer.outPos, AUSIZ); audioBuffer.outPos += AUSIZ; } } if (FD_ISSET(inFd,&inFdSet)) { /* need to read */ cnt = read(inFd, audioBuffer.bufferPtr + audioBuffer.inPos, MIN(AUSIZ, AUDIO_BUFFER_SIZE - audioBuffer.inPos)); if (cnt >= 0) { audioBuffer.inPos = (audioBuffer.inPos + cnt) % AUDIO_BUFFER_SIZE; if (cnt==0) inputFinished=TRUE; } else _exit(-1); } if (FD_ISSET(ctlFd,&inFdSet)) { int dummy; cnt = read(ctlFd, &dummy, sizeof dummy); if (cnt >= 0) { audioBuffer.inPos = audioBuffer.outPos = 0; audioFlush(); } else _exit(-1); } } else _exit(-1); } close(inFd); audioClose(); exit(0); return 0; /* just to get rid of warnings */ }
int decodeMPEG_2(int inFilefd) { struct AUDIO_HEADER header; int cnt,g,err=0; TControlMsg message; if ((in_file=fdopen(inFilefd,"r"))==NULL) { return(1); } append=data=nch=0; /* initialize globals */ GUI_STOPPED = FALSE; GUI_PLAYING = TRUE; GUI_FD_TO_PLAY = -1; for (cnt=0;;cnt++) { if ((g=gethdr(&header))!=0) { switch (g) { case GETHDR_ERR: die("error reading mpeg bitstream. exiting.\n"); break; case GETHDR_NS : warn("this is a file in MPEG 2.5 format, which is not defined\n"); warn("by ISO/MPEG. It is \"a special Fraunhofer format\".\n"); warn("amp does not support this format. sorry.\n"); break; case GETHDR_FL1: warn("ISO/MPEG layer 1 is not supported by amp (yet).\n"); break; case GETHDR_FF : warn("free format bitstreams are not supported. sorry.\n"); break; case GETHDR_SYN: warn("oops, we're out of sync.\n"); break; default: } break; } if (!(cnt%10)){ GUIstatusDisplay(cnt); } if(get_msg(&message) >= 0) { int pflag = 0; cnt = parse_msg(&message,&header,cnt); if (GUI_PAUSE) { int flags; pflag = 1; #if 0 /* Set stdin to blocking */ if((flags = fcntl(STDIN_FILENO, F_GETFL, 0)) < 0) perror("fcntl"); flags ^= O_NONBLOCK; if(fcntl(STDIN_FILENO, F_SETFL, flags) < 0) perror("fcntl"); #endif } while(GUI_PAUSE){ if(get_msg(&message) >= 0) cnt = parse_msg(&message,&header,cnt); } if (pflag) { int flags; /* Set stdin to non-blocking */ #if 0 if((flags = fcntl(STDIN_FILENO, F_GETFL, 0)) < 0) perror("fcntl"); flags |= O_NONBLOCK; if(fcntl(STDIN_FILENO, F_SETFL, flags) < 0) perror("fcntl"); #endif } if (GUI_STOP || (GUI_FD_TO_PLAY != -1)){ break; } } /* crc is read just to get out of the way. */ if (header.protection_bit==0) getcrc(); if (!cnt && A_AUDIO_PLAY) { /* setup the audio when we have the frame info */ if (AUDIO_BUFFER_SIZE==0) audioOpen(t_sampling_frequency[header.ID][header.sampling_frequency], (header.mode!=3), A_SET_VOLUME); else audioBufferOpen(t_sampling_frequency[header.ID][header.sampling_frequency],(header.mode!=3),A_SET_VOLUME); } if (layer3_frame(&header,cnt)) { warn(" error. blip.\n"); err=1; break; } } fclose(in_file); if (A_AUDIO_PLAY) if (AUDIO_BUFFER_SIZE!=0) audioBufferClose(); else audioClose(); else fclose(out_file); if (!(GUI_STOP) && (GUI_FD_TO_PLAY == -1)) { /* We've reached the end of the track, notify the jukebox... */ TControlMsg rmsg; rmsg.type = MSG_NEXT; rmsg.data = 0; send_msg(&rmsg, TRUE); } GUI_STOPPED = TRUE; GUI_PLAYING = FALSE; return(err); }