aboutsummaryrefslogtreecommitdiffstats
path: root/quantum/process_keycode/process_audio.c
blob: e9b20512e7440b196136580b6b54a4a6794dc11d (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
#include "audio.h"
#include "process_audio.h"

#ifndef VOICE_CHANGE_SONG
    #define VOICE_CHANGE_SONG SONG(VOICE_CHANGE_SOUND)
#endif
float voice_change_song[][2] = VOICE_CHANGE_SONG;

#ifndef PITCH_STANDARD_A
    #define PITCH_STANDARD_A 440.0f
#endif



static float compute_freq_for_midi_note(uint8_t note)
{
    // https://en.wikipedia.org/wiki/MIDI_tuning_standard
    return pow(2.0, (note - 69) / 12.0) * PITCH_STANDARD_A;
}

bool process_audio(uint16_t keycode, keyrecord_t *record) {

    if (keycode == AU_ON && record->event.pressed) {
      audio_on();
      return false;
    }

    if (keycode == AU_OFF && record->event.pressed) {
      audio_off();
      return false;
    }

    if (keycode == AU_TOG && record->event.pressed) {
        if (is_audio_on()) {
            audio_off();
        } else {
            audio_on();
        }
        return false;
    }

    if (keycode == MUV_IN && record->event.pressed) {
        voice_iterate();
        PLAY_SONG(voice_change_song);
        return false;
    }

    if (keycode == MUV_DE && record->event.pressed) {
        voice_deiterate();
        PLAY_SONG(voice_change_song);
        return false;
    }

    return true;
}

void process_audio_noteon(uint8_t note) {
    play_note(compute_freq_for_midi_note(note), 0xF);
}

void process_audio_noteoff(uint8_t note) {
    stop_note(compute_freq_for_midi_note(note));
}

void process_audio_all_notes_off(void) {
    stop_all_notes();
}

__attribute__ ((weak))
void audio_on_user() {}
pan> #if defined(__AVR__) //__attribute__ ((noinline)) void * memset8 ( void * ptr, uint8_t val, uint16_t num ) { asm volatile( " movw r26, %[ptr] \n\t" " sbrs %A[num], 0 \n\t" " rjmp Lseteven_%= \n\t" " rjmp Lsetodd_%= \n\t" "Lsetloop_%=: \n\t" " st X+, %[val] \n\t" "Lsetodd_%=: \n\t" " st X+, %[val] \n\t" "Lseteven_%=: \n\t" " subi %A[num], 2 \n\t" " brcc Lsetloop_%= \n\t" " sbci %B[num], 0 \n\t" " brcc Lsetloop_%= \n\t" : [num] "+r" (num) : [ptr] "r" (ptr), [val] "r" (val) : "memory" ); return ptr; } //__attribute__ ((noinline)) void * memcpy8 ( void * dst, const void* src, uint16_t num ) { asm volatile( " movw r30, %[src] \n\t" " movw r26, %[dst] \n\t" " sbrs %A[num], 0 \n\t" " rjmp Lcpyeven_%= \n\t" " rjmp Lcpyodd_%= \n\t" "Lcpyloop_%=: \n\t" " ld __tmp_reg__, Z+ \n\t" " st X+, __tmp_reg__ \n\t" "Lcpyodd_%=: \n\t" " ld __tmp_reg__, Z+ \n\t" " st X+, __tmp_reg__ \n\t" "Lcpyeven_%=: \n\t" " subi %A[num], 2 \n\t" " brcc Lcpyloop_%= \n\t" " sbci %B[num], 0 \n\t" " brcc Lcpyloop_%= \n\t" : [num] "+r" (num) : [src] "r" (src), [dst] "r" (dst) : "memory" ); return dst; } //__attribute__ ((noinline)) void * memmove8 ( void * dst, const void* src, uint16_t num ) { if( src > dst) { // if src > dst then we can use the forward-stepping memcpy8 return memcpy8( dst, src, num); } else { // if src < dst then we have to step backward: dst = (char*)dst + num; src = (char*)src + num; asm volatile( " movw r30, %[src] \n\t" " movw r26, %[dst] \n\t" " sbrs %A[num], 0 \n\t" " rjmp Lmoveven_%= \n\t" " rjmp Lmovodd_%= \n\t" "Lmovloop_%=: \n\t" " ld __tmp_reg__, -Z \n\t" " st -X, __tmp_reg__ \n\t" "Lmovodd_%=: \n\t" " ld __tmp_reg__, -Z \n\t" " st -X, __tmp_reg__ \n\t" "Lmoveven_%=: \n\t" " subi %A[num], 2 \n\t" " brcc Lmovloop_%= \n\t" " sbci %B[num], 0 \n\t" " brcc Lmovloop_%= \n\t" : [num] "+r" (num) : [src] "r" (src), [dst] "r" (dst) : "memory" ); return dst; } } #endif /* AVR */ #if 0 // TEST / VERIFICATION CODE ONLY BELOW THIS POINT #include <Arduino.h> #include "lib8tion.h" void test1abs( int8_t i) { Serial.print("abs("); Serial.print(i); Serial.print(") = "); int8_t j = abs8(i); Serial.print(j); Serial.println(" "); } void testabs() { delay(5000); for( int8_t q = -128; q != 127; q++) { test1abs(q); } for(;;){}; } void testmul8() { delay(5000); byte r, c; Serial.println("mul8:"); for( r = 0; r <= 20; r += 1) { Serial.print(r); Serial.print(" : "); for( c = 0; c <= 20; c += 1) { byte t; t = mul8( r, c); Serial.print(t); Serial.print(' '); } Serial.println(' '); } Serial.println("done."); for(;;){}; } void testscale8() { delay(5000); byte r, c; Serial.println("scale8:"); for( r = 0; r <= 240; r += 10) { Serial.print(r); Serial.print(" : "); for( c = 0; c <= 240; c += 10) { byte t; t = scale8( r, c); Serial.print(t); Serial.print(' '); } Serial.println(' '); } Serial.println(' '); Serial.println("scale8_video:"); for( r = 0; r <= 100; r += 4) { Serial.print(r); Serial.print(" : "); for( c = 0; c <= 100; c += 4) { byte t; t = scale8_video( r, c); Serial.print(t); Serial.print(' '); } Serial.println(' '); } Serial.println("done."); for(;;){}; } void testqadd8() { delay(5000); byte r, c; for( r = 0; r <= 240; r += 10) { Serial.print(r); Serial.print(" : "); for( c = 0; c <= 240; c += 10) { byte t; t = qadd8( r, c); Serial.print(t); Serial.print(' '); } Serial.println(' '); } Serial.println("done."); for(;;){}; } void testnscale8x3() { delay(5000); byte r, g, b, sc; for( byte z = 0; z < 10; z++) { r = random8(); g = random8(); b = random8(); sc = random8(); Serial.print("nscale8x3_video( "); Serial.print(r); Serial.print(", "); Serial.print(g); Serial.print(", "); Serial.print(b); Serial.print(", "); Serial.print(sc); Serial.print(") = [ "); nscale8x3_video( r, g, b, sc); Serial.print(r); Serial.print(", "); Serial.print(g); Serial.print(", "); Serial.print(b); Serial.print("]"); Serial.println(' '); } Serial.println("done."); for(;;){}; } #endif