|
From: Benno S. <be...@ga...> - 2003-08-14 17:00:33
|
Scrive Christian Henz <ch...@gm...>: > > Ok I agree with you when we consider decompression of compressed formats. > > But (being an efficiency obsessed person by definition) I just wanted to > make > > sure that the disk reading operations would be as fast as possible. > > For example in evo I avoid any copies and temporary buffers: > > the data from disk is read directly into a large ring buffer where > > the audio thread directly resamples the data from putting it into > > the output buffer (which is sent to sound card). > > > > But for the real thing you'll need one buffer per voice anyway, right? Not necessarily: for example for a MIDI device you usually have an instrument assigned to each channel thus in presence of polyphonic instruments many voices get downmixed to the same channel. This means that if you do it right you can just mix the current sample output of each voice to to the channel buffer. So yes my former statement was a bit incorrect, you have more than one output buffers (mixdown buffers) which at the last stage get mixed down to the final soundcard audio out buffer. > > > So as long as your library gives us an efficient > > read(buffer, numsamples) function > > that in case of uncompressed samples just calls posix read() then I have > > nothing to object to let your library handle the I/O. > > Well, at some point the decoding/de-interleaving/resampling has to happen, so > why not in the respective loaders? Then you could have a unified concept of a > sample. Instead of reading raw data, the voices would call something like > sample->read(int channel, sample_t *voice_buffer, int num_samples) ok, but the library needs to supply uncompressed samples (linear block of samples) because the engine has to handle complex ring buffer issues, code that cannot be put within loaders. But the abstraction read(buffer, numsamples) (which internally does decompression, deinterleaving etc) is ok since it allows you to real any sample format you like. > > I've also been thinking about the case where you got several voices reading > from one (streamed) sample (like when you map a sample across several notes > or for polyphony on the same note). The sample start would of course be > buffered globally for all 'instances' of the streamed sample, but you'd also > need a mechanism of reading/buffering for each instance individually. I thought about the same but I came to the conclusion that if it is a large sample (eg let's say a sample that is 10-20MB long) you need to stream from different parts of the file anyway (you cannot keep MBs worth of cached sample just in the hope that it will be accessed at different positions simultaneously) so your method does not pay off. If the samples are short or the notes are short, then most of the time only the RAM cached part of the sample will be accessed requiring no disk accesses anyway or if there are any disk accesses the linux filesystem cache will cache the data for you thus disk accesses will be mostly avoided. (just play around with evo by loading large samples and hitting keys on your midi keyboard to convince yourself that this approach works) cheers, Benno. ------------------------------------------------- This mail sent through http://www.gardena.net |