Tabread4~ or granular player implementation

Hey there, Daisy enthusiasts!

Let me take a moment to introduce myself and share why I’m here.

I’m currently in a musical computation doctorate program at the University of São Paulo, Brazil (USP). I have joined a free software course, which has ignited my passion for open-source projects and the boundless creativity that emerges from collaborative programming. As part of my coursework, I’ve been assigned the task of contributing to a free and open-source project. While my course primarily focuses on larger open-source projects like React, I was able to make a case to my course teacher about the potential of Daisy. Consequently, I secured the opportunity to contribute to this project. Since I already have experience with Daisy Seed board, I’m looking forward to applying it to enhance the project.

Based on topic such as:

in Daisy Forum, I believe that a contribution focused on flexible parameterizable players would be welcomed by the Daisy community.

At this juncture, I am contemplating two distinct directions for my contribution, and I’d love to gather insights from the experienced members of this community to make an informed decision.

Option 1: Simplicity with a Class like Pure Data ‘tabread4~’

One approach I’m considering is implementing a straightforward class akin to ‘tabread4~’ in Pure Data. This would provide users with a simple and efficient means of wavetable reading, making it accessible to those who prefer a more direct and hands-on approach to audio programming. While this approach may lack some of the advanced features, it can serve as a robust foundation for basic wavetable synthesis and granular players.

Option 2: A High-Level Granular Player

On the other hand, I’m also contemplating a more high-level approach – the creation of a granular player. This player would come equipped with a plethora of parameters, such as grain size, spectral lock (allowing pitch-independent playback), grain envelope shaping, and more. Such a versatile tool would cater to those seeking a more intricate and versatile wavetable reading solution, offering a range of creative possibilities for sound design and manipulation.

My aim is to align my efforts with the broader needs of the Daisy community. So, I’d love to hear your thoughts on these two directions. Which option do you believe would be more beneficial and impactful for the Daisy project and its users? Your valuable insights and feedback will guide my contribution, and I’m excited to embark on this journey together with you all! :notes::blossom:

4 Likes

You can of course also literally use pd to design your DSP, including [tabread4~] object and convert it to Daisy :wink:

But I suspect you want to have this for DaispSP right?

1 Like

hmmm, the way you’ve presented the two options seems like a false choice between them to me. It seems to me that the “Class like Pure Data ‘tabread4~’” would be used to implement “A High-Level Granular Player”.

2 Likes

Hi @dreamer! Thanks for the response! :slightly_smiling_face: Yes, I am aware of pd2daisy, plugdata, and other software for converting PD patches into Daisy programs. I have tried them, and they are really great and useful. As you already mentioned, I am aiming to contribute to the DaisySP repository specifically. I was trying to figure out if such a “port” of this object to DaisySP would be useful for the community or if it would be too “simplistic.” So, I thought about coding a higher-level module that could be considered a “granular player” offering control over parameters such as the ones mentioned above. This way, users could use it and skip all the necessary implementation for granular manipulation.

1 Like

Hey @tunagenes. I suppose you’re right. I could have framed the question better. :melting_face: My uncertainty revolves more around whether a “class similar to Pure Data’s tabread4~” would be too simplistic and have limited value for the community. In that case, a higher-level granular player with control over granular parameters, like the ones mentioned earlier, could be more useful. Such an approach would still be based on the techniques used in tabread4~ but might not offer as much versatility, as it would primarily be used for granular manipulation rather than, for example, as a wavetable oscillator.

1 Like

If you want to go down the granular route, please check out my implementation:

You could use it as a starting point or even suggest better ways of doing things.

Cheers

Hey @jaradical! Wow, great work, man! I just watched the full video you posted, and it sounds really great. I think your implementation goes exactly in the direction I want to contribute. I will set aside some time in the following days to test it out, experiment with it, and carefully read your code. I’m pretty sure I can make use of a lot of the work you’ve already done. Thanks so much for sharing! :open_hands:

Cheers !

Hi Vinícius!
I’m excited to have you contribute! And thank you for choosing the Daisy :slight_smile:

I tend to see a demand for something like the WavPlayer but with more features (especially playback speed and pitch control): libDaisy: daisy::WavPlayer Class Reference.

1 Like

Thanks for taking a look.

If you do decide to go in that direction there are a couple of things on my TODO list for the project, so hit me up if you’d like more info.

Cheers

2 Likes

Hi @Takumi_Ogata, thank you for your kind words!

Great! I’ve already had a look and played around with the class a bit. I will certainly try to address your suggestion!

1 Like

Great, @jaradical! I’ll definitely give you a shout if I run into any issues with this implementation. Thanks so much for the support !

@viniciusfersil You plan is great. I am not sure if I would like a simple tabread4 style player more or a full featured granular player. In the past I often looked into granular implementations in c++. For example with maximilian in openframeworks. The thing was mainly that those were great but aspects of them I didnt like and I had the feeling that implenting the features I was missing would mean that I have to change the code of the classes. In that case maximilian. That didnt feel right.
What about a pack of functions and classes which would make it easy to build a full featured grain player. Something in a more modular way. And what might maybe important as well would be a good documentation with a tutorial how to build the granular player out of those modules. Anyway I am really looking forward what you will come up with.

2 Likes

Hey @grello, thank you so much for sharing your experience and thoughts on granular sound processing. I believe you’ve grasped precisely what I was trying to convey: determining the most effective level of abstraction for developing modules that assist in granular synthesis and processing. With the current classes, it is entirely possible to create a granular player; it just requires understanding the theory and techniques involved. I’m leaning towards taking the “high-level abstraction” approach while always considering how to model the inputs and outputs for easy connection to other control and DSP modules in the library.

Hey There !

I’m excited to share with you my latest contribution to the DaisySP project – the GranularPlayer module. I’ve opened a pull request, and I’m looking forward to your feedback and suggestions. You can find the pull request here.

About the GranularPlayer

The GranularPlayer module is designed to playback arrays of samples offering independent control over time-stretching and pitch-shifting. Here are some key features:

  • Playback Speed Control: This module allows you to adjust the playback speed. You can set it to 1 for normal playback, 2 to double the original playback speed, 0.5 to halve the original speed, or use negative values to play the sample in reverse.
  • Transposition: You can transpose the sample in cents (with 100 cents equal to one semitone). This feature enables creative pitch-shifting effects, allowing you to raise or lower the pitch as needed.
  • Grain Size Control: You can adjust the grain size in milliseconds, ranging from 1 millisecond to your desired value. This capability lets you manipulate the granularity of your sound.
  • Dual Grains with Overlapping Envelopes: The GranularPlayer module is implemented using two grains of sound, each multiplied by a half cosine envelope with 180-degree phase difference. This design is inspired by the “grain.player~” object in Pure Data’s else lib, by Alexandre Porres, which, in turn, draws inspiration from the B section of an audio example in Miller Puckette’s Pure Data examples.

Folder Organization

I’ve organized this module under a new “Sampling” folder. The reason behind this categorization is that the GranularPlayer module incorporates several features that didn’t quite fit neatly into any of the existing categories within the DaisySP repository. The creation of the “Sampling” category serves a dual purpose. Firstly, it provides a logical home for this module, making it easier for developers and users to find and utilize it. Secondly, I hope that this new category can serve as an inspiration for other developers to explore and develop modules based on various sampling algorithms. I’ve also taken care of the necessary changes in the Makefile and CMakeLists.txt to ensure a seamless integration of the “Sampling” category into the DaisySP project.

  • Demonstration Video and Sample Sound Effect

I am also sharing a demonstration video to showcase it in action. In the video, I am using a small array that contains the iconic sound effect of Super Mario growing after eating a mushroom. This choice was intentional, as it’s both small enough to fit into the flash memory of the Daisy Seed and culturally recognizable, making it a fun sound to experiment with.

The decision to use a small sample and an array pointer input, rather than a file system in SDRAM or an SD card module, is to keep the module as agnostic as possible. This way, users can easily pass a pointer to their array and the array’s size, making it straightforward to integrate the GranularPlayer into their projects.

Link for the showcase video: DaisySP GranularPlayer Module Showcase

3 Likes

This is exciting!! I’m looking forward to trying it out :slight_smile:

1 Like

Super nice! Thanks for the contribution! It might be nice to be able to have smaller grain sizes then 1 millisecond. I am looking forward to give it a go.

Sorry for the super late response ! Thank you very much for the feedback ! :slightly_smiling_face:

@grello Thank you for your thoughts. I’ve been considering the idea of limiting the grain size to numbers between 0 and 1. I was wondering if you might have any suggestions for a more elegant way to go about it, rather than just picking a random very small float. I really appreciate your thoughts on this! Thanks for sharing your input.