Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | initial eraser implementation |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk | origin/sfml |
Files: | files | file ages | folders |
SHA3-256: |
c385cdab1c45febc6365e35de77af5a3 |
User & Date: | jesse.mcclure@umassmed.edu 2016-02-15 23:13:36 |
Context
2016-02-16
| ||
14:37 | SFML branch reached minimal functionality check-in: db9843bacb user: jesse.mcclure@umassmed.edu tags: trunk, origin/sfml | |
2016-02-15
| ||
23:13 | initial eraser implementation check-in: c385cdab1c user: jesse.mcclure@umassmed.edu tags: trunk, origin/sfml | |
19:42 | crop window implemented check-in: 57f7252666 user: jesse.mcclure@umassmed.edu tags: trunk, origin/sfml | |
Changes
Changes to TODO.
1 2 | - change function names to camelCase in spectrogram | | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | - change function names to camelCase in spectrogram x Add eraser function to spectrogram module - needs testing - Add log transformation to frequency? - Add cursorFG to config.cpp and python code - Too many "magic numbers" for eraser sizes... x Implement config file reading * offloaded to pyfex * fex only uses command line parameters * this makes porting across platforms easier * at least for me: I have no idea where a Win user would keep config files. |
Changes to src/fft.cpp.
1 2 3 4 5 6 7 8 9 10 11 | #include "fft.hpp" // TODO configurable window_function static double window_function[4] = { 0.5, 0.5, 0, 0 }; // hanning /* Hamming 0.54 0.46 0.00 0.00 Hanning 0.50 0.50 0.00 0.00 Blackman 0.42659 0.49656 0.076849 0.00 Nuttall 0.355768 0.487396 0.144232 0.012604 BlackNutt 0.3635819 0.4891775 0.1365995 0.0106411 | > | 1 2 3 4 5 6 7 8 9 10 11 12 | #include "fft.hpp" // TODO configurable window_function // * Maybe these should just be defined from the command line. static double window_function[4] = { 0.5, 0.5, 0, 0 }; // hanning /* Hamming 0.54 0.46 0.00 0.00 Hanning 0.50 0.50 0.00 0.00 Blackman 0.42659 0.49656 0.076849 0.00 Nuttall 0.355768 0.487396 0.144232 0.012604 BlackNutt 0.3635819 0.4891775 0.1365995 0.0106411 |
︙ | ︙ |
Changes to src/fft.hpp.
1 2 3 4 5 6 7 8 9 10 11 12 | #include "config.hpp" #include <math.h> #include <fftw3.h> #include <SFML/Audio.hpp> class Fft : public Config { private: sf::Texture texSpec, texThresh; double *freq = NULL, *time = NULL, *amp = NULL; unsigned short int *erase = NULL; int t1, t2, f1, f2; | > < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include "config.hpp" #include <math.h> #include <fftw3.h> #include <SFML/Audio.hpp> class Fft : public Config { private: sf::Texture texSpec, texThresh; sf::VertexArray points, lines; double *freq = NULL, *time = NULL, *amp = NULL; unsigned short int *erase = NULL; int t1, t2, f1, f2; protected: sf::Sprite spec, thresh; sf::SoundBuffer song; int ntime, nfreq; double pathLength, timeLength; |
︙ | ︙ |
Changes to src/spectrogram.cpp.
1 2 3 4 5 6 7 8 9 | #include "spectrogram.hpp" Spectrogram::Spectrogram(int argc, char *const *argv) : Fft(argc, argv) { // if (getenv("FEX_FULLSCREEN")) win.create(sf::VideoMode::getDesktopMode(), "Fex", sf::Style::Fullscreen); // else // win.create(sf::VideoMode(640,480), "Fex"); aspect = (ntime * win.getSize().y * conf.hop) / (float) (nfreq * win.getSize().x * conf.winlen); | > | 1 2 3 4 5 6 7 8 9 10 | #include "spectrogram.hpp" #include <unistd.h> Spectrogram::Spectrogram(int argc, char *const *argv) : Fft(argc, argv) { // if (getenv("FEX_FULLSCREEN")) win.create(sf::VideoMode::getDesktopMode(), "Fex", sf::Style::Fullscreen); // else // win.create(sf::VideoMode(640,480), "Fex"); aspect = (ntime * win.getSize().y * conf.hop) / (float) (nfreq * win.getSize().x * conf.winlen); |
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 | dot.setOutlineThickness(-8); render_ball.draw(dot); ball = render_ball.getTexture(); back.setSize(sf::Vector2f(ntime,-nfreq)); back.setFillColor(conf.specBG); mouse.x = ntime / 2; mouse.y = - nfreq / 2; crop1 = sf::Vector2f(-1, -1); } Spectrogram::~Spectrogram() { } int Spectrogram::main_loop() { sf::Event ev; while (win.isOpen() && win.waitEvent(ev)) { | > > > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | dot.setOutlineThickness(-8); render_ball.draw(dot); ball = render_ball.getTexture(); back.setSize(sf::Vector2f(ntime,-nfreq)); back.setFillColor(conf.specBG); mouse.x = ntime / 2; mouse.y = - nfreq / 2; crop1 = sf::Vector2f(-1, -1); eraser.setSize(sf::Vector2f(4, 18)); eraser.setFillColor(sf::Color(255,200,0,200)); eraser.setPosition(0, 0); eraser.setOrigin(2, 10); } Spectrogram::~Spectrogram() { } int Spectrogram::main_loop() { sf::Event ev; while (win.isOpen() && win.waitEvent(ev)) { |
︙ | ︙ | |||
68 69 70 71 72 73 74 75 76 77 78 79 80 81 | win.draw(back); win.draw(spec); thresh.setColor(conf.threshFG); if (show.overlay) { win.draw(thresh); win.draw(getPoints(), &ball); win.draw(getLines()); } } void Spectrogram::draw_cursor(float x, float y) { // TODO get config cursor color sf::RectangleShape lineV(sf::Vector2f(1, nfreq)); lineV.setFillColor(conf.cursorFG); | > | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | win.draw(back); win.draw(spec); thresh.setColor(conf.threshFG); if (show.overlay) { win.draw(thresh); win.draw(getPoints(), &ball); win.draw(getLines()); win.draw(eraser); } } void Spectrogram::draw_cursor(float x, float y) { // TODO get config cursor color sf::RectangleShape lineV(sf::Vector2f(1, nfreq)); lineV.setFillColor(conf.cursorFG); |
︙ | ︙ | |||
131 132 133 134 135 136 137 | } void Spectrogram::ev_resize(sf::Event ev) { aspect = (ntime * win.getSize().y * conf.hop) / (float) (nfreq * win.getSize().x * conf.winlen); } void Spectrogram::ev_mousemove(sf::Event ev) { | | | > > | > > > > > > | | | | | | | | < | > > > > > > > > > > > > > > > > > | 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | } void Spectrogram::ev_resize(sf::Event ev) { aspect = (ntime * win.getSize().y * conf.hop) / (float) (nfreq * win.getSize().x * conf.winlen); } void Spectrogram::ev_mousemove(sf::Event ev) { sf::Vector2f prev = mouse; mouse = win.mapPixelToCoords(sf::Vector2i(ev.mouseMove.x,ev.mouseMove.y)); checkModKeys(); if (mod_ctrl) { } else if (mod_shift) { } else if (mod_alt) { if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) erase(); } else { if (sf::Mouse::isButtonPressed(sf::Mouse::Right)) { view.setSize(view.getSize().x + prev.x - mouse.x, view.getSize().y + prev.y - mouse.y); view.move((prev.x - mouse.x)/2.0, (prev.y - mouse.y)/2.0); } if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) { view.move(prev.x - mouse.x, prev.y - mouse.y); } win.setView(view); } mouse = win.mapPixelToCoords(sf::Vector2i(ev.mouseMove.x,ev.mouseMove.y)); if (mouse.x < 0) mouse.x = 0.0; else if (mouse.x > ntime) mouse.x = ntime; if (mouse.y > 0) mouse.y = 0.0; else if (mouse.y < - nfreq) mouse.y = - nfreq; eraser.setPosition(mouse); } void Spectrogram::checkModKeys() { mod_ctrl = mod_shift = mod_alt = false; if (sf::Keyboard::isKeyPressed(sf::Keyboard::LControl)) mod_ctrl = true; if (sf::Keyboard::isKeyPressed(sf::Keyboard::RControl)) mod_ctrl = true; if (sf::Keyboard::isKeyPressed(sf::Keyboard::LShift)) mod_shift = true; if (sf::Keyboard::isKeyPressed(sf::Keyboard::RShift)) mod_shift = true; if (sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt)) mod_alt = true; if (sf::Keyboard::isKeyPressed(sf::Keyboard::RAlt)) mod_alt = true; } void Spectrogram::erase() { sf::FloatRect rect = eraser.getGlobalBounds(); sf::Transform t = eraser.getInverseTransform(); sf::Vector2f point; int i, j; for (i = rect.left - 0.5; i < rect.left + rect.width + 1; ++i) { for (j = rect.top - 0.5; j < rect.top + rect.height + 1; ++j) { point = t.transformPoint(i + 0.5, j - 0.5); if (point.x > -0.25 && point.x < 4.25 && point.y > -0.25 && point.y < 18.25) erasePoint(i, -j); } } makeOverlay(); } void Spectrogram::ev_button(sf::Event ev) { checkModKeys(); sf::FloatRect rect; /* Control + button combinations are for working with the threshold: */ if (mod_ctrl) switch (ev.mouseButton.button) { } |
︙ | ︙ | |||
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | case sf::Mouse::Button::Right: crop1.x = -1; setCrop(crop1, mouse); break; } /* Alt + button combinations are for working with the eraser: */ else if (mod_alt) switch (ev.mouseButton.button) { } else switch (ev.mouseButton.button) { /* NOTE: left and right are handled in ev_mousemove */ /* zoom to fit song to window */ case sf::Mouse::Button::Middle: view.reset(sf::FloatRect(0, -nfreq * (1 + aspect)/2.0, ntime, nfreq * aspect)); win.setView(view); break; } } void Spectrogram::ev_wheel(sf::Event ev) { checkModKeys(); bool vert = (ev.mouseWheelScroll.wheel == 0); /* Control + wheel combinations are for working with the threshold: */ if (mod_ctrl && vert) { // TODO: threshold up/down } /* Shift + wheel combinations are for working with the crop area: */ else if (mod_shift) { // TODO: anything here? Probably not. } /* Alt + wheel combinations are for working with the eraser: */ else if (mod_alt && vert) { // TODO: size up/down | > > > > > > > > > > > | > > > > > > | < > < | | 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | case sf::Mouse::Button::Right: crop1.x = -1; setCrop(crop1, mouse); break; } /* Alt + button combinations are for working with the eraser: */ else if (mod_alt) switch (ev.mouseButton.button) { case sf::Mouse::Button::Left: erase(); break; } else switch (ev.mouseButton.button) { /* NOTE: left and right are handled in ev_mousemove */ /* zoom to fit song to window */ case sf::Mouse::Button::Middle: view.reset(sf::FloatRect(0, -nfreq * (1 + aspect)/2.0, ntime, nfreq * aspect)); win.setView(view); break; } } void Spectrogram::ev_wheel(sf::Event ev) { checkModKeys(); bool vert = (ev.mouseWheelScroll.wheel == 0); float dx = ev.mouseWheelScroll.delta; /* Control + wheel combinations are for working with the threshold: */ if (mod_ctrl && vert) { // TODO: threshold up/down } /* Shift + wheel combinations are for working with the crop area: */ else if (mod_shift) { // TODO: anything here? Probably not. } /* Alt + wheel combinations are for working with the eraser: */ else if (mod_alt && vert) { // TODO: size up/down sf::Vector2f scale = eraser.getScale(); float r = eraser.getRotation(); if (r < 30 || r > 330 || (r > 150 && r < 210) ) scale.y += 0.008 * dx; else if ( (r > 60 && r < 120) || (r > 240 && r < 300) ) scale.x += 0.008 * dx; else { scale.x += 0.004 * dx; scale.y += 0.004 * dx; } if (scale.x < 0.5) scale.x = 0.5; else if (scale.x > 5.0) scale.x = 5.0; if (scale.y < 0.5) scale.y = 0.5; else if (scale.y > 5.0) scale.y = 5.0; eraser.setScale(scale); } else if (mod_alt && !vert) { eraser.rotate(-dx); } /* No modifier wheel movements are for zooming: */ else if (vert) { // TODO: make 0.0075 step size customizable? float vx = view.getSize().x / ntime, vy = view.getSize().y / nfreq; if (dx < 0 && vx > 1.20 && vy > 1.20) return; if (dx > 0 && vx < 0.01 && vy > 0.01) return; view.zoom(1.0 - 0.0075 * dx); win.setView(view); } } |
Changes to src/spectrogram.hpp.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include "fft.hpp" #include <SFML/Audio.hpp> #include <SFML/Graphics.hpp> #include <SFML/Window.hpp> class Spectrogram : public Fft { private: sf::RenderWindow win; sf::View view; sf::Vector2f mouse, crop1; sf::RectangleShape back; sf::Texture ball; bool mod_ctrl, mod_shift, mod_alt; float aspect; void draw_main(); void draw_cursor(float, float); void draw_hud(); void checkModKeys(); void ev_handler(sf::Event); void ev_close(sf::Event); void ev_keypress(sf::Event); void ev_keyrelease(sf::Event); void ev_mousemove(sf::Event); | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include "fft.hpp" #include <SFML/Audio.hpp> #include <SFML/Graphics.hpp> #include <SFML/Window.hpp> class Spectrogram : public Fft { private: sf::RenderWindow win; sf::View view; sf::Vector2f mouse, crop1; sf::RectangleShape back; sf::Texture ball; sf::RectangleShape eraser; bool mod_ctrl, mod_shift, mod_alt; float aspect; void draw_main(); void draw_cursor(float, float); void draw_hud(); void erase(); void checkModKeys(); void ev_handler(sf::Event); void ev_close(sf::Event); void ev_keypress(sf::Event); void ev_keyrelease(sf::Event); void ev_mousemove(sf::Event); |
︙ | ︙ |