From 8093c5f5343c2973f827c59c1078cf4ff8d09e88 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Br=C3=A1zio?= <jbrazio@gmail.com>
Date: Thu, 28 Jul 2016 23:54:46 +0100
Subject: [PATCH 1/2] Non-blocking speaker now uses arduino's tone()

---
 Marlin/speaker.h | 30 +++++++-----------------------
 1 file changed, 7 insertions(+), 23 deletions(-)

diff --git a/Marlin/speaker.h b/Marlin/speaker.h
index e3a0f9670b..5f3b6362f3 100644
--- a/Marlin/speaker.h
+++ b/Marlin/speaker.h
@@ -31,8 +31,7 @@ class Speaker: public Buzzer {
 
     struct state_t {
       tone_t   tone;
-      uint16_t period;
-      uint16_t counter;
+      millis_t next;
     } state;
 
   protected:
@@ -42,8 +41,7 @@ class Speaker: public Buzzer {
      */
     void reset() {
       super::reset();
-      this->state.period = 0;
-      this->state.counter = 0;
+      this->state.next = 0;
     }
 
   public:
@@ -60,29 +58,15 @@ class Speaker: public Buzzer {
      * playing the tones in the queue.
      */
     virtual void tick() {
-      if (!this->state.counter) {
+      const uint32_t now = millis();
+
+      if (now >= this->state.next) {
         if (this->buffer.isEmpty()) return;
 
         this->reset();
         this->state.tone = this->buffer.dequeue();
-
-        // Period is uint16, min frequency will be ~16Hz
-        this->state.period = 1000000UL / this->state.tone.frequency;
-
-        this->state.counter =
-          (this->state.tone.duration * 1000L) / this->state.period;
-
-        this->state.period   >>= 1;
-        this->state.counter <<= 1;
-      } else {
-        const  uint32_t  now = micros();
-        static uint32_t next = now + this->state.period;
-
-        if (now >= next) {
-          --this->state.counter;
-          next = now + this->state.period;
-          if (this->state.tone.frequency > 0) this->invert();
-        }
+        this->state.next = now + this->state.tone.duration;
+        ::tone(BEEPER_PIN, this->state.tone.frequency, this->state.tone.duration);
       }
     }
 };

From 2b5faa61e2fcd345eb1b86136e40b465b9d208f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Br=C3=A1zio?= <jbrazio@gmail.com>
Date: Fri, 29 Jul 2016 17:39:07 +0100
Subject: [PATCH 2/2] Consolidates Buzzer and Speaker into a single object

---
 Marlin/Marlin.h        |  9 ++---
 Marlin/Marlin_main.cpp |  4 ---
 Marlin/buzzer.h        | 16 ++++++---
 Marlin/speaker.h       | 74 ------------------------------------------
 4 files changed, 14 insertions(+), 89 deletions(-)
 delete mode 100644 Marlin/speaker.h

diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h
index ded8b1f50e..b0fcbb78f3 100644
--- a/Marlin/Marlin.h
+++ b/Marlin/Marlin.h
@@ -386,13 +386,8 @@ void calculate_volumetric_multipliers();
 
 // Buzzer
 #if HAS_BUZZER
-  #if ENABLED(SPEAKER)
-    #include "speaker.h"
-    extern Speaker buzzer;
-  #else
-    #include "buzzer.h"
-    extern Buzzer buzzer;
-  #endif
+  #include "buzzer.h"
+  extern Buzzer buzzer;
 #endif
 
 /**
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 777d910163..dc5f407aa5 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -375,11 +375,7 @@ static millis_t stepper_inactive_time = (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL
 
 // Buzzer
 #if HAS_BUZZER
-  #if ENABLED(SPEAKER)
-    Speaker buzzer;
-  #else
     Buzzer buzzer;
-  #endif
 #endif
 
 static uint8_t target_extruder;
diff --git a/Marlin/buzzer.h b/Marlin/buzzer.h
index e691160688..a398269d71 100644
--- a/Marlin/buzzer.h
+++ b/Marlin/buzzer.h
@@ -32,7 +32,6 @@
 /**
  * @brief Tone structure
  * @details Simple abstraction of a tone based on a duration and a frequency.
- *
  */
 struct tone_t {
   uint16_t duration;
@@ -116,14 +115,23 @@ class Buzzer {
      *          playing the tones in the queue.
      */
     virtual void tick() {
+      const millis_t now = millis();
+
       if (!this->state.endtime) {
         if (this->buffer.isEmpty()) return;
 
         this->state.tone = this->buffer.dequeue();
-        this->state.endtime = millis() + this->state.tone.duration;
-        if (this->state.tone.frequency > 0) this->on();
+        this->state.endtime = now + this->state.tone.duration;
+
+        if (this->state.tone.frequency > 0) {
+          #if ENABLED(SPEAKER)
+            ::tone(BEEPER_PIN, this->state.tone.frequency, this->state.tone.duration);
+          #else
+            this->on();
+          #endif
+        }
       }
-      else if (ELAPSED(millis(), this->state.endtime)) this->reset();
+      else if (ELAPSED(now, this->state.endtime)) this->reset();
     }
 };
 
diff --git a/Marlin/speaker.h b/Marlin/speaker.h
deleted file mode 100644
index 5f3b6362f3..0000000000
--- a/Marlin/speaker.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * Based on Sprinter and grbl.
- * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef __SPEAKER_H__
-#define __SPEAKER_H__
-
-#include "buzzer.h"
-
-class Speaker: public Buzzer {
-  private:
-    typedef Buzzer super;
-
-    struct state_t {
-      tone_t   tone;
-      millis_t next;
-    } state;
-
-  protected:
-    /**
-     * @brief Resets the state of the class
-     * @details Brings the class state to a known one.
-     */
-    void reset() {
-      super::reset();
-      this->state.next = 0;
-    }
-
-  public:
-    /**
-     * @brief Class constructor
-     */
-    Speaker() {
-      this->reset();
-    }
-
-    /**
-     * @brief Loop function
-     * @details This function should be called at loop, it will take care of
-     * playing the tones in the queue.
-     */
-    virtual void tick() {
-      const uint32_t now = millis();
-
-      if (now >= this->state.next) {
-        if (this->buffer.isEmpty()) return;
-
-        this->reset();
-        this->state.tone = this->buffer.dequeue();
-        this->state.next = now + this->state.tone.duration;
-        ::tone(BEEPER_PIN, this->state.tone.frequency, this->state.tone.duration);
-      }
-    }
-};
-
-#endif