meadowlarkdaw / creek Goto Github PK
View Code? Open in Web Editor NEWRealtime disk streaming IO for audio
License: Other
Realtime disk streaming IO for audio
License: Other
Hi,
Would you consider adding a peek method?
pub fn peek(
&mut self,
mut frames: usize,
) -> Result<ReadData<'_, D::T>, ReadError<D::FatalError>> {
}
It'd be the same as read, except that it would not change the read position.
It can be useful if you have non linear playback of the audio input, you want to interpolate the samples so you need data before and after your current playback position. After what, the playback engine would perform the seek accordingly to its needs.
Thanks,
Alex
The CI workflows fails now with the error:
package `addr2line v0.21.0` cannot be built because it requires rustc 1.65 or newer, while the currently active rustc version is 1.62.0
I believe this dependency is only used by egui
which is used for the demos. Is there a way to exclude the demos from the CI workflow?
I find the API of ReadDiskStream unintuitive:
let ch1 = read_data.read_channel(0);
let ch2 = read_data.read_channel(1);
for f in 0..frames {
self.buffer[f * 2] = ch1[f];
self.buffer[f * 2 + 1] = ch2[f];
}
It would be nice to implement dasp::signal::Signal on this type.
Hi,
It'd be convenient to allow stream.seek() to go to negative position and return silence, similar to seek after the end.
Cheers,
Alex
Hi I just came upon creek today, the idea of the buffers and the ability to seek in realtime is excellent.
This may be a massive scope creep, however, for a project I need to do resampling (and looping).
I have used https://crates.io/crates/rubato to do sample interpolation in another project.
Would it be possible to create a Decoder/Encoder using rubato as a wrapper to the underlying Codec?
To enable seeking it would be great for there to be 2 different caches.
I imagine that there could be a pipeline something like
Data in File Format -> Cached Buffers of float -> Cached Resampled data (at different rate) - in chronological order -> Playback sampling (possibly in reverse issue #14, or sample accurate looping)
Is any of this currently possible?
Thanks
read_disk_stream.seek(read_disk.stream.playhead(), SeekMode::Auto);
This causes a cache miss on the next read even though the playhead has not actually moved.
When the Symphonia stream is seeked, it does not in general advance to the position requested, but rather to a packet boundary less than or equal to that position. However the Symphonia decoder in creek
does not currently use the return value, resulting in duplicate chunks of audio in the stream.
https://docs.rs/symphonia-core/0.5.3/symphonia_core/formats/trait.FormatReader.html#tymethod.seek
Note: The FormatReader by itself cannot seek to an exact audio frame, it is only capable of seeking to the nearest Packet. Therefore, to seek to an exact frame, a Decoder must decode packets until the requested position is reached. When using the accurate SeekMode, the seeked position will always be before the requested position. If the coarse SeekMode is used, then the seek position may be after the requested position. Coarse seeking is an optional performance enhancement, therefore, a coarse seek may sometimes be an accurate seek.
In practice, this results in an audible glitch in playback at around 11 seconds into the stream if you are using a similar setup to the Player demo.
The seek offset can also be seen in debug logs from the Symphonia library, for example for this MP3 of Carlie Rae Jepsen's "Emotion":
[2023-08-26][22:38:11][DEBUG][symphonia_bundle_mp3::demuxer] seeking to ts=0 (+0 delay = 0)
[2023-08-26][22:38:11][DEBUG][symphonia_bundle_mp3::demuxer] found frame with ts=0 (0) @ pos=11558 with main_data_begin=0
[2023-08-26][22:38:11][DEBUG][symphonia_bundle_mp3::demuxer] seeked to ts=0 (0) (delta=0)
[2023-08-26][22:38:11][DEBUG][symphonia_bundle_mp3::demuxer] seeking to ts=458752 (+0 delay = 458752)
[2023-08-26][22:38:11][DEBUG][symphonia_bundle_mp3::demuxer] found frame with ts=458496 (458496) @ pos=427427 with main_data_begin=480
[2023-08-26][22:38:11][DEBUG][symphonia_bundle_mp3::demuxer] will seek -1 frame(s) to ts=457344 (457344) @ pos=426382 (-1045 bytes)
[2023-08-26][22:38:11][DEBUG][symphonia_bundle_mp3::demuxer] seeked to ts=457344 (457344) (delta=-1408)
I've attempted to fix this with jacobstern@10b989a in my fork, but this seems to have introduced an artifact at the end of playback for a track, probably because the bookkeeping of chunk durations is still off.
Any assistance with the fix would be appreciated. Thanks!
For moire I'm currently evaluating what needs to be done for playing files in reverse (we need this for vinyl simulation, where you can pull the vinyl backwards and the audio plays in reverse). Are there already any ideas on how to implement this into creek?
Have you considered using Symphonia for supporting compressed codecs?
https://www.kernel.org/doc/html/latest/block/ioprio.html#scheduling-classes
Unfortunately it seems there isn't currently a way to set a thread's ionice with Rust.
Hi @BillyDM
We are happily using this library over at https://github.com/orottier/web-audio-api-rs
We would love to see the open pull requests for creek #22 and #23 merged.
If there is any way we can help share the burden of maintenance, please let us know. We would need to have repository access and publishing rights for crates.io [1] if you are alright with that. Perhaps @Be-ing and/or @uklotzde would like to chime in too?
Thanks!
[1] https://doc.rust-lang.org/cargo/commands/cargo-owner.html
while data.len() >= num_channels {
let read_frames = data.len() / 2;
In the demo/player/src/process.rs
file, what does this do exactly?
Why is it dividing cpal's data length to 2?
Is it to adjust the buffer length for creek to parse through?
I am new to working with sound so I apologize if this is obvious for you.
It would be really convenient if creek could do automatic resampling to a specified sample rate. When JACK is running at 44100 Hz, I want to be able to play 48000 kHz files at the correct pitch. This could already be done by the user after getting audio data from creek. However, that is not trivial because resampling changes the rate at which creek needs to read from the file to get the desired number of frames at the desired sample rate. This could be done with rubato.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.