size_t wave_write(void* theHandler, char* theMono16BitsWaveBuffer, size_t theSize) { ENTER("wave_write"); size_t bytes_written = 0; // space in ringbuffer for the sample needed: 1x mono channel but 2x for 1 stereo channel size_t bytes_to_write = (out_channels==1) ? theSize : theSize*2; my_stream_could_start = 0; if(pa_stream == NULL) { SHOW_TIME("wave_write > wave_open_sound\n"); if (0 != wave_open_sound()) { SHOW_TIME("wave_write > wave_open_sound fails!"); return 0; } my_stream_could_start=1; } else if (!wave_is_busy(NULL)) { my_stream_could_start = 1; } assert(BUFFER_LENGTH >= bytes_to_write); if (myWrite >= myBuffer + BUFFER_LENGTH) { myWrite = myBuffer; } // end if (myWrite >= myBuffer + BUFFER_LENGTH) size_t aTotalFreeMem=0; char* aRead = myRead; SHOW("wave_write > aRead=%x, myWrite=%x\n", (int)aRead, (int)myWrite); while (1) { if (my_callback_is_output_enabled && (0==my_callback_is_output_enabled())) { SHOW_TIME("wave_write > my_callback_is_output_enabled: no!"); return 0; } aRead = myRead; // write pointer is before read pointer? if (myWrite >= aRead) { aTotalFreeMem = aRead + BUFFER_LENGTH - myWrite; } else // read pointer is before write pointer! { aTotalFreeMem = aRead - myWrite; } // end if (myWrite >= aRead) if (aTotalFreeMem>1) { // -1 because myWrite must be different of aRead // otherwise buffer would be considered as empty aTotalFreeMem -= 1; } // end if (aTotalFreeMem>1) if (aTotalFreeMem >= bytes_to_write) { break; } // end if (aTotalFreeMem >= bytes_to_write) //SHOW_TIME("wave_write > wait"); SHOW("wave_write > wait: aTotalFreeMem=%d\n", aTotalFreeMem); SHOW("wave_write > aRead=%x, myWrite=%x\n", (int)aRead, (int)myWrite); usleep(10000); } // end while (1) aRead = myRead; // write pointer is ahead the read pointer? if (myWrite >= aRead) { SHOW_TIME("wave_write > myWrite >= aRead"); // determine remaining free memory to the end of the ringbuffer size_t aFreeMem = myBuffer + BUFFER_LENGTH - myWrite; // is enough linear space available (regardless 1 or 2 channels)? if (aFreeMem >= bytes_to_write) { // copy direct - no wrap around at end of ringbuffer needed myWrite += copyBuffer(myWrite, theMono16BitsWaveBuffer, theSize); } else // not enough linear space available { // 2 channels (stereo)? if (out_channels == 2) { // copy with wrap around at the end of ringbuffer copyBuffer(myWrite, theMono16BitsWaveBuffer, aFreeMem/2); myWrite = myBuffer; myWrite += copyBuffer(myWrite, theMono16BitsWaveBuffer+aFreeMem/2, theSize - aFreeMem/2); } else // 1 channel (mono) { // copy with wrap around at the end of ringbuffer copyBuffer(myWrite, theMono16BitsWaveBuffer, aFreeMem); myWrite = myBuffer; myWrite += copyBuffer(myWrite, theMono16BitsWaveBuffer+aFreeMem, theSize - aFreeMem); } // end if (out_channels == 2) } // end if (aFreeMem >= bytes_to_write) } // if (myWrite >= aRead) else // read pointer is ahead the write pointer { SHOW_TIME("wave_write > myWrite <= aRead"); myWrite += copyBuffer(myWrite, theMono16BitsWaveBuffer, theSize); } // end if (myWrite >= aRead) bytes_written = bytes_to_write; myWritePosition += theSize/sizeof(uint16_t); // add number of samples if (my_stream_could_start && (get_used_mem() >= out_channels * sizeof(uint16_t) * FRAMES_PER_BUFFER)) { start_stream(); } // end if (my_stream_could_start && (get_used_mem() >= out_channels * sizeof(uint16_t) * FRAMES_PER_BUFFER)) SHOW_TIME("wave_write > LEAVE"); return bytes_written; }
int main(void) { init_pmm(); if (init_mm()) return(1); vid_init(); vid_set_attr(FG_COLOR, RED); printf("\naMOS BOSS V.%s %s\n", STRING_VERSION, BUILD_ARCH); printf("Build %s %s by %s on %s\n\n", COMPILE_DATE, COMPILE_TIME, COMPILE_BY, COMPILE_HOST); vid_set_attr(FG_COLOR, WHITE); init_pit(); init_tss(); if (init_intr()) return(1); init_cpu(); if (init_sched()) return(1); init_fd(); printf("System memory: %d Mb\n\n", (int)pmm_get_size_mb()); printf("Free kernel mem: %d bytes\nUsed kernel mem: %d bytes\n", (int)get_free_mem(), (int)get_used_mem()); for (;;) {} return(0); }