aboutsummaryrefslogtreecommitdiffstats
path: root/quantum/process_keycode/process_clicky.c
blob: 6ab382d4aadf7f57e804516bf853548ee7089ec7 (plain)
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include "audio.h"
#include "process_clicky.h"

#ifdef AUDIO_CLICKY

#    ifndef AUDIO_CLICKY_DELAY_DURATION
#        define AUDIO_CLICKY_DELAY_DURATION 1
#    endif  // !AUDIO_CLICKY_DELAY_DURATION
#    ifndef AUDIO_CLICKY_FREQ_DEFAULT
#        define AUDIO_CLICKY_FREQ_DEFAULT 440.0f
#    endif  // !AUDIO_CLICKY_FREQ_DEFAULT
#    ifndef AUDIO_CLICKY_FREQ_MIN
#        define AUDIO_CLICKY_FREQ_MIN 65.0f
#    endif  // !AUDIO_CLICKY_FREQ_MIN
#    ifndef AUDIO_CLICKY_FREQ_MAX
#        define AUDIO_CLICKY_FREQ_MAX 1500.0f
#    endif  // !AUDIO_CLICKY_FREQ_MAX
#    ifndef AUDIO_CLICKY_FREQ_FACTOR
#        define AUDIO_CLICKY_FREQ_FACTOR 1.18921f
#    endif  // !AUDIO_CLICKY_FREQ_FACTOR
#    ifndef AUDIO_CLICKY_FREQ_RANDOMNESS
#        define AUDIO_CLICKY_FREQ_RANDOMNESS 0.05f
#    endif  // !AUDIO_CLICKY_FREQ_RANDOMNESS

float clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT;
float clicky_rand = AUDIO_CLICKY_FREQ_RANDOMNESS;

// the first "note" is an intentional delay; the 2nd and 3rd notes are the "clicky"
float clicky_song[][2] = {{AUDIO_CLICKY_FREQ_MIN, AUDIO_CLICKY_DELAY_DURATION}, {AUDIO_CLICKY_FREQ_DEFAULT, 3}, {AUDIO_CLICKY_FREQ_DEFAULT, 1}};  // 3 and 1 --> durations

extern audio_config_t audio_config;

#    ifndef NO_MUSIC_MODE
extern bool music_activated;
extern bool midi_activated;
#    endif  // !NO_MUSIC_MODE

void clicky_play(void) {
#    ifndef NO_MUSIC_MODE
    if (music_activated || midi_activated || !audio_config.enable) return;
#    endif  // !NO_MUSIC_MODE
    clicky_song[1][0] = 2.0f * clicky_freq * (1.0f + clicky_rand * (((float)rand()) / ((float)(RAND_MAX))));
    clicky_song[2][0] = clicky_freq * (1.0f + clicky_rand * (((float)rand()) / ((float)(RAND_MAX))));
    PLAY_SONG(clicky_song);
}

void clicky_freq_up(void) {
    float new_freq = clicky_freq * AUDIO_CLICKY_FREQ_FACTOR;
    if (new_freq < AUDIO_CLICKY_FREQ_MAX) {
        clicky_freq = new_freq;
    }
}

void clicky_freq_down(void) {
    float new_freq = clicky_freq / AUDIO_CLICKY_FREQ_FACTOR;
    if (new_freq > AUDIO_CLICKY_FREQ_MIN) {
        clicky_freq = new_freq;
    }
}

void clicky_freq_reset(void) { clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT; }

void clicky_toggle(void) {
    audio_config.clicky_enable ^= 1;
    eeconfig_update_audio(audio_config.raw);
}

void clicky_on(void) {
    audio_config.clicky_enable = 1;
    eeconfig_update_audio(audio_config.raw);
}

void clicky_off(void) {
    audio_config.clicky_enable = 0;
    eeconfig_update_audio(audio_config.raw);
}

bool is_clicky_on(void) { return (audio_config.clicky_enable != 0); }

bool process_clicky(uint16_t keycode, keyrecord_t *record) {
    if (keycode == CLICKY_TOGGLE && record->event.pressed) {
        clicky_toggle();
    }

    if (keycode == CLICKY_ENABLE && record->event.pressed) {
        clicky_on();
    }
    if (keycode == CLICKY_DISABLE && record->event.pressed) {
        clicky_off();
    }

    if (keycode == CLICKY_RESET && record->event.pressed) {
        clicky_freq_reset();
    }

    if (keycode == CLICKY_UP && record->event.pressed) {
        clicky_freq_up();
    }
    if (keycode == CLICKY_DOWN && record->event.pressed) {
        clicky_freq_down();
    }

    if (audio_config.enable && audio_config.clicky_enable) {
        if (record->event.pressed) {                       // Leave this separate so it's easier to add upstroke sound
            if (keycode != AU_OFF && keycode != AU_TOG) {  // DO NOT PLAY if audio will be disabled, and causes issuse on ARM
                clicky_play();
            }
        }
    }
    return true;
}

#endif  // AUDIO_CLICKY
.raises(RuntimeError): v_int2.extend([8, "a"]) assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7]) # test extending from a generator v_int2.extend(x for x in range(5)) assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4]) # test negative indexing assert v_int2[-1] == 4 # insert with negative index v_int2.insert(-1, 88) assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 88, 4]) # delete negative index del v_int2[-1] assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 88]) v_int2.clear() assert len(v_int2) == 0 # Older PyPy's failed here, related to the PyPy's buffer protocol. def test_vector_buffer(): b = bytearray([1, 2, 3, 4]) v = m.VectorUChar(b) assert v[1] == 2 v[2] = 5 mv = memoryview(v) # We expose the buffer interface if not env.PY2: assert mv[2] == 5 mv[2] = 6 else: assert mv[2] == "\x05" mv[2] = "\x06" assert v[2] == 6 if not env.PY2: mv = memoryview(b) v = m.VectorUChar(mv[::2]) assert v[1] == 3 with pytest.raises(RuntimeError) as excinfo: m.create_undeclstruct() # Undeclared struct contents, no buffer interface assert "NumPy type info missing for " in str(excinfo.value) def test_vector_buffer_numpy(): np = pytest.importorskip("numpy") a = np.array([1, 2, 3, 4], dtype=np.int32) with pytest.raises(TypeError): m.VectorInt(a) a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.uintc) v = m.VectorInt(a[0, :]) assert len(v) == 4 assert v[2] == 3 ma = np.asarray(v) ma[2] = 5 assert v[2] == 5 v = m.VectorInt(a[:, 1]) assert len(v) == 3 assert v[2] == 10 v = m.get_vectorstruct() assert v[0].x == 5 ma = np.asarray(v) ma[1]["x"] = 99 assert v[1].x == 99 v = m.VectorStruct( np.zeros( 3, dtype=np.dtype( [("w", "bool"), ("x", "I"), ("y", "float64"), ("z", "bool")], align=True ), ) ) assert len(v) == 3 b = np.array([1, 2, 3, 4], dtype=np.uint8) v = m.VectorUChar(b[::2]) assert v[1] == 3 def test_vector_bool(): import pybind11_cross_module_tests as cm vv_c = cm.VectorBool() for i in range(10): vv_c.append(i % 2 == 0) for i in range(10): assert vv_c[i] == (i % 2 == 0) assert str(vv_c) == "VectorBool[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]" def test_vector_custom(): v_a = m.VectorEl() v_a.append(m.El(1)) v_a.append(m.El(2)) assert str(v_a) == "VectorEl[El{1}, El{2}]" vv_a = m.VectorVectorEl() vv_a.append(v_a) vv_b = vv_a[0] assert str(vv_b) == "VectorEl[El{1}, El{2}]" def test_map_string_double(): mm = m.MapStringDouble() mm["a"] = 1 mm["b"] = 2.5 assert list(mm) == ["a", "b"] assert list(mm.items()) == [("a", 1), ("b", 2.5)] assert str(mm) == "MapStringDouble{a: 1, b: 2.5}" um = m.UnorderedMapStringDouble() um["ua"] = 1.1 um["ub"] = 2.6 assert sorted(list(um)) == ["ua", "ub"] assert sorted(list(um.items())) == [("ua", 1.1), ("ub", 2.6)] assert "UnorderedMapStringDouble" in str(um) def test_map_string_double_const(): mc = m.MapStringDoubleConst() mc["a"] = 10 mc["b"] = 20.5 assert str(mc) == "MapStringDoubleConst{a: 10, b: 20.5}" umc = m.UnorderedMapStringDoubleConst() umc["a"] = 11 umc["b"] = 21.5 str(umc) def test_noncopyable_containers(): # std::vector vnc = m.get_vnc(5) for i in range(0, 5): assert vnc[i].value == i + 1 for i, j in enumerate(vnc, start=1): assert j.value == i # std::deque dnc = m.get_dnc(5) for i in range(0, 5): assert dnc[i].value == i + 1 i = 1 for j in dnc: assert j.value == i i += 1 # std::map mnc = m.get_mnc(5) for i in range(1, 6): assert mnc[i].value == 10 * i vsum = 0 for k, v in mnc.items(): assert v.value == 10 * k vsum += v.value assert vsum == 150 # std::unordered_map mnc = m.get_umnc(5) for i in range(1, 6): assert mnc[i].value == 10 * i vsum = 0 for k, v in mnc.items(): assert v.value == 10 * k vsum += v.value assert vsum == 150 # nested std::map<std::vector> nvnc = m.get_nvnc(5) for i in range(1, 6): for j in range(0, 5): assert nvnc[i][j].value == j + 1 # Note: maps do not have .values() for _, v in nvnc.items(): for i, j in enumerate(v, start=1): assert j.value == i # nested std::map<std::map> nmnc = m.get_nmnc(5) for i in range(1, 6): for j in range(10, 60, 10): assert nmnc[i][j].value == 10 * j vsum = 0 for _, v_o in nmnc.items(): for k_i, v_i in v_o.items(): assert v_i.value == 10 * k_i vsum += v_i.value assert vsum == 7500 # nested std::unordered_map<std::unordered_map> numnc = m.get_numnc(5) for i in range(1, 6): for j in range(10, 60, 10): assert numnc[i][j].value == 10 * j vsum = 0 for _, v_o in numnc.items(): for k_i, v_i in v_o.items(): assert v_i.value == 10 * k_i vsum += v_i.value assert vsum == 7500 def test_map_delitem(): mm = m.MapStringDouble() mm["a"] = 1 mm["b"] = 2.5 assert list(mm) == ["a", "b"] assert list(mm.items()) == [("a", 1), ("b", 2.5)] del mm["a"] assert list(mm) == ["b"] assert list(mm.items()) == [("b", 2.5)] um = m.UnorderedMapStringDouble() um["ua"] = 1.1 um["ub"] = 2.6 assert sorted(list(um)) == ["ua", "ub"] assert sorted(list(um.items())) == [("ua", 1.1), ("ub", 2.6)] del um["ua"] assert sorted(list(um)) == ["ub"] assert sorted(list(um.items())) == [("ub", 2.6)]