Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIDI implemenation and Sine_Generator changes #9

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

FrankBuss
Copy link

@FrankBuss FrankBuss commented Sep 14, 2017

In this patch I added support for MIDI. I wrote the MIDI class in a way that it can be easily reused with any MIDI byte stream, e.g. on embedded platforms. For testing it, I used the Sine_Generator, but I noticed that the way you implemented it, the frequency can only be changed after one full period. I changed this, so that the frequency can be changed for each sample (I noticed the problem, because when I used 0 as the frequency, it could never be changed again). This allows now more interesting FM effects. Note, the audio and audio_2 examples sound different with this patch, I guess because of the changed Sine_Generator. Might need some tweaking for the frequencies to sound better, like the old versions.

I also added two procedures for the ADSR class, to manually turn the gate on and off.

PS: I started learning Ada two weeks ago. I'm sorry in advance for your additional work to make my code look like real Ada :-) if you like the ideas and merge my pull request.


This change is Reviewable

@raph-amiard
Copy link
Owner

Hello Frank !

First of all, thank you very much for this ! It's amazing that you implemented support for midi, I'll definitely look over the code and do my best to integrate this into mainline.

I'll do that as soon as possible, probably next week end since this is a personal project :)

@FrankBuss
Copy link
Author

My pleasure. BTW, real life example: https://www.youtube.com/watch?v=lhhW-_Qcd-o
But unfortunately I had to use my own audio generator. Your library worked nicely, but needed about 30% CPU usage on this microcontroller, even with only one voice. My simple non-flexible approach needs about 10%, and that's all I need for my planned 10 voices polyphonic synthesizer.

@raph-amiard
Copy link
Owner

That's a shame for CPU usage ! Was 30% CPU only for a simple waveform ? That seems awfully high indeed.

ada-synth-lib was mostly used on desktop intel and rpi, so not optimized for bareboard yet, but it seems awfully high, I'll try to investigate this, also because using it on bareboards is one of the goals ultimately.

@FrankBuss
Copy link
Author

Ok, if you want to check it out, it was a sine wave and a mixer with an ADSR. The old version is here:
https://github.com/FrankBuss/Ada_Synth/tree/d3ec9de2ba5039f1e3d909605da2fa12f27c6239
Worked on my STM32 Discovery board (the one with the STM32F407). I used the PD0 GPIO to measure the time with a scope. It varied from half a ms when idle, to one ms when a note was played, for my three ms audio loop.
BTW, I'm not sure if your idea with the buffer is good, makes programming a bit more complicated. With my simple latest version I used just a Next_Sample function. If it is all inlined, there should be no performance penalty, unless the tagged types causes some problems.

@raph-amiard
Copy link
Owner

BTW, I'm not sure if your idea with the buffer is good, makes programming a bit more complicated. With my simple latest version I used just a Next_Sample function. If it is all inlined, there should be no performance penalty, unless the tagged types causes some problems.

Do you mean having a function that computes several samples at the same time, rather than one that computes only one sample at a time ?

It was indeed to alleviate the cost of dispatch with tagged types. ada-synth-lib has been conceived so that users can create new circuits at runtime, and so a lot of connections use dispatch when they calculate the next samples for their components.

This in turns makes inlining next to impossible, since the compiler cannot know the exact types at compile time.

This is why I added buffers, which indeed tends to make adding stuff to ada-synth-lib more difficult, but should alleviate the cost of dispatch..

I never did any profiling but theoretically this should have even more effect on simple processors with less poweful branch prediction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants