Subversion Repositories DIN Is Noise

Rev

Rev 2229 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
964 jag 1
/*
2
* morse_code.cc
2302 jag 3
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
1713 jag 4
* DIN Is Noise is released under GNU Public License 2.0
1479 jag 5
* For more information, please visit https://dinisnoise.org/
964 jag 6
*/
7
 
8
 
9
#include "morse_code.h"
10
#include "tokenizer.h"
11
#include "command.h"
12
#include "ui_list.h"
13
#include <algorithm>
2229 jag 14
 
964 jag 15
using namespace std;
16
 
17
#define result cmdlst.result
18
 
19
extern cmdlist cmdlst;
20
extern ui_list uis;
21
extern string user_data_dir;
22
 
23
 
24
morse_code::morse_code (const string& ln, const string& sn) : command (ln, sn), dot ("dot.crv"), dash ("dash.crv"), inner_space ("inner.crv"), letter_space ("letter.crv"), word_space ("word.crv"), ed ("morse-code.ed") {
25
 
26
  load ("i8n_morse_code");
27
 
28
  ed.add (&dot, &lis);
29
  ed.add (&dash, &lis);
30
  ed.add (&inner_space, &lis);
31
  ed.add (&letter_space, &lis);
32
  ed.add (&word_space, &lis);
33
 
34
  add_first_vertex = 1; // of pattern for first letter of sentence. otherwise continue pattern from last added vertex
35
 
36
}
37
 
38
morse_code::~morse_code() {
39
  dot.save ("dot.crv");
40
  dash.save ("dash.crv");
2229 jag 41
  inner_space.save ("inner_space.crv");
42
  letter_space.save ("letter_space.crv");
43
  word_space.save ("word_space.crv");
964 jag 44
}
45
 
46
int morse_code::load (const string& fname) {
47
 
48
  ifstream file ((user_data_dir + fname).c_str(), ios::in);
49
  ncodes = 0;
50
  if (file) {
51
    char c;
52
    string dnd;
53
    string ignore;
54
    file >> ignore >> ncodes;
55
    code.clear ();
56
    for (int i = 0; i < ncodes; ++i) {
57
      file >> c >> dnd;
58
      code[c] = dnd;
59
    }
60
    return 1;
61
  } else return 0;
62
 
63
}
64
 
65
int morse_code::operator() (tokenizer& tz) { // called when user executes morse-code <text> [nbeats]
66
 
67
    float nbeats;
2228 jag 68
    string text; tz >> text >> nbeats;
964 jag 69
 
70
    std::transform (text.begin(), text.end(), text.begin(), (int(*)(int)) toupper); // morse is upper case
2228 jag 71
    return create_pattern (text, nbeats);
964 jag 72
}
73
 
2228 jag 74
int morse_code::create_pattern (const string& text, float tox) {
964 jag 75
 
2228 jag 76
  multi_curve& morse = curve_editor::copy;
77
  morse.clear ();
964 jag 78
  char prev_let = 0;
1103 jag 79
 
80
  string outs;
964 jag 81
  for (int i = 0, j = text.length(); i < j; ++i) {
82
    char cur_let = text[i];
2228 jag 83
    if (cur_let == ' ') {
84
      append (morse, word_space); // word complete
964 jag 85
      prev_let = 0;
1695 jag 86
      outs += spc;
964 jag 87
    } else {
2228 jag 88
      if (prev_let != 0) {
2135 jag 89
        append (morse, letter_space); // letter complete
1695 jag 90
        outs += spc;
2228 jag 91
      }
92
      prev_let = cur_let;
93
      string dnd (code[cur_let]);
94
      outs += dnd;
95
      if (dnd != "") {
96
        char prev_in = 0, cur_in = 0;
97
        for (int m = 0, n = dnd.length(); m < n; ++m) {
98
            cur_in = dnd[m];
2229 jag 99
            if (prev_in != 0) append (morse, inner_space);
2228 jag 100
            prev_in = cur_in;
101
            if (cur_in == '.') append(morse, dot); else append(morse, dash);
964 jag 102
        }
103
      }
104
    }
105
  }
106
 
2229 jag 107
  if (tox > 0.0f) scale_tox (morse, tox);
964 jag 108
 
2228 jag 109
  morse.evaluate ();
110
  result = "morse code for " + text + " (" + outs + ") on copy curve. go paste!";
964 jag 111
 
2228 jag 112
  add_first_vertex = 1; // prep for next time
2142 jag 113
 
964 jag 114
  return 1;
115
 
116
}
117
 
118
void morse_code::append (multi_curve& m, multi_curve& p) {
119
 
2228 jag 120
  int n = p.num_vertices;
121
  if (n == 0) return;
964 jag 122
 
2228 jag 123
  point<float> v0 (p.vertices[0]); // first vertex of morse code pattern (dot, dash, letter, word or inner spacings)
964 jag 124
 
125
  int start = 1;
2228 jag 126
  if (add_first_vertex) { // only when we start conversion of text -> morse code.
964 jag 127
    org = v0;
128
    start = 0;
2228 jag 129
    add_first_vertex = 0;
964 jag 130
  } else { // continue pattern from last added vertex in conversion
2228 jag 131
    org = vi;
964 jag 132
    point<float> rt0 (p.right_tangents[0]);
2228 jag 133
    m.set_right_tangent (m.last_vertex, vi.x + (rt0.x - v0.x), vi.y + (rt0.y - v0.y));
964 jag 134
  }
135
 
136
  // position the vertices & tangents of the pattern
2228 jag 137
  for (int i = start; i < n; ++i) {
964 jag 138
    vi = p.vertices[i];
139
    point<float>& lt = p.left_tangents[i];
140
    point<float>& rt = p.right_tangents[i];
141
    point<float> ltv (lt.x - vi.x, lt.y - vi.y);
142
    point<float> rtv (rt.x - vi.x, rt.y - vi.y);
143
    vi.x = org.x + vi.x - v0.x;
144
    vi.y = org.y + vi.y - v0.y;
145
    m.add_vertex (vi.x, vi.y);
146
    m.add_left_tangent (vi.x + ltv.x, vi.y + ltv.y);
147
    m.add_right_tangent (vi.x + rtv.x, vi.y + rtv.y);
148
  }
149
 
150
}
151
 
152
void morse_code::scale_tox (multi_curve& m, float tox) {
153
 
154
  // assumes x is increasing & first vertex x = 0
155
  //
156
  // suitable when input curve is from waveform, gater, FM/AM and octave shift
157
  //
158
 
159
  int n = m.num_vertices;
2228 jag 160
  if (n == 0) return;
964 jag 161
 
162
  int last = n - 1;
163
  point<float> vlast (m.vertices[last]);
164
 
165
  float factor = 1.0f;
2129 jag 166
  if (vlast.x != 0) factor = tox / vlast.x;
964 jag 167
 
168
  for (int i = 0; i < n; ++i) {
169
    vi = m.vertices[i];
2229 jag 170
    pointinfo<float>& lt = m.left_tangents[i];
171
    int ltp = lt.pin;
172
    pointinfo<float>& rt = m.right_tangents[i];
173
    int rtp = rt.pin;
174
    lt.pin = rt.pin = 1;
964 jag 175
    m.set_vertex (i, vi.x * factor, vi.y);
176
    m.set_left_tangent (i, lt.x * factor, lt.y);
177
    m.set_right_tangent (i, rt.x * factor, rt.y);
2229 jag 178
    lt.pin = ltp;
179
    rt.pin = rtp;
964 jag 180
  }
181
 
2229 jag 182
  m.evaluate ();
183
 
964 jag 184
}