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

Fix Piezo.prototype.note() #1324

Closed

Conversation

islemaster
Copy link
Contributor

@islemaster islemaster commented Apr 13, 2017

Fixes #1323 - FYI @lyzadanger.

The note() method was passing a frequency (Hz) to the tone() method, which is expecting to receive a duty cycle (μs), leading to the wrong note being played. The solution is for note() to call frequency() instead, which will do the appropriate conversion.

Since it took me a while to understand the relationships between tone, frequency and note I've added some documentation to those methods to clear things up for the next person. I've also made some unit tests more aggressive about checking that values are converted appropriately as they're passed around, and commented note-frequency-duty equivalencies to help the test read nicer.

Question: How is the documentation at http://johnny-five.io/api/piezo/#api generated? The documentation for tone there was very helpful in understanding the intent of these methods, but it's also confusing because the first argument is misnamed in the signature tone(frequency, duration). I couldn't find a way to update that from this repo. EDIT: Found the docs on the repository wiki and updated accordingly.

The `note()` method was passing a frequency (Hz) to the `tone()` method, which is expecting to receive a duty cycle (μs), leading to the wrong note being played.  The solution is for `note()` to call `frequency()` instead, which will do the appropriate conversion.

Since it took me a while to understand the relationships between `tone`, `frequency` and `note` I've added some documentation to those methods to clear things up for the next person.  I've also made some unit tests more aggressive about checking that values are converted appropriately as they're passed around, and commented note-frequency-duty equivalencies to help the test read nicer.
@@ -781,10 +807,11 @@ exports["Piezo - I2C Backpack"] = {
tone: function(test) {
test.expect(3);

this.piezo.tone(262, 1000);
// C4 = 262Hz = 1908μs duty cycle (half-period)
this.piezo.tone(1908, 1000);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated this test because it could be misleading and imply that tone was supposed to be called with a frequency (since 262Hz is a familiar frequency C4, used elsewhere in these tests).

@islemaster
Copy link
Contributor Author

😖 Seeing a flaky animation test failure on Travis again, and one failure I haven't seen before:

Testing rgb.collection.js.Fatal error: Cannot read property 'setUp' of undefined�
npm ERR! Test failed.  See above for more details.

I don't repro locally, would appreciate thoughts on what went wrong here.

@rwaldron
Copy link
Owner

@lyzadanger review?

Copy link
Collaborator

@lyzadanger lyzadanger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your work on this! I added a bunch of very fine-grained nit comments, but they are all optional from my point of view. I have not tested this on hardware; let me know if that level of review is needed—this is a code/API-level/test review only.

@@ -401,16 +401,37 @@ Piezo.ToSong = function(stringSong, beats) {
return song;
};

/**
* Play a note for a duration.
* @param {string} note - see Piezo.Notes. Case-insensitive.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a case-sensitivity test (i.e. invoke this method with a different case in the tests; tests—at least the ones you added—look like they're all lower-case)?

lib/piezo.js Outdated

return this.tone(tone, duration);
var frequency = Piezo.Parsers.hzFromInput(note);
return this.frequency(frequency, duration);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stylistically, this could all be done in one statement, e.g.:

return this.frequency(Piezo.Parsers.hzFromInput(note), duration);

as you do in frequency, eliminating the need for the var declaration and being consistent, but that's totally up to you.

* @param {number} tone - Given as a computed duty-cycle,
* in microseconds. Larger values produce lower tones.
* See https://en.wikipedia.org/wiki/Duty_cycle
* @param {number} duration - in milliseconds.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good commenting. Thank you!

test/piezo.js Outdated

// note delegates to tone;
// note delegates to frequncy, which delegates to tone;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

frequency is misspelled but this is in an incredibly nitpicky comment. Only change it if you have other reason to edit the test file :)

lib/piezo.js Outdated
/**
* Play a note for a duration.
* @param {string} note - see Piezo.Notes. Case-insensitive.
* If an octave is not given, the configured default octave
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps extend this comment to explain what octave means in this context (e.g. in the string value "a4", "a" is the note and 4 is the octave)?

test/piezo.js Outdated
var toneSpy = this.sandbox.spy(this.piezo, "tone");
var frequencySpy = this.sandbox.spy(this.piezo, "frequency");

// accepts octave.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly to comments for the note attribute of the note method...maybe drop in definition of difference between note and octave here?

@islemaster
Copy link
Contributor Author

Thank you for the review @lyzadanger! I'll push an update addressing your comments by this time tomorrow. I can test these changes locally with an Adafruit Circuit Playground board and Circuit Playground Firmata but I don't have access to any other hardware for testing. If you feel additional testing is required I'll need help with that.

- Test that `note()` is case-insensitive
- Better description of default octave
- One-line Piezo.prototype.note
- s/frequncy/frequency
- Note tests demonstrate the difference between note letter and octave number better
@islemaster
Copy link
Contributor Author

Review feedback addressed.

@lyzadanger
Copy link
Collaborator

@islemaster Lookin' good! I'd love to see the fixup commits squashed when this merges but that's probably in @rwaldron 's purview... :)

islemaster added a commit to code-dot-org/johnny-five that referenced this pull request Apr 18, 2017
This commit applies upstream fix rwaldron#1324 for issue rwaldron#1323 to code-dot-org/johnny-five early, even though we're behind.  This should merge trivially when we catch up.

The `note()` method was passing a frequency (Hz) to the `tone()` method, which is expecting to receive a duty cycle (μs), leading to the wrong note being played.  The solution is for `note()` to call `frequency()` instead, which will do the appropriate conversion.

Since it took me a while to understand the relationships between `tone`, `frequency` and `note` I've added some documentation to those methods to clear things up for the next person.  I've also made some unit tests more aggressive about checking that values are converted appropriately as they're passed around, and commented note-frequency-duty equivalencies to help the test read nicer.

Includes squashed fixups:

- Fix lint error.

- Address review feedback:
  - Test that `note()` is case-insensitive
  - Better description of default octave
  - One-line Piezo.prototype.note
  - s/frequncy/frequency
  - Note tests demonstrate the difference between note letter and octave number better
@islemaster islemaster deleted the piezo-note-calls-frequency branch April 21, 2017 17:08
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