static void sound_dmacallback( void ) { if( sfifo_used( &sound_fifo ) < 128) return; dmalen = MIN( BUFSIZE, sfifo_used( &sound_fifo ) ); sfifo_read( &sound_fifo, dmabuf, dmalen ); DCFlushRange( dmabuf, dmalen ); AUDIO_InitDMA( (u32)dmabuf, dmalen ); AUDIO_StartDMA(); }
static OSStatus playProc(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets, AudioBufferList *outOutputData, AudioStreamPacketDescription **outDataPacketDescription, void* inClientData) { mpg123_coreaudio_t *ca = (mpg123_coreaudio_t *)inClientData; long n; if(ca->last_buffer) { ca->play_done = 1; return noErr; } for(n = 0; n < outOutputData->mNumberBuffers; n++) { unsigned int wanted = *ioNumberDataPackets * ca->channels * ca->bps; unsigned char *dest; unsigned int read; if(ca->buffer_size < wanted) { debug1("Allocating %d byte sample conversion buffer", wanted); ca->buffer = realloc( ca->buffer, wanted); ca->buffer_size = wanted; } dest = ca->buffer; /* Only play if we have data left */ if ( sfifo_used( &ca->fifo ) < (int)wanted ) { if(!ca->decode_done) { warning("Didn't have any audio data in callback (buffer underflow)"); return -1; } wanted = sfifo_used( &ca->fifo ); ca->last_buffer = 1; } /* Read audio from FIFO to SDL's buffer */ read = sfifo_read( &ca->fifo, dest, wanted ); if (wanted!=read) warning2("Error reading from the ring buffer (wanted=%u, read=%u).\n", wanted, read); outOutputData->mBuffers[n].mDataByteSize = read; outOutputData->mBuffers[n].mData = dest; } return noErr; }
static int n2s_sender_thread(void *data) { char buf[N2S_SEND_FRAGMENT]; REAL_EB_socket *rs = (REAL_EB_socket *)data; while(!rs->closed && !rs->status) { int count; SDL_Delay(rs->pollperiod); count = sfifo_used(&rs->fifo); if(!count) continue; while(count) { int res; int n = count; if(n > N2S_SEND_FRAGMENT) n = N2S_SEND_FRAGMENT; sfifo_read(&rs->fifo, buf, n); res = NET2_TCPSend(rs->n2socket, buf, n); if(res < 0) { rs->status = EEL_XDEVICEWRITE; break; } count -= n; } } // Detach from the EEL wrapper object rs->sender = NULL; return 0; }
/* * Read bytes from a FIFO * Return number of bytes read, or an error code */ int sfifo_read(sfifo_t *f, void *_buf, int len) { int total; int i; char *buf = (char *)_buf; if(!f->buffer) return -ENODEV; /* No buffer! */ /* total = len = min(used, len) */ total = sfifo_used(f); DBG(printf("sfifo_used() = %d\n",total)); if(len > total) len = total; else total = len; i = f->readpos; if(i + len > f->size) { memcpy(buf, f->buffer + i, f->size - i); buf += f->size - i; len -= f->size - i; i = 0; } memcpy(buf, f->buffer + i, len); f->readpos = i + len; return total; }
/* This is the audio processing callback. */ OSStatus coreaudiowrite( void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData ) { int f; int len = deviceFormat.mBytesPerFrame * inNumberFrames; uint8_t* out = ioData->mBuffers[0].mData; /* Try to only read an even number of bytes so as not to fragment a sample */ len = MIN( len, sfifo_used( &sound_fifo ) ); len &= sound_stereo ? 0xfffc : 0xfffe; /* Read input_size bytes from fifo into sound stream */ while( ( f = sfifo_read( &sound_fifo, out, len ) ) > 0 ) { out += f; len -= f; } /* If we ran out of sound, make do with silence :( */ if( f < 0 ) { for( f=0; f<len; f++ ) { *out++ = 0; } } return noErr; }
int sfifo_read(sfifo_t *f, void *_buf, int len) { int total; int i; char *buf = (char *)_buf; if(!f->buffer) return -1; /*total = len = used > len ? len : used;*/ total = sfifo_used(f); if(len > total) len = total; else total = len; i = f->readpos; if(i + len > f->size) { memcpy(buf, f->buffer + i, f->size - i); buf += f->size - i; len -= f->size - i; i = 0; } memcpy(buf, f->buffer + i, len); f->readpos = i + len; return total; }
static int write_sdl(out123_handle *ao, unsigned char *buf, int len) { sfifo_t *fifo = (sfifo_t*)ao->userptr; /* Sleep for half the length of the FIFO */ while (sfifo_space( fifo ) < len ) #ifdef WIN32 Sleep( (FIFO_DURATION/2) * 1000); #else usleep( (FIFO_DURATION/2) * 1000000 ); #endif /* Bung decoded audio into the FIFO SDL Audio locking probably isn't actually needed as SFIFO claims to be thread safe... */ SDL_LockAudio(); sfifo_write( fifo, buf, len); SDL_UnlockAudio(); /* Unpause once the buffer is 50% full */ if (sfifo_used(fifo) > (sfifo_size(fifo)*0.5) ) SDL_PauseAudio(0); return len; }
/* * This is where buffered asynchronous commands are * processed. Some of them turn directly into timestamped * events right here. */ static void _run_commands(void) { int d = hold_until - get_time(); if(labs(d) > 1000) hold_until = get_time(); else if(d > 0) return; while(sfifo_used(&commands) >= sizeof(command_t)) { command_t cmd; if(sfifo_read(&commands, &cmd, (unsigned)sizeof(cmd)) < 0) { log_printf(ELOG, "audio.c: Engine failure!\n"); _audio_running = 0; return; } switch(cmd.action) { case CMD_STOP: DBG2(log_printf(D3LOG, "%d: CMD_STOP\n", get_time());) (void)ce_stop(channeltab + cmd.cid, 0, cmd.tag, 32768); break; case CMD_STOP_ALL: DBG2(log_printf(D3LOG, "%d: CMD_STOP_ALL\n", get_time());) channel_stop_all(); break; case CMD_PLAY: DBG2(log_printf(D3LOG, "%d: CMD_PLAY\n", get_time());)
static OSStatus playProc(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets, AudioBufferList *outOutputData, AudioStreamPacketDescription **outDataPacketDescription, void* inClientData) { mpg123_coreaudio_t *ca = (mpg123_coreaudio_t *)inClientData; long n; if(ca->last_buffer) { ca->play_done = 1; return noErr; } for(n = 0; n < outOutputData->mNumberBuffers; n++) { unsigned int wanted = *ioNumberDataPackets * ca->channels * ca->bps; unsigned char *dest; unsigned int read; if(ca->buffer_size < wanted) { ca->buffer = realloc( ca->buffer, wanted); ca->buffer_size = wanted; } dest = ca->buffer; /* Only play if we have data left */ if ( sfifo_used( &ca->fifo ) < wanted ) { if(!ca->decode_done) { return -1; } wanted = sfifo_used( &ca->fifo ); ca->last_buffer = 1; } /* Read audio from FIFO to SDL's buffer */ read = sfifo_read( &ca->fifo, dest, wanted ); outOutputData->mBuffers[n].mDataByteSize = read; outOutputData->mBuffers[n].mData = dest; } return noErr; }
static void send_data(struct tcp_pcb *pcb, struct ftpd_datastate *fsd) { err_t err; u16_t len; /* This function is not reentrant */ if (fsd->sending) return; fsd->sending = 1; if (sfifo_used(&fsd->fifo) > 0 && tcp_sndbuf(pcb) > 15) { int i; /* We cannot send more data than space available in the send buffer. */ if (tcp_sndbuf(pcb) < sfifo_used(&fsd->fifo)) { len = tcp_sndbuf(pcb); } else { len = (u16_t) sfifo_used(&fsd->fifo); } i = fsd->fifo.readpos; if ((i + len) > fsd->fifo.size) { err = tcp_write(pcb, fsd->fifo.buffer + i, (u16_t)(fsd->fifo.size - i), 1); if (err != ERR_OK) { dbg_printf("send_data: error writing!\n"); fsd->sending = 0; return; } len -= fsd->fifo.size - i; fsd->fifo.readpos = 0; i = 0; } err = tcp_write(pcb, fsd->fifo.buffer + i, len, 1); if (err != ERR_OK) { dbg_printf("send_data: error writing!\n"); fsd->sending = 0; return; } fsd->fifo.readpos += len; } fsd->sending = 0; }
static err_t ftpd_msgsent(void *arg, struct tcp_pcb *pcb, u16_t len) { struct ftpd_msgstate *fsm = arg; if ((sfifo_used(&fsm->fifo) == 0) && (fsm->state == FTPD_QUIT)) { ftpd_msgclose(pcb, fsm); return ERR_OK; } if (pcb->state <= ESTABLISHED) send_msgdata(pcb, fsm); return ERR_OK; }
static void send_msgdata(struct tcp_pcb *pcb, struct ftpd_msgstate *fsm) { err_t err; u16_t len; if (sfifo_used(&fsm->fifo) > 0) { int i; /* We cannot send more data than space available in the send buffer. */ if (tcp_sndbuf(pcb) < sfifo_used(&fsm->fifo)) { len = tcp_sndbuf(pcb); } else { len = (u16_t) sfifo_used(&fsm->fifo); } i = fsm->fifo.readpos; if ((i + len) > fsm->fifo.size) { err = tcp_write(pcb, fsm->fifo.buffer + i, (u16_t)(fsm->fifo.size - i), 1); if (err != ERR_OK) { dbg_printf("send_msgdata: error writing!\n"); return; } len -= fsm->fifo.size - i; fsm->fifo.readpos = 0; i = 0; } err = tcp_write(pcb, fsm->fifo.buffer + i, len, 1); if (err != ERR_OK) { dbg_printf("send_msgdata: error writing!\n"); return; } fsm->fifo.readpos += len; } }
/* The audio function callback takes the following parameters: stream: A pointer to the audio buffer to be filled len: The length (in bytes) of the audio buffer */ static void audio_callback_sdl(void *udata, Uint8 *stream, int len) { out123_handle *ao = (out123_handle*)udata; sfifo_t *fifo = (sfifo_t*)ao->userptr; int bytes_read; int bytes_avail; bytes_avail = sfifo_used(fifo); if(bytes_avail < len) len = bytes_avail; /* Read audio from FIFO to SDL's buffer */ bytes_read = sfifo_read( fifo, stream, len ); if (len!=bytes_read) warning2("Error reading from the FIFO (wanted=%u, bytes_read=%u).\n", len, bytes_read); }
static void send_file(struct ftpd_datastate *fsd, struct tcp_pcb *pcb) { if (!fsd->connected) return; if (fsd->vfs_file) { char buffer[2048]; int len; len = sfifo_space(&fsd->fifo); if (len == 0) { send_data(pcb, fsd); return; } if (len > 2048) len = 2048; len = vfs_read(buffer, 1, len, fsd->vfs_file); if (len == 0) { if (vfs_eof(fsd->vfs_file) == 0) return; vfs_close(fsd->vfs_file); fsd->vfs_file = NULL; return; } sfifo_write(&fsd->fifo, buffer, len); send_data(pcb, fsd); } else { struct ftpd_msgstate *fsm; struct tcp_pcb *msgpcb; if (sfifo_used(&fsd->fifo) > 0) { send_data(pcb, fsd); return; } fsm = fsd->msgfs; msgpcb = fsd->msgpcb; vfs_close(fsd->vfs_file); fsd->vfs_file = NULL; ftpd_dataclose(pcb, fsd); fsm->datapcb = NULL; fsm->datafs = NULL; fsm->state = FTPD_IDLE; send_msg(msgpcb, fsm, msg226); return; } }
static int close_sdl(out123_handle *ao) { int stuff; sfifo_t *fifo = (sfifo_t*)ao->userptr; /* Wait at least until SDL emptied the FIFO. */ while((stuff = sfifo_used(fifo))>0) { int msecs = stuff*1000/ao->rate; debug1("still stuff for about %i ms there", msecs); #ifdef WIN32 Sleep(msecs/2); #else usleep(msecs*1000/2); #endif } SDL_CloseAudio(); /* Free up the memory used by the FIFO */ sfifo_close( fifo ); return 0; }
static void send_next_directory(struct ftpd_datastate *fsd, struct tcp_pcb *pcb, int shortlist) { char buffer[1024]; int len; while (1) { if (fsd->vfs_dirent == NULL) fsd->vfs_dirent = vfs_readdir(fsd->vfs_dir); if (fsd->vfs_dirent) { if (shortlist) { len = sprintf(buffer, "%s\r\n", fsd->vfs_dirent->name); if (sfifo_space(&fsd->fifo) < len) { send_data(pcb, fsd); return; } sfifo_write(&fsd->fifo, buffer, len); fsd->vfs_dirent = NULL; } else { vfs_stat_t st; time_t current_time; int current_year; struct tm *s_time; time(¤t_time); s_time = gmtime(¤t_time); current_year = s_time->tm_year; vfs_stat(fsd->msgfs->vfs, fsd->vfs_dirent->name, &st); s_time = gmtime(&st.st_mtime); if (s_time->tm_year == current_year) len = sprintf(buffer, "-rw-rw-rw- 1 user ftp %11ld %s %02i %02i:%02i %s\r\n", st.st_size, month_table[s_time->tm_mon], s_time->tm_mday, s_time->tm_hour, s_time->tm_min, fsd->vfs_dirent->name); else len = sprintf(buffer, "-rw-rw-rw- 1 user ftp %11ld %s %02i %5i %s\r\n", st.st_size, month_table[s_time->tm_mon], s_time->tm_mday, s_time->tm_year + 1900, fsd->vfs_dirent->name); if (VFS_ISDIR(st.st_mode)) buffer[0] = 'd'; if (sfifo_space(&fsd->fifo) < len) { send_data(pcb, fsd); return; } sfifo_write(&fsd->fifo, buffer, len); fsd->vfs_dirent = NULL; } } else { struct ftpd_msgstate *fsm; struct tcp_pcb *msgpcb; if (sfifo_used(&fsd->fifo) > 0) { send_data(pcb, fsd); return; } fsm = fsd->msgfs; msgpcb = fsd->msgpcb; vfs_closedir(fsd->vfs_dir); fsd->vfs_dir = NULL; ftpd_dataclose(pcb, fsd); fsm->datapcb = NULL; fsm->datafs = NULL; fsm->state = FTPD_IDLE; send_msg(msgpcb, fsm, msg226); return; } } }