-
Notifications
You must be signed in to change notification settings - Fork 193
RP2040 on tune #254
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
RP2040 on tune #254
Conversation
the ideal value of the period
|
Memory usage change @ a5c2639
Click for full report table
Click for full report CSV |
|
Fairly straightforward! EXTERNAL_TIMED/PWM was initially tested to see that the small patch corrected the detuning. PWM output has been switched to DMA buffered transfer using PWMAudio. Both mono and stereo have been tested. Crude EXTERNAL_TIMED (with pwm in user sketch) has been tested (not clean at all, the cycle is probably too low, but seems at the correct frequency). |
|
Memory usage change @ 7cd06ac
Click for full report table
Click for full report CSV |
|
Memory usage change @ b89e39f
Click for full report table
Click for full report CSV |
tfry-git
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me (without any testing done). Some comments / questions added.
internal/MozziGuts_impl_RP2040.hpp
Outdated
| do { | ||
| defaultAudioOutput(); | ||
| next_audio_update = delayed_by_us(next_audio_update, micros_per_update); | ||
| flip_flop = !flip_flop;; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was rather thinking along the following lines (pseudocode):
uint64_t next_audio_update_shifted = 0;
const uint64_t us_persample_shifted = (1000000l << 8) / MOZZI_AUDIO_RATE;
[...]
next_audio_update_shifted += us_per_sample_shifted;
while(hardware_alarm_set_target(alarm_num, delayed_by_us(0, next_audio_update_shifted >> 8));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I understand what you meant now!
I guess it would even more simpler be: while (hardware_alarm_set_target(audio_update_alarm_num, next_audio_update_shifted>>8)); // absolute time, so no need for delayed_by_us
Indeed, that would be more general, I can try. My version works only for this case where we are basically nearly exactly between two values. I have a hard time trying to intuitively figure out which one is faster but yours might be (you: 1 add, 1 shift, me: 2 add, 1 shift). I'll try! Thanks for that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tfry-git What do you think of the new version? Note the needed addition to startMozzi()
internal/MozziGuts_impl_RP2040.hpp
Outdated
|
|
||
| static void startAudio() { | ||
| #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PWM) | ||
| // calling analogWrite for the first time will try to init the pwm frequency and range on all pins. We don't want that happening after we've set up our own, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose this comment block is essentially obsolete, then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeeed
| gpio_set_drive_strength(MOZZI_AUDIO_PIN_1, GPIO_DRIVE_STRENGTH_12MA); // highest we can get | ||
| # if (MOZZI_AUDIO_CHANNELS > 1) | ||
| # if ((MOZZI_AUDIO_PIN_1 / 2) != (MOZZI_AUDIO_PIN_1 / 2)) | ||
| # error Audio channel pins for stereo or HIFI must be on the same PWM slice (which is the case for the pairs (0,1), (2,3), (4,5), etc. Adjust MOZZI_AUDIO_PIN_1/2 . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a requirement with PWMAudio, too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup! (Can't find the reference ATM, but I read that somewhere in PWMAudio)
https://arduino-pico.readthedocs.io/en/latest/pwm.html#pwmaudio-pin-true
| # define MOZZI_AUDIO_PIN_2 1 | ||
| # endif | ||
| # define BYPASS_MOZZI_OUTPUT_BUFFER true | ||
| # define MOZZI_RP2040_BUFFERS 8 // number of DMA buffers used |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be worth documenting: Is that 8 the result to experimentation, or would other values be expected to work, too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used the same values that the library example (which are the same than for I2S). Other values might be expected to work, but I did not test thoughtfully.
|
PS: this incurs a quite penalty on flash, but is more beneficial for RAM in terms of percentage so I think this is worth it. There is no lack of flash on the RP… |
|
Memory usage change @ fc3e0f9
Click for full report table
Click for full report CSV |
internal/MozziGuts_impl_RP2040.hpp
Outdated
| micros_per_update = 1000000l / MOZZI_AUDIO_RATE; | ||
| do { | ||
| next_audio_update = make_timeout_time_us(micros_per_update); | ||
| next_audio_update_shifted = to_us_since_boot(next_audio_update); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is not correct (but wasn't before, either): startMozzi() may not necessarily be called a time 0. Rather (I think):
next_audio_update_shifted = make_timeout_time_us(delayed_by_us(time_us_64(), micros_per_update) << 8;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure? I am okay to admit that I forgot a shift there, so more like:
next_audio_update_shifted = to_us_since_boot(next_audio_update) <<8;
But, the next_audio_update = make_timeout_time_us(micros_per_update); increment from the time it is called on (does not need to be zeros), but returns an absolute time. delayed_by_us will return an absolute time, in the future already, and the make_timeout_time_us will give a "timestamp a number of microseconds from the current time.", hence a absolute time, starting at the current time and delayed by (current_time + micros_per_update), returned by the delayed_by_us. I might be wrong though because I am not sure I understand all the absolute_time_t correctly. The shift is missing though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, I got confused with relative and absolute timestamps!
|
Memory usage change @ 2b0d752
Click for full report table
Click for full report CSV |
|
Ok for merging this? |
Fix #251
Draft for now, until DMA driven PWM is implemented.