static void inline add_to_buffer(void* stream, unsigned int length){ // This shouldn't lose any data and works for any size unsigned int stream_offset = 0; // Length calculations are in samples (stereo (short) sample pairs) unsigned int lengthi, rlengthi; unsigned int lengthLeft = length >> 2; unsigned int rlengthLeft = ceilf(lengthLeft / freq_ratio); while(1){ rlengthi = (buffer_offset + (rlengthLeft << 2) <= buffer_size) ? rlengthLeft : ((buffer_size - buffer_offset) >> 2); lengthi = rlengthi * freq_ratio; #ifdef THREADED_AUDIO // Wait for a buffer we can copy into LWP_SemWait(buffer_empty); #endif copy_to_buffer(buffer[which_buffer] + buffer_offset, stream + stream_offset, rlengthi); if(buffer_offset + (rlengthLeft << 2) < buffer_size){ buffer_offset += rlengthi << 2; #ifdef THREADED_AUDIO // This is a little weird, but we didn't fill this buffer. // So it is still considered 'empty', but since we 'decremented' // buffer_empty coming in here, we want to set it back how // it was, so we don't cause a deadlock LWP_SemPost(buffer_empty); #endif return; } lengthLeft -= lengthi; stream_offset += lengthi << 2; rlengthLeft -= rlengthi; #ifdef THREADED_AUDIO // Start the thread if this is the first sample if(!thread_running){ thread_running = 1; LWP_SemPost(first_audio); } // Let the audio thread know that we've filled a new buffer LWP_SemPost(buffer_full); #else play_buffer(); #endif #ifdef AIDUMP if(AIdump) fwrite(&buffer[which_buffer][0],1,buffer_size,AIdump); #endif NEXT(which_buffer); buffer_offset = 0; } }
void wave_play_file(int wavfd, int dspfd, short *current, short *audioend, int interval) { while (current < audioend) { short *endcurrent = current + interval; if (endcurrent > audioend) endcurrent = audioend; if (play_buffer(dspfd,current,endcurrent) == -1) endcurrent = audioend; current = endcurrent; } }
static void inline add_to_buffer(void* stream, unsigned int length) { unsigned int lengthLeft; unsigned int rlengthLeft; lengthLeft = length >> 2; rlengthLeft = ceil(lengthLeft * freq_ratio); // copy_to_buffer((int *)buffer, stream , rlengthLeft, lengthLeft); ResampleLinear((s16 *) stream, lengthLeft, (s16 *) buffer, rlengthLeft); buffer_size = rlengthLeft << 2; play_buffer(); }
/** * * playing sound from file * */ int play_wav(char* filename) { int fd; int len=0; int res; char* buf; unsigned long size; Wav* wf; struct stat st; syslog(LOG_INFO, "файл %s\n", filename); res=stat(filename, &st); if(res<0) { syslog(LOG_ERR, "file %s not exist", filename); go_out(); }; len=st.st_size; buf=get_wav(filename, len); if(buf==NULL) { syslog(LOG_ERR, "Error getting file %s", filename); go_out(); }; if(validate_wav(buf)!=0) { syslog(LOG_ERR, "Inappropriate sound file %s", filename); go_out(); }; wf=(Wav*) buf; buf=(char*)&(wf->Data); size=(wf->SubChunk2Size)*(wf->SampleRate)/(wf->ByteRate); syslog(LOG_INFO, "samples: %d", size); play_buffer(buf, size); //drain_sound(); if(munmap(buf, len)!=0) { syslog(LOG_ERR, "Cannot unmap memory used for file %s", filename); //go_out(); }; return(0); }
void play_wav_file(char *filename) { char *inwavbuf; short *current; short *audioend; short *audio; WAVE_HEADER *wav_info; int wavfd; int dspfd; struct stat input_fstat; size_t interval; newtComponent vu_1sec; newtComponent vu_total; newtComponent wav_length; newtComponent label_length; newtComponent mainwaveform; newtComponent label_1sec; newtComponent label_total; newtComponent rf_result; char labelstr_1sec[10] = "0"; char labelstr_total[10] = "0"; char labelstr_length[10] = ""; short one_sec_max, total_max; wavfd = open(filename,O_RDONLY,0600); if (wavfd == -1) { printf("Error: open() %s\n",strerror(errno)); exit(1); } if (fstat(wavfd,&input_fstat) != 0) { printf("Error: fstat() %s\n",strerror(errno)); return; } if (input_fstat.st_size < sizeof(WAVE_HEADER)) { printf("File is not large enough to hold a .wav file header even!\n"); return; } inwavbuf = mmap(NULL,input_fstat.st_size,PROT_READ,MAP_SHARED,wavfd,0); if (inwavbuf == MAP_FAILED) { printf("Error: mmap() %s\n",strerror(errno)); exit(1); } audio = (short *)validate_wav_header(inwavbuf,0); current = audio; if (current == NULL) { printf("This program didn't like the wav file\n"); exit(1); } wav_info = (WAVE_HEADER *)inwavbuf; audioend = (short *)((char *)audio + wav_info->nDataBytes); dspfd = open_dsp(wav_info); newtCls(); newtDrawRootText(0, 0, filename); mainwaveform = newtForm(NULL, NULL, NEWT_FLAG_NOF12); vu_1sec = newtScale(9,5,68,(long long)(SHRT_MAX)); label_1sec = newtLabel(1,5,labelstr_1sec); wav_length = newtScale(9,3,68,audioend - audio); label_length = newtLabel(1,3,labelstr_length); vu_total = newtScale(9,8,68,(long long)(SHRT_MAX)); label_total = newtLabel(1,8,labelstr_total); newtFormAddComponent(mainwaveform,vu_1sec); newtFormAddComponent(mainwaveform,vu_total); newtFormAddComponent(mainwaveform,label_1sec); newtFormAddComponent(mainwaveform,label_total); one_sec_max = 0; total_max = 0; newtFormWatchFd(mainwaveform,dspfd,NEWT_FD_WRITE); newtFormAddHotKey(mainwaveform,NEWT_KEY_ENTER); newtPushHelpLine("Hit Enter to end playing"); newtCenteredWindow(78,10,"now playing .wav file"); newtRefresh(); /* presently every second */ interval = (size_t )((double )wav_info->nSamplesPerSec * interval_s * 2); while ((current) < audioend) { short *endcurrent = current + interval; if (endcurrent > audioend) { endcurrent = audioend; } one_sec_max = get_peak_value(current,endcurrent); newtScaleSet(vu_1sec,one_sec_max); sprintf(labelstr_1sec,"%1.6f",((float )one_sec_max/ (float )SHRT_MAX)); newtLabelSetText(label_1sec,labelstr_1sec); newtScaleSet(wav_length,current - audio); sprintf(labelstr_length,"%4.2f", ((double )(current - audio) / 88200)); newtLabelSetText(label_length,labelstr_length); if (one_sec_max > total_max) { total_max = one_sec_max; sprintf(labelstr_total,"%1.6f",((float )total_max/ (float )SHRT_MAX)); newtLabelSetText(label_total,labelstr_total); newtScaleSet(vu_total,total_max); } rf_result = newtRunForm(mainwaveform); if (play_buffer(dspfd,current,endcurrent) == -1) { current = audioend; } current = endcurrent; if (rf_result == NULL) current = audioend; newtRefresh(); } newtFormDestroy(mainwaveform); munmap(inwavbuf,input_fstat.st_size); close(wavfd); close(dspfd); return; }