From c14c47d97feca15354ac296fc2f5957057e3d9eb Mon Sep 17 00:00:00 2001 From: Johannes Date: Sun, 15 Sep 2019 18:37:58 +0200 Subject: [PATCH 001/153] Redo Arm DAC implementation for additive, wavetable synthesis, sample playback changes by Jack Humbert on an implementation for DAC audio on arm/chibios platforms this commits bundles the changes from the arm-dac-work branch focused on audio/audio_arm.* into one commit (leaving out the test-keyboard) f52faeb5d (origin/arm-dac-work) add sample and wavetable examples, parsers for both -> only the changes on audio_arm_.*, the keyboard related parts are split off to a separate commit bfe468ef1 start morphing wavetable 474d100b5 refined a bit 208bee10f play_notes working 3e6478b0b start in-place documentation of dac settings 3e1826a33 fixed blip (rounding error), other waves, added key selection (left/right) 73853d651 5 voices at 44.1khz dfb401b95 limit voices to working number 9632b3379 configuration for the ez 6241f3f3b notes working in a new way --- quantum/audio/audio.h | 4 + quantum/audio/audio_arm.h | 97 ++++ quantum/audio/audio_chibios.c | 887 ++++++++++++++-------------------- 3 files changed, 455 insertions(+), 533 deletions(-) create mode 100644 quantum/audio/audio_arm.h diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index dccf03d5f65a..7f0ade50378d 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -27,6 +27,9 @@ #include "voices.h" #include "quantum.h" #include +#if defined(PROTOCOL_CHIBIOS) + #include "audio_arm.h" +#endif // Largely untested PWM audio mode (doesn't sound as good) // #define PWM_AUDIO @@ -103,4 +106,5 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat); #define PLAY_SONG(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), false) #define PLAY_LOOP(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), true) +bool is_playing_note(void); bool is_playing_notes(void); diff --git a/quantum/audio/audio_arm.h b/quantum/audio/audio_arm.h new file mode 100644 index 000000000000..dea6c9068d2e --- /dev/null +++ b/quantum/audio/audio_arm.h @@ -0,0 +1,97 @@ +/* Copyright 2019 Jack Humbert + * + * 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 2 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 . + */ +#pragma once + +#include "ch.h" + +/** + * Size of the dac_buffer arrays. All must be the same size. + */ +#define DAC_BUFFER_SIZE 256U + +/** + * Highest value allowed by our 12bit DAC. + */ +#ifndef DAC_SAMPLE_MAX + #define DAC_SAMPLE_MAX 4095U +#endif + +// #define DAC_LOW_QUALITY + +/** + * These presets allow you to quickly switch between quality/voice settings for + * the DAC. The sample rate and number of voices roughly has an inverse + * relationship - slightly higher sample rates may be possible. + */ +#ifdef DAC_VERY_LOW_QUALITY + #define DAC_SAMPLE_RATE 11025U + #define DAC_VOICES_MAX 8 +#endif + +#ifdef DAC_LOW_QUALITY + #define DAC_SAMPLE_RATE 22050U + #define DAC_VOICES_MAX 4 +#endif + +#ifdef DAC_HIGH_QUALITY + #define DAC_SAMPLE_RATE 44100U + #define DAC_VOICES_MAX 2 +#endif + +#ifdef DAC_VERY_HIGH_QUALITY + #define DAC_SAMPLE_RATE 88200U + #define DAC_VOICES_MAX 1 +#endif + +/** + * Effective bitrate of the DAC. 44.1khz is the standard for most audio - any + * lower will sacrifice perceptible audio quality. Any higher will limit the + * number of simultaneous voices. In most situations, a tenth (1/10) of the + * sample rate is where notes become unbearable. + */ +#ifndef DAC_SAMPLE_RATE + #define DAC_SAMPLE_RATE 44100U +#endif + +/** + * The number of voices (in polyphony) that are supported. If too high a value + * is used here, the keyboard will freeze and glitch-out when that many voices + * are being played. + */ +#ifndef DAC_VOICES_MAX + #define DAC_VOICES_MAX 2 +#endif + +/** + * The default value of the DAC when not playing anything. Certain hardware + * setups may require a high (DAC_SAMPLE_MAX) or low (0) value here. + */ +#ifndef DAC_OFF_VALUE + #define DAC_OFF_VALUE DAC_SAMPLE_MAX / 2 +#endif + +/** + * choose pins for the speaker + */ +#ifndef A4_AUDIO + #define A4_AUDIO +//#define A5_AUDIO +#endif + +uint8_t dac_number_of_voices(void); +float dac_get_frequency(uint8_t index); +uint16_t dac_value_generate(void); +void dac_setup_note(void); diff --git a/quantum/audio/audio_chibios.c b/quantum/audio/audio_chibios.c index b267e574633a..b29796e06ef0 100644 --- a/quantum/audio/audio_chibios.c +++ b/quantum/audio/audio_chibios.c @@ -1,4 +1,4 @@ -/* Copyright 2016 Jack Humbert +/* Copyright 2016-2019 Jack Humbert * * 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 @@ -26,41 +26,26 @@ // ----------------------------------------------------------------------------- -int voices = 0; -int voice_place = 0; -float frequency = 0; -float frequency_alt = 0; -int volume = 0; -long position = 0; +uint8_t dac_voices = 0; +float dac_frequencies[8] = { 0.0 }; -float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -bool sliding = false; - -float place = 0; - -uint8_t *sample; -uint16_t sample_length = 0; - -bool playing_notes = false; -bool playing_note = false; +bool playing_notes = false; +bool playing_note = false; float note_frequency = 0; -float note_length = 0; -uint8_t note_tempo = TEMPO_DEFAULT; -float note_timbre = TIMBRE_DEFAULT; -uint16_t note_position = 0; -float (*notes_pointer)[][2]; +float note_length = 0; +uint8_t note_tempo = TEMPO_DEFAULT; +float note_timbre = TIMBRE_DEFAULT; +uint32_t note_position = 0; +float (* notes_pointer)[][2]; uint16_t notes_count; bool notes_repeat; -bool note_resting = false; uint16_t current_note = 0; -uint8_t rest_counter = 0; #ifdef VIBRATO_ENABLE -float vibrato_counter = 0; +float vibrato_counter = 0; float vibrato_strength = .5; -float vibrato_rate = 0.125; +float vibrato_rate = 0.125; #endif float polyphony_rate = 0; @@ -70,216 +55,241 @@ static bool audio_initialized = false; audio_config_t audio_config; uint16_t envelope_index = 0; -bool glissando = true; +bool glissando = true; #ifndef STARTUP_SONG -# define STARTUP_SONG SONG(STARTUP_SOUND) + #define STARTUP_SONG SONG(STARTUP_SOUND) #endif float startup_song[][2] = STARTUP_SONG; -static void gpt_cb8(GPTDriver *gptp); - -#define DAC_BUFFER_SIZE 100 -#ifndef DAC_SAMPLE_MAX -# define DAC_SAMPLE_MAX 65535U -#endif +static const dacsample_t dac_buffer_sine[DAC_BUFFER_SIZE] = { + // 256 values, max 4095 + 0x800,0x832,0x864,0x896,0x8c8,0x8fa,0x92c,0x95e, + 0x98f,0x9c0,0x9f1,0xa22,0xa52,0xa82,0xab1,0xae0, + 0xb0f,0xb3d,0xb6b,0xb98,0xbc5,0xbf1,0xc1c,0xc47, + 0xc71,0xc9a,0xcc3,0xceb,0xd12,0xd39,0xd5f,0xd83, + 0xda7,0xdca,0xded,0xe0e,0xe2e,0xe4e,0xe6c,0xe8a, + 0xea6,0xec1,0xedc,0xef5,0xf0d,0xf24,0xf3a,0xf4f, + 0xf63,0xf76,0xf87,0xf98,0xfa7,0xfb5,0xfc2,0xfcd, + 0xfd8,0xfe1,0xfe9,0xff0,0xff5,0xff9,0xffd,0xffe, + 0xfff,0xffe,0xffd,0xff9,0xff5,0xff0,0xfe9,0xfe1, + 0xfd8,0xfcd,0xfc2,0xfb5,0xfa7,0xf98,0xf87,0xf76, + 0xf63,0xf4f,0xf3a,0xf24,0xf0d,0xef5,0xedc,0xec1, + 0xea6,0xe8a,0xe6c,0xe4e,0xe2e,0xe0e,0xded,0xdca, + 0xda7,0xd83,0xd5f,0xd39,0xd12,0xceb,0xcc3,0xc9a, + 0xc71,0xc47,0xc1c,0xbf1,0xbc5,0xb98,0xb6b,0xb3d, + 0xb0f,0xae0,0xab1,0xa82,0xa52,0xa22,0x9f1,0x9c0, + 0x98f,0x95e,0x92c,0x8fa,0x8c8,0x896,0x864,0x832, + 0x800,0x7cd,0x79b,0x769,0x737,0x705,0x6d3,0x6a1, + 0x670,0x63f,0x60e,0x5dd,0x5ad,0x57d,0x54e,0x51f, + 0x4f0,0x4c2,0x494,0x467,0x43a,0x40e,0x3e3,0x3b8, + 0x38e,0x365,0x33c,0x314,0x2ed,0x2c6,0x2a0,0x27c, + 0x258,0x235,0x212,0x1f1,0x1d1,0x1b1,0x193,0x175, + 0x159,0x13e,0x123,0x10a,0xf2, 0xdb, 0xc5, 0xb0, + 0x9c, 0x89, 0x78, 0x67, 0x58, 0x4a, 0x3d, 0x32, + 0x27, 0x1e, 0x16, 0xf, 0xa, 0x6, 0x2, 0x1, + 0x0, 0x1, 0x2, 0x6, 0xa, 0xf, 0x16, 0x1e, + 0x27, 0x32, 0x3d, 0x4a, 0x58, 0x67, 0x78, 0x89, + 0x9c, 0xb0, 0xc5, 0xdb, 0xf2, 0x10a,0x123,0x13e, + 0x159,0x175,0x193,0x1b1,0x1d1,0x1f1,0x212,0x235, + 0x258,0x27c,0x2a0,0x2c6,0x2ed,0x314,0x33c,0x365, + 0x38e,0x3b8,0x3e3,0x40e,0x43a,0x467,0x494,0x4c2, + 0x4f0,0x51f,0x54e,0x57d,0x5ad,0x5dd,0x60e,0x63f, + 0x670,0x6a1,0x6d3,0x705,0x737,0x769,0x79b,0x7cd +}; -#define START_CHANNEL_1() \ - gptStart(&GPTD6, &gpt6cfg1); \ - gptStartContinuous(&GPTD6, 2U); \ - palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG) -#define START_CHANNEL_2() \ - gptStart(&GPTD7, &gpt7cfg1); \ - gptStartContinuous(&GPTD7, 2U); \ - palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG) -#define STOP_CHANNEL_1() \ - gptStopTimer(&GPTD6); \ - palSetPadMode(GPIOA, 4, PAL_MODE_OUTPUT_PUSHPULL); \ - palSetPad(GPIOA, 4) -#define STOP_CHANNEL_2() \ - gptStopTimer(&GPTD7); \ - palSetPadMode(GPIOA, 5, PAL_MODE_OUTPUT_PUSHPULL); \ - palSetPad(GPIOA, 5) -#define RESTART_CHANNEL_1() \ - STOP_CHANNEL_1(); \ - START_CHANNEL_1() -#define RESTART_CHANNEL_2() \ - STOP_CHANNEL_2(); \ - START_CHANNEL_2() -#define UPDATE_CHANNEL_1_FREQ(freq) \ - gpt6cfg1.frequency = freq * DAC_BUFFER_SIZE; \ - RESTART_CHANNEL_1() -#define UPDATE_CHANNEL_2_FREQ(freq) \ - gpt7cfg1.frequency = freq * DAC_BUFFER_SIZE; \ - RESTART_CHANNEL_2() -#define GET_CHANNEL_1_FREQ (uint16_t)(gpt6cfg1.frequency * DAC_BUFFER_SIZE) -#define GET_CHANNEL_2_FREQ (uint16_t)(gpt7cfg1.frequency * DAC_BUFFER_SIZE) - -/* - * GPT6 configuration. - */ -// static const GPTConfig gpt6cfg1 = { -// .frequency = 1000000U, -// .callback = NULL, -// .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ -// .dier = 0U -// }; - -GPTConfig gpt6cfg1 = {.frequency = 440U * DAC_BUFFER_SIZE, - .callback = NULL, - .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ - .dier = 0U}; - -GPTConfig gpt7cfg1 = {.frequency = 440U * DAC_BUFFER_SIZE, - .callback = NULL, - .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ - .dier = 0U}; - -GPTConfig gpt8cfg1 = {.frequency = 10, - .callback = gpt_cb8, - .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ - .dier = 0U}; - -/* - * DAC test buffer (sine wave). - */ -// static const dacsample_t dac_buffer[DAC_BUFFER_SIZE] = { -// 2047, 2082, 2118, 2154, 2189, 2225, 2260, 2296, 2331, 2367, 2402, 2437, -// 2472, 2507, 2542, 2576, 2611, 2645, 2679, 2713, 2747, 2780, 2813, 2846, -// 2879, 2912, 2944, 2976, 3008, 3039, 3070, 3101, 3131, 3161, 3191, 3221, -// 3250, 3278, 3307, 3335, 3362, 3389, 3416, 3443, 3468, 3494, 3519, 3544, -// 3568, 3591, 3615, 3637, 3660, 3681, 3703, 3723, 3744, 3763, 3782, 3801, -// 3819, 3837, 3854, 3870, 3886, 3902, 3917, 3931, 3944, 3958, 3970, 3982, -// 3993, 4004, 4014, 4024, 4033, 4041, 4049, 4056, 4062, 4068, 4074, 4078, -// 4082, 4086, 4089, 4091, 4092, 4093, 4094, 4093, 4092, 4091, 4089, 4086, -// 4082, 4078, 4074, 4068, 4062, 4056, 4049, 4041, 4033, 4024, 4014, 4004, -// 3993, 3982, 3970, 3958, 3944, 3931, 3917, 3902, 3886, 3870, 3854, 3837, -// 3819, 3801, 3782, 3763, 3744, 3723, 3703, 3681, 3660, 3637, 3615, 3591, -// 3568, 3544, 3519, 3494, 3468, 3443, 3416, 3389, 3362, 3335, 3307, 3278, -// 3250, 3221, 3191, 3161, 3131, 3101, 3070, 3039, 3008, 2976, 2944, 2912, -// 2879, 2846, 2813, 2780, 2747, 2713, 2679, 2645, 2611, 2576, 2542, 2507, -// 2472, 2437, 2402, 2367, 2331, 2296, 2260, 2225, 2189, 2154, 2118, 2082, -// 2047, 2012, 1976, 1940, 1905, 1869, 1834, 1798, 1763, 1727, 1692, 1657, -// 1622, 1587, 1552, 1518, 1483, 1449, 1415, 1381, 1347, 1314, 1281, 1248, -// 1215, 1182, 1150, 1118, 1086, 1055, 1024, 993, 963, 933, 903, 873, -// 844, 816, 787, 759, 732, 705, 678, 651, 626, 600, 575, 550, -// 526, 503, 479, 457, 434, 413, 391, 371, 350, 331, 312, 293, -// 275, 257, 240, 224, 208, 192, 177, 163, 150, 136, 124, 112, -// 101, 90, 80, 70, 61, 53, 45, 38, 32, 26, 20, 16, -// 12, 8, 5, 3, 2, 1, 0, 1, 2, 3, 5, 8, -// 12, 16, 20, 26, 32, 38, 45, 53, 61, 70, 80, 90, -// 101, 112, 124, 136, 150, 163, 177, 192, 208, 224, 240, 257, -// 275, 293, 312, 331, 350, 371, 391, 413, 434, 457, 479, 503, -// 526, 550, 575, 600, 626, 651, 678, 705, 732, 759, 787, 816, -// 844, 873, 903, 933, 963, 993, 1024, 1055, 1086, 1118, 1150, 1182, -// 1215, 1248, 1281, 1314, 1347, 1381, 1415, 1449, 1483, 1518, 1552, 1587, -// 1622, 1657, 1692, 1727, 1763, 1798, 1834, 1869, 1905, 1940, 1976, 2012 -// }; - -// static const dacsample_t dac_buffer_2[DAC_BUFFER_SIZE] = { -// 12, 8, 5, 3, 2, 1, 0, 1, 2, 3, 5, 8, -// 12, 16, 20, 26, 32, 38, 45, 53, 61, 70, 80, 90, -// 101, 112, 124, 136, 150, 163, 177, 192, 208, 224, 240, 257, -// 275, 293, 312, 331, 350, 371, 391, 413, 434, 457, 479, 503, -// 526, 550, 575, 600, 626, 651, 678, 705, 732, 759, 787, 816, -// 844, 873, 903, 933, 963, 993, 1024, 1055, 1086, 1118, 1150, 1182, -// 1215, 1248, 1281, 1314, 1347, 1381, 1415, 1449, 1483, 1518, 1552, 1587, -// 1622, 1657, 1692, 1727, 1763, 1798, 1834, 1869, 1905, 1940, 1976, 2012, -// 2047, 2082, 2118, 2154, 2189, 2225, 2260, 2296, 2331, 2367, 2402, 2437, -// 2472, 2507, 2542, 2576, 2611, 2645, 2679, 2713, 2747, 2780, 2813, 2846, -// 2879, 2912, 2944, 2976, 3008, 3039, 3070, 3101, 3131, 3161, 3191, 3221, -// 3250, 3278, 3307, 3335, 3362, 3389, 3416, 3443, 3468, 3494, 3519, 3544, -// 3568, 3591, 3615, 3637, 3660, 3681, 3703, 3723, 3744, 3763, 3782, 3801, -// 3819, 3837, 3854, 3870, 3886, 3902, 3917, 3931, 3944, 3958, 3970, 3982, -// 3993, 4004, 4014, 4024, 4033, 4041, 4049, 4056, 4062, 4068, 4074, 4078, -// 4082, 4086, 4089, 4091, 4092, 4093, 4094, 4093, 4092, 4091, 4089, 4086, -// 4082, 4078, 4074, 4068, 4062, 4056, 4049, 4041, 4033, 4024, 4014, 4004, -// 3993, 3982, 3970, 3958, 3944, 3931, 3917, 3902, 3886, 3870, 3854, 3837, -// 3819, 3801, 3782, 3763, 3744, 3723, 3703, 3681, 3660, 3637, 3615, 3591, -// 3568, 3544, 3519, 3494, 3468, 3443, 3416, 3389, 3362, 3335, 3307, 3278, -// 3250, 3221, 3191, 3161, 3131, 3101, 3070, 3039, 3008, 2976, 2944, 2912, -// 2879, 2846, 2813, 2780, 2747, 2713, 2679, 2645, 2611, 2576, 2542, 2507, -// 2472, 2437, 2402, 2367, 2331, 2296, 2260, 2225, 2189, 2154, 2118, 2082, -// 2047, 2012, 1976, 1940, 1905, 1869, 1834, 1798, 1763, 1727, 1692, 1657, -// 1622, 1587, 1552, 1518, 1483, 1449, 1415, 1381, 1347, 1314, 1281, 1248, -// 1215, 1182, 1150, 1118, 1086, 1055, 1024, 993, 963, 933, 903, 873, -// 844, 816, 787, 759, 732, 705, 678, 651, 626, 600, 575, 550, -// 526, 503, 479, 457, 434, 413, 391, 371, 350, 331, 312, 293, -// 275, 257, 240, 224, 208, 192, 177, 163, 150, 136, 124, 112, -// 101, 90, 80, 70, 61, 53, 45, 38, 32, 26, 20, 16 -// }; - -// squarewave -static const dacsample_t dac_buffer[DAC_BUFFER_SIZE] = { - // First half is max, second half is 0 - [0 ... DAC_BUFFER_SIZE / 2 - 1] = DAC_SAMPLE_MAX, - [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = 0, +static const dacsample_t dac_buffer_triangle[DAC_BUFFER_SIZE] = { + // 256 values, max 4095 + 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x100, + 0x120,0x140,0x160,0x180,0x1a0,0x1c0,0x1e0,0x200, + 0x220,0x240,0x260,0x280,0x2a0,0x2c0,0x2e0,0x300, + 0x320,0x340,0x360,0x380,0x3a0,0x3c0,0x3e0,0x400, + 0x420,0x440,0x460,0x480,0x4a0,0x4c0,0x4e0,0x500, + 0x520,0x540,0x560,0x580,0x5a0,0x5c0,0x5e0,0x600, + 0x620,0x640,0x660,0x680,0x6a0,0x6c0,0x6e0,0x700, + 0x720,0x740,0x760,0x780,0x7a0,0x7c0,0x7e0,0x800, + 0x81f,0x83f,0x85f,0x87f,0x89f,0x8bf,0x8df,0x8ff, + 0x91f,0x93f,0x95f,0x97f,0x99f,0x9bf,0x9df,0x9ff, + 0xa1f,0xa3f,0xa5f,0xa7f,0xa9f,0xabf,0xadf,0xaff, + 0xb1f,0xb3f,0xb5f,0xb7f,0xb9f,0xbbf,0xbdf,0xbff, + 0xc1f,0xc3f,0xc5f,0xc7f,0xc9f,0xcbf,0xcdf,0xcff, + 0xd1f,0xd3f,0xd5f,0xd7f,0xd9f,0xdbf,0xddf,0xdff, + 0xe1f,0xe3f,0xe5f,0xe7f,0xe9f,0xebf,0xedf,0xeff, + 0xf1f,0xf3f,0xf5f,0xf7f,0xf9f,0xfbf,0xfdf,0xfff, + 0xfdf,0xfbf,0xf9f,0xf7f,0xf5f,0xf3f,0xf1f,0xeff, + 0xedf,0xebf,0xe9f,0xe7f,0xe5f,0xe3f,0xe1f,0xdff, + 0xddf,0xdbf,0xd9f,0xd7f,0xd5f,0xd3f,0xd1f,0xcff, + 0xcdf,0xcbf,0xc9f,0xc7f,0xc5f,0xc3f,0xc1f,0xbff, + 0xbdf,0xbbf,0xb9f,0xb7f,0xb5f,0xb3f,0xb1f,0xaff, + 0xadf,0xabf,0xa9f,0xa7f,0xa5f,0xa3f,0xa1f,0x9ff, + 0x9df,0x9bf,0x99f,0x97f,0x95f,0x93f,0x91f,0x8ff, + 0x8df,0x8bf,0x89f,0x87f,0x85f,0x83f,0x81f,0x800, + 0x7e0,0x7c0,0x7a0,0x780,0x760,0x740,0x720,0x700, + 0x6e0,0x6c0,0x6a0,0x680,0x660,0x640,0x620,0x600, + 0x5e0,0x5c0,0x5a0,0x580,0x560,0x540,0x520,0x500, + 0x4e0,0x4c0,0x4a0,0x480,0x460,0x440,0x420,0x400, + 0x3e0,0x3c0,0x3a0,0x380,0x360,0x340,0x320,0x300, + 0x2e0,0x2c0,0x2a0,0x280,0x260,0x240,0x220,0x200, + 0x1e0,0x1c0,0x1a0,0x180,0x160,0x140,0x120,0x100, + 0xe0, 0xc0, 0xa0, 0x80, 0x60, 0x40, 0x20, 0x0 }; -// squarewave -static const dacsample_t dac_buffer_2[DAC_BUFFER_SIZE] = { - // opposite of dac_buffer above - [0 ... DAC_BUFFER_SIZE / 2 - 1] = 0, - [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = DAC_SAMPLE_MAX, +static const dacsample_t dac_buffer_square[DAC_BUFFER_SIZE] = { + // First half is max, second half is 0 + [0 ... DAC_BUFFER_SIZE/2-1] = DAC_SAMPLE_MAX, + [DAC_BUFFER_SIZE/2 ... DAC_BUFFER_SIZE -1] = 0, }; -/* - * DAC streaming callback. - */ -size_t nz = 0; -static void end_cb1(DACDriver *dacp) { - (void)dacp; +static dacsample_t dac_buffer_empty[DAC_BUFFER_SIZE] = { DAC_OFF_VALUE }; + +static float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; - nz++; - if ((nz % 1000) == 0) { - // palTogglePad(GPIOD, GPIOD_LED3); +/** + * Generation of the waveform being passed to the callback. Declared weak so users + * can override it with their own waveforms/noises. + */ +__attribute__ ((weak)) +uint16_t dac_value_generate(void) { + uint16_t value = DAC_OFF_VALUE; + uint8_t working_voices = dac_voices; + if (working_voices > DAC_VOICES_MAX) + working_voices = DAC_VOICES_MAX; + + if (working_voices > 0) { + uint16_t value_avg = 0; + for (uint8_t i = 0; i < working_voices; i++) { + dac_if[i] = dac_if[i] + ((dac_frequencies[i] * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE); + + // Needed because % doesn't work with floats + while (dac_if[i] >= (DAC_BUFFER_SIZE)) + dac_if[i] = dac_if[i] - DAC_BUFFER_SIZE; + + // Wavetable generation/lookup + uint16_t dac_i = (uint16_t)dac_if[i]; + // SINE + value_avg += dac_buffer_sine[dac_i] / working_voices / 3; + // TRIANGLE + value_avg += dac_buffer_triangle[dac_i] / working_voices / 3; + // SQUARE + value_avg += dac_buffer_square[dac_i] / working_voices / 3; } + value = value_avg; + } + return value; } -/* - * DAC error callback. +/** + * DAC streaming callback. Does all of the main computing for playing songs. */ -static void error_cb1(DACDriver *dacp, dacerror_t err) { - (void)dacp; - (void)err; +static void dac_end(DACDriver * dacp, dacsample_t * sample_p, size_t sample_count) { + + (void)dacp; - chSysHalt("DAC failure"); + for (uint8_t s = 0; s < sample_count; s++) { + sample_p[s] = dac_value_generate(); + } + + if (playing_notes) { + note_position += sample_count; + + // End of the note - 35 is arbitary here, but gets us close to AVR's timing + if ((note_position >= (note_length*DAC_SAMPLE_RATE/35))) { + stop_note((*notes_pointer)[current_note][0]); + current_note++; + if (current_note >= notes_count) { + if (notes_repeat) { + current_note = 0; + } else { + playing_notes = false; + return; + } + } + play_note((*notes_pointer)[current_note][0], 15); + envelope_index = 0; + note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); + + // Skip forward in the next note's length if we've over shot the last, so + // the overall length of the song is the same + note_position = note_position - (note_length*DAC_SAMPLE_RATE/35); + } + } } -static const DACConfig dac1cfg1 = {.init = DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; +static void dac_error(DACDriver *dacp, dacerror_t err) { + + (void)dacp; + (void)err; -static const DACConversionGroup dacgrpcfg1 = {.num_channels = 1U, .end_cb = end_cb1, .error_cb = error_cb1, .trigger = DAC_TRG(0)}; + chSysHalt("DAC failure. halp"); +} -static const DACConfig dac1cfg2 = {.init = DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; +static const GPTConfig gpt6cfg1 = { + .frequency = DAC_SAMPLE_RATE * 3, + .callback = NULL, + .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ + .dier = 0U +}; -static const DACConversionGroup dacgrpcfg2 = {.num_channels = 1U, .end_cb = end_cb1, .error_cb = error_cb1, .trigger = DAC_TRG(0)}; +static const DACConfig dac_conf = { + .init = DAC_SAMPLE_MAX, + .datamode = DAC_DHRM_12BIT_RIGHT +}; + +/** + * @note The DAC_TRG(0) here selects the Timer 6 TRGO event, which is triggered + * on the rising edge after 3 APB1 clock cycles, causing our gpt6cfg1.frequency + * to be a third of what we expect. + * + * Here are all the values for DAC_TRG (TSEL in the ref manual) + * TIM15_TRGO 0b011 + * TIM2_TRGO 0b100 + * TIM3_TRGO 0b001 + * TIM6_TRGO 0b000 + * TIM7_TRGO 0b010 + * EXTI9 0b110 + * SWTRIG 0b111 + */ +static const DACConversionGroup dac_conv_cfg = { + .num_channels = 1U, + .end_cb = dac_end, + .error_cb = dac_error, + .trigger = DAC_TRG(0b000) +}; void audio_init() { - if (audio_initialized) { - return; - } -// Check EEPROM + if (audio_initialized) { + return; + } + + // Check EEPROM #ifdef EEPROM_ENABLE if (!eeconfig_is_enabled()) { - eeconfig_init(); + eeconfig_init(); } audio_config.raw = eeconfig_read_audio(); -#else // ARM EEPROM - audio_config.enable = true; -# ifdef AUDIO_CLICKY_ON +#else // ARM EEPROM + audio_config.enable = true; + #ifdef AUDIO_CLICKY_ON audio_config.clicky_enable = true; -# endif -#endif // ARM EEPROM - /* - * Starting DAC1 driver, setting up the output pin as analog as suggested - * by the Reference Manual. - */ - palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); - palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); - dacStart(&DACD1, &dac1cfg1); - dacStart(&DACD2, &dac1cfg2); + #endif +#endif // ARM EEPROM + + +#if defined(A4_AUDIO) + palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG ); + dacStart(&DACD1, &dac_conf); + dacStartConversion(&DACD1, &dac_conv_cfg, dac_buffer_empty, DAC_BUFFER_SIZE); +#endif +#if defined(A5_AUDIO) + palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG ); + dacStart(&DACD2, &dac_conf); + dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, DAC_BUFFER_SIZE); +#endif + + gptStart(&GPTD6, &gpt6cfg1); + gptStartContinuous(&GPTD6, 2U); /* * Start the note timer @@ -287,27 +297,15 @@ void audio_init() { gptStart(&GPTD8, &gpt8cfg1); gptStartContinuous(&GPTD8, 2U); - /* - * Starting GPT6/7 driver, it is used for triggering the DAC. - */ - START_CHANNEL_1(); - START_CHANNEL_2(); - - /* - * Starting a continuous conversion. - */ - dacStartConversion(&DACD1, &dacgrpcfg1, (dacsample_t *)dac_buffer, DAC_BUFFER_SIZE); - dacStartConversion(&DACD2, &dacgrpcfg2, (dacsample_t *)dac_buffer_2, DAC_BUFFER_SIZE); - - audio_initialized = true; + audio_initialized = true; stop_all_notes(); } void audio_startup() { - if (audio_config.enable) { - PLAY_SONG(startup_song); - } + if (audio_config.enable) { + PLAY_SONG(startup_song); + } } void stop_all_notes() { @@ -316,334 +314,121 @@ void stop_all_notes() { if (!audio_initialized) { audio_init(); } - voices = 0; - - gptStopTimer(&GPTD6); - gptStopTimer(&GPTD7); - gptStopTimer(&GPTD8); + dac_voices = 0; playing_notes = false; - playing_note = false; - frequency = 0; - frequency_alt = 0; - volume = 0; + playing_note = false; for (uint8_t i = 0; i < 8; i++) { - frequencies[i] = 0; - volumes[i] = 0; + dac_frequencies[i] = 0; } } void stop_note(float freq) { - dprintf("audio stop note freq=%d", (int)freq); + dprintf("audio stop note freq=%d", (int)freq); - if (playing_note) { - if (!audio_initialized) { - audio_init(); - } - for (int i = 7; i >= 0; i--) { - if (frequencies[i] == freq) { - frequencies[i] = 0; - volumes[i] = 0; - for (int j = i; (j < 7); j++) { - frequencies[j] = frequencies[j + 1]; - frequencies[j + 1] = 0; - volumes[j] = volumes[j + 1]; - volumes[j + 1] = 0; - } - break; - } - } - voices--; - if (voices < 0) { - voices = 0; - } - if (voice_place >= voices) { - voice_place = 0; - } - if (voices == 0) { - STOP_CHANNEL_1(); - STOP_CHANNEL_2(); - gptStopTimer(&GPTD8); - frequency = 0; - frequency_alt = 0; - volume = 0; - playing_note = false; + if (playing_note) { + if (!audio_initialized) { + audio_init(); + } + for (int i = 7; i >= 0; i--) { + if (dac_frequencies[i] == freq) { + dac_frequencies[i] = 0; + for (int j = i; (j < 7); j++) { + dac_frequencies[j] = dac_frequencies[j+1]; + dac_frequencies[j+1] = 0; } + break; + } + } + dac_voices--; + if (dac_voices < 0) { + dac_voices = 0; } + if (dac_voices == 0) { + playing_note = false; + } + } } #ifdef VIBRATO_ENABLE float mod(float a, int b) { - float r = fmod(a, b); - return r < 0 ? r + b : r; + float r = fmod(a, b); + return r < 0 ? r + b : r; } float vibrato(float average_freq) { -# ifdef VIBRATO_STRENGTH_ENABLE + #ifdef VIBRATO_STRENGTH_ENABLE float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); -# else + #else float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; -# endif - vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0 / average_freq)), VIBRATO_LUT_LENGTH); - return vibrated_freq; + #endif + vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH); + return vibrated_freq; } #endif -static void gpt_cb8(GPTDriver *gptp) { - float freq; - - if (playing_note) { - if (voices > 0) { - float freq_alt = 0; - if (voices > 1) { - if (polyphony_rate == 0) { - if (glissando) { - if (frequency_alt != 0 && frequency_alt < frequencies[voices - 2] && frequency_alt < frequencies[voices - 2] * pow(2, -440 / frequencies[voices - 2] / 12 / 2)) { - frequency_alt = frequency_alt * pow(2, 440 / frequency_alt / 12 / 2); - } else if (frequency_alt != 0 && frequency_alt > frequencies[voices - 2] && frequency_alt > frequencies[voices - 2] * pow(2, 440 / frequencies[voices - 2] / 12 / 2)) { - frequency_alt = frequency_alt * pow(2, -440 / frequency_alt / 12 / 2); - } else { - frequency_alt = frequencies[voices - 2]; - } - } else { - frequency_alt = frequencies[voices - 2]; - } - -#ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq_alt = vibrato(frequency_alt); - } else { - freq_alt = frequency_alt; - } -#else - freq_alt = frequency_alt; -#endif - } - - if (envelope_index < 65535) { - envelope_index++; - } - - freq_alt = voice_envelope(freq_alt); - - if (freq_alt < 30.517578125) { - freq_alt = 30.52; - } - - if (GET_CHANNEL_2_FREQ != (uint16_t)freq_alt) { - UPDATE_CHANNEL_2_FREQ(freq_alt); - } else { - RESTART_CHANNEL_2(); - } - // note_timbre; - } - - if (polyphony_rate > 0) { - if (voices > 1) { - voice_place %= voices; - if (place++ > (frequencies[voice_place] / polyphony_rate)) { - voice_place = (voice_place + 1) % voices; - place = 0.0; - } - } - -#ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq = vibrato(frequencies[voice_place]); - } else { - freq = frequencies[voice_place]; - } -#else - freq = frequencies[voice_place]; -#endif - } else { - if (glissando) { - if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440 / frequencies[voices - 1] / 12 / 2)) { - frequency = frequency * pow(2, 440 / frequency / 12 / 2); - } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440 / frequencies[voices - 1] / 12 / 2)) { - frequency = frequency * pow(2, -440 / frequency / 12 / 2); - } else { - frequency = frequencies[voices - 1]; - } - } else { - frequency = frequencies[voices - 1]; - } - -#ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq = vibrato(frequency); - } else { - freq = frequency; - } -#else - freq = frequency; -#endif - } - - if (envelope_index < 65535) { - envelope_index++; - } - - freq = voice_envelope(freq); - - if (freq < 30.517578125) { - freq = 30.52; - } - - if (GET_CHANNEL_1_FREQ != (uint16_t)freq) { - UPDATE_CHANNEL_1_FREQ(freq); - } else { - RESTART_CHANNEL_1(); - } - // note_timbre; - } - } - - if (playing_notes) { - if (note_frequency > 0) { -#ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq = vibrato(note_frequency); - } else { - freq = note_frequency; - } -#else - freq = note_frequency; -#endif - - if (envelope_index < 65535) { - envelope_index++; - } - freq = voice_envelope(freq); - if (GET_CHANNEL_1_FREQ != (uint16_t)freq) { - UPDATE_CHANNEL_1_FREQ(freq); - UPDATE_CHANNEL_2_FREQ(freq); - } - // note_timbre; - } else { - // gptStopTimer(&GPTD6); - // gptStopTimer(&GPTD7); - } +void play_note(float freq, int vol) { - note_position++; - bool end_of_note = false; - if (GET_CHANNEL_1_FREQ > 0) { - if (!note_resting) - end_of_note = (note_position >= (note_length * 8 - 1)); - else - end_of_note = (note_position >= (note_length * 8)); - } else { - end_of_note = (note_position >= (note_length * 8)); - } + dprintf("audio play note freq=%d vol=%d", (int)freq, vol); - if (end_of_note) { - current_note++; - if (current_note >= notes_count) { - if (notes_repeat) { - current_note = 0; - } else { - STOP_CHANNEL_1(); - STOP_CHANNEL_2(); - // gptStopTimer(&GPTD8); - playing_notes = false; - return; - } - } - if (!note_resting) { - note_resting = true; - current_note--; - if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) { - note_frequency = 0; - note_length = 1; - } else { - note_frequency = (*notes_pointer)[current_note][0]; - note_length = 1; - } - } else { - note_resting = false; - envelope_index = 0; - note_frequency = (*notes_pointer)[current_note][0]; - note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); - } - - note_position = 0; - } - } + if (!audio_initialized) { + audio_init(); + } - if (!audio_config.enable) { - playing_notes = false; - playing_note = false; + if (audio_config.enable && dac_voices < 8) { + playing_note = true; + if (freq > 0) { + envelope_index = 0; + dac_frequencies[dac_voices] = freq; + dac_voices++; } + } } -void play_note(float freq, int vol) { - dprintf("audio play note freq=%d vol=%d", (int)freq, vol); +__attribute__ ((weak)) +void dac_setup_note(void) { + dac_if[dac_voices] = 0.0f; +} - if (!audio_initialized) { - audio_init(); - } +void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) { - if (audio_config.enable && voices < 8) { - // Cancel notes if notes are playing - if (playing_notes) { - stop_all_notes(); - } + if (!audio_initialized) { + audio_init(); + } - playing_note = true; + if (audio_config.enable) { - envelope_index = 0; + playing_notes = true; - if (freq > 0) { - frequencies[voices] = freq; - volumes[voices] = vol; - voices++; - } + notes_pointer = np; + notes_count = n_count; + notes_repeat = n_repeat; - gptStart(&GPTD8, &gpt8cfg1); - gptStartContinuous(&GPTD8, 2U); - RESTART_CHANNEL_1(); - RESTART_CHANNEL_2(); - } -} + current_note = 0; -void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) { - if (!audio_initialized) { - audio_init(); - } + note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); + note_position = 0; - if (audio_config.enable) { - // Cancel note if a note is playing - if (playing_note) { - stop_all_notes(); - } - - playing_notes = true; - - notes_pointer = np; - notes_count = n_count; - notes_repeat = n_repeat; - - place = 0; - current_note = 0; + play_note((*notes_pointer)[current_note][0], 15); - note_frequency = (*notes_pointer)[current_note][0]; - note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); - note_position = 0; + } +} - gptStart(&GPTD8, &gpt8cfg1); - gptStartContinuous(&GPTD8, 2U); - RESTART_CHANNEL_1(); - RESTART_CHANNEL_2(); - } +bool is_playing_note(void) { + return playing_note; } -bool is_playing_notes(void) { return playing_notes; } +bool is_playing_notes(void) { + return playing_notes; +} -bool is_audio_on(void) { return (audio_config.enable != 0); } +bool is_audio_on(void) { + return (audio_config.enable != 0); +} void audio_toggle(void) { if (audio_config.enable) { @@ -657,65 +442,101 @@ void audio_toggle(void) { } void audio_on(void) { - audio_config.enable = 1; - eeconfig_update_audio(audio_config.raw); - audio_on_user(); + audio_config.enable = 1; + eeconfig_update_audio(audio_config.raw); + audio_on_user(); } void audio_off(void) { - stop_all_notes(); - audio_config.enable = 0; - eeconfig_update_audio(audio_config.raw); + stop_all_notes(); + audio_config.enable = 0; + eeconfig_update_audio(audio_config.raw); } #ifdef VIBRATO_ENABLE // Vibrato rate functions -void set_vibrato_rate(float rate) { vibrato_rate = rate; } +void set_vibrato_rate(float rate) { + vibrato_rate = rate; +} -void increase_vibrato_rate(float change) { vibrato_rate *= change; } +void increase_vibrato_rate(float change) { + vibrato_rate *= change; +} -void decrease_vibrato_rate(float change) { vibrato_rate /= change; } +void decrease_vibrato_rate(float change) { + vibrato_rate /= change; +} -# ifdef VIBRATO_STRENGTH_ENABLE +#ifdef VIBRATO_STRENGTH_ENABLE -void set_vibrato_strength(float strength) { vibrato_strength = strength; } +void set_vibrato_strength(float strength) { + vibrato_strength = strength; +} -void increase_vibrato_strength(float change) { vibrato_strength *= change; } +void increase_vibrato_strength(float change) { + vibrato_strength *= change; +} -void decrease_vibrato_strength(float change) { vibrato_strength /= change; } +void decrease_vibrato_strength(float change) { + vibrato_strength /= change; +} -# endif /* VIBRATO_STRENGTH_ENABLE */ +#endif /* VIBRATO_STRENGTH_ENABLE */ #endif /* VIBRATO_ENABLE */ // Polyphony functions -void set_polyphony_rate(float rate) { polyphony_rate = rate; } +void set_polyphony_rate(float rate) { + polyphony_rate = rate; +} -void enable_polyphony() { polyphony_rate = 5; } +void enable_polyphony() { + polyphony_rate = 5; +} -void disable_polyphony() { polyphony_rate = 0; } +void disable_polyphony() { + polyphony_rate = 0; +} -void increase_polyphony_rate(float change) { polyphony_rate *= change; } +void increase_polyphony_rate(float change) { + polyphony_rate *= change; +} -void decrease_polyphony_rate(float change) { polyphony_rate /= change; } +void decrease_polyphony_rate(float change) { + polyphony_rate /= change; +} // Timbre function -void set_timbre(float timbre) { note_timbre = timbre; } +void set_timbre(float timbre) { + note_timbre = timbre; +} // Tempo functions -void set_tempo(uint8_t tempo) { note_tempo = tempo; } +void set_tempo(uint8_t tempo) { + note_tempo = tempo; +} -void decrease_tempo(uint8_t tempo_change) { note_tempo += tempo_change; } +void decrease_tempo(uint8_t tempo_change) { + note_tempo += tempo_change; +} void increase_tempo(uint8_t tempo_change) { - if (note_tempo - tempo_change < 10) { - note_tempo = 10; - } else { - note_tempo -= tempo_change; - } + if (note_tempo - tempo_change < 10) { + note_tempo = 10; + } else { + note_tempo -= tempo_change; + } +} + +uint8_t dac_number_of_voices(void) { + return dac_voices; +} + +float dac_get_frequency(uint8_t index) { + return dac_frequencies[index]; } From a483d40d041aa5515ed33bb04ba61b25d776a18c Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 16 Sep 2019 08:11:25 +0200 Subject: [PATCH 002/153] Redo Arm DAC implementation for additive, wavetable synthesis, sample playback changes by Jack Humbert on an implementation for DAC audio on arm/chibios platforms this commit splits off the plank example keymap from commit f52faeb5d (origin/arm-dac-work) add sample and wavetable examples, parsers for both --- .../planck/keymaps/synth_sample/config.h | 39 + .../planck/keymaps/synth_sample/keymap.c | 298 ++ .../planck/keymaps/synth_sample/rules.mk | 0 .../planck/keymaps/synth_sample/sample.h | 3780 +++++++++++++++++ .../planck/keymaps/synth_wavetable/config.h | 39 + .../planck/keymaps/synth_wavetable/keymap.c | 326 ++ .../planck/keymaps/synth_wavetable/rules.mk | 0 .../keymaps/synth_wavetable/wavetable.h | 2180 ++++++++++ util/sample_parser.py | 39 + util/wavetable_parser.py | 40 + 10 files changed, 6741 insertions(+) create mode 100644 keyboards/planck/keymaps/synth_sample/config.h create mode 100644 keyboards/planck/keymaps/synth_sample/keymap.c create mode 100644 keyboards/planck/keymaps/synth_sample/rules.mk create mode 100644 keyboards/planck/keymaps/synth_sample/sample.h create mode 100644 keyboards/planck/keymaps/synth_wavetable/config.h create mode 100644 keyboards/planck/keymaps/synth_wavetable/keymap.c create mode 100644 keyboards/planck/keymaps/synth_wavetable/rules.mk create mode 100644 keyboards/planck/keymaps/synth_wavetable/wavetable.h create mode 100644 util/sample_parser.py create mode 100644 util/wavetable_parser.py diff --git a/keyboards/planck/keymaps/synth_sample/config.h b/keyboards/planck/keymaps/synth_sample/config.h new file mode 100644 index 000000000000..6fa31cc8a76f --- /dev/null +++ b/keyboards/planck/keymaps/synth_sample/config.h @@ -0,0 +1,39 @@ +#pragma once + +#ifdef AUDIO_ENABLE + #define STARTUP_SONG SONG(PLANCK_SOUND) + // #define STARTUP_SONG SONG(NO_SOUND) + + #define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \ + SONG(COLEMAK_SOUND), \ + SONG(DVORAK_SOUND) \ + } +#endif + +/* + * MIDI options + */ + +/* Prevent use of disabled MIDI features in the keymap */ +//#define MIDI_ENABLE_STRICT 1 + +/* enable basic MIDI features: + - MIDI notes can be sent when in Music mode is on +*/ + +#define MIDI_BASIC + +/* enable advanced MIDI features: + - MIDI notes can be added to the keymap + - Octave shift and transpose + - Virtual sustain, portamento, and modulation wheel + - etc. +*/ +//#define MIDI_ADVANCED + +/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */ +//#define MIDI_TONE_KEYCODE_OCTAVES 2 + +// Most tactile encoders have detents every 4 stages +#define ENCODER_RESOLUTION 4 + diff --git a/keyboards/planck/keymaps/synth_sample/keymap.c b/keyboards/planck/keymaps/synth_sample/keymap.c new file mode 100644 index 000000000000..36e88390aa91 --- /dev/null +++ b/keyboards/planck/keymaps/synth_sample/keymap.c @@ -0,0 +1,298 @@ +/* Copyright 2019 Jack Humbert + * + * 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 2 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 . + */ + +#include QMK_KEYBOARD_H + +extern keymap_config_t keymap_config; + +enum planck_layers { + _QWERTY, + _COLEMAK, + _DVORAK, + _LOWER, + _RAISE, + _PLOVER, + _ADJUST +}; + +enum planck_keycodes { + QWERTY = SAFE_RANGE, + COLEMAK, + DVORAK, + PLOVER, + BACKLIT, + EXT_PLV +}; + +#define LOWER MO(_LOWER) +#define RAISE MO(_RAISE) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +/* Qwerty + * ,-----------------------------------------------------------------------------------. + * | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Esc | A | S | D | F | G | H | J | K | L | ; | " | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Shift| Z | X | C | V | B | N | M | , | . | / |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_QWERTY] = LAYOUT_planck_grid( + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, + KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , + BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT +), + +/* Colemak + * ,-----------------------------------------------------------------------------------. + * | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Esc | A | R | S | T | D | H | N | E | I | O | " | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Shift| Z | X | C | V | B | K | M | , | . | / |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_COLEMAK] = LAYOUT_planck_grid( + KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, + KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , + BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT +), + +/* Dvorak + * ,-----------------------------------------------------------------------------------. + * | Tab | " | , | . | P | Y | F | G | C | R | L | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Esc | A | O | E | U | I | D | H | T | N | S | / | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_DVORAK] = LAYOUT_planck_grid( + KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC, + KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH, + KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT , + BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT +), + +/* Lower + * ,-----------------------------------------------------------------------------------. + * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Del | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | Home | End | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | Next | Vol- | Vol+ | Play | + * `-----------------------------------------------------------------------------------' + */ +[_LOWER] = LAYOUT_planck_grid( + KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, + KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, + _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, S(KC_NUHS), S(KC_NUBS), KC_HOME, KC_END, _______, + _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY +), + +/* Raise + * ,-----------------------------------------------------------------------------------. + * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Del | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / |Pg Up |Pg Dn | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | Next | Vol- | Vol+ | Play | + * `-----------------------------------------------------------------------------------' + */ +[_RAISE] = LAYOUT_planck_grid( + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, + KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, + _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, KC_PGUP, KC_PGDN, _______, + _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY +), + +/* Plover layer (http://opensteno.org) + * ,-----------------------------------------------------------------------------------. + * | # | # | # | # | # | # | # | # | # | # | # | # | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | | S | T | P | H | * | * | F | P | L | T | D | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | S | K | W | R | * | * | R | B | G | S | Z | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Exit | | | A | O | | E | U | | | | + * `-----------------------------------------------------------------------------------' + */ +[_PLOVER] = LAYOUT_planck_grid( + KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1 , + XXXXXXX, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, + XXXXXXX, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, + EXT_PLV, XXXXXXX, XXXXXXX, KC_C, KC_V, XXXXXXX, XXXXXXX, KC_N, KC_M, XXXXXXX, XXXXXXX, XXXXXXX +), + +/* Adjust (Lower + Raise) + * ,-----------------------------------------------------------------------------------. + * | | Reset| | | | | | | | | | Del | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak|Plover| | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof| | | | | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | | | | | + * `-----------------------------------------------------------------------------------' + */ +[_ADJUST] = LAYOUT_planck_grid( + _______, RESET, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL , + _______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______, + _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, TERM_ON, TERM_OFF, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ +) + +}; + +#ifdef AUDIO_ENABLE + float plover_song[][2] = SONG(PLOVER_SOUND); + float plover_gb_song[][2] = SONG(PLOVER_GOODBYE_SOUND); +#endif + +uint32_t layer_state_set_user(uint32_t state) { + return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); +} + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case QWERTY: + if (record->event.pressed) { + print("mode just switched to qwerty and this is a huge string\n"); + set_single_persistent_default_layer(_QWERTY); + } + return false; + break; + case COLEMAK: + if (record->event.pressed) { + set_single_persistent_default_layer(_COLEMAK); + } + return false; + break; + case DVORAK: + if (record->event.pressed) { + set_single_persistent_default_layer(_DVORAK); + } + return false; + break; + case BACKLIT: + if (record->event.pressed) { + register_code(KC_RSFT); + #ifdef BACKLIGHT_ENABLE + backlight_step(); + #endif + #ifdef KEYBOARD_planck_rev5 + PORTE &= ~(1<<6); + #endif + } else { + unregister_code(KC_RSFT); + #ifdef KEYBOARD_planck_rev5 + PORTE |= (1<<6); + #endif + } + return false; + break; + case PLOVER: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + stop_all_notes(); + PLAY_SONG(plover_song); + #endif + layer_off(_RAISE); + layer_off(_LOWER); + layer_off(_ADJUST); + layer_on(_PLOVER); + if (!eeconfig_is_enabled()) { + eeconfig_init(); + } + keymap_config.raw = eeconfig_read_keymap(); + keymap_config.nkro = 1; + eeconfig_update_keymap(keymap_config.raw); + } + return false; + break; + case EXT_PLV: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + PLAY_SONG(plover_gb_song); + #endif + layer_off(_PLOVER); + } + return false; + break; + } + return true; +} + +void encoder_update(bool clockwise) { + if (clockwise) { + #ifdef MOUSEKEY_ENABLE + register_code(KC_MS_WH_DOWN); + unregister_code(KC_MS_WH_DOWN); + #else + register_code(KC_PGDN); + unregister_code(KC_PGDN); + #endif + } else { + #ifdef MOUSEKEY_ENABLE + register_code(KC_MS_WH_UP); + unregister_code(KC_MS_WH_UP); + #else + register_code(KC_PGUP); + unregister_code(KC_PGUP); + #endif + } +} + +void matrix_scan_user(void) { + +} + +bool music_mask_user(uint16_t keycode) { + switch (keycode) { + case RAISE: + case LOWER: + return false; + default: + return true; + } +} + +#include "sample.h" + +uint32_t dac_sample_custom_counter = 0; + +uint16_t dac_value_generate(void) { + if (is_playing_note()) { + uint16_t sample = dac_sample_custom[dac_sample_custom_counter]; + dac_sample_custom_counter = (dac_sample_custom_counter + 1) % DAC_SAMPLE_CUSTOM_LENGTH; + return sample; + } else { + return DAC_OFF_VALUE; + } +} diff --git a/keyboards/planck/keymaps/synth_sample/rules.mk b/keyboards/planck/keymaps/synth_sample/rules.mk new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/keyboards/planck/keymaps/synth_sample/sample.h b/keyboards/planck/keymaps/synth_sample/sample.h new file mode 100644 index 000000000000..5ba1be1b9738 --- /dev/null +++ b/keyboards/planck/keymaps/synth_sample/sample.h @@ -0,0 +1,3780 @@ +#define DAC_SAMPLE_CUSTOM_LENGTH 30208 + +static const dacsample_t dac_sample_custom[30208] = { + 2041, 2039, 2039, 2037, 2035, 2037, 2037, 2037, + 2038, 2037, 2037, 2040, 2039, 2038, 2036, 2035, + 2036, 2036, 2036, 2034, 2034, 2034, 2032, 2032, + 2033, 2034, 2032, 2030, 2029, 2031, 2030, 2029, + 2029, 2030, 2029, 2030, 2030, 2031, 2028, 2028, + 2028, 2027, 2025, 2026, 2027, 2026, 2025, 2026, + 2026, 2025, 2023, 2022, 2023, 2021, 2021, 2023, + 2020, 2023, 2023, 2022, 2022, 2021, 2021, 2020, + 2022, 2020, 2017, 2016, 2015, 2018, 2017, 2015, + 2013, 2012, 2015, 2013, 2011, 2012, 2011, 2011, + 2010, 2008, 2008, 2010, 2010, 2006, 2006, 2006, + 2004, 2005, 2006, 2006, 2005, 2002, 2005, 2003, + 2003, 2004, 2002, 2001, 2003, 2003, 2002, 2003, + 2003, 2000, 2000, 2000, 1998, 1997, 1998, 1999, + 1997, 1995, 1995, 1996, 1996, 1992, 1995, 1995, + 1994, 1994, 1995, 1997, 1996, 1996, 1997, 1997, + 1997, 1996, 1996, 1995, 1997, 1997, 1996, 1998, + 1995, 1996, 1996, 1996, 1996, 1994, 1990, 1991, + 1992, 1991, 1994, 1992, 1993, 1995, 1994, 1995, + 1992, 1991, 1991, 1992, 1993, 1992, 1992, 1993, + 1993, 1992, 1990, 1989, 1991, 1992, 1991, 1991, + 1990, 1990, 1992, 1992, 1991, 1992, 1992, 1994, + 1992, 1992, 1992, 1993, 1993, 1994, 1995, 1993, + 1991, 1992, 1990, 1989, 1990, 1988, 1988, 1987, + 1989, 1989, 1985, 1986, 1987, 1985, 1986, 1986, + 1987, 1988, 1988, 1989, 1989, 1988, 1988, 1990, + 1991, 1991, 1990, 1991, 1992, 1994, 1994, 1995, + 1994, 1995, 1997, 1995, 1995, 1995, 1997, 1997, + 1997, 1996, 1999, 2000, 1997, 1998, 1999, 2002, + 2001, 2001, 2001, 2002, 2000, 1998, 2000, 2004, + 2002, 2001, 2003, 2005, 2004, 2004, 2002, 2004, + 2004, 2001, 2000, 2001, 2003, 2005, 2005, 2005, + 2005, 2006, 2010, 2010, 2009, 2007, 2006, 2008, + 2006, 2007, 2007, 2005, 2005, 2005, 2007, 2005, + 2006, 2007, 2009, 2010, 2008, 2007, 2006, 2006, + 2005, 2005, 2005, 2004, 2005, 2004, 2004, 2003, + 2007, 2006, 2006, 2004, 2005, 2006, 2007, 2007, + 2006, 2010, 2007, 2008, 2009, 2012, 2012, 2010, + 2011, 2010, 2014, 2012, 2013, 2013, 2014, 2014, + 2013, 2012, 2012, 2012, 2010, 2013, 2012, 2010, + 2011, 2011, 2012, 2012, 2013, 2013, 2015, 2016, + 2015, 2015, 2015, 2015, 2015, 2014, 2012, 2014, + 2016, 2017, 2016, 2015, 2018, 2019, 2017, 2017, + 2017, 2017, 2016, 2016, 2017, 2017, 2018, 2021, + 2020, 2019, 2019, 2022, 2022, 2024, 2024, 2023, + 2023, 2023, 2024, 2025, 2026, 2025, 2024, 2025, + 2025, 2026, 2026, 2023, 2023, 2023, 2023, 2023, + 2023, 2024, 2024, 2025, 2024, 2022, 2022, 2021, + 2021, 2022, 2022, 2024, 2023, 2023, 2023, 2021, + 2023, 2023, 2024, 2024, 2025, 2024, 2026, 2027, + 2025, 2026, 2028, 2026, 2027, 2027, 2025, 2024, + 2027, 2028, 2027, 2028, 2027, 2027, 2028, 2028, + 2030, 2029, 2032, 2031, 2030, 2029, 2028, 2030, + 2027, 2028, 2028, 2028, 2026, 2027, 2028, 2027, + 2029, 2032, 2030, 2030, 2032, 2033, 2030, 2030, + 2032, 2030, 2030, 2030, 2032, 2032, 2033, 2031, + 2034, 2032, 2029, 2028, 2028, 2030, 2028, 2029, + 2030, 2028, 2029, 2029, 2029, 2030, 2032, 2033, + 2031, 2036, 2034, 2032, 2032, 2031, 2032, 2031, + 2032, 2033, 2035, 2033, 2032, 2034, 2035, 2036, + 2037, 2038, 2039, 2038, 2038, 2038, 2040, 2040, + 2041, 2041, 2041, 2043, 2041, 2041, 2043, 2043, + 2041, 2040, 2042, 2042, 2042, 2044, 2044, 2041, + 2042, 2043, 2042, 2044, 2043, 2044, 2044, 2045, + 2045, 2044, 2045, 2044, 2045, 2043, 2042, 2043, + 2043, 2043, 2043, 2044, 2044, 2044, 2045, 2044, + 2044, 2043, 2042, 2045, 2046, 2045, 2046, 2048, + 2048, 2046, 2046, 2046, 2049, 2048, 2050, 2049, + 2049, 2050, 2053, 2051, 2049, 2050, 2047, 2050, + 2048, 2052, 2050, 2051, 2053, 2051, 2051, 2048, + 2051, 2050, 2049, 2051, 2052, 2051, 2050, 2051, + 2050, 2050, 2051, 2050, 2048, 2049, 2049, 2048, + 2050, 2050, 2050, 2049, 2048, 2048, 2048, 2048, + 2049, 2049, 2049, 2050, 2051, 2050, 2053, 2051, + 2051, 2053, 2052, 2052, 2052, 2051, 2053, 2055, + 2056, 2056, 2055, 2056, 2056, 2056, 2059, 2058, + 2055, 2057, 2059, 2057, 2056, 2056, 2056, 2057, + 2059, 2060, 2060, 2059, 2059, 2059, 2059, 2061, + 2059, 2059, 2060, 2061, 2059, 2057, 2058, 2060, + 2060, 2061, 2060, 2061, 2062, 2063, 2062, 2060, + 2062, 2060, 2061, 2061, 2060, 2060, 2061, 2062, + 2062, 2062, 2061, 2059, 2062, 2063, 2062, 2063, + 2063, 2063, 2063, 2063, 2063, 2063, 2065, 2063, + 2063, 2065, 2065, 2066, 2065, 2067, 2067, 2066, + 2065, 2065, 2065, 2066, 2066, 2063, 2064, 2062, + 2063, 2062, 2062, 2061, 2062, 2063, 2062, 2061, + 2061, 2062, 2058, 2059, 2061, 2062, 2062, 2062, + 2062, 2064, 2063, 2063, 2062, 2061, 2061, 2063, + 2060, 2059, 2059, 2058, 2059, 2059, 2059, 2062, + 2063, 2063, 2062, 2061, 2061, 2061, 2061, 2062, + 2060, 2058, 2059, 2060, 2060, 2059, 2059, 2057, + 2059, 2059, 2056, 2057, 2056, 2057, 2056, 2056, + 2056, 2057, 2057, 2057, 2055, 2055, 2055, 2053, + 2054, 2054, 2054, 2054, 2052, 2051, 2054, 2055, + 2055, 2053, 2055, 2054, 2055, 2055, 2053, 2053, + 2054, 2052, 2051, 2053, 2051, 2052, 2052, 2054, + 2054, 2053, 2051, 2051, 2053, 2052, 2051, 2050, + 2049, 2049, 2048, 2049, 2049, 2047, 2046, 2047, + 2047, 2047, 2046, 2048, 2046, 2046, 2046, 2044, + 2043, 2044, 2045, 2046, 2043, 2044, 2043, 2046, + 2044, 2044, 2043, 2043, 2042, 2039, 2037, 2039, + 2038, 2039, 2039, 2038, 2038, 2038, 2039, 2036, + 2034, 2034, 2033, 2035, 2034, 2032, 2031, 2034, + 2035, 2033, 2034, 2032, 2032, 2033, 2031, 2031, + 2031, 2032, 2032, 2032, 2030, 2030, 2029, 2029, + 2029, 2025, 2024, 2024, 2024, 2025, 2025, 2028, + 2028, 2025, 2024, 2026, 2025, 2022, 2023, 2021, + 2018, 2019, 2020, 2020, 2020, 2021, 2021, 2018, + 2017, 2019, 2017, 2016, 2018, 2019, 2018, 2016, + 2017, 2016, 2014, 2017, 2017, 2017, 2016, 2014, + 2012, 2011, 2011, 2011, 2011, 2012, 2011, 2009, + 2011, 2011, 2011, 2012, 2009, 2009, 2010, 2011, + 2011, 2011, 2008, 2008, 2010, 2009, 2009, 2008, + 2007, 2010, 2009, 2011, 2012, 2011, 2012, 2012, + 2010, 2010, 2011, 2009, 2010, 2010, 2010, 2012, + 2011, 2011, 2011, 2010, 2010, 2009, 2012, 2008, + 2009, 2010, 2010, 2008, 2008, 2009, 2007, 2007, + 2007, 2007, 2009, 2008, 2006, 2006, 2010, 2011, + 2011, 2009, 2010, 2007, 2008, 2007, 2009, 2011, + 2009, 2009, 2008, 2009, 2009, 2009, 2007, 2010, + 2008, 2009, 2013, 2011, 2011, 2009, 2010, 2009, + 2007, 2007, 2008, 2008, 2009, 2010, 2008, 2009, + 2009, 2010, 2010, 2010, 2009, 2007, 2008, 2007, + 2011, 2012, 2010, 2009, 2009, 2010, 2008, 2010, + 2011, 2010, 2010, 2012, 2011, 2010, 2013, 2014, + 2013, 2014, 2016, 2015, 2016, 2017, 2016, 2020, + 2022, 2022, 2020, 2022, 2023, 2024, 2023, 2022, + 2021, 2020, 2023, 2022, 2023, 2022, 2023, 2024, + 2022, 2021, 2021, 2021, 2021, 2021, 2021, 2023, + 2024, 2024, 2022, 2022, 2023, 2026, 2027, 2024, + 2025, 2029, 2027, 2029, 2030, 2029, 2029, 2028, + 2029, 2029, 2028, 2031, 2031, 2029, 2027, 2026, + 2026, 2028, 2025, 2025, 2021, 2022, 2025, 2025, + 2028, 2026, 2025, 2025, 2023, 2024, 2024, 2027, + 2027, 2029, 2028, 2025, 2027, 2029, 2031, 2028, + 2026, 2028, 2028, 2028, 2028, 2030, 2026, 2028, + 2029, 2029, 2030, 2030, 2030, 2032, 2032, 2032, + 2031, 2030, 2031, 2031, 2033, 2035, 2033, 2032, + 2031, 2032, 2032, 2032, 2032, 2031, 2030, 2030, + 2028, 2030, 2029, 2027, 2029, 2028, 2027, 2029, + 2032, 2031, 2031, 2032, 2030, 2029, 2032, 2033, + 2032, 2027, 2026, 2029, 2030, 2031, 2033, 2033, + 2033, 2035, 2035, 2034, 2035, 2034, 2035, 2036, + 2037, 2035, 2035, 2034, 2034, 2034, 2037, 2036, + 2035, 2033, 2033, 2034, 2033, 2035, 2035, 2036, + 2038, 2037, 2035, 2038, 2038, 2033, 2033, 2035, + 2036, 2036, 2038, 2037, 2037, 2038, 2038, 2039, + 2039, 2038, 2038, 2040, 2041, 2040, 2042, 2042, + 2042, 2043, 2042, 2040, 2041, 2040, 2041, 2043, + 2040, 2042, 2042, 2041, 2044, 2045, 2043, 2043, + 2045, 2045, 2047, 2045, 2044, 2046, 2045, 2048, + 2049, 2050, 2050, 2050, 2050, 2048, 2050, 2051, + 2050, 2050, 2052, 2053, 2053, 2055, 2054, 2053, + 2055, 2053, 2053, 2052, 2050, 2052, 2052, 2053, + 2053, 2054, 2053, 2055, 2056, 2055, 2053, 2053, + 2054, 2054, 2056, 2054, 2054, 2056, 2054, 2053, + 2054, 2057, 2055, 2054, 2056, 2057, 2056, 2058, + 2057, 2058, 2059, 2057, 2058, 2057, 2057, 2055, + 2056, 2056, 2055, 2059, 2057, 2055, 2052, 2050, + 2053, 2054, 2052, 2053, 2055, 2056, 2055, 2054, + 2055, 2055, 2053, 2053, 2053, 2054, 2055, 2055, + 2055, 2052, 2054, 2056, 2057, 2059, 2058, 2055, + 2056, 2057, 2056, 2056, 2056, 2057, 2057, 2056, + 2057, 2056, 2057, 2055, 2056, 2057, 2057, 2058, + 2057, 2055, 2055, 2056, 2057, 2056, 2056, 2056, + 2057, 2057, 2058, 2058, 2058, 2059, 2057, 2056, + 2057, 2055, 2053, 2055, 2056, 2056, 2056, 2057, + 2059, 2058, 2058, 2058, 2057, 2060, 2058, 2058, + 2058, 2059, 2059, 2060, 2061, 2060, 2058, 2059, + 2060, 2060, 2058, 2058, 2059, 2058, 2056, 2058, + 2059, 2059, 2058, 2058, 2057, 2059, 2060, 2058, + 2058, 2058, 2057, 2059, 2058, 2056, 2061, 2061, + 2060, 2059, 2061, 2062, 2062, 2062, 2059, 2061, + 2059, 2058, 2060, 2061, 2058, 2058, 2058, 2059, + 2059, 2057, 2060, 2058, 2058, 2057, 2055, 2054, + 2056, 2056, 2059, 2056, 2056, 2059, 2059, 2057, + 2055, 2052, 2051, 2052, 2052, 2052, 2053, 2051, + 2052, 2052, 2051, 2050, 2048, 2049, 2050, 2052, + 2050, 2052, 2051, 2052, 2053, 2052, 2050, 2050, + 2052, 2051, 2051, 2053, 2052, 2051, 2053, 2055, + 2055, 2054, 2053, 2054, 2051, 2052, 2052, 2053, + 2053, 2052, 2052, 2053, 2053, 2049, 2048, 2051, + 2048, 2048, 2049, 2050, 2051, 2049, 2047, 2047, + 2049, 2050, 2051, 2049, 2048, 2045, 2045, 2046, + 2046, 2046, 2045, 2046, 2045, 2043, 2044, 2043, + 2043, 2043, 2044, 2042, 2042, 2042, 2044, 2046, + 2044, 2039, 2040, 2039, 2038, 2040, 2040, 2040, + 2040, 2039, 2039, 2039, 2037, 2036, 2036, 2037, + 2037, 2034, 2036, 2035, 2034, 2033, 2033, 2031, + 2029, 2027, 2029, 2028, 2028, 2029, 2030, 2029, + 2027, 2027, 2026, 2028, 2028, 2026, 2026, 2024, + 2025, 2028, 2027, 2025, 2026, 2027, 2023, 2018, + 2017, 2021, 2020, 2019, 2018, 2016, 2014, 2013, + 2011, 2010, 2007, 2010, 2009, 2006, 2008, 2008, + 2004, 2005, 2006, 2009, 2009, 2010, 2009, 2007, + 2007, 2008, 2007, 2006, 2008, 2009, 2008, 2008, + 2006, 2007, 2009, 2008, 2007, 2007, 2008, 2007, + 2007, 2009, 2008, 2007, 2008, 2009, 2007, 2006, + 2005, 2004, 2007, 2006, 2006, 2004, 2004, 2003, + 2001, 2001, 2002, 2004, 2003, 2003, 2001, 2001, + 2002, 1998, 2000, 1999, 2000, 2001, 2001, 1999, + 2000, 1999, 1998, 1998, 2001, 2000, 1998, 1997, + 1996, 1995, 1994, 1994, 1995, 1995, 1993, 1996, + 1996, 1994, 1992, 1992, 1993, 1991, 1990, 1989, + 1991, 1987, 1988, 1989, 1989, 1989, 1992, 1990, + 1992, 1993, 1992, 1993, 1992, 1990, 1989, 1991, + 1990, 1990, 1988, 1989, 1991, 1991, 1992, 1991, + 1994, 1993, 1991, 1991, 1991, 1991, 1989, 1990, + 1990, 1991, 1989, 1991, 1990, 1991, 1989, 1988, + 1988, 1987, 1987, 1990, 1990, 1988, 1988, 1988, + 1988, 1987, 1987, 1984, 1986, 1985, 1986, 1988, + 1988, 1987, 1987, 1988, 1987, 1988, 1989, 1988, + 1989, 1991, 1990, 1988, 1990, 1989, 1987, 1987, + 1987, 1985, 1986, 1987, 1988, 1985, 1987, 1985, + 1986, 1988, 1988, 1988, 1988, 1987, 1988, 1988, + 1988, 1988, 1989, 1987, 1988, 1989, 1989, 1991, + 1990, 1992, 1990, 1990, 1991, 1991, 1993, 1994, + 1994, 1996, 1993, 1995, 1995, 1998, 1997, 1996, + 1997, 1997, 1998, 1998, 1997, 1999, 1999, 2000, + 2001, 2003, 2004, 2004, 2006, 2005, 2003, 2008, + 2006, 2005, 2005, 2005, 2008, 2009, 2011, 2011, + 2009, 2008, 2010, 2010, 2012, 2013, 2014, 2015, + 2015, 2014, 2015, 2015, 2013, 2013, 2013, 2013, + 2014, 2015, 2018, 2018, 2016, 2016, 2018, 2019, + 2017, 2015, 2017, 2016, 2016, 2016, 2015, 2017, + 2018, 2018, 2017, 2016, 2018, 2017, 2019, 2018, + 2016, 2015, 2014, 2014, 2016, 2018, 2018, 2015, + 2016, 2016, 2017, 2017, 2016, 2015, 2015, 2015, + 2015, 2018, 2016, 2017, 2016, 2014, 2016, 2017, + 2020, 2019, 2018, 2018, 2016, 2017, 2019, 2017, + 2017, 2013, 2015, 2016, 2015, 2015, 2016, 2016, + 2017, 2015, 2013, 2016, 2016, 2017, 2018, 2017, + 2016, 2017, 2016, 2016, 2017, 2019, 2019, 2021, + 2020, 2018, 2019, 2019, 2019, 2018, 2018, 2018, + 2020, 2021, 2022, 2023, 2019, 2018, 2022, 2022, + 2022, 2022, 2023, 2024, 2021, 2022, 2023, 2024, + 2024, 2024, 2025, 2027, 2028, 2029, 2030, 2028, + 2029, 2027, 2028, 2026, 2029, 2028, 2029, 2030, + 2029, 2031, 2029, 2030, 2029, 2028, 2028, 2030, + 2029, 2029, 2031, 2029, 2029, 2030, 2029, 2030, + 2030, 2029, 2027, 2026, 2025, 2024, 2024, 2023, + 2024, 2024, 2024, 2023, 2024, 2024, 2025, 2029, + 2027, 2025, 2027, 2029, 2029, 2033, 2034, 2035, + 2034, 2036, 2038, 2035, 2035, 2036, 2037, 2038, + 2036, 2038, 2038, 2037, 2038, 2039, 2039, 2033, + 2031, 2031, 2030, 2030, 2029, 2031, 2031, 2031, + 2031, 2032, 2034, 2034, 2037, 2038, 2038, 2039, + 2038, 2037, 2040, 2039, 2041, 2040, 2039, 2039, + 2038, 2041, 2038, 2035, 2037, 2037, 2037, 2035, + 2033, 2036, 2037, 2037, 2037, 2036, 2036, 2037, + 2035, 2036, 2038, 2039, 2040, 2039, 2039, 2038, + 2039, 2041, 2042, 2042, 2044, 2042, 2042, 2041, + 2041, 2040, 2041, 2041, 2040, 2041, 2041, 2042, + 2042, 2039, 2041, 2040, 2040, 2038, 2030, 2025, + 2024, 2015, 1982, 1933, 1910, 1911, 1896, 1878, + 1888, 1889, 1882, 1894, 1915, 1938, 1950, 1959, + 1977, 1987, 1989, 2008, 2032, 2054, 2074, 2093, + 2112, 2129, 2145, 2158, 2166, 2164, 2146, 2135, + 2129, 2105, 2079, 2064, 2040, 2017, 1999, 1987, + 1980, 1972, 1963, 1962, 1963, 1965, 1968, 1974, + 1982, 1991, 2001, 2014, 2031, 2043, 2058, 2074, + 2089, 2102, 2120, 2136, 2134, 2127, 2123, 2121, + 2116, 2102, 2092, 2087, 2073, 2048, 2032, 2017, + 1998, 1986, 1973, 1960, 1956, 1949, 1945, 1951, + 1957, 1960, 1964, 1976, 1985, 1994, 2014, 2031, + 2039, 2059, 2079, 2089, 2104, 2113, 2117, 2118, + 2114, 2115, 2117, 2112, 2108, 2106, 2085, 2057, + 2049, 2039, 2026, 2019, 2006, 1988, 1975, 1961, + 1958, 1961, 1957, 1956, 1962, 1965, 1966, 1975, + 1988, 1997, 2008, 2012, 2018, 2029, 2036, 2047, + 2059, 2063, 2061, 2057, 2059, 2065, 2062, 2053, + 2048, 2042, 2029, 2024, 2023, 2023, 2023, 2020, + 2015, 2015, 2020, 2021, 2028, 2040, 2042, 2043, + 2049, 2053, 2053, 2058, 2066, 2068, 2061, 2071, + 2089, 2081, 2072, 2088, 2089, 2074, 2061, 2052, + 2049, 2041, 2027, 2014, 2011, 2007, 2010, 2025, + 2026, 2000, 1982, 1984, 1991, 1993, 1992, 1998, + 1997, 2001, 2015, 2038, 2052, 2052, 2057, 2068, + 2070, 2067, 2071, 2084, 2092, 2087, 2079, 2086, + 2089, 2076, 2091, 2106, 2076, 2063, 2079, 2070, + 2058, 2064, 2060, 2040, 2022, 2035, 2043, 2023, + 2024, 2042, 2037, 2022, 2026, 2044, 2030, 2014, + 2025, 2029, 2023, 2034, 2043, 2048, 2051, 2031, + 2030, 2043, 2037, 2039, 2046, 2041, 2033, 2026, + 2038, 2050, 2044, 2050, 2056, 2047, 2041, 2035, + 2036, 2044, 2035, 2028, 2033, 2028, 2029, 2031, + 2038, 2048, 2027, 2017, 2036, 2036, 2033, 2036, + 2039, 2039, 2031, 2034, 2049, 2050, 2045, 2033, + 2032, 2037, 2022, 2021, 2036, 2032, 2031, 2028, + 2032, 2038, 2028, 2028, 2036, 2025, 2017, 2013, + 2017, 2021, 2014, 2018, 2027, 2020, 2021, 2038, + 2042, 2032, 2021, 2026, 2036, 2026, 2014, 2021, + 2023, 2009, 2001, 2003, 2002, 1998, 1986, 1985, + 1992, 1981, 1979, 2006, 2013, 2003, 2013, 2026, + 2027, 2029, 2047, 2064, 2055, 2040, 2052, 2069, + 2069, 2063, 2053, 2052, 2046, 2028, 2007, 1999, + 1993, 1985, 1981, 1977, 1976, 1971, 1976, 1986, + 1977, 1973, 1984, 1996, 2006, 2018, 2029, 2038, + 2045, 2052, 2073, 2092, 2105, 2115, 2106, 2063, + 2025, 2028, 2033, 1998, 1963, 1962, 1957, 1928, + 1932, 1964, 1977, 1980, 1979, 1996, 2011, 2003, + 2001, 2012, 2028, 2039, 2041, 2060, 2086, 2091, + 2093, 2112, 2108, 2078, 2072, 2073, 2047, 2018, + 1989, 1972, 1968, 1939, 1916, 1928, 1925, 1906, + 1904, 1923, 1950, 1953, 1945, 1974, 2006, 2012, + 2042, 2095, 2105, 2098, 2110, 2108, 2097, 2111, + 2111, 2067, 2035, 2022, 1989, 1970, 1956, 1929, + 1915, 1889, 1861, 1867, 1873, 1875, 1893, 1898, + 1916, 1937, 1945, 1985, 2034, 2062, 2080, 2101, + 2113, 2117, 2142, 2178, 2174, 2152, 2142, 2126, + 2110, 2077, 2040, 2046, 2017, 1943, 1932, 1944, + 1911, 1882, 1892, 1928, 1922, 1899, 1949, 1987, + 1968, 1974, 2010, 2042, 2041, 2024, 2063, 2094, + 2082, 2105, 2114, 2114, 2123, 2111, 2131, 2121, + 2064, 2060, 2046, 2015, 2001, 1965, 1958, 1953, + 1938, 1957, 1955, 1979, 2008, 1983, 2027, 2079, + 2038, 2052, 2115, 2120, 2093, 2092, 2122, 2126, + 2103, 2103, 2109, 2106, 2073, 2025, 2035, 2018, + 1956, 1950, 1939, 1887, 1861, 1850, 1851, 1873, + 1863, 1870, 1912, 1936, 1960, 1994, 2022, 2060, + 2082, 2081, 2114, 2142, 2132, 2146, 2165, 2166, + 2156, 2137, 2143, 2144, 2100, 2076, 2083, 2051, + 2018, 2004, 1984, 1971, 1946, 1935, 1955, 1962, + 1973, 1991, 1990, 2012, 2041, 2054, 2094, 2122, + 2104, 2120, 2135, 2114, 2136, 2152, 2137, 2137, + 2123, 2128, 2127, 2082, 2083, 2077, 2017, 1986, + 1969, 1938, 1910, 1894, 1901, 1896, 1905, 1928, + 1921, 1958, 2016, 2007, 2012, 2046, 2031, 2038, + 2079, 2074, 2074, 2093, 2091, 2102, 2131, 2117, + 2102, 2109, 2101, 2084, 2076, 2073, 2058, 2032, + 2016, 2006, 2004, 2009, 1990, 1981, 2006, 1996, + 1982, 2010, 2035, 2023, 2021, 2040, 2045, 2035, + 2033, 2065, 2079, 2050, 2047, 2074, 2093, 2116, + 2124, 2123, 2129, 2117, 2126, 2145, 2157, 2161, + 2115, 2056, 2011, 1943, 1899, 1882, 1861, 1837, + 1795, 1781, 1812, 1825, 1842, 1895, 1920, 1929, + 1948, 1966, 1998, 2039, 2072, 2100, 2139, 2179, + 2230, 2299, 2359, 2371, 2355, 2347, 2345, 2314, + 2274, 2244, 2183, 2096, 2018, 1968, 1954, 1911, + 1860, 1868, 1870, 1850, 1854, 1874, 1916, 1951, + 1948, 1976, 2058, 2103, 2106, 2166, 2246, 2250, + 2237, 2292, 2361, 2357, 2314, 2333, 2334, 2254, + 2225, 2223, 2161, 2099, 2047, 2009, 2004, 1971, + 1936, 1926, 1887, 1852, 1883, 1911, 1896, 1942, + 1999, 1955, 1965, 2055, 2063, 2096, 2166, 2165, + 2156, 2152, 2153, 2179, 2174, 2160, 2142, 2090, + 2086, 2085, 2045, 2052, 2047, 2003, 1985, 1996, + 2024, 2019, 2009, 2035, 2003, 1957, 1988, 2028, + 2047, 2039, 2015, 2029, 2040, 2024, 2046, 2086, + 2086, 2049, 2036, 2066, 2056, 2031, 2046, 2058, + 2024, 2008, 2029, 2032, 2023, 2038, 2043, 2026, + 2034, 2052, 2059, 2071, 2082, 2069, 2042, 2059, + 2091, 2079, 2065, 2085, 2086, 2066, 2100, 2140, + 2106, 2090, 2131, 2120, 2080, 2087, 2088, 2031, + 1987, 1986, 1965, 1930, 1928, 1957, 1972, 1962, + 1969, 2023, 2075, 2066, 2085, 2149, 2139, 2113, + 2166, 2204, 2159, 2145, 2185, 2183, 2164, 2192, + 2207, 2198, 2220, 2226, 2194, 2186, 2185, 2160, + 2127, 2116, 2092, 2018, 1990, 2024, 2011, 1975, + 2015, 2069, 2056, 2051, 2112, 2149, 2131, 2136, + 2165, 2167, 2147, 2143, 2161, 2183, 2178, 2173, + 2217, 2237, 2217, 2227, 2217, 2182, 2153, 2107, + 2080, 2073, 2026, 1969, 1939, 1909, 1879, 1869, + 1888, 1899, 1891, 1904, 1935, 1966, 1995, 2030, + 2069, 2105, 2107, 2085, 2107, 2134, 2109, 2104, + 2149, 2159, 2133, 2156, 2196, 2187, 2184, 2200, + 2191, 2162, 2140, 2110, 2059, 1991, 1940, 1916, + 1882, 1870, 1864, 1831, 1829, 1866, 1889, 1900, + 1928, 1948, 1934, 1917, 1941, 1954, 1934, 1942, + 1953, 1937, 1957, 1998, 2036, 2076, 2104, 2124, + 2126, 2111, 2113, 2116, 2079, 2029, 1992, 1945, + 1883, 1881, 1918, 1894, 1878, 1928, 1936, 1936, + 1997, 2025, 2012, 2037, 2053, 2045, 2058, 2068, + 2078, 2105, 2120, 2110, 2107, 2116, 2123, 2133, + 2150, 2145, 2135, 2139, 2111, 2106, 2141, 2125, + 2099, 2107, 2100, 2097, 2109, 2113, 2126, 2133, + 2135, 2158, 2179, 2177, 2167, 2177, 2189, 2156, + 2127, 2146, 2115, 2068, 2098, 2095, 2055, 2055, + 2064, 2077, 2086, 2096, 2135, 2152, 2148, 2171, + 2176, 2162, 2172, 2168, 2159, 2144, 2126, 2121, + 2095, 2097, 2110, 2083, 2090, 2108, 2094, 2086, + 2083, 2064, 2042, 2027, 2022, 2000, 1986, 1994, + 1989, 1997, 2002, 2004, 2048, 2075, 2066, 2096, + 2114, 2096, 2102, 2113, 2081, 2049, 2051, 2061, + 2039, 2025, 2034, 2017, 2016, 2032, 2055, 2065, + 2063, 2080, 2084, 2063, 2042, 2053, 2030, 1987, + 2002, 1986, 1928, 1937, 1953, 1924, 1937, 1982, + 1985, 1973, 1983, 1989, 1971, 1963, 1975, 1953, + 1915, 1900, 1906, 1928, 1934, 1936, 1935, 1944, + 1964, 1966, 1954, 1945, 1926, 1895, 1876, 1856, + 1826, 1814, 1808, 1791, 1785, 1797, 1802, 1819, + 1840, 1849, 1875, 1900, 1890, 1886, 1908, 1923, + 1913, 1891, 1897, 1915, 1902, 1902, 1923, 1935, + 1960, 1988, 2021, 2066, 2093, 2121, 2153, 2175, + 2204, 2227, 2229, 2241, 2257, 2266, 2270, 2291, + 2314, 2318, 2338, 2362, 2337, 2306, 2310, 2309, + 2272, 2231, 2194, 2176, 2193, 2173, 2148, 2166, + 2180, 2188, 2212, 2244, 2271, 2300, 2316, 2313, + 2346, 2371, 2353, 2356, 2371, 2361, 2340, 2332, + 2340, 2330, 2322, 2329, 2336, 2339, 2331, 2337, + 2354, 2328, 2297, 2297, 2276, 2254, 2251, 2251, + 2267, 2287, 2299, 2312, 2353, 2396, 2393, 2380, + 2388, 2374, 2323, 2274, 2243, 2211, 2164, 2120, + 2103, 2099, 2073, 2055, 2068, 2065, 2049, 2043, + 2037, 2025, 2017, 2011, 2000, 1995, 1992, 1977, + 1967, 1979, 1977, 1955, 1948, 1951, 1946, 1923, + 1905, 1895, 1864, 1815, 1765, 1733, 1683, 1627, + 1593, 1563, 1542, 1544, 1551, 1563, 1590, 1613, + 1631, 1654, 1676, 1692, 1698, 1703, 1716, 1731, + 1743, 1767, 1789, 1802, 1817, 1839, 1859, 1863, + 1856, 1843, 1827, 1801, 1774, 1754, 1727, 1695, + 1677, 1654, 1635, 1635, 1625, 1610, 1618, 1634, + 1634, 1643, 1665, 1681, 1689, 1711, 1726, 1742, + 1774, 1815, 1880, 1951, 2022, 2119, 2197, 2263, + 2363, 2462, 2534, 2609, 2666, 2684, 2710, 2746, + 2766, 2776, 2767, 2757, 2763, 2765, 2770, 2760, + 2731, 2718, 2701, 2673, 2666, 2653, 2622, 2604, + 2616, 2632, 2630, 2655, 2718, 2777, 2832, 2873, + 2915, 2982, 3039, 3059, 3076, 3083, 3031, 2947, + 2886, 2790, 2659, 2541, 2422, 2298, 2187, 2089, + 2012, 1960, 1912, 1862, 1820, 1812, 1835, 1854, + 1884, 1926, 1963, 1992, 2034, 2093, 2133, 2162, + 2205, 2232, 2233, 2245, 2258, 2252, 2247, 2228, + 2184, 2136, 2088, 2040, 1994, 1963, 1932, 1898, + 1889, 1908, 1931, 1964, 2010, 2050, 2083, 2116, + 2151, 2177, 2197, 2209, 2200, 2178, 2150, 2115, + 2066, 2015, 1957, 1883, 1804, 1730, 1654, 1568, + 1487, 1408, 1326, 1253, 1202, 1167, 1145, 1151, + 1180, 1227, 1295, 1377, 1462, 1555, 1648, 1727, + 1796, 1855, 1892, 1913, 1929, 1931, 1916, 1892, + 1856, 1820, 1784, 1738, 1689, 1637, 1584, 1541, + 1504, 1470, 1443, 1431, 1421, 1422, 1454, 1496, + 1546, 1619, 1694, 1765, 1857, 1957, 2043, 2126, + 2187, 2228, 2280, 2307, 2307, 2322, 2309, 2280, + 2262, 2240, 2227, 2237, 2241, 2254, 2279, 2311, + 2352, 2392, 2436, 2473, 2505, 2567, 2638, 2668, + 2697, 2757, 2812, 2856, 2902, 2928, 2945, 2967, + 2985, 2986, 2985, 2982, 2970, 2957, 2932, 2917, + 2937, 2958, 2961, 2977, 3007, 3023, 3065, 3135, + 3154, 3137, 3091, 2996, 2881, 2762, 2607, 2430, + 2270, 2102, 1967, 1888, 1827, 1784, 1774, 1771, + 1771, 1779, 1790, 1792, 1788, 1781, 1776, 1780, + 1798, 1843, 1889, 1941, 2014, 2092, 2170, 2242, + 2299, 2344, 2381, 2408, 2411, 2392, 2350, 2297, + 2244, 2188, 2151, 2119, 2096, 2080, 2086, 2108, + 2139, 2178, 2208, 2221, 2219, 2211, 2187, 2143, + 2087, 2017, 1940, 1863, 1792, 1733, 1681, 1631, + 1583, 1530, 1478, 1435, 1393, 1353, 1316, 1282, + 1257, 1246, 1248, 1269, 1308, 1345, 1390, 1452, + 1515, 1573, 1631, 1676, 1708, 1738, 1755, 1752, + 1740, 1718, 1678, 1636, 1597, 1560, 1527, 1500, + 1476, 1460, 1463, 1478, 1487, 1506, 1540, 1576, + 1612, 1668, 1726, 1786, 1863, 1927, 1999, 2116, + 2199, 2257, 2356, 2424, 2455, 2493, 2514, 2529, + 2536, 2529, 2516, 2496, 2487, 2480, 2468, 2461, + 2452, 2449, 2466, 2501, 2527, 2557, 2594, 2636, + 2682, 2733, 2769, 2807, 2872, 2910, 2921, 2966, + 3030, 3088, 3147, 3185, 3218, 3259, 3314, 3374, + 3388, 3375, 3362, 3368, 3375, 3366, 3338, 3227, + 3059, 2936, 2802, 2623, 2447, 2265, 2083, 1951, + 1873, 1837, 1819, 1812, 1806, 1806, 1824, 1841, + 1851, 1853, 1825, 1786, 1762, 1759, 1778, 1799, + 1811, 1841, 1898, 1971, 2050, 2110, 2151, 2179, + 2195, 2203, 2203, 2192, 2176, 2146, 2138, 2149, + 2172, 2204, 2235, 2273, 2315, 2363, 2418, 2466, + 2496, 2505, 2495, 2469, 2439, 2397, 2321, 2217, + 2109, 2007, 1915, 1837, 1772, 1708, 1649, 1602, + 1566, 1526, 1470, 1398, 1324, 1250, 1186, 1129, + 1086, 1072, 1075, 1104, 1155, 1226, 1311, 1390, + 1462, 1520, 1560, 1586, 1597, 1584, 1562, 1537, + 1500, 1471, 1448, 1423, 1402, 1392, 1403, 1417, + 1436, 1462, 1497, 1531, 1571, 1613, 1654, 1693, + 1722, 1758, 1814, 1873, 1932, 1999, 2068, 2129, + 2200, 2288, 2360, 2394, 2415, 2415, 2392, 2377, + 2356, 2314, 2263, 2220, 2206, 2218, 2251, 2294, + 2337, 2363, 2393, 2438, 2495, 2547, 2566, 2559, + 2562, 2588, 2624, 2666, 2709, 2732, 2741, 2785, + 2857, 2907, 2948, 2987, 3028, 3078, 3140, 3206, + 3255, 3286, 3297, 3318, 3359, 3381, 3376, 3373, + 3353, 3261, 3141, 3049, 2919, 2735, 2553, 2360, + 2188, 2078, 2000, 1936, 1890, 1861, 1845, 1848, + 1861, 1863, 1847, 1832, 1817, 1805, 1799, 1786, + 1774, 1775, 1787, 1792, 1805, 1849, 1912, 1961, + 1996, 2042, 2087, 2111, 2118, 2115, 2101, 2083, + 2073, 2081, 2105, 2128, 2151, 2186, 2238, 2297, + 2350, 2399, 2441, 2474, 2487, 2480, 2458, 2418, + 2344, 2245, 2137, 2031, 1931, 1843, 1758, 1680, + 1623, 1574, 1514, 1466, 1423, 1358, 1288, 1243, + 1198, 1146, 1111, 1103, 1113, 1150, 1195, 1244, + 1311, 1383, 1443, 1495, 1540, 1567, 1569, 1559, + 1540, 1517, 1485, 1447, 1408, 1367, 1337, 1320, + 1311, 1321, 1340, 1356, 1389, 1459, 1526, 1582, + 1659, 1739, 1799, 1864, 1928, 1978, 2035, 2088, + 2126, 2179, 2241, 2284, 2325, 2368, 2389, 2399, + 2414, 2406, 2385, 2367, 2333, 2295, 2294, 2309, + 2314, 2334, 2371, 2399, 2441, 2502, 2553, 2596, + 2635, 2651, 2679, 2731, 2789, 2823, 2844, 2861, + 2884, 2921, 2960, 3004, 3027, 3029, 3057, 3111, + 3181, 3251, 3291, 3320, 3363, 3407, 3433, 3458, + 3475, 3419, 3287, 3161, 3060, 2925, 2788, 2641, + 2459, 2316, 2249, 2211, 2185, 2170, 2134, 2079, + 2044, 2037, 2017, 1964, 1880, 1795, 1725, 1681, + 1658, 1653, 1655, 1661, 1694, 1754, 1843, 1947, + 2015, 2054, 2081, 2102, 2127, 2137, 2118, 2081, + 2049, 2039, 2058, 2094, 2124, 2144, 2165, 2204, + 2265, 2332, 2388, 2414, 2420, 2416, 2411, 2405, + 2381, 2315, 2216, 2133, 2069, 2004, 1955, 1909, + 1847, 1795, 1757, 1709, 1660, 1607, 1516, 1410, + 1330, 1252, 1168, 1113, 1080, 1063, 1082, 1126, + 1180, 1255, 1338, 1398, 1449, 1496, 1523, 1519, + 1495, 1465, 1438, 1404, 1357, 1317, 1292, 1272, + 1262, 1270, 1293, 1314, 1343, 1394, 1447, 1498, + 1554, 1607, 1645, 1702, 1762, 1800, 1846, 1912, + 1975, 2039, 2110, 2189, 2264, 2336, 2396, 2435, + 2467, 2473, 2457, 2433, 2402, 2364, 2333, 2317, + 2315, 2329, 2356, 2391, 2441, 2503, 2557, 2593, + 2632, 2678, 2718, 2738, 2745, 2762, 2784, 2803, + 2835, 2876, 2895, 2927, 2997, 3046, 3098, 3186, + 3242, 3273, 3344, 3410, 3434, 3453, 3465, 3456, + 3444, 3411, 3316, 3201, 3100, 2979, 2842, 2716, + 2594, 2480, 2382, 2314, 2287, 2267, 2228, 2179, + 2143, 2119, 2086, 2047, 2013, 1979, 1939, 1893, + 1847, 1832, 1837, 1824, 1802, 1801, 1828, 1864, + 1900, 1931, 1955, 1974, 1982, 1989, 1997, 2002, + 1990, 1983, 2001, 2040, 2081, 2108, 2145, 2201, + 2261, 2317, 2368, 2413, 2445, 2458, 2460, 2458, + 2449, 2422, 2357, 2270, 2201, 2148, 2088, 2020, + 1948, 1869, 1802, 1737, 1670, 1617, 1554, 1464, + 1386, 1338, 1296, 1250, 1212, 1189, 1191, 1213, + 1236, 1271, 1320, 1364, 1392, 1423, 1454, 1468, + 1455, 1429, 1400, 1373, 1340, 1305, 1263, 1234, + 1211, 1192, 1197, 1219, 1242, 1268, 1303, 1353, + 1421, 1491, 1555, 1618, 1679, 1757, 1830, 1879, + 1944, 2019, 2070, 2119, 2181, 2235, 2279, 2319, + 2346, 2361, 2380, 2383, 2365, 2357, 2355, 2347, + 2335, 2344, 2368, 2396, 2431, 2472, 2520, 2574, + 2619, 2666, 2725, 2772, 2805, 2838, 2875, 2914, + 2949, 2979, 3001, 3024, 3055, 3082, 3106, 3134, + 3177, 3221, 3258, 3312, 3367, 3408, 3456, 3495, + 3502, 3481, 3419, 3321, 3218, 3105, 2971, 2827, + 2692, 2583, 2498, 2440, 2404, 2379, 2350, 2316, + 2286, 2255, 2220, 2176, 2115, 2057, 1997, 1929, + 1867, 1819, 1781, 1752, 1726, 1714, 1726, 1754, + 1793, 1837, 1879, 1922, 1953, 1968, 1976, 1982, + 1979, 1967, 1966, 1976, 1985, 1999, 2030, 2074, + 2130, 2188, 2247, 2309, 2355, 2385, 2403, 2412, + 2403, 2378, 2338, 2284, 2218, 2152, 2109, 2076, + 2025, 1959, 1898, 1840, 1775, 1715, 1658, 1580, + 1500, 1425, 1356, 1307, 1269, 1221, 1177, 1165, + 1162, 1160, 1184, 1220, 1250, 1276, 1309, 1337, + 1359, 1372, 1375, 1364, 1345, 1319, 1288, 1252, + 1217, 1188, 1163, 1152, 1157, 1178, 1204, 1244, + 1288, 1344, 1407, 1466, 1524, 1589, 1649, 1710, + 1771, 1834, 1901, 1960, 2014, 2073, 2125, 2176, + 2223, 2261, 2295, 2329, 2348, 2362, 2376, 2384, + 2391, 2403, 2417, 2418, 2421, 2439, 2465, 2501, + 2540, 2581, 2624, 2676, 2722, 2765, 2824, 2870, + 2891, 2916, 2943, 2961, 2993, 3028, 3063, 3097, + 3136, 3183, 3238, 3300, 3345, 3372, 3400, 3428, + 3440, 3420, 3379, 3313, 3222, 3138, 3059, 2955, + 2843, 2738, 2634, 2561, 2514, 2465, 2418, 2379, + 2338, 2299, 2283, 2268, 2230, 2181, 2127, 2056, + 1974, 1906, 1857, 1802, 1741, 1704, 1690, 1699, + 1727, 1761, 1793, 1825, 1850, 1868, 1881, 1891, + 1887, 1875, 1873, 1881, 1885, 1895, 1920, 1950, + 1988, 2035, 2085, 2133, 2175, 2214, 2248, 2264, + 2275, 2286, 2280, 2258, 2233, 2198, 2148, 2109, + 2083, 2027, 1964, 1908, 1840, 1773, 1732, 1686, + 1620, 1566, 1512, 1443, 1392, 1359, 1301, 1247, + 1218, 1187, 1163, 1171, 1189, 1205, 1224, 1252, + 1279, 1300, 1323, 1338, 1335, 1319, 1303, 1288, + 1265, 1238, 1213, 1189, 1181, 1186, 1187, 1195, + 1223, 1250, 1283, 1334, 1388, 1436, 1500, 1563, + 1619, 1679, 1740, 1802, 1859, 1914, 1962, 2008, + 2057, 2107, 2156, 2209, 2258, 2293, 2321, 2359, + 2388, 2407, 2427, 2442, 2446, 2445, 2452, 2471, + 2494, 2516, 2543, 2579, 2620, 2666, 2717, 2769, + 2816, 2854, 2889, 2933, 2971, 3001, 3042, 3079, + 3106, 3147, 3185, 3217, 3254, 3285, 3299, 3323, + 3344, 3334, 3313, 3300, 3253, 3184, 3133, 3067, + 2976, 2893, 2808, 2725, 2666, 2615, 2555, 2509, + 2470, 2425, 2393, 2374, 2345, 2315, 2282, 2231, + 2180, 2124, 2060, 2004, 1955, 1900, 1851, 1821, + 1799, 1792, 1804, 1815, 1827, 1841, 1848, 1860, + 1876, 1881, 1882, 1888, 1893, 1893, 1898, 1914, + 1932, 1951, 1980, 2011, 2047, 2082, 2116, 2147, + 2170, 2184, 2199, 2208, 2201, 2187, 2157, 2122, + 2101, 2066, 2014, 1960, 1903, 1839, 1794, 1760, + 1711, 1669, 1632, 1587, 1555, 1537, 1503, 1467, + 1444, 1412, 1372, 1358, 1353, 1341, 1344, 1350, + 1354, 1363, 1384, 1393, 1401, 1402, 1397, 1393, + 1383, 1358, 1334, 1310, 1288, 1273, 1266, 1266, + 1268, 1275, 1299, 1334, 1370, 1415, 1467, 1515, + 1564, 1620, 1676, 1722, 1775, 1825, 1861, 1903, + 1945, 1981, 2024, 2073, 2109, 2143, 2190, 2241, + 2276, 2320, 2372, 2402, 2426, 2457, 2481, 2498, + 2521, 2544, 2563, 2584, 2603, 2629, 2662, 2696, + 2729, 2758, 2785, 2808, 2839, 2876, 2907, 2936, + 2972, 3010, 3045, 3083, 3121, 3150, 3175, 3200, + 3217, 3234, 3245, 3238, 3220, 3201, 3178, 3145, + 3107, 3061, 3001, 2936, 2877, 2827, 2774, 2718, + 2665, 2610, 2561, 2522, 2484, 2447, 2410, 2366, + 2317, 2266, 2210, 2155, 2110, 2059, 2010, 1968, + 1935, 1910, 1905, 1903, 1896, 1898, 1906, 1903, + 1903, 1912, 1912, 1910, 1919, 1926, 1926, 1927, + 1937, 1948, 1952, 1965, 1980, 1986, 2000, 2015, + 2021, 2031, 2046, 2058, 2061, 2059, 2048, 2036, + 2025, 2005, 1976, 1943, 1905, 1860, 1823, 1798, + 1772, 1745, 1719, 1685, 1659, 1644, 1621, 1597, + 1580, 1550, 1511, 1484, 1466, 1451, 1450, 1453, + 1443, 1434, 1441, 1454, 1460, 1458, 1453, 1445, + 1434, 1423, 1406, 1386, 1371, 1360, 1343, 1334, + 1335, 1333, 1336, 1350, 1370, 1394, 1429, 1471, + 1509, 1546, 1585, 1641, 1696, 1740, 1781, 1824, + 1865, 1905, 1950, 1988, 2018, 2056, 2093, 2130, + 2176, 2220, 2252, 2289, 2337, 2370, 2389, 2427, + 2464, 2479, 2504, 2542, 2566, 2591, 2627, 2654, + 2677, 2712, 2753, 2788, 2812, 2841, 2886, 2932, + 2976, 3012, 3042, 3078, 3118, 3143, 3160, 3180, + 3197, 3204, 3206, 3206, 3202, 3195, 3183, 3166, + 3140, 3105, 3074, 3045, 3003, 2952, 2903, 2859, + 2823, 2780, 2725, 2682, 2646, 2608, 2573, 2532, + 2486, 2443, 2399, 2342, 2287, 2244, 2199, 2152, + 2109, 2065, 2033, 2022, 2002, 1975, 1960, 1952, + 1938, 1935, 1934, 1928, 1921, 1922, 1924, 1924, + 1933, 1944, 1947, 1958, 1973, 1981, 1985, 1992, + 2002, 2004, 2004, 2013, 2020, 2019, 2009, 1999, + 1993, 1984, 1969, 1945, 1904, 1864, 1831, 1797, + 1768, 1741, 1709, 1678, 1655, 1641, 1628, 1613, + 1605, 1595, 1572, 1557, 1554, 1547, 1537, 1535, + 1531, 1522, 1520, 1525, 1520, 1512, 1509, 1497, + 1480, 1465, 1446, 1427, 1406, 1392, 1378, 1364, + 1360, 1354, 1347, 1355, 1374, 1390, 1413, 1439, + 1471, 1510, 1558, 1606, 1657, 1707, 1748, 1791, + 1834, 1869, 1906, 1940, 1965, 1998, 2029, 2063, + 2099, 2138, 2175, 2211, 2250, 2283, 2310, 2340, + 2370, 2396, 2422, 2455, 2477, 2504, 2533, 2565, + 2596, 2632, 2667, 2695, 2730, 2768, 2806, 2845, + 2889, 2920, 2951, 2991, 3035, 3069, 3094, 3113, + 3129, 3141, 3149, 3150, 3145, 3139, 3127, 3111, + 3102, 3091, 3065, 3039, 3017, 2982, 2948, 2918, + 2886, 2846, 2807, 2770, 2729, 2696, 2669, 2632, + 2587, 2544, 2495, 2441, 2389, 2344, 2289, 2232, + 2189, 2143, 2101, 2072, 2048, 2023, 2002, 1987, + 1970, 1954, 1949, 1935, 1922, 1923, 1914, 1906, + 1911, 1919, 1927, 1936, 1946, 1950, 1955, 1959, + 1959, 1950, 1942, 1930, 1922, 1916, 1905, 1889, + 1879, 1871, 1854, 1836, 1807, 1772, 1738, 1707, + 1679, 1653, 1632, 1608, 1582, 1569, 1559, 1542, + 1534, 1531, 1515, 1497, 1492, 1487, 1482, 1485, + 1487, 1481, 1478, 1482, 1484, 1479, 1473, 1458, + 1437, 1416, 1395, 1372, 1348, 1332, 1317, 1303, + 1295, 1293, 1294, 1301, 1313, 1328, 1347, 1367, + 1390, 1421, 1458, 1496, 1534, 1576, 1621, 1660, + 1696, 1734, 1765, 1797, 1829, 1853, 1877, 1910, + 1939, 1970, 2010, 2049, 2077, 2111, 2144, 2166, + 2196, 2231, 2253, 2281, 2309, 2331, 2361, 2403, + 2436, 2469, 2507, 2536, 2567, 2600, 2636, 2673, + 2707, 2743, 2776, 2812, 2856, 2893, 2921, 2950, + 2976, 2994, 3003, 3010, 3014, 3014, 3015, 3013, + 3005, 2999, 2989, 2978, 2966, 2953, 2939, 2915, + 2891, 2861, 2835, 2809, 2781, 2758, 2734, 2705, + 2666, 2628, 2588, 2532, 2478, 2426, 2371, 2312, + 2257, 2206, 2159, 2124, 2094, 2064, 2034, 2016, + 1990, 1973, 1967, 1947, 1929, 1921, 1907, 1890, + 1888, 1892, 1893, 1897, 1902, 1908, 1907, 1908, + 1906, 1893, 1879, 1864, 1849, 1830, 1814, 1803, + 1789, 1775, 1765, 1748, 1722, 1693, 1662, 1629, + 1597, 1568, 1539, 1512, 1496, 1481, 1467, 1458, + 1452, 1437, 1425, 1412, 1399, 1390, 1389, 1391, + 1394, 1392, 1394, 1404, 1406, 1410, 1411, 1403, + 1383, 1364, 1345, 1318, 1294, 1276, 1257, 1238, + 1231, 1226, 1222, 1227, 1234, 1240, 1255, 1274, + 1291, 1314, 1346, 1384, 1420, 1460, 1504, 1544, + 1583, 1622, 1651, 1679, 1707, 1733, 1750, 1773, + 1802, 1829, 1857, 1892, 1927, 1955, 1985, 2014, + 2040, 2061, 2090, 2114, 2132, 2160, 2194, 2226, + 2265, 2306, 2346, 2383, 2419, 2459, 2497, 2534, + 2571, 2603, 2633, 2671, 2709, 2742, 2778, 2811, + 2836, 2864, 2886, 2902, 2915, 2925, 2924, 2932, + 2938, 2943, 2943, 2944, 2945, 2942, 2941, 2935, + 2923, 2914, 2897, 2878, 2861, 2840, 2818, 2800, + 2779, 2755, 2726, 2693, 2651, 2602, 2556, 2504, + 2453, 2399, 2341, 2291, 2243, 2208, 2172, 2138, + 2111, 2082, 2053, 2035, 2022, 2002, 1987, 1977, + 1958, 1944, 1939, 1934, 1931, 1932, 1934, 1930, + 1928, 1925, 1916, 1898, 1883, 1861, 1839, 1824, + 1810, 1800, 1787, 1775, 1762, 1741, 1714, 1682, + 1650, 1616, 1578, 1545, 1514, 1482, 1464, 1449, + 1430, 1420, 1414, 1396, 1380, 1373, 1367, 1355, + 1352, 1349, 1345, 1346, 1352, 1360, 1362, 1365, + 1366, 1355, 1341, 1332, 1317, 1294, 1277, 1255, + 1233, 1221, 1215, 1209, 1208, 1212, 1212, 1219, + 1233, 1250, 1270, 1293, 1319, 1353, 1388, 1425, + 1469, 1515, 1552, 1580, 1612, 1636, 1655, 1678, + 1698, 1712, 1734, 1769, 1789, 1813, 1848, 1878, + 1901, 1929, 1952, 1969, 1991, 2013, 2035, 2059, + 2092, 2123, 2156, 2192, 2233, 2275, 2314, 2360, + 2404, 2440, 2479, 2518, 2555, 2595, 2632, 2669, + 2705, 2739, 2766, 2794, 2818, 2836, 2861, 2881, + 2889, 2901, 2915, 2929, 2946, 2966, 2973, 2975, + 2988, 2990, 2982, 2985, 2976, 2953, 2937, 2926, + 2910, 2889, 2876, 2858, 2831, 2800, 2767, 2722, + 2670, 2624, 2575, 2517, 2462, 2414, 2361, 2314, + 2276, 2243, 2208, 2180, 2156, 2125, 2099, 2085, + 2068, 2051, 2041, 2029, 2015, 2008, 2007, 2011, + 2013, 2010, 2007, 1996, 1985, 1972, 1958, 1933, + 1908, 1892, 1873, 1855, 1845, 1836, 1821, 1807, + 1790, 1762, 1733, 1706, 1674, 1638, 1604, 1576, + 1547, 1521, 1503, 1483, 1462, 1449, 1431, 1410, + 1396, 1383, 1366, 1360, 1355, 1346, 1343, 1343, + 1343, 1343, 1342, 1340, 1334, 1323, 1311, 1297, + 1283, 1268, 1251, 1236, 1220, 1209, 1204, 1200, + 1201, 1202, 1208, 1215, 1227, 1244, 1262, 1287, + 1318, 1352, 1385, 1424, 1459, 1490, 1522, 1554, + 1578, 1598, 1620, 1637, 1656, 1680, 1711, 1740, + 1764, 1797, 1826, 1854, 1884, 1916, 1945, 1967, + 1994, 2019, 2044, 2074, 2108, 2145, 2178, 2217, + 2253, 2294, 2334, 2374, 2419, 2463, 2506, 2552, + 2594, 2640, 2681, 2717, 2756, 2793, 2820, 2849, + 2878, 2903, 2924, 2948, 2968, 2982, 3009, 3030, + 3045, 3064, 3082, 3095, 3100, 3105, 3103, 3093, + 3089, 3073, 3057, 3045, 3028, 3009, 2985, 2956, + 2922, 2881, 2833, 2776, 2716, 2661, 2599, 2537, + 2483, 2428, 2378, 2336, 2295, 2260, 2229, 2206, + 2178, 2153, 2136, 2116, 2102, 2092, 2084, 2069, + 2061, 2058, 2057, 2055, 2056, 2054, 2046, 2036, + 2025, 2008, 1990, 1969, 1946, 1923, 1903, 1888, + 1873, 1860, 1852, 1833, 1811, 1788, 1760, 1735, + 1711, 1686, 1662, 1634, 1608, 1593, 1569, 1541, + 1518, 1491, 1454, 1426, 1406, 1382, 1369, 1364, + 1347, 1326, 1324, 1318, 1307, 1298, 1290, 1277, + 1261, 1252, 1242, 1229, 1219, 1211, 1195, 1178, + 1171, 1163, 1149, 1145, 1145, 1137, 1139, 1149, + 1159, 1173, 1191, 1215, 1239, 1265, 1293, 1321, + 1353, 1382, 1414, 1446, 1469, 1497, 1524, 1551, + 1583, 1614, 1642, 1665, 1697, 1727, 1753, 1787, + 1818, 1840, 1868, 1896, 1921, 1948, 1980, 2009, + 2040, 2077, 2113, 2149, 2187, 2226, 2267, 2309, + 2357, 2405, 2452, 2501, 2549, 2596, 2644, 2685, + 2722, 2759, 2797, 2831, 2863, 2900, 2934, 2958, + 2993, 3021, 3042, 3068, 3094, 3116, 3134, 3152, + 3165, 3173, 3181, 3180, 3173, 3164, 3154, 3139, + 3123, 3103, 3075, 3049, 3014, 2979, 2933, 2869, + 2798, 2732, 2669, 2597, 2532, 2466, 2396, 2341, + 2299, 2259, 2228, 2201, 2176, 2148, 2125, 2107, + 2094, 2082, 2076, 2066, 2044, 2034, 2033, 2031, + 2033, 2038, 2032, 2023, 2020, 2010, 1995, 1976, + 1956, 1932, 1907, 1887, 1870, 1854, 1843, 1834, + 1811, 1788, 1770, 1748, 1728, 1712, 1700, 1684, + 1667, 1652, 1636, 1615, 1592, 1569, 1534, 1489, + 1447, 1408, 1380, 1354, 1328, 1301, 1280, 1260, + 1242, 1231, 1219, 1201, 1179, 1159, 1137, 1121, + 1108, 1095, 1087, 1077, 1069, 1064, 1058, 1055, + 1057, 1054, 1051, 1059, 1064, 1070, 1081, 1096, + 1113, 1134, 1158, 1179, 1200, 1218, 1240, 1267, + 1293, 1322, 1349, 1373, 1409, 1452, 1491, 1529, + 1570, 1605, 1632, 1663, 1693, 1718, 1749, 1780, + 1799, 1822, 1858, 1896, 1928, 1963, 2001, 2033, + 2066, 2107, 2141, 2177, 2223, 2264, 2301, 2351, + 2400, 2449, 2498, 2546, 2593, 2636, 2683, 2730, + 2769, 2810, 2858, 2901, 2939, 2986, 3032, 3065, + 3101, 3137, 3164, 3193, 3219, 3236, 3257, 3273, + 3275, 3276, 3281, 3273, 3258, 3247, 3225, 3201, + 3173, 3143, 3108, 3061, 3009, 2947, 2872, 2788, + 2704, 2627, 2545, 2457, 2380, 2310, 2243, 2191, + 2156, 2123, 2094, 2072, 2046, 2025, 2014, 2002, + 1984, 1972, 1967, 1955, 1950, 1958, 1961, 1965, + 1970, 1975, 1972, 1964, 1960, 1943, 1920, 1898, + 1872, 1844, 1816, 1799, 1781, 1767, 1757, 1748, + 1733, 1716, 1706, 1700, 1701, 1704, 1706, 1710, + 1710, 1702, 1692, 1675, 1648, 1616, 1578, 1536, + 1492, 1453, 1411, 1382, 1356, 1321, 1289, 1266, + 1241, 1208, 1179, 1152, 1115, 1085, 1062, 1038, + 1020, 1006, 997, 994, 988, 987, 986, 993, + 998, 1002, 1012, 1021, 1036, 1049, 1060, 1076, + 1091, 1109, 1128, 1149, 1166, 1179, 1193, 1215, + 1245, 1276, 1307, 1339, 1374, 1413, 1456, 1500, + 1540, 1574, 1602, 1635, 1670, 1709, 1747, 1783, + 1820, 1860, 1899, 1941, 1988, 2035, 2076, 2112, + 2146, 2181, 2215, 2252, 2287, 2320, 2360, 2401, + 2450, 2498, 2546, 2597, 2649, 2697, 2747, 2800, + 2851, 2901, 2953, 3010, 3057, 3100, 3144, 3182, + 3221, 3265, 3301, 3327, 3359, 3385, 3406, 3427, + 3442, 3454, 3457, 3447, 3431, 3412, 3385, 3351, + 3320, 3284, 3234, 3187, 3136, 3076, 3012, 2935, + 2845, 2749, 2654, 2562, 2465, 2374, 2289, 2216, + 2153, 2100, 2059, 2020, 1990, 1968, 1946, 1926, + 1911, 1899, 1891, 1889, 1887, 1887, 1894, 1902, + 1915, 1926, 1932, 1937, 1932, 1922, 1911, 1893, + 1876, 1861, 1845, 1827, 1808, 1794, 1784, 1779, + 1776, 1762, 1745, 1734, 1725, 1730, 1743, 1757, + 1771, 1783, 1787, 1790, 1792, 1781, 1756, 1720, + 1674, 1624, 1580, 1541, 1498, 1459, 1422, 1384, + 1352, 1326, 1281, 1230, 1189, 1144, 1086, 1040, + 1005, 966, 939, 923, 915, 908, 911, 917, + 919, 922, 931, 944, 948, 952, 961, 972, + 981, 1004, 1031, 1046, 1060, 1074, 1088, 1104, + 1126, 1151, 1174, 1203, 1239, 1279, 1322, 1376, + 1421, 1457, 1494, 1528, 1559, 1586, 1625, 1665, + 1702, 1747, 1794, 1851, 1909, 1968, 2021, 2064, + 2103, 2136, 2169, 2198, 2223, 2252, 2281, 2316, + 2356, 2398, 2446, 2496, 2543, 2593, 2645, 2697, + 2748, 2803, 2862, 2919, 2979, 3036, 3090, 3140, + 3185, 3221, 3251, 3278, 3300, 3323, 3348, 3375, + 3398, 3422, 3441, 3464, 3489, 3504, 3505, 3499, + 3489, 3467, 3440, 3414, 3375, 3335, 3309, 3270, + 3221, 3180, 3122, 3038, 2947, 2844, 2737, 2623, + 2503, 2388, 2277, 2176, 2098, 2039, 1989, 1943, + 1901, 1864, 1828, 1809, 1791, 1762, 1748, 1749, + 1745, 1753, 1780, 1804, 1828, 1854, 1876, 1889, + 1902, 1911, 1910, 1896, 1888, 1889, 1886, 1879, + 1876, 1875, 1866, 1859, 1857, 1841, 1817, 1795, + 1771, 1753, 1754, 1763, 1769, 1785, 1813, 1843, + 1868, 1885, 1883, 1853, 1819, 1786, 1750, 1709, + 1667, 1624, 1580, 1548, 1525, 1496, 1462, 1419, + 1361, 1298, 1228, 1154, 1083, 1016, 951, 889, + 843, 808, 789, 778, 772, 776, 785, 797, + 812, 830, 841, 858, 880, 893, 912, 938, + 960, 985, 1021, 1052, 1081, 1115, 1145, 1182, + 1227, 1268, 1313, 1356, 1390, 1424, 1460, 1487, + 1507, 1530, 1547, 1561, 1586, 1620, 1659, 1709, + 1764, 1823, 1885, 1945, 1994, 2039, 2079, 2113, + 2138, 2162, 2190, 2211, 2237, 2270, 2316, 2368, + 2419, 2473, 2530, 2584, 2638, 2705, 2766, 2821, + 2877, 2941, 2995, 3046, 3103, 3157, 3202, 3240, + 3280, 3322, 3364, 3401, 3433, 3476, 3516, 3548, + 3588, 3630, 3656, 3656, 3652, 3650, 3629, 3599, + 3563, 3524, 3479, 3434, 3398, 3367, 3334, 3294, + 3252, 3205, 3128, 3029, 2911, 2771, 2633, 2492, + 2352, 2209, 2076, 1972, 1887, 1824, 1787, 1752, + 1719, 1689, 1660, 1634, 1620, 1605, 1591, 1586, + 1588, 1592, 1610, 1642, 1675, 1703, 1733, 1762, + 1787, 1819, 1843, 1856, 1865, 1872, 1877, 1878, + 1867, 1854, 1840, 1821, 1804, 1786, 1765, 1743, + 1726, 1723, 1741, 1769, 1793, 1828, 1861, 1902, + 1944, 1976, 1994, 2000, 1988, 1959, 1929, 1908, + 1883, 1843, 1800, 1754, 1711, 1658, 1596, 1535, + 1455, 1354, 1259, 1171, 1075, 977, 877, 780, + 701, 638, 580, 545, 531, 516, 513, 548, + 590, 623, 669, 724, 767, 808, 859, 898, + 925, 951, 978, 1007, 1033, 1070, 1111, 1141, + 1169, 1209, 1251, 1287, 1318, 1342, 1356, 1376, + 1397, 1415, 1431, 1450, 1475, 1504, 1544, 1595, + 1645, 1687, 1739, 1799, 1853, 1903, 1953, 1994, + 2023, 2052, 2082, 2102, 2123, 2147, 2168, 2184, + 2213, 2256, 2294, 2331, 2382, 2434, 2480, 2536, + 2592, 2645, 2699, 2760, 2820, 2878, 2951, 3015, + 3072, 3132, 3193, 3263, 3327, 3380, 3423, 3474, + 3526, 3562, 3598, 3642, 3672, 3691, 3711, 3728, + 3735, 3723, 3700, 3678, 3657, 3608, 3548, 3499, + 3457, 3382, 3313, 3273, 3208, 3142, 3075, 2959, + 2817, 2667, 2519, 2370, 2221, 2069, 1919, 1806, + 1717, 1645, 1604, 1570, 1528, 1489, 1456, 1427, + 1402, 1369, 1344, 1348, 1363, 1373, 1404, 1457, + 1507, 1553, 1606, 1660, 1709, 1755, 1788, 1814, + 1831, 1842, 1851, 1841, 1823, 1812, 1799, 1787, + 1788, 1790, 1774, 1756, 1750, 1751, 1765, 1798, + 1819, 1836, 1865, 1907, 1947, 1986, 2017, 2027, + 2025, 2025, 2033, 2050, 2070, 2073, 2068, 2054, + 2022, 1971, 1907, 1814, 1695, 1575, 1452, 1322, + 1207, 1104, 999, 907, 833, 756, 684, 625, + 552, 482, 446, 421, 396, 394, 417, 445, + 486, 556, 636, 709, 784, 863, 927, 986, + 1044, 1096, 1138, 1182, 1228, 1277, 1328, 1379, + 1423, 1452, 1474, 1484, 1485, 1486, 1495, 1510, + 1525, 1544, 1574, 1609, 1638, 1671, 1709, 1738, + 1758, 1777, 1800, 1826, 1856, 1892, 1932, 1975, + 2014, 2050, 2083, 2116, 2140, 2148, 2151, 2157, + 2161, 2170, 2187, 2210, 2240, 2284, 2344, 2409, + 2477, 2550, 2624, 2702, 2778, 2854, 2938, 3026, + 3115, 3202, 3281, 3353, 3429, 3507, 3561, 3601, + 3650, 3683, 3706, 3747, 3797, 3830, 3873, 3924, + 3949, 3972, 3978, 3955, 3922, 3887, 3821, 3732, + 3655, 3579, 3479, 3401, 3352, 3285, 3209, 3141, + 3040, 2876, 2688, 2517, 2355, 2168, 1979, 1819, + 1679, 1564, 1495, 1459, 1424, 1386, 1344, 1301, + 1274, 1256, 1223, 1201, 1210, 1236, 1261, 1312, + 1384, 1449, 1511, 1577, 1641, 1695, 1750, 1801, + 1834, 1853, 1880, 1912, 1919, 1911, 1910, 1906, + 1897, 1903, 1903, 1884, 1856, 1834, 1824, 1842, + 1887, 1927, 1954, 1992, 2046, 2096, 2142, 2177, + 2194, 2185, 2167, 2166, 2186, 2213, 2246, 2277, + 2306, 2334, 2333, 2288, 2207, 2101, 1966, 1800, + 1634, 1475, 1312, 1164, 1042, 941, 857, 784, + 716, 654, 599, 541, 481, 435, 405, 384, + 379, 399, 446, 520, 616, 713, 806, 898, + 986, 1072, 1150, 1217, 1280, 1331, 1368, 1404, + 1442, 1478, 1507, 1520, 1518, 1506, 1489, 1474, + 1482, 1505, 1526, 1549, 1577, 1614, 1655, 1687, + 1707, 1719, 1719, 1711, 1715, 1727, 1744, 1767, + 1803, 1848, 1899, 1953, 1994, 2024, 2043, 2045, + 2035, 2020, 2002, 1986, 1975, 1971, 1987, 2018, + 2059, 2111, 2166, 2228, 2299, 2377, 2464, 2553, + 2637, 2724, 2814, 2914, 3028, 3140, 3240, 3332, + 3412, 3474, 3542, 3616, 3671, 3720, 3764, 3805, + 3855, 3908, 3953, 3986, 4025, 4042, 4044, 4048, + 4038, 3998, 3961, 3927, 3885, 3828, 3774, 3712, + 3639, 3573, 3491, 3406, 3320, 3221, 3102, 2943, + 2742, 2530, 2346, 2173, 1982, 1799, 1648, 1520, + 1422, 1366, 1330, 1297, 1248, 1199, 1170, 1160, + 1130, 1098, 1100, 1128, 1156, 1198, 1264, 1342, + 1427, 1518, 1601, 1680, 1763, 1838, 1889, 1930, + 1965, 1996, 2010, 2003, 1990, 1980, 1974, 1977, + 1988, 1997, 1998, 1992, 1984, 2002, 2047, 2085, + 2102, 2124, 2152, 2181, 2216, 2246, 2262, 2268, + 2263, 2275, 2302, 2335, 2376, 2413, 2447, 2483, + 2511, 2513, 2494, 2446, 2364, 2246, 2118, 1985, + 1833, 1679, 1530, 1383, 1250, 1135, 1038, 947, + 858, 776, 700, 640, 579, 518, 464, 420, + 396, 395, 421, 465, 520, 577, 648, 746, + 848, 938, 1029, 1115, 1188, 1256, 1322, 1372, + 1413, 1441, 1448, 1443, 1450, 1461, 1469, 1480, + 1500, 1528, 1562, 1606, 1649, 1675, 1692, 1699, + 1687, 1682, 1680, 1671, 1665, 1675, 1693, 1724, + 1764, 1809, 1853, 1888, 1915, 1933, 1945, 1947, + 1929, 1901, 1866, 1838, 1823, 1814, 1817, 1829, + 1846, 1875, 1915, 1969, 2030, 2093, 2161, 2232, + 2308, 2389, 2471, 2554, 2644, 2731, 2823, 2918, + 3032, 3147, 3228, 3317, 3411, 3490, 3582, 3674, + 3736, 3781, 3821, 3846, 3882, 3932, 3947, 3947, + 3976, 4000, 4013, 4047, 4080, 4083, 4083, 4079, + 4052, 4025, 3978, 3903, 3825, 3745, 3646, 3543, + 3457, 3355, 3229, 3081, 2872, 2637, 2440, 2233, + 2004, 1804, 1624, 1462, 1332, 1234, 1156, 1091, + 1036, 971, 913, 884, 848, 800, 797, 850, + 917, 990, 1081, 1192, 1306, 1426, 1536, 1625, + 1715, 1785, 1832, 1867, 1904, 1953, 1978, 1982, + 1993, 2014, 2031, 2047, 2067, 2072, 2064, 2041, + 2013, 2008, 2027, 2043, 2045, 2054, 2088, 2131, + 2168, 2198, 2230, 2248, 2259, 2287, 2329, 2375, + 2421, 2470, 2517, 2569, 2613, 2619, 2593, 2547, + 2484, 2404, 2326, 2256, 2172, 2065, 1941, 1812, + 1679, 1549, 1416, 1271, 1127, 994, 860, 747, + 663, 577, 491, 424, 376, 356, 342, 336, + 334, 347, 378, 429, 509, 594, 677, 766, + 867, 969, 1064, 1145, 1220, 1288, 1342, 1389, + 1428, 1461, 1481, 1503, 1528, 1554, 1589, 1622, + 1627, 1615, 1602, 1584, 1577, 1569, 1559, 1560, + 1566, 1571, 1585, 1614, 1640, 1660, 1670, 1685, + 1706, 1720, 1723, 1727, 1731, 1736, 1740, 1743, + 1747, 1745, 1731, 1709, 1690, 1678, 1671, 1667, + 1676, 1700, 1740, 1787, 1841, 1903, 1965, 2033, + 2109, 2189, 2267, 2352, 2441, 2527, 2626, 2743, + 2857, 2965, 3071, 3173, 3259, 3334, 3404, 3461, + 3530, 3603, 3653, 3704, 3752, 3795, 3834, 3883, + 3935, 3970, 4002, 4038, 4052, 4058, 4075, 4095, + 4094, 4084, 4076, 4046, 4017, 3989, 3933, 3855, + 3773, 3674, 3558, 3452, 3351, 3209, 3023, 2797, + 2555, 2342, 2122, 1878, 1665, 1482, 1308, 1166, + 1067, 979, 909, 855, 779, 731, 714, 658, + 615, 635, 679, 744, 832, 920, 1027, 1152, + 1272, 1387, 1507, 1618, 1709, 1767, 1810, 1867, + 1929, 1956, 1961, 1974, 1984, 1992, 2018, 2034, + 2038, 2044, 2024, 2000, 2018, 2051, 2063, 2059, + 2067, 2090, 2128, 2158, 2185, 2209, 2224, 2237, + 2277, 2334, 2395, 2452, 2504, 2562, 2627, 2677, + 2694, 2677, 2632, 2570, 2504, 2446, 2397, 2332, + 2259, 2182, 2109, 2034, 1951, 1852, 1732, 1593, + 1437, 1291, 1167, 1047, 926, 810, 706, 632, + 577, 522, 487, 465, 427, 397, 412, 435, + 454, 488, 532, 593, 675, 760, 828, 903, + 980, 1041, 1108, 1181, 1249, 1306, 1354, 1402, + 1465, 1533, 1578, 1605, 1614, 1611, 1609, 1603, + 1592, 1592, 1597, 1588, 1594, 1620, 1651, 1686, + 1702, 1700, 1696, 1700, 1695, 1694, 1695, 1690, + 1693, 1699, 1717, 1743, 1753, 1754, 1754, 1751, + 1742, 1731, 1719, 1702, 1688, 1687, 1693, 1706, + 1723, 1741, 1767, 1803, 1851, 1905, 1964, 2034, + 2106, 2183, 2272, 2373, 2471, 2564, 2660, 2756, + 2847, 2947, 3037, 3120, 3209, 3289, 3362, 3432, + 3508, 3576, 3621, 3668, 3712, 3749, 3784, 3803, + 3821, 3862, 3892, 3900, 3928, 3973, 3988, 4005, + 4037, 4047, 4036, 4022, 3988, 3946, 3912, 3858, + 3784, 3710, 3633, 3546, 3446, 3344, 3221, 3046, + 2803, 2566, 2353, 2113, 1878, 1678, 1481, 1308, + 1191, 1088, 989, 921, 837, 727, 653, 596, + 519, 479, 498, 538, 606, 699, 799, 919, + 1049, 1174, 1286, 1387, 1485, 1579, 1642, 1695, + 1788, 1878, 1921, 1960, 2014, 2042, 2065, 2100, + 2117, 2128, 2133, 2116, 2104, 2123, 2160, 2166, + 2160, 2179, 2208, 2224, 2237, 2255, 2260, 2261, + 2285, 2325, 2381, 2455, 2530, 2598, 2674, 2751, + 2806, 2823, 2811, 2779, 2726, 2681, 2652, 2618, + 2569, 2519, 2465, 2408, 2352, 2286, 2196, 2075, + 1944, 1798, 1652, 1527, 1395, 1256, 1133, 1024, + 935, 856, 784, 704, 619, 550, 509, 485, + 458, 435, 419, 429, 462, 503, 547, 591, + 633, 673, 727, 792, 851, 912, 984, 1059, + 1136, 1222, 1305, 1377, 1427, 1460, 1488, 1512, + 1532, 1549, 1570, 1601, 1635, 1683, 1734, 1790, + 1841, 1867, 1888, 1905, 1912, 1910, 1904, 1894, + 1890, 1904, 1926, 1936, 1943, 1950, 1957, 1959, + 1952, 1930, 1901, 1864, 1822, 1795, 1773, 1754, + 1730, 1700, 1677, 1663, 1646, 1629, 1627, 1634, + 1652, 1687, 1739, 1801, 1868, 1938, 2004, 2077, + 2152, 2223, 2290, 2356, 2436, 2523, 2615, 2721, + 2831, 2939, 3034, 3118, 3199, 3263, 3307, 3338, + 3360, 3385, 3412, 3443, 3484, 3532, 3590, 3636, + 3678, 3741, 3795, 3823, 3843, 3860, 3869, 3883, + 3905, 3922, 3931, 3949, 3961, 3967, 3971, 3950, + 3917, 3867, 3796, 3725, 3641, 3527, 3364, 3145, + 2925, 2727, 2501, 2257, 2038, 1833, 1624, 1458, + 1332, 1208, 1102, 997, 875, 772, 695, 608, + 539, 519, 519, 538, 589, 658, 758, 881, + 1002, 1121, 1249, 1370, 1484, 1576, 1646, 1729, + 1821, 1872, 1910, 1966, 2011, 2047, 2093, 2135, + 2168, 2194, 2196, 2185, 2192, 2210, 2209, 2187, + 2176, 2179, 2183, 2183, 2191, 2198, 2198, 2214, + 2249, 2296, 2358, 2432, 2503, 2580, 2662, 2731, + 2778, 2798, 2799, 2781, 2760, 2744, 2719, 2690, + 2660, 2627, 2593, 2566, 2531, 2471, 2388, 2293, + 2188, 2074, 1965, 1850, 1725, 1591, 1448, 1321, + 1214, 1114, 1024, 945, 875, 819, 781, 749, + 711, 677, 640, 606, 595, 587, 579, 581, + 595, 622, 669, 735, 803, 875, 950, 1028, + 1106, 1177, 1229, 1266, 1295, 1321, 1350, 1381, + 1407, 1440, 1481, 1528, 1587, 1654, 1716, 1771, + 1812, 1836, 1853, 1871, 1877, 1876, 1877, 1878, + 1887, 1903, 1917, 1932, 1943, 1947, 1954, 1959, + 1961, 1953, 1935, 1911, 1883, 1851, 1812, 1763, + 1708, 1651, 1605, 1568, 1536, 1512, 1488, 1474, + 1470, 1482, 1502, 1527, 1554, 1580, 1608, 1649, + 1698, 1750, 1808, 1878, 1960, 2048, 2149, 2257, + 2358, 2448, 2534, 2620, 2711, 2796, 2863, 2917, + 2964, 3004, 3034, 3064, 3108, 3140, 3164, 3205, + 3250, 3293, 3327, 3355, 3386, 3423, 3462, 3484, + 3508, 3534, 3552, 3569, 3604, 3639, 3672, 3707, + 3737, 3772, 3803, 3829, 3844, 3850, 3840, 3814, + 3772, 3714, 3647, 3559, 3425, 3233, 3027, 2851, + 2657, 2445, 2257, 2089, 1918, 1770, 1645, 1522, + 1414, 1300, 1158, 1036, 939, 826, 725, 680, + 664, 668, 707, 755, 830, 935, 1031, 1122, + 1213, 1296, 1373, 1440, 1486, 1558, 1641, 1689, + 1732, 1791, 1842, 1889, 1940, 1977, 2013, 2045, + 2051, 2040, 2045, 2053, 2046, 2029, 2016, 2016, + 2020, 2012, 2010, 2013, 2013, 2034, 2069, 2111, + 2173, 2244, 2312, 2387, 2472, 2545, 2598, 2627, + 2643, 2655, 2658, 2667, 2675, 2678, 2686, 2699, + 2704, 2707, 2705, 2682, 2629, 2562, 2483, 2394, + 2306, 2212, 2115, 2022, 1933, 1845, 1755, 1661, + 1569, 1481, 1391, 1305, 1234, 1166, 1093, 1024, + 968, 922, 897, 866, 837, 821, 809, 795, + 792, 812, 829, 848, 872, 913, 966, 1020, + 1062, 1098, 1135, 1167, 1191, 1217, 1244, 1277, + 1316, 1357, 1410, 1472, 1532, 1583, 1633, 1677, + 1716, 1747, 1761, 1770, 1783, 1802, 1821, 1844, + 1872, 1897, 1918, 1929, 1934, 1937, 1934, 1922, + 1908, 1891, 1875, 1863, 1849, 1833, 1815, 1797, + 1774, 1753, 1730, 1706, 1679, 1652, 1636, 1622, + 1616, 1617, 1624, 1633, 1648, 1671, 1695, 1721, + 1752, 1794, 1843, 1894, 1958, 2022, 2084, 2144, + 2203, 2264, 2320, 2372, 2412, 2457, 2501, 2538, + 2577, 2616, 2651, 2683, 2711, 2736, 2764, 2789, + 2798, 2808, 2817, 2824, 2838, 2858, 2873, 2897, + 2921, 2939, 2971, 3004, 3030, 3054, 3079, 3104, + 3131, 3168, 3202, 3242, 3282, 3308, 3342, 3376, + 3408, 3432, 3444, 3445, 3442, 3428, 3404, 3378, + 3344, 3295, 3219, 3110, 2992, 2886, 2763, 2622, + 2498, 2377, 2254, 2155, 2056, 1960, 1891, 1803, + 1704, 1622, 1549, 1471, 1411, 1370, 1342, 1334, + 1331, 1342, 1378, 1427, 1475, 1521, 1557, 1594, + 1638, 1671, 1699, 1738, 1774, 1794, 1821, 1855, + 1876, 1905, 1924, 1930, 1937, 1943, 1935, 1919, + 1905, 1898, 1885, 1871, 1865, 1867, 1867, 1863, + 1862, 1859, 1865, 1878, 1891, 1909, 1942, 1989, + 2040, 2100, 2166, 2229, 2279, 2325, 2362, 2394, + 2427, 2458, 2478, 2496, 2523, 2549, 2567, 2590, + 2601, 2602, 2588, 2564, 2529, 2490, 2444, 2390, + 2334, 2279, 2227, 2174, 2121, 2068, 2014, 1954, + 1887, 1820, 1760, 1701, 1638, 1580, 1524, 1479, + 1444, 1415, 1391, 1372, 1355, 1338, 1322, 1314, + 1304, 1293, 1293, 1302, 1311, 1328, 1351, 1377, + 1413, 1450, 1478, 1506, 1535, 1567, 1604, 1641, + 1678, 1714, 1746, 1777, 1808, 1834, 1856, 1867, + 1870, 1869, 1870, 1866, 1856, 1852, 1852, 1853, + 1858, 1861, 1865, 1868, 1872, 1880, 1883, 1885, + 1885, 1886, 1887, 1888, 1891, 1895, 1895, 1888, + 1885, 1881, 1872, 1860, 1841, 1834, 1823, 1813, + 1809, 1804, 1803, 1804, 1810, 1817, 1825, 1836, + 1847, 1857, 1870, 1888, 1904, 1919, 1937, 1960, + 1983, 2004, 2026, 2045, 2066, 2084, 2098, 2115, + 2132, 2150, 2169, 2185, 2206, 2227, 2243, 2257, + 2271, 2285, 2295, 2302, 2309, 2316, 2323, 2333, + 2347, 2361, 2379, 2395, 2410, 2421, 2436, 2449, + 2465, 2480, 2491, 2500, 2513, 2525, 2538, 2557, + 2577, 2595, 2613, 2632, 2651, 2674, 2691, 2710, + 2727, 2745, 2758, 2769, 2785, 2800, 2810, 2816, + 2826, 2832, 2828, 2823, 2817, 2805, 2797, 2779, + 2750, 2716, 2684, 2650, 2609, 2569, 2528, 2485, + 2447, 2408, 2377, 2351, 2323, 2301, 2281, 2267, + 2257, 2247, 2241, 2243, 2247, 2247, 2253, 2259, + 2270, 2289, 2301, 2308, 2320, 2331, 2341, 2346, + 2348, 2350, 2347, 2338, 2330, 2321, 2311, 2302, + 2290, 2271, 2256, 2239, 2211, 2183, 2161, 2140, + 2115, 2087, 2064, 2047, 2029, 2015, 2001, 1988, + 1980, 1971, 1959, 1954, 1955, 1956, 1962, 1970, + 1978, 1987, 1995, 1998, 2001, 2003, 2000, 1997, + 1989, 1984, 1980, 1973, 1967, 1963, 1958, 1947, + 1939, 1929, 1917, 1905, 1893, 1880, 1869, 1860, + 1850, 1841, 1833, 1827, 1820, 1820, 1821, 1822, + 1824, 1824, 1822, 1824, 1830, 1831, 1837, 1849, + 1857, 1864, 1874, 1880, 1884, 1894, 1902, 1901, + 1900, 1900, 1903, 1909, 1910, 1909, 1901, 1895, + 1891, 1884, 1875, 1867, 1854, 1839, 1829, 1821, + 1811, 1803, 1791, 1779, 1774, 1764, 1751, 1735, + 1724, 1714, 1703, 1693, 1684, 1676, 1669, 1663, + 1659, 1656, 1655, 1653, 1650, 1650, 1651, 1652, + 1652, 1652, 1654, 1656, 1661, 1670, 1677, 1681, + 1690, 1700, 1711, 1719, 1729, 1742, 1750, 1761, + 1771, 1782, 1793, 1803, 1815, 1826, 1836, 1849, + 1861, 1874, 1884, 1894, 1910, 1921, 1934, 1947, + 1960, 1969, 1980, 1995, 2005, 2014, 2022, 2029, + 2035, 2040, 2048, 2054, 2059, 2066, 2074, 2082, + 2088, 2091, 2096, 2102, 2100, 2101, 2104, 2107, + 2113, 2121, 2131, 2136, 2140, 2145, 2148, 2151, + 2156, 2162, 2165, 2170, 2175, 2179, 2184, 2191, + 2198, 2206, 2219, 2229, 2240, 2252, 2268, 2282, + 2295, 2310, 2328, 2346, 2364, 2383, 2402, 2420, + 2439, 2456, 2472, 2489, 2503, 2516, 2530, 2545, + 2561, 2575, 2587, 2595, 2602, 2610, 2615, 2620, + 2620, 2619, 2615, 2612, 2609, 2600, 2594, 2583, + 2571, 2559, 2545, 2531, 2513, 2496, 2477, 2465, + 2451, 2438, 2426, 2409, 2395, 2385, 2369, 2354, + 2344, 2332, 2321, 2310, 2299, 2293, 2289, 2284, + 2277, 2265, 2256, 2249, 2234, 2223, 2215, 2201, + 2189, 2180, 2169, 2158, 2148, 2136, 2120, 2105, + 2091, 2073, 2053, 2034, 2016, 1998, 1982, 1968, + 1959, 1946, 1936, 1929, 1919, 1914, 1909, 1902, + 1899, 1894, 1892, 1890, 1891, 1894, 1895, 1897, + 1895, 1895, 1892, 1892, 1888, 1882, 1877, 1872, + 1869, 1862, 1859, 1858, 1854, 1849, 1843, 1837, + 1828, 1821, 1813, 1801, 1788, 1781, 1772, 1763, + 1752, 1745, 1735, 1724, 1713, 1704, 1693, 1685, + 1677, 1671, 1667, 1667, 1668, 1668, 1670, 1674, + 1678, 1680, 1681, 1683, 1686, 1688, 1689, 1694, + 1696, 1694, 1694, 1700, 1704, 1707, 1711, 1717, + 1721, 1730, 1736, 1741, 1746, 1753, 1760, 1765, + 1775, 1782, 1786, 1793, 1798, 1803, 1811, 1815, + 1822, 1830, 1836, 1844, 1852, 1857, 1864, 1870, + 1873, 1878, 1883, 1885, 1888, 1893, 1894, 1900, + 1905, 1908, 1912, 1916, 1921, 1925, 1927, 1931, + 1936, 1935, 1940, 1945, 1945, 1946, 1952, 1955, + 1958, 1963, 1965, 1967, 1970, 1969, 1969, 1974, + 1974, 1973, 1974, 1975, 1977, 1979, 1983, 1984, + 1989, 1996, 2002, 2002, 2007, 2016, 2021, 2022, + 2029, 2038, 2039, 2041, 2049, 2051, 2054, 2058, + 2063, 2065, 2072, 2079, 2084, 2091, 2100, 2109, + 2114, 2122, 2128, 2135, 2142, 2153, 2162, 2167, + 2179, 2191, 2195, 2204, 2215, 2222, 2233, 2244, + 2253, 2259, 2267, 2275, 2281, 2289, 2297, 2302, + 2301, 2308, 2316, 2316, 2321, 2324, 2324, 2329, + 2334, 2335, 2337, 2339, 2339, 2341, 2342, 2344, + 2344, 2345, 2346, 2349, 2348, 2349, 2350, 2351, + 2350, 2351, 2352, 2350, 2350, 2351, 2347, 2346, + 2346, 2346, 2340, 2339, 2340, 2341, 2337, 2335, + 2335, 2329, 2327, 2324, 2322, 2318, 2318, 2315, + 2311, 2309, 2305, 2303, 2300, 2303, 2301, 2295, + 2292, 2290, 2286, 2282, 2277, 2272, 2267, 2256, + 2248, 2242, 2231, 2220, 2207, 2196, 2185, 2176, + 2166, 2153, 2144, 2132, 2121, 2111, 2100, 2087, + 2074, 2060, 2051, 2042, 2030, 2025, 2015, 2005, + 1998, 1993, 1985, 1978, 1969, 1960, 1954, 1947, + 1940, 1932, 1928, 1921, 1915, 1912, 1904, 1899, + 1892, 1889, 1887, 1879, 1873, 1866, 1860, 1852, + 1848, 1842, 1837, 1835, 1833, 1832, 1828, 1827, + 1826, 1825, 1825, 1824, 1823, 1827, 1829, 1830, + 1833, 1835, 1839, 1841, 1843, 1842, 1846, 1848, + 1851, 1853, 1857, 1863, 1866, 1870, 1871, 1875, + 1877, 1879, 1880, 1881, 1882, 1882, 1883, 1882, + 1884, 1885, 1886, 1886, 1889, 1890, 1890, 1893, + 1893, 1891, 1891, 1893, 1892, 1894, 1896, 1897, + 1900, 1904, 1908, 1913, 1913, 1914, 1919, 1919, + 1923, 1929, 1932, 1937, 1940, 1945, 1949, 1953, + 1955, 1958, 1962, 1967, 1973, 1976, 1977, 1982, + 1986, 1989, 1993, 1999, 2001, 2007, 2009, 2012, + 2018, 2022, 2025, 2033, 2040, 2045, 2051, 2059, + 2064, 2073, 2081, 2082, 2092, 2098, 2105, 2111, + 2116, 2121, 2128, 2133, 2136, 2139, 2142, 2146, + 2152, 2156, 2158, 2161, 2167, 2165, 2169, 2173, + 2174, 2179, 2175, 2176, 2179, 2181, 2184, 2185, + 2186, 2188, 2191, 2189, 2190, 2190, 2191, 2193, + 2197, 2197, 2196, 2199, 2199, 2199, 2201, 2203, + 2205, 2208, 2210, 2212, 2214, 2216, 2219, 2222, + 2222, 2227, 2229, 2229, 2233, 2234, 2236, 2238, + 2240, 2242, 2244, 2248, 2249, 2251, 2250, 2250, + 2251, 2248, 2248, 2247, 2248, 2250, 2250, 2248, + 2247, 2247, 2247, 2247, 2248, 2250, 2252, 2253, + 2253, 2254, 2256, 2258, 2257, 2257, 2256, 2259, + 2258, 2257, 2257, 2256, 2253, 2256, 2258, 2254, + 2251, 2247, 2245, 2243, 2240, 2236, 2231, 2227, + 2224, 2221, 2217, 2215, 2214, 2210, 2206, 2202, + 2200, 2199, 2193, 2190, 2186, 2182, 2180, 2175, + 2171, 2168, 2162, 2157, 2152, 2148, 2144, 2139, + 2131, 2125, 2118, 2113, 2109, 2104, 2099, 2095, + 2090, 2087, 2082, 2076, 2070, 2068, 2065, 2056, + 2052, 2051, 2048, 2048, 2043, 2041, 2037, 2034, + 2030, 2026, 2023, 2021, 2020, 2017, 2014, 2011, + 2009, 2005, 2004, 2003, 2002, 2001, 2000, 1995, + 1993, 1992, 1987, 1984, 1984, 1979, 1976, 1972, + 1967, 1966, 1962, 1960, 1957, 1956, 1956, 1955, + 1953, 1951, 1949, 1946, 1944, 1942, 1938, 1936, + 1937, 1934, 1932, 1932, 1930, 1928, 1929, 1926, + 1925, 1925, 1923, 1923, 1922, 1919, 1922, 1920, + 1920, 1921, 1919, 1924, 1926, 1928, 1929, 1929, + 1934, 1936, 1936, 1937, 1937, 1939, 1939, 1943, + 1944, 1947, 1948, 1950, 1952, 1955, 1959, 1959, + 1963, 1964, 1967, 1970, 1972, 1975, 1978, 1981, + 1985, 1985, 1991, 1994, 1997, 2002, 2007, 2013, + 2016, 2022, 2025, 2028, 2031, 2032, 2033, 2035, + 2040, 2043, 2046, 2049, 2053, 2052, 2052, 2051, + 2050, 2052, 2054, 2053, 2053, 2058, 2062, 2063, + 2064, 2066, 2068, 2066, 2069, 2070, 2071, 2073, + 2074, 2074, 2076, 2076, 2076, 2078, 2077, 2079, + 2078, 2079, 2079, 2078, 2078, 2077, 2074, 2074, + 2073, 2074, 2070, 2068, 2070, 2069, 2067, 2067, + 2064, 2064, 2066, 2065, 2065, 2064, 2063, 2066, + 2066, 2066, 2064, 2065, 2067, 2065, 2067, 2068, + 2067, 2067, 2068, 2068, 2068, 2068, 2069, 2069, + 2071, 2071, 2072, 2075, 2076, 2076, 2076, 2076, + 2076, 2077, 2078, 2080, 2082, 2084, 2087, 2089, + 2090, 2091, 2091, 2093, 2091, 2093, 2097, 2097, + 2098, 2100, 2102, 2102, 2105, 2104, 2103, 2103, + 2105, 2105, 2111, 2112, 2109, 2111, 2111, 2110, + 2108, 2108, 2109, 2110, 2112, 2110, 2106, 2106, + 2106, 2106, 2101, 2102, 2103, 2101, 2098, 2098, + 2098, 2096, 2092, 2092, 2088, 2089, 2085, 2082, + 2081, 2077, 2074, 2069, 2068, 2062, 2058, 2057, + 2054, 2051, 2048, 2046, 2042, 2041, 2037, 2037, + 2031, 2026, 2026, 2021, 2018, 2015, 2011, 2006, + 2000, 1999, 1994, 1991, 1986, 1983, 1984, 1982, + 1980, 1978, 1978, 1977, 1976, 1975, 1973, 1974, + 1974, 1974, 1974, 1974, 1977, 1978, 1977, 1976, + 1976, 1977, 1976, 1978, 1981, 1982, 1980, 1983, + 1984, 1985, 1986, 1985, 1982, 1983, 1983, 1984, + 1984, 1987, 1984, 1983, 1984, 1980, 1979, 1984, + 1981, 1980, 1983, 1985, 1984, 1984, 1982, 1982, + 1987, 1987, 1986, 1992, 1989, 1989, 1998, 2001, + 2000, 2002, 2003, 2003, 2004, 2005, 2007, 2009, + 2010, 2010, 2013, 2013, 2014, 2014, 2016, 2021, + 2018, 2019, 2022, 2026, 2029, 2028, 2029, 2029, + 2033, 2034, 2032, 2035, 2035, 2035, 2038, 2039, + 2041, 2044, 2047, 2046, 2047, 2052, 2054, 2058, + 2059, 2058, 2060, 2063, 2065, 2068, 2067, 2069, + 2068, 2067, 2071, 2073, 2073, 2073, 2075, 2073, + 2071, 2069, 2072, 2072, 2072, 2073, 2072, 2067, + 2063, 2068, 2069, 2068, 2067, 2066, 2066, 2064, + 2065, 2064, 2063, 2061, 2061, 2059, 2061, 2061, + 2059, 2058, 2059, 2056, 2051, 2052, 2051, 2047, + 2045, 2042, 2039, 2041, 2041, 2036, 2035, 2032, + 2031, 2032, 2031, 2028, 2028, 2026, 2026, 2023, + 2022, 2021, 2022, 2022, 2020, 2019, 2016, 2018, + 2017, 2016, 2015, 2013, 2016, 2019, 2019, 2021, + 2023, 2024, 2025, 2027, 2029, 2030, 2033, 2032, + 2035, 2041, 2042, 2043, 2046, 2050, 2051, 2053, + 2057, 2056, 2058, 2055, 2056, 2056, 2054, 2051, + 2051, 2051, 2046, 2045, 2047, 2046, 2046, 2047, + 2046, 2043, 2044, 2041, 2041, 2040, 2040, 2041, + 2040, 2041, 2038, 2036, 2035, 2036, 2037, 2037, + 2034, 2035, 2033, 2030, 2030, 2029, 2029, 2028, + 2027, 2028, 2028, 2026, 2025, 2025, 2028, 2028, + 2030, 2031, 2031, 2033, 2038, 2039, 2040, 2042, + 2044, 2048, 2050, 2050, 2055, 2059, 2064, 2065, + 2068, 2071, 2074, 2076, 2076, 2080, 2086, 2085, + 2086, 2091, 2090, 2092, 2096, 2096, 2097, 2100, + 2103, 2105, 2103, 2104, 2104, 2106, 2107, 2106, + 2107, 2108, 2107, 2108, 2109, 2107, 2107, 2109, + 2107, 2108, 2105, 2103, 2102, 2101, 2101, 2101, + 2101, 2100, 2102, 2099, 2100, 2103, 2100, 2098, + 2095, 2096, 2091, 2088, 2087, 2087, 2086, 2084, + 2084, 2081, 2082, 2081, 2077, 2075, 2073, 2071, + 2069, 2067, 2067, 2067, 2066, 2065, 2068, 2068, + 2066, 2066, 2064, 2063, 2063, 2060, 2058, 2058, + 2057, 2057, 2057, 2055, 2051, 2048, 2049, 2047, + 2046, 2045, 2042, 2042, 2042, 2040, 2040, 2039, + 2038, 2034, 2032, 2032, 2032, 2031, 2029, 2029, + 2028, 2028, 2028, 2026, 2024, 2025, 2026, 2023, + 2024, 2024, 2023, 2023, 2020, 2021, 2020, 2021, + 2023, 2024, 2024, 2026, 2026, 2026, 2026, 2030, + 2028, 2030, 2032, 2034, 2032, 2032, 2032, 2034, + 2038, 2039, 2039, 2037, 2036, 2041, 2043, 2043, + 2044, 2046, 2050, 2052, 2046, 2045, 2048, 2051, + 2049, 2049, 2047, 2047, 2046, 2042, 2041, 2043, + 2040, 2040, 2045, 2045, 2043, 2043, 2038, 2040, + 2037, 2030, 2027, 2031, 2038, 2034, 2038, 2039, + 2033, 2032, 2032, 2028, 2029, 2035, 2037, 2038, + 2038, 2038, 2044, 2047, 2042, 2039, 2043, 2042, + 2044, 2048, 2048, 2051, 2051, 2056, 2058, 2058, + 2055, 2055, 2055, 2060, 2066, 2067, 2070, 2072, + 2074, 2069, 2069, 2070, 2070, 2074, 2076, 2074, + 2074, 2077, 2079, 2080, 2080, 2081, 2078, 2082, + 2084, 2084, 2086, 2086, 2087, 2081, 2087, 2090, + 2088, 2089, 2090, 2087, 2087, 2087, 2086, 2090, + 2094, 2090, 2088, 2093, 2093, 2091, 2090, 2089, + 2087, 2088, 2089, 2092, 2095, 2092, 2086, 2085, + 2085, 2085, 2088, 2087, 2084, 2078, 2075, 2078, + 2079, 2073, 2065, 2063, 2066, 2066, 2065, 2067, + 2063, 2056, 2060, 2062, 2060, 2059, 2062, 2057, + 2056, 2055, 2056, 2059, 2058, 2059, 2052, 2052, + 2054, 2054, 2057, 2055, 2053, 2055, 2056, 2054, + 2048, 2044, 2043, 2041, 2037, 2033, 2031, 2033, + 2035, 2035, 2030, 2025, 2024, 2025, 2028, 2024, + 2021, 2023, 2020, 2016, 2020, 2020, 2012, 2009, + 2015, 2019, 2021, 2019, 2015, 2018, 2017, 2012, + 2011, 2017, 2015, 2012, 2011, 2010, 2011, 2017, + 2018, 2014, 2013, 2015, 2011, 2006, 2006, 2005, + 2005, 2006, 2001, 2002, 2009, 2009, 2010, 2013, + 2017, 2021, 2019, 2020, 2024, 2025, 2028, 2029, + 2028, 2032, 2034, 2037, 2040, 2038, 2036, 2036, + 2040, 2039, 2034, 2034, 2033, 2027, 2030, 2033, + 2030, 2030, 2032, 2030, 2028, 2029, 2027, 2023, + 2022, 2022, 2017, 2018, 2021, 2020, 2017, 2014, + 2017, 2017, 2015, 2020, 2021, 2018, 2019, 2020, + 2021, 2019, 2017, 2017, 2018, 2021, 2021, 2021, + 2024, 2029, 2031, 2035, 2035, 2035, 2036, 2035, + 2038, 2043, 2047, 2048, 2046, 2043, 2045, 2047, + 2046, 2047, 2047, 2048, 2051, 2052, 2052, 2052, + 2052, 2051, 2052, 2050, 2045, 2047, 2050, 2048, + 2049, 2048, 2046, 2050, 2051, 2051, 2052, 2052, + 2055, 2056, 2056, 2055, 2060, 2061, 2057, 2061, + 2064, 2064, 2061, 2061, 2060, 2064, 2064, 2065, + 2068, 2067, 2066, 2066, 2067, 2069, 2070, 2068, + 2069, 2069, 2069, 2073, 2074, 2074, 2075, 2078, + 2082, 2081, 2079, 2084, 2088, 2086, 2085, 2088, + 2091, 2092, 2096, 2100, 2107, 2109, 2110, 2110, + 2113, 2112, 2110, 2114, 2116, 2116, 2116, 2115, + 2114, 2112, 2109, 2110, 2111, 2112, 2112, 2109, + 2108, 2108, 2111, 2113, 2113, 2111, 2109, 2107, + 2107, 2106, 2106, 2106, 2106, 2104, 2100, 2105, + 2105, 2101, 2104, 2104, 2104, 2103, 2098, 2096, + 2100, 2102, 2098, 2098, 2097, 2094, 2094, 2091, + 2089, 2090, 2091, 2091, 2087, 2086, 2086, 2086, + 2087, 2088, 2085, 2082, 2079, 2078, 2079, 2077, + 2079, 2077, 2078, 2078, 2077, 2078, 2083, 2083, + 2082, 2082, 2085, 2086, 2092, 2095, 2092, 2092, + 2096, 2096, 2100, 2102, 2103, 2106, 2108, 2106, + 2104, 2106, 2108, 2109, 2108, 2108, 2106, 2106, + 2103, 2103, 2105, 2103, 2102, 2099, 2098, 2101, + 2101, 2103, 2104, 2107, 2106, 2105, 2106, 2108, + 2108, 2107, 2107, 2106, 2109, 2111, 2108, 2107, + 2107, 2108, 2104, 2105, 2104, 2102, 2101, 2103, + 2107, 2103, 2101, 2099, 2096, 2097, 2098, 2098, + 2098, 2098, 2098, 2100, 2099, 2098, 2099, 2098, + 2098, 2100, 2102, 2099, 2098, 2096, 2095, 2097, + 2094, 2095, 2092, 2086, 2081, 2079, 2070, 2063, + 2053, 2046, 1902, 1613, 1570, 1719, 1812, 1882, + 1946, 1964, 1959, 1931, 1918, 1942, 1980, 2003, + 2025, 2040, 2049, 2063, 2059, 2053, 2062, 2086, + 2102, 2119, 2114, 2081, 2034, 2009, 2013, 2033, + 2068, 2109, 2134, 2126, 2096, 2053, 2007, 1980, + 1980, 2016, 2063, 2086, 2092, 2088, 2082, 2065, + 2051, 2037, 2030, 2040, 2056, 2065, 2048, 2026, + 2014, 2015, 2032, 2054, 2075, 2080, 2069, 2054, + 2031, 2011, 1994, 1982, 1987, 2005, 2030, 2055, + 2064, 2037, 1997, 1967, 1965, 1984, 2004, 2011, + 2007, 2002, 1993, 1985, 1985, 1984, 1985, 1988, + 1994, 1991, 1979, 1960, 1946, 1938, 1931, 1937, + 1952, 1972, 1984, 1979, 1953, 1927, 1909, 1894, + 1897, 1914, 1932, 1939, 1932, 1920, 1914, 1907, + 1913, 1933, 1944, 1937, 1933, 1935, 1925, 1916, + 1909, 1909, 1918, 1936, 1954, 1958, 1953, 1941, + 1927, 1914, 1908, 1925, 1941, 1949, 1955, 1954, + 1950, 1946, 1940, 1929, 1926, 1929, 1937, 1945, + 1950, 1942, 1932, 1925, 1928, 1940, 1947, 1950, + 1951, 1947, 1937, 1924, 1922, 1928, 1931, 1939, + 1947, 1950, 1948, 1941, 1938, 1932, 1927, 1924, + 1926, 1929, 1929, 1931, 1928, 1915, 1909, 1906, + 1909, 1914, 1919, 1921, 1919, 1912, 1903, 1897, + 1899, 1901, 1906, 1909, 1901, 1896, 1897, 1896, + 1893, 1887, 1880, 1884, 1884, 1878, 1878, 1881, + 1875, 1866, 1863, 1854, 1852, 1860, 1865, 1861, + 1853, 1859, 1865, 1865, 1858, 1859, 1858, 1853, + 1852, 1849, 1848, 1846, 1845, 1841, 1830, 1820, + 1827, 1834, 1827, 1828, 1826, 1806, 1804, 1805, + 1806, 1818, 1818, 1813, 1814, 1808, 1804, 1806, + 1813, 1816, 1820, 1821, 1816, 1815, 1813, 1814, + 1818, 1823, 1831, 1841, 1844, 1831, 1825, 1825, + 1821, 1826, 1827, 1827, 1831, 1836, 1841, 1840, + 1830, 1834, 1843, 1845, 1851, 1855, 1849, 1842, + 1839, 1838, 1837, 1841, 1841, 1842, 1842, 1836, + 1830, 1826, 1830, 1842, 1846, 1855, 1864, 1860, + 1859, 1857, 1850, 1853, 1859, 1858, 1862, 1867, + 1868, 1862, 1850, 1842, 1842, 1839, 1847, 1864, + 1870, 1869, 1870, 1862, 1850, 1842, 1846, 1856, + 1859, 1866, 1870, 1866, 1857, 1847, 1844, 1848, + 1858, 1863, 1863, 1861, 1856, 1853, 1858, 1867, + 1873, 1883, 1889, 1892, 1891, 1885, 1884, 1886, + 1891, 1904, 1919, 1925, 1924, 1919, 1911, 1904, + 1894, 1894, 1904, 1915, 1927, 1936, 1937, 1936, + 1926, 1918, 1920, 1926, 1931, 1938, 1937, 1935, + 1936, 1946, 1958, 1962, 1965, 1963, 1953, 1950, + 1947, 1935, 1923, 1914, 1911, 1914, 1925, 1931, + 1933, 1934, 1927, 1923, 1921, 1926, 1926, 1924, + 1929, 1938, 1952, 1956, 1956, 1959, 1957, 1960, + 1964, 1958, 1946, 1947, 1953, 1960, 1969, 1977, + 1983, 1981, 1975, 1965, 1955, 1948, 1937, 1921, + 1916, 1922, 1931, 1945, 1954, 1960, 1957, 1944, + 1927, 1922, 1923, 1925, 1929, 1932, 1943, 1952, + 1960, 1958, 1953, 1953, 1939, 1914, 1901, 1887, + 1880, 1878, 1878, 1883, 1881, 1882, 1888, 1896, + 1895, 1879, 1864, 1846, 1829, 1831, 1842, 1846, + 1851, 1867, 1873, 1866, 1852, 1838, 1834, 1833, + 1831, 1828, 1823, 1820, 1829, 1836, 1838, 1838, + 1837, 1827, 1814, 1801, 1801, 1802, 1797, 1797, + 1814, 1830, 1837, 1844, 1847, 1840, 1830, 1818, + 1803, 1797, 1801, 1811, 1823, 1838, 1837, 1823, + 1810, 1798, 1783, 1765, 1744, 1723, 1708, 1701, + 1701, 1715, 1728, 1737, 1731, 1725, 1723, 1719, + 1700, 1679, 1672, 1671, 1668, 1672, 1678, 1683, + 1692, 1698, 1695, 1684, 1671, 1662, 1660, 1653, + 1641, 1639, 1644, 1657, 1672, 1668, 1647, 1632, + 1626, 1617, 1598, 1584, 1588, 1597, 1603, 1613, + 1622, 1621, 1614, 1606, 1600, 1592, 1575, 1551, + 1537, 1531, 1525, 1531, 1557, 1573, 1574, 1571, + 1571, 1568, 1558, 1561, 1554, 1538, 1531, 1539, + 1553, 1560, 1558, 1547, 1531, 1511, 1498, 1493, + 1491, 1500, 1509, 1508, 1505, 1502, 1505, 1519, + 1531, 1527, 1524, 1529, 1524, 1513, 1517, 1521, + 1527, 1547, 1569, 1592, 1598, 1587, 1569, 1553, + 1538, 1528, 1531, 1538, 1540, 1540, 1544, 1552, + 1552, 1552, 1551, 1557, 1560, 1557, 1557, 1550, + 1535, 1513, 1493, 1501, 1524, 1536, 1543, 1542, + 1534, 1531, 1533, 1544, 1568, 1596, 1616, 1636, + 1653, 1658, 1654, 1647, 1641, 1634, 1637, 1632, + 1630, 1634, 1634, 1637, 1639, 1639, 1650, 1674, + 1689, 1687, 1672, 1663, 1647, 1635, 1646, 1661, + 1680, 1707, 1728, 1731, 1732, 1727, 1710, 1702, + 1711, 1730, 1758, 1770, 1772, 1779, 1778, 1776, + 1793, 1811, 1815, 1822, 1828, 1821, 1811, 1809, + 1812, 1828, 1852, 1871, 1891, 1899, 1881, 1856, + 1837, 1828, 1834, 1853, 1882, 1912, 1930, 1936, + 1931, 1924, 1934, 1962, 1991, 2007, 2007, 2003, + 2001, 1999, 2015, 2038, 2066, 2093, 2112, 2120, + 2119, 2112, 2104, 2106, 2123, 2136, 2155, 2178, + 2195, 2188, 2162, 2145, 2144, 2148, 2160, 2180, + 2194, 2201, 2196, 2189, 2186, 2197, 2213, 2233, + 2243, 2238, 2230, 2217, 2201, 2203, 2216, 2232, + 2251, 2267, 2278, 2283, 2276, 2258, 2252, 2264, + 2279, 2294, 2304, 2302, 2293, 2283, 2277, 2285, + 2302, 2315, 2320, 2313, 2309, 2311, 2316, 2322, + 2334, 2349, 2359, 2368, 2381, 2390, 2384, 2377, + 2381, 2404, 2430, 2449, 2464, 2479, 2481, 2471, + 2475, 2491, 2510, 2524, 2528, 2524, 2520, 2516, + 2523, 2539, 2550, 2559, 2572, 2582, 2583, 2579, + 2573, 2570, 2572, 2574, 2581, 2589, 2600, 2610, + 2602, 2594, 2596, 2610, 2629, 2641, 2642, 2638, + 2643, 2648, 2652, 2660, 2672, 2683, 2682, 2682, + 2692, 2700, 2699, 2703, 2715, 2721, 2724, 2734, + 2740, 2740, 2732, 2726, 2729, 2733, 2731, 2725, + 2721, 2722, 2718, 2708, 2703, 2707, 2714, 2720, + 2722, 2722, 2719, 2708, 2701, 2698, 2693, 2686, + 2679, 2678, 2676, 2676, 2672, 2671, 2663, 2648, + 2632, 2620, 2614, 2615, 2617, 2616, 2611, 2609, + 2603, 2592, 2586, 2587, 2590, 2594, 2590, 2584, + 2574, 2561, 2548, 2534, 2522, 2511, 2503, 2503, + 2501, 2496, 2488, 2488, 2486, 2484, 2492, 2504, + 2499, 2484, 2478, 2474, 2467, 2461, 2458, 2456, + 2449, 2438, 2429, 2426, 2422, 2413, 2404, 2394, + 2387, 2390, 2392, 2392, 2389, 2382, 2375, 2372, + 2367, 2355, 2347, 2346, 2344, 2340, 2333, 2325, + 2317, 2313, 2307, 2303, 2307, 2305, 2297, 2292, + 2288, 2282, 2280, 2282, 2289, 2295, 2298, 2289, + 2276, 2262, 2254, 2253, 2254, 2252, 2249, 2246, + 2234, 2221, 2213, 2214, 2208, 2198, 2192, 2194, + 2190, 2179, 2169, 2167, 2166, 2167, 2167, 2163, + 2155, 2144, 2133, 2130, 2130, 2127, 2123, 2124, + 2124, 2120, 2120, 2116, 2112, 2114, 2116, 2103, + 2083, 2074, 2068, 2068, 2069, 2079, 2093, 2098, + 2089, 2085, 2088, 2090, 2084, 2075, 2074, 2075, + 2079, 2081, 2079, 2075, 2076, 2086, 2096, 2099, + 2104, 2107, 2109, 2112, 2112, 2111, 2113, 2119, + 2123, 2128, 2131, 2130, 2123, 2117, 2118, 2120, + 2125, 2128, 2134, 2135, 2139, 2137, 2131, 2126, + 2123, 2127, 2127, 2126, 2121, 2119, 2114, 2115, + 2118, 2121, 2123, 2123, 2123, 2119, 2113, 2110, + 2107, 2102, 2102, 2105, 2109, 2109, 2099, 2085, + 2077, 2076, 2081, 2087, 2097, 2101, 2102, 2103, + 2104, 2103, 2104, 2108, 2111, 2112, 2111, 2109, + 2106, 2100, 2097, 2095, 2089, 2094, 2094, 2085, + 2074, 2067, 2058, 2053, 2056, 2058, 2056, 2052, + 2044, 2038, 2030, 2023, 2024, 2027, 2028, 2026, + 2019, 2015, 2020, 2022, 2020, 2013, 2013, 2010, + 2005, 2005, 2007, 2009, 2017, 2019, 2020, 2020, + 2021, 2021, 2019, 2015, 2019, 2023, 2031, 2039, + 2044, 2046, 2042, 2041, 2039, 2042, 2039, 2034, + 2030, 2025, 2019, 2020, 2022, 2026, 2028, 2026, + 2017, 2007, 1996, 1983, 1981, 1984, 1984, 1976, + 1973, 1974, 1966, 1953, 1947, 1948, 1947, 1943, + 1933, 1922, 1911, 1905, 1911, 1918, 1924, 1934, + 1942, 1938, 1933, 1927, 1928, 1932, 1937, 1950, + 1960, 1963, 1961, 1960, 1964, 1962, 1959, 1963, + 1964, 1956, 1946, 1936, 1935, 1931, 1925, 1926, + 1935, 1935, 1927, 1914, 1905, 1899, 1901, 1907, + 1910, 1912, 1910, 1908, 1908, 1909, 1914, 1918, + 1917, 1912, 1909, 1911, 1909, 1905, 1909, 1921, + 1931, 1936, 1938, 1940, 1942, 1937, 1934, 1926, + 1929, 1948, 1961, 1960, 1960, 1963, 1963, 1957, + 1954, 1955, 1955, 1953, 1950, 1948, 1953, 1959, + 1956, 1945, 1945, 1952, 1951, 1941, 1929, 1923, + 1926, 1931, 1933, 1940, 1959, 1969, 1961, 1949, + 1948, 1956, 1955, 1955, 1952, 1952, 1957, 1961, + 1968, 1977, 1986, 1991, 1985, 1987, 1991, 1988, + 1989, 1996, 2004, 2010, 2019, 2036, 2048, 2048, + 2044, 2041, 2040, 2048, 2062, 2075, 2078, 2074, + 2080, 2092, 2105, 2118, 2129, 2129, 2123, 2130, + 2141, 2144, 2148, 2163, 2173, 2168, 2169, 2179, + 2187, 2187, 2182, 2179, 2178, 2183, 2181, 2182, + 2190, 2202, 2204, 2195, 2194, 2196, 2198, 2197, + 2193, 2187, 2186, 2189, 2192, 2196, 2199, 2201, + 2198, 2196, 2201, 2201, 2196, 2191, 2193, 2202, + 2216, 2225, 2226, 2224, 2223, 2229, 2231, 2231, + 2236, 2241, 2242, 2240, 2251, 2260, 2265, 2267, + 2277, 2277, 2271, 2278, 2290, 2294, 2292, 2293, + 2301, 2308, 2320, 2332, 2339, 2336, 2327, 2320, + 2330, 2349, 2359, 2361, 2361, 2364, 2361, 2366, + 2371, 2378, 2380, 2379, 2374, 2367, 2367, 2370, + 2375, 2376, 2373, 2374, 2376, 2366, 2361, 2363, + 2362, 2358, 2354, 2351, 2355, 2360, 2359, 2361, + 2364, 2368, 2372, 2374, 2376, 2378, 2382, 2385, + 2393, 2400, 2400, 2393, 2394, 2399, 2399, 2397, + 2397, 2398, 2399, 2399, 2406, 2415, 2414, 2408, + 2402, 2405, 2408, 2405, 2404, 2404, 2404, 2410, + 2414, 2417, 2423, 2419, 2419, 2420, 2418, 2420, + 2423, 2423, 2420, 2424, 2421, 2420, 2426, 2431, + 2429, 2423, 2417, 2413, 2413, 2413, 2420, 2425, + 2424, 2424, 2419, 2416, 2417, 2422, 2418, 2420, + 2423, 2423, 2422, 2426, 2436, 2441, 2442, 2444, + 2446, 2446, 2442, 2443, 2446, 2449, 2446, 2445, + 2449, 2454, 2459, 2457, 2453, 2451, 2448, 2443, + 2441, 2445, 2447, 2449, 2450, 2452, 2455, 2459, + 2457, 2451, 2444, 2439, 2439, 2441, 2448, 2453, + 2455, 2462, 2468, 2471, 2476, 2482, 2486, 2490, + 2486, 2488, 2493, 2500, 2511, 2517, 2520, 2518, + 2521, 2526, 2525, 2521, 2528, 2539, 2545, 2547, + 2554, 2562, 2568, 2573, 2578, 2581, 2586, 2592, + 2596, 2600, 2607, 2612, 2619, 2631, 2639, 2641, + 2639, 2635, 2634, 2639, 2647, 2647, 2645, 2651, + 2650, 2649, 2646, 2635, 2628, 2628, 2627, 2621, + 2614, 2604, 2593, 2591, 2596, 2601, 2595, 2588, + 2590, 2587, 2578, 2579, 2585, 2590, 2589, 2587, + 2589, 2587, 2581, 2582, 2583, 2578, 2572, 2576, + 2576, 2578, 2577, 2576, 2577, 2580, 2584, 2586, + 2588, 2583, 2581, 2587, 2588, 2585, 2591, 2602, + 2605, 2607, 2607, 2609, 2611, 2612, 2614, 2615, + 2615, 2610, 2610, 2610, 2608, 2608, 2609, 2611, + 2600, 2591, 2593, 2592, 2589, 2582, 2575, 2572, + 2572, 2567, 2562, 2557, 2553, 2541, 2532, 2534, + 2534, 2530, 2529, 2526, 2522, 2518, 2512, 2504, + 2507, 2514, 2506, 2494, 2493, 2495, 2490, 2485, + 2487, 2489, 2483, 2470, 2468, 2471, 2471, 2468, + 2465, 2458, 2454, 2449, 2444, 2438, 2429, 2418, + 2416, 2412, 2408, 2404, 2394, 2395, 2395, 2384, + 2376, 2369, 2365, 2359, 2350, 2343, 2343, 2339, + 2331, 2330, 2324, 2320, 2315, 2303, 2295, 2292, + 2289, 2281, 2279, 2276, 2273, 2268, 2266, 2264, + 2259, 2251, 2248, 2244, 2242, 2238, 2234, 2231, + 2231, 2223, 2218, 2218, 2221, 2217, 2209, 2205, + 2201, 2200, 2199, 2202, 2205, 2207, 2203, 2202, + 2201, 2198, 2195, 2195, 2194, 2192, 2191, 2194, + 2196, 2200, 2199, 2202, 2200, 2199, 2196, 2197, + 2203, 2201, 2202, 2204, 2207, 2208, 2211, 2216, + 2215, 2214, 2212, 2213, 2217, 2223, 2227, 2230, + 2236, 2239, 2248, 2254, 2258, 2263, 2269, 2277, + 2286, 2300, 2315, 2331, 2342, 2355, 2371, 2385, + 2398, 2413, 2430, 2443, 2458, 2473, 2486, 2497, + 2512, 2523, 2529, 2533, 2538, 2542, 2546, 2549, + 2553, 2559, 2564, 2564, 2560, 2563, 2559, 2552, + 2548, 2546, 2545, 2540, 2540, 2541, 2537, 2539, + 2544, 2542, 2536, 2531, 2532, 2528, 2522, 2519, + 2516, 2524, 2527, 2527, 2531, 2536, 2536, 2532, + 2531, 2539, 2544, 2544, 2545, 2553, 2564, 2570, + 2571, 2571, 2573, 2574, 2578, 2587, 2595, 2598, + 2603, 2610, 2618, 2628, 2632, 2640, 2652, 2653, + 2650, 2652, 2655, 2660, 2671, 2676, 2681, 2691, + 2688, 2681, 2687, 2690, 2696, 2699, 2698, 2704, + 2709, 2706, 2708, 2717, 2717, 2711, 2710, 2709, + 2710, 2704, 2696, 2691, 2681, 2675, 2668, 2654, + 2634, 2608, 2581, 2560, 2539, 2511, 2479, 2446, + 2408, 2367, 2330, 2289, 2248, 2195, 2139, 2091, + 2037, 1980, 1927, 1871, 1817, 1766, 1716, 1665, + 1613, 1558, 1507, 1465, 1427, 1394, 1363, 1339, + 1315, 1291, 1276, 1266, 1257, 1252, 1253, 1260, + 1271, 1279, 1294, 1316, 1338, 1365, 1393, 1420, + 1443, 1471, 1502, 1534, 1568, 1599, 1629, 1655, + 1681, 1709, 1734, 1755, 1774, 1789, 1803, 1818, + 1828, 1841, 1851, 1855, 1859, 1862, 1864, 1869, + 1868, 1860, 1856, 1850, 1845, 1842, 1837, 1832, + 1824, 1818, 1807, 1802, 1794, 1792, 1786, 1778, + 1773, 1767, 1767, 1769, 1772, 1773, 1772, 1773, + 1777, 1782, 1788, 1799, 1816, 1836, 1857, 1880, + 1905, 1928, 1951, 1974, 2000, 2027, 2055, 2085, + 2120, 2149, 2179, 2208, 2240, 2272, 2298, 2323, + 2347, 2371, 2397, 2422, 2446, 2467, 2487, 2501, + 2516, 2532, 2544, 2550, 2557, 2561, 2567, 2575, + 2578, 2578, 2579, 2580, 2583, 2585, 2585, 2586, + 2587, 2585, 2582, 2590, 2595, 2599, 2601, 2602, + 2608, 2619, 2631, 2635, 2642, 2649, 2660, 2669, + 2683, 2704, 2721, 2739, 2755, 2769, 2791, 2811, + 2829, 2849, 2870, 2888, 2909, 2931, 2948, 2968, + 2989, 3004, 3031, 3052, 3063, 3069, 3081, 3095, + 3102, 3097, 3073, 3042, 3007, 2964, 2919, 2869, + 2814, 2755, 2694, 2634, 2584, 2535, 2473, 2404, + 2319, 2222, 2138, 2079, 2021, 1957, 1890, 1819, + 1758, 1713, 1675, 1641, 1610, 1569, 1526, 1500, + 1493, 1504, 1519, 1531, 1548, 1567, 1587, 1608, + 1634, 1661, 1680, 1704, 1738, 1782, 1844, 1901, + 1949, 1987, 2025, 2062, 2095, 2129, 2158, 2179, + 2192, 2209, 2225, 2246, 2277, 2294, 2301, 2296, + 2281, 2267, 2259, 2260, 2268, 2267, 2258, 2245, + 2229, 2214, 2201, 2187, 2168, 2145, 2119, 2090, + 2065, 2040, 2013, 1981, 1950, 1932, 1907, 1860, + 1805, 1751, 1700, 1661, 1626, 1591, 1554, 1504, + 1442, 1388, 1340, 1296, 1263, 1237, 1213, 1194, + 1173, 1159, 1154, 1154, 1160, 1173, 1190, 1202, + 1210, 1213, 1242, 1277, 1318, 1370, 1421, 1473, + 1517, 1558, 1603, 1657, 1711, 1762, 1812, 1857, + 1895, 1926, 1956, 1985, 2009, 2027, 2039, 2044, + 2042, 2038, 2037, 2039, 2047, 2055, 2057, 2049, + 2030, 2008, 1990, 1981, 1974, 1971, 1966, 1957, + 1949, 1943, 1944, 1953, 1964, 1979, 1986, 1991, + 2002, 2018, 2040, 2069, 2099, 2130, 2163, 2189, + 2212, 2233, 2261, 2297, 2338, 2381, 2416, 2454, + 2493, 2537, 2578, 2621, 2664, 2701, 2730, 2753, + 2776, 2805, 2841, 2877, 2914, 2940, 2961, 2975, + 2984, 2993, 3008, 3028, 3044, 3054, 3055, 3054, + 3058, 3063, 3072, 3080, 3086, 3082, 3074, 3069, + 3070, 3078, 3094, 3116, 3134, 3147, 3155, 3161, + 3171, 3185, 3203, 3222, 3235, 3235, 3229, 3218, + 3210, 3205, 3190, 3171, 3144, 3109, 3055, 3002, + 2953, 2902, 2840, 2760, 2669, 2559, 2445, 2337, + 2236, 2132, 2031, 1930, 1828, 1731, 1635, 1546, + 1473, 1410, 1352, 1298, 1258, 1226, 1205, 1195, + 1206, 1238, 1269, 1305, 1354, 1404, 1461, 1534, + 1624, 1727, 1839, 1952, 2056, 2159, 2258, 2362, + 2465, 2569, 2668, 2751, 2819, 2882, 2944, 3005, + 3063, 3111, 3143, 3152, 3148, 3135, 3115, 3092, + 3068, 3039, 2996, 2942, 2881, 2812, 2744, 2679, + 2611, 2549, 2481, 2412, 2346, 2283, 2230, 2185, + 2142, 2090, 2025, 1945, 1869, 1809, 1762, 1720, + 1681, 1633, 1574, 1519, 1480, 1451, 1427, 1397, + 1363, 1325, 1286, 1258, 1241, 1236, 1234, 1229, + 1226, 1224, 1222, 1220, 1230, 1252, 1284, 1329, + 1379, 1436, 1490, 1540, 1591, 1652, 1720, 1787, + 1850, 1907, 1961, 2016, 2078, 2145, 2213, 2274, + 2319, 2349, 2369, 2380, 2387, 2400, 2411, 2407, + 2392, 2366, 2329, 2292, 2255, 2225, 2192, 2149, + 2101, 2046, 1995, 1956, 1932, 1913, 1897, 1880, + 1851, 1825, 1806, 1799, 1808, 1830, 1854, 1880, + 1905, 1935, 1978, 2031, 2093, 2154, 2209, 2259, + 2315, 2369, 2428, 2497, 2564, 2630, 2685, 2733, + 2777, 2822, 2862, 2904, 2943, 2976, 3003, 3026, + 3043, 3062, 3076, 3079, 3077, 3076, 3075, 3063, + 3048, 3035, 3029, 3022, 3021, 3021, 3020, 3012, + 3004, 3001, 2998, 3004, 3013, 3022, 3031, 3035, + 3038, 3044, 3054, 3058, 3057, 3050, 3036, 3019, + 2998, 2976, 2955, 2925, 2883, 2829, 2770, 2691, + 2600, 2506, 2403, 2296, 2176, 2054, 1938, 1819, + 1703, 1592, 1488, 1383, 1281, 1183, 1096, 1024, + 961, 917, 890, 874, 873, 880, 901, 937, + 983, 1040, 1112, 1195, 1283, 1390, 1504, 1623, + 1753, 1883, 2011, 2131, 2245, 2356, 2464, 2566, + 2664, 2752, 2833, 2906, 2968, 3010, 3039, 3068, + 3070, 3054, 3033, 3002, 2960, 2908, 2853, 2792, + 2724, 2645, 2564, 2476, 2380, 2289, 2199, 2116, + 2039, 1969, 1899, 1839, 1780, 1722, 1670, 1626, + 1585, 1544, 1503, 1462, 1412, 1370, 1340, 1320, + 1299, 1272, 1252, 1224, 1193, 1168, 1156, 1155, + 1152, 1147, 1140, 1129, 1116, 1113, 1115, 1130, + 1143, 1146, 1152, 1169, 1187, 1215, 1258, 1301, + 1345, 1385, 1428, 1469, 1511, 1555, 1611, 1669, + 1716, 1761, 1802, 1841, 1880, 1920, 1959, 1995, + 2024, 2045, 2060, 2069, 2073, 2071, 2067, 2057, + 2039, 2006, 1965, 1921, 1879, 1835, 1799, 1764, + 1727, 1688, 1654, 1621, 1596, 1575, 1562, 1556, + 1549, 1545, 1545, 1557, 1578, 1610, 1654, 1700, + 1752, 1808, 1869, 1935, 2007, 2089, 2173, 2253, + 2327, 2396, 2458, 2518, 2580, 2640, 2694, 2739, + 2772, 2798, 2824, 2852, 2878, 2901, 2925, 2935, + 2940, 2938, 2935, 2931, 2927, 2927, 2921, 2911, + 2897, 2881, 2866, 2861, 2861, 2860, 2860, 2859, + 2858, 2855, 2858, 2860, 2863, 2864, 2863, 2856, + 2841, 2817, 2798, 2777, 2750, 2716, 2676, 2629, + 2570, 2498, 2413, 2325, 2232, 2122, 2010, 1907, + 1791, 1673, 1558, 1448, 1348, 1253, 1159, 1073, + 993, 920, 863, 823, 799, 791, 793, 806, + 836, 870, 913, 973, 1048, 1135, 1229, 1332, + 1440, 1556, 1679, 1806, 1939, 2067, 2184, 2295, + 2398, 2490, 2579, 2663, 2733, 2800, 2849, 2882, + 2903, 2910, 2900, 2880, 2851, 2810, 2755, 2692, + 2623, 2550, 2473, 2393, 2308, 2220, 2127, 2035, + 1944, 1859, 1783, 1713, 1649, 1596, 1549, 1509, + 1478, 1445, 1415, 1385, 1360, 1340, 1317, 1291, + 1271, 1259, 1243, 1229, 1219, 1212, 1199, 1181, + 1170, 1164, 1165, 1161, 1158, 1156, 1153, 1149, + 1150, 1159, 1173, 1185, 1196, 1212, 1236, 1264, + 1297, 1339, 1383, 1424, 1464, 1507, 1547, 1584, + 1627, 1668, 1711, 1747, 1781, 1813, 1845, 1872, + 1901, 1928, 1947, 1958, 1964, 1965, 1962, 1954, + 1943, 1927, 1906, 1875, 1838, 1802, 1770, 1737, + 1702, 1671, 1644, 1620, 1597, 1577, 1565, 1556, + 1550, 1547, 1549, 1557, 1572, 1587, 1610, 1645, + 1686, 1734, 1786, 1845, 1906, 1973, 2045, 2126, + 2209, 2289, 2365, 2435, 2502, 2571, 2632, 2690, + 2745, 2789, 2826, 2859, 2890, 2916, 2935, 2955, + 2975, 2991, 2997, 2994, 2989, 2977, 2966, 2959, + 2952, 2949, 2937, 2913, 2888, 2865, 2848, 2834, + 2820, 2794, 2762, 2729, 2699, 2671, 2644, 2619, + 2584, 2538, 2488, 2428, 2368, 2301, 2224, 2142, + 2053, 1956, 1853, 1754, 1662, 1572, 1481, 1390, + 1308, 1226, 1147, 1074, 1012, 962, 921, 893, + 877, 865, 870, 889, 924, 970, 1024, 1086, + 1153, 1230, 1315, 1407, 1510, 1618, 1729, 1841, + 1944, 2043, 2141, 2233, 2319, 2402, 2475, 2538, + 2598, 2649, 2685, 2714, 2732, 2734, 2725, 2703, + 2663, 2611, 2549, 2481, 2415, 2348, 2276, 2196, + 2114, 2031, 1949, 1867, 1792, 1723, 1661, 1605, + 1552, 1505, 1468, 1436, 1411, 1383, 1352, 1314, + 1281, 1252, 1236, 1221, 1201, 1186, 1171, 1157, + 1149, 1149, 1146, 1136, 1132, 1127, 1123, 1124, + 1135, 1145, 1155, 1163, 1160, 1169, 1187, 1210, + 1238, 1273, 1311, 1355, 1404, 1452, 1503, 1550, + 1598, 1647, 1691, 1729, 1764, 1798, 1828, 1857, + 1885, 1910, 1928, 1939, 1953, 1964, 1968, 1963, + 1955, 1941, 1919, 1892, 1865, 1834, 1804, 1772, + 1731, 1695, 1659, 1627, 1603, 1584, 1566, 1557, + 1554, 1551, 1552, 1560, 1580, 1595, 1617, 1646, + 1679, 1724, 1772, 1825, 1882, 1938, 1994, 2063, + 2135, 2205, 2276, 2347, 2419, 2491, 2564, 2640, + 2709, 2770, 2815, 2857, 2897, 2932, 2966, 2993, + 3017, 3035, 3045, 3052, 3059, 3067, 3068, 3072, + 3071, 3054, 3030, 3006, 2988, 2967, 2945, 2926, + 2897, 2854, 2807, 2758, 2711, 2665, 2621, 2573, + 2512, 2443, 2366, 2289, 2212, 2128, 2034, 1924, + 1801, 1677, 1567, 1465, 1369, 1283, 1202, 1126, + 1051, 982, 931, 896, 866, 842, 835, 845, + 865, 900, 951, 1014, 1086, 1160, 1242, 1332, + 1430, 1535, 1650, 1772, 1896, 2020, 2142, 2253, + 2352, 2438, 2514, 2578, 2632, 2675, 2708, 2731, + 2748, 2755, 2752, 2738, 2707, 2660, 2601, 2531, + 2453, 2371, 2289, 2206, 2121, 2038, 1951, 1867, + 1784, 1701, 1624, 1556, 1497, 1452, 1413, 1382, + 1366, 1357, 1345, 1330, 1316, 1299, 1272, 1237, + 1203, 1181, 1167, 1153, 1142, 1134, 1123, 1102, + 1086, 1080, 1077, 1072, 1067, 1071, 1079, 1087, + 1099, 1120, 1149, 1174, 1197, 1227, 1260, 1301, + 1348, 1402, 1464, 1528, 1587, 1642, 1694, 1739, + 1779, 1814, 1845, 1873, 1894, 1913, 1928, 1946, + 1962, 1974, 1982, 1978, 1964, 1939, 1912, 1883, + 1856, 1827, 1793, 1758, 1719, 1677, 1640, 1610, + 1583, 1561, 1542, 1537, 1538, 1546, 1567, 1592, + 1623, 1659, 1689, 1718, 1751, 1791, 1831, 1877, + 1930, 1990, 2051, 2110, 2172, 2236, 2297, 2353, + 2402, 2449, 2495, 2541, 2584, 2619, 2648, 2671, + 2693, 2711, 2727, 2742, 2753, 2769, 2782, 2803, + 2829, 2851, 2878, 2904, 2927, 2941, 2950, 2951, + 2942, 2928, 2917, 2901, 2876, 2843, 2803, 2766, + 2714, 2660, 2605, 2539, 2459, 2361, 2250, 2134, + 2021, 1900, 1768, 1634, 1507, 1377, 1254, 1147, + 1050, 960, 877, 803, 754, 726, 703, 690, + 699, 722, 757, 805, 874, 956, 1044, 1134, + 1238, 1357, 1481, 1608, 1737, 1864, 1991, 2113, + 2225, 2328, 2418, 2488, 2545, 2587, 2618, 2635, + 2642, 2639, 2620, 2592, 2552, 2505, 2447, 2375, + 2296, 2214, 2126, 2035, 1947, 1857, 1771, 1686, + 1604, 1532, 1471, 1415, 1371, 1338, 1316, 1304, + 1307, 1318, 1330, 1339, 1343, 1344, 1338, 1328, + 1319, 1297, 1262, 1225, 1196, 1172, 1148, 1120, + 1093, 1068, 1037, 1005, 987, 976, 965, 949, + 943, 942, 943, 953, 976, 1006, 1038, 1073, + 1118, 1173, 1236, 1308, 1381, 1456, 1531, 1599, + 1659, 1718, 1767, 1807, 1843, 1878, 1908, 1926, + 1936, 1943, 1945, 1941, 1934, 1917, 1890, 1851, + 1806, 1761, 1719, 1673, 1624, 1579, 1538, 1496, + 1460, 1442, 1435, 1437, 1447, 1467, 1499, 1536, + 1581, 1632, 1683, 1737, 1795, 1853, 1914, 1979, + 2042, 2105, 2168, 2238, 2308, 2369, 2428, 2482, + 2533, 2582, 2623, 2661, 2688, 2700, 2712, 2724, + 2733, 2739, 2735, 2729, 2724, 2719, 2718, 2734, + 2756, 2772, 2784, 2800, 2822, 2836, 2839, 2823, + 2803, 2780, 2749, 2714, 2676, 2636, 2582, 2508, + 2439, 2379, 2307, 2207, 2097, 1977, 1841, 1695, + 1563, 1455, 1351, 1237, 1117, 1015, 923, 843, + 781, 739, 709, 686, 675, 696, 742, 803, + 874, 961, 1055, 1146, 1237, 1334, 1440, 1562, + 1693, 1830, 1968, 2097, 2218, 2322, 2415, 2498, + 2564, 2606, 2631, 2638, 2623, 2603, 2579, 2547, + 2506, 2451, 2371, 2276, 2176, 2077, 1988, 1900, + 1818, 1734, 1648, 1571, 1500, 1429, 1366, 1308, + 1252, 1206, 1176, 1163, 1164, 1186, 1215, 1244, + 1267, 1279, 1285, 1271, 1246, 1230, 1216, 1196, + 1172, 1147, 1109, 1061, 1018, 988, 970, 944, + 908, 878, 858, 847, 850, 874, 915, 942, + 958, 979, 1013, 1060, 1118, 1193, 1280, 1361, + 1435, 1512, 1598, 1679, 1755, 1819, 1866, 1903, + 1928, 1939, 1954, 1973, 1977, 1973, 1961, 1934, + 1892, 1842, 1790, 1744, 1700, 1654, 1600, 1540, + 1483, 1428, 1385, 1354, 1329, 1309, 1296, 1298, + 1318, 1358, 1414, 1485, 1560, 1628, 1696, 1767, + 1842, 1913, 1991, 2071, 2150, 2229, 2292, 2350, + 2414, 2479, 2535, 2582, 2628, 2658, 2673, 2682, + 2700, 2721, 2728, 2725, 2719, 2707, 2679, 2653, + 2642, 2645, 2649, 2649, 2658, 2676, 2697, 2726, + 2755, 2770, 2767, 2755, 2739, 2722, 2696, 2663, + 2621, 2565, 2499, 2432, 2359, 2262, 2157, 2046, + 1915, 1769, 1624, 1487, 1368, 1254, 1134, 1031, + 931, 833, 759, 706, 669, 645, 635, 651, + 689, 745, 819, 914, 1021, 1131, 1240, 1348, + 1460, 1580, 1706, 1839, 1977, 2111, 2231, 2338, + 2431, 2513, 2577, 2616, 2638, 2643, 2627, 2592, + 2550, 2503, 2451, 2386, 2304, 2208, 2103, 1997, + 1897, 1801, 1719, 1645, 1576, 1513, 1455, 1402, + 1358, 1322, 1296, 1270, 1253, 1244, 1252, 1269, + 1290, 1315, 1335, 1346, 1342, 1325, 1299, 1269, + 1236, 1190, 1140, 1090, 1038, 986, 931, 880, + 837, 794, 755, 723, 711, 714, 726, 754, + 795, 844, 896, 954, 1020, 1100, 1186, 1273, + 1369, 1472, 1574, 1672, 1766, 1855, 1932, 1995, + 2040, 2069, 2094, 2106, 2103, 2096, 2079, 2048, + 2006, 1953, 1897, 1834, 1774, 1708, 1641, 1579, + 1520, 1465, 1414, 1377, 1348, 1328, 1321, 1319, + 1329, 1361, 1410, 1471, 1540, 1618, 1698, 1779, + 1866, 1952, 2034, 2117, 2192, 2258, 2320, 2377, + 2431, 2479, 2521, 2558, 2581, 2596, 2610, 2617, + 2616, 2618, 2625, 2624, 2610, 2601, 2597, 2589, + 2584, 2589, 2594, 2612, 2633, 2651, 2692, 2745, + 2787, 2813, 2835, 2854, 2852, 2837, 2821, 2803, + 2774, 2715, 2641, 2566, 2481, 2384, 2272, 2143, + 2003, 1843, 1666, 1507, 1374, 1251, 1128, 1015, + 915, 821, 744, 691, 659, 650, 654, 671, + 713, 783, 872, 979, 1108, 1238, 1364, 1477, + 1592, 1713, 1838, 1966, 2090, 2207, 2314, 2405, + 2475, 2525, 2559, 2571, 2561, 2537, 2497, 2435, + 2363, 2295, 2229, 2157, 2073, 1981, 1880, 1778, + 1689, 1613, 1551, 1506, 1470, 1436, 1418, 1406, + 1398, 1399, 1408, 1421, 1435, 1449, 1461, 1480, + 1502, 1516, 1514, 1500, 1473, 1432, 1372, 1303, + 1236, 1162, 1081, 995, 917, 848, 785, 718, + 669, 632, 595, 575, 574, 601, 646, 693, + 755, 835, 929, 1024, 1124, 1236, 1354, 1468, + 1576, 1688, 1800, 1903, 1985, 2051, 2106, 2150, + 2168, 2162, 2149, 2130, 2093, 2045, 1989, 1929, + 1862, 1792, 1715, 1639, 1573, 1511, 1451, 1398, + 1359, 1335, 1321, 1323, 1331, 1356, 1402, 1453, + 1507, 1576, 1665, 1755, 1838, 1929, 2023, 2110, + 2190, 2261, 2323, 2373, 2415, 2449, 2473, 2497, + 2513, 2504, 2491, 2485, 2468, 2443, 2430, 2413, + 2380, 2358, 2355, 2354, 2349, 2368, 2388, 2403, + 2436, 2478, 2526, 2594, 2673, 2745, 2809, 2877, + 2926, 2942, 2962, 2981, 2972, 2937, 2882, 2829, + 2752, 2666, 2568, 2448, 2320, 2183, 2012, 1813, + 1625, 1455, 1286, 1138, 1015, 902, 802, 715, + 646, 613, 614, 626, 649, 694, 772, 872, + 983, 1118, 1271, 1428, 1569, 1695, 1806, 1920, + 2040, 2151, 2251, 2344, 2415, 2460, 2491, 2500, + 2491, 2458, 2398, 2319, 2231, 2136, 2038, 1941, + 1856, 1782, 1709, 1633, 1556, 1487, 1428, 1387, + 1366, 1364, 1378, 1396, 1416, 1443, 1479, 1520, + 1565, 1604, 1637, 1658, 1671, 1679, 1685, 1674, + 1649, 1602, 1528, 1432, 1320, 1199, 1073, 955, + 842, 731, 635, 553, 482, 426, 391, 382, + 389, 409, 450, 515, 603, 706, 824, 959, + 1108, 1257, 1397, 1531, 1672, 1808, 1928, 2040, + 2137, 2213, 2259, 2286, 2291, 2285, 2256, 2196, + 2120, 2038, 1952, 1861, 1764, 1679, 1604, 1528, + 1451, 1384, 1332, 1293, 1267, 1256, 1265, 1294, + 1334, 1386, 1453, 1535, 1634, 1741, 1845, 1948, + 2053, 2151, 2234, 2305, 2380, 2451, 2504, 2523, + 2527, 2531, 2528, 2509, 2474, 2446, 2422, 2382, + 2322, 2274, 2253, 2240, 2215, 2184, 2172, 2186, + 2199, 2212, 2257, 2327, 2392, 2450, 2522, 2612, + 2714, 2823, 2921, 3008, 3092, 3154, 3180, 3186, + 3189, 3174, 3128, 3049, 2951, 2839, 2711, 2572, + 2418, 2254, 2092, 1912, 1708, 1505, 1315, 1151, + 1010, 895, 805, 739, 696, 670, 667, 710, + 786, 872, 967, 1070, 1196, 1336, 1482, 1634, + 1793, 1945, 2069, 2157, 2225, 2301, 2370, 2412, + 2438, 2451, 2442, 2407, 2349, 2283, 2213, 2133, + 2031, 1925, 1823, 1731, 1643, 1573, 1531, 1507, + 1497, 1485, 1485, 1492, 1520, 1560, 1611, 1676, + 1738, 1796, 1848, 1893, 1934, 1964, 1978, 1976, + 1957, 1904, 1815, 1726, 1631, 1513, 1380, 1243, + 1097, 940, 788, 649, 532, 436, 351, 290, + 258, 256, 276, 316, 391, 494, 613, 739, + 878, 1029, 1181, 1343, 1509, 1669, 1819, 1947, + 2052, 2145, 2220, 2263, 2282, 2284, 2264, 2223, + 2158, 2081, 1997, 1914, 1827, 1736, 1646, 1560, + 1483, 1424, 1377, 1346, 1339, 1346, 1359, 1391, + 1444, 1512, 1579, 1658, 1751, 1849, 1944, 2040, + 2133, 2221, 2300, 2372, 2426, 2464, 2490, 2496, + 2484, 2467, 2437, 2400, 2360, 2309, 2255, 2205, + 2169, 2130, 2080, 2051, 2049, 2068, 2081, 2113, + 2173, 2239, 2309, 2396, 2499, 2606, 2715, 2815, + 2917, 3026, 3140, 3237, 3323, 3408, 3472, 3491, + 3454, 3398, 3342, 3252, 3136, 3009, 2868, 2715, + 2552, 2390, 2240, 2090, 1934, 1769, 1609, 1465, + 1338, 1221, 1116, 1058, 1049, 1040, 1032, 1052, + 1100, 1169, 1245, 1330, 1438, 1550, 1650, 1740, + 1838, 1933, 2015, 2072, 2112, 2149, 2167, 2156, + 2133, 2126, 2121, 2105, 2072, 2027, 1981, 1930, + 1881, 1839, 1802, 1768, 1740, 1723, 1721, 1739, + 1773, 1812, 1866, 1924, 1988, 2047, 2102, 2159, + 2210, 2251, 2274, 2286, 2278, 2254, 2212, 2157, + 2084, 1999, 1909, 1802, 1678, 1548, 1416, 1278, + 1139, 997, 841, 704, 599, 505, 421, 370, + 363, 374, 395, 448, 538, 646, 759, 880, + 1015, 1157, 1299, 1422, 1541, 1671, 1790, 1879, + 1949, 2008, 2060, 2084, 2077, 2065, 2043, 2003, + 1939, 1867, 1803, 1735, 1659, 1589, 1536, 1507, + 1486, 1466, 1462, 1485, 1534, 1587, 1638, 1703, + 1781, 1853, 1917, 1987, 2058, 2121, 2172, 2215, + 2258, 2301, 2331, 2335, 2341, 2355, 2355, 2327, + 2291, 2261, 2221, 2172, 2122, 2080, 2050, 2030, + 2012, 2015, 2042, 2060, 2081, 2126, 2184, 2241, + 2296, 2369, 2449, 2526, 2596, 2663, 2741, 2830, + 2900, 2954, 3003, 3058, 3092, 3101, 3128, 3167, + 3178, 3160, 3129, 3100, 3050, 2972, 2880, 2785, + 2696, 2597, 2481, 2383, 2299, 2221, 2146, 2075, + 2018, 1959, 1883, 1804, 1739, 1681, 1619, 1568, + 1548, 1541, 1536, 1536, 1548, 1577, 1613, 1648, + 1678, 1710, 1737, 1750, 1758, 1779, 1804, 1822, + 1826, 1831, 1845, 1852, 1858, 1872, 1904, 1943, + 1970, 1991, 2015, 2044, 2070, 2084, 2097, 2110, + 2117, 2118, 2120, 2135, 2155, 2171, 2188, 2210, + 2226, 2223, 2208, 2194, 2173, 2142, 2097, 2046, + 1988, 1918, 1836, 1761, 1699, 1622, 1528, 1438, + 1355, 1269, 1186, 1109, 1036, 968, 906, 845, + 798, 773, 757, 749, 762, 803, 857, 915, + 984, 1067, 1151, 1229, 1305, 1380, 1451, 1518, + 1568, 1613, 1657, 1693, 1716, 1736, 1756, 1768, + 1769, 1759, 1750, 1750, 1744, 1728, 1709, 1700, + 1702, 1700, 1700, 1712, 1735, 1766, 1799, 1839, + 1887, 1935, 1969, 1999, 2036, 2069, 2092, 2106, + 2117, 2130, 2136, 2136, 2145, 2153, 2148, 2145, + 2142, 2141, 2136, 2131, 2134, 2147, 2154, 2157, + 2164, 2171, 2176, 2200, 2244, 2290, 2326, 2368, + 2436, 2502, 2560, 2631, 2712, 2769, 2814, 2855, + 2894, 2939, 2991, 3028, 3042, 3069, 3115, 3144, + 3139, 3149, 3177, 3146, 3045, 2956, 2888, 2804, + 2708, 2608, 2497, 2401, 2333, 2263, 2194, 2157, + 2126, 2058, 1970, 1902, 1862, 1818, 1760, 1719, + 1681, 1625, 1582, 1558, 1531, 1528, 1528, 1526, + 1534, 1553, 1588, 1610, 1631, 1655, 1670, 1654, + 1639, 1651, 1670, 1683, 1721, 1789, 1857, 1919, + 1977, 2027, 2076, 2120, 2145, 2162, 2177, 2191, + 2200, 2201, 2211, 2226, 2230, 2219, 2210, 2200, + 2188, 2183, 2180, 2179, 2162, 2132, 2093, 2045, + 1983, 1911, 1840, 1773, 1711, 1638, 1572, 1539, + 1512, 1456, 1381, 1314, 1248, 1178, 1112, 1042, + 980, 936, 887, 833, 809, 817, 825, 832, + 859, 909, 961, 1014, 1085, 1169, 1246, 1316, + 1375, 1420, 1468, 1524, 1575, 1623, 1672, 1715, + 1746, 1773, 1802, 1822, 1833, 1823, 1807, 1794, + 1778, 1761, 1754, 1754, 1768, 1792, 1804, 1818, + 1845, 1882, 1918, 1951, 1984, 2014, 2036, 2047, + 2062, 2071, 2068, 2066, 2068, 2068, 2064, 2063, + 2077, 2103, 2118, 2120, 2135, 2152, 2149, 2139, + 2148, 2171, 2185, 2192, 2211, 2254, 2303, 2353, + 2404, 2436, 2463, 2510, 2546, 2562, 2586, 2620, + 2648, 2674, 2701, 2718, 2744, 2786, 2828, 2847, + 2860, 2897, 2940, 2944, 2953, 2989, 3012, 3010, + 3010, 3007, 2977, 2931, 2881, 2830, 2764, 2696, + 2632, 2553, 2463, 2383, 2308, 2227, 2147, 2068, + 1981, 1885, 1804, 1738, 1656, 1584, 1538, 1514, + 1501, 1484, 1482, 1504, 1534, 1573, 1613, 1649, + 1691, 1734, 1762, 1782, 1814, 1847, 1865, 1877, + 1896, 1922, 1940, 1954, 1973, 1997, 2022, 2036, + 2039, 2043, 2052, 2057, 2055, 2059, 2061, 2064, + 2065, 2076, 2094, 2119, 2139, 2155, 2175, 2187, + 2186, 2175, 2156, 2131, 2096, 2051, 1997, 1944, + 1877, 1783, 1686, 1620, 1554, 1449, 1335, 1249, + 1153, 1045, 978, 932, 869, 820, 804, 793, + 790, 821, 881, 942, 1009, 1099, 1189, 1267, + 1349, 1437, 1508, 1563, 1617, 1660, 1676, 1686, + 1705, 1723, 1722, 1712, 1703, 1688, 1666, 1651, + 1646, 1636, 1634, 1650, 1663, 1682, 1726, 1772, + 1822, 1888, 1957, 2014, 2065, 2121, 2172, 2209, + 2237, 2255, 2252, 2240, 2225, 2204, 2169, 2139, + 2119, 2081, 2047, 2036, 2029, 2002, 1986, 2001, + 2023, 2039, 2065, 2114, 2155, 2197, 2257, 2326, + 2387, 2446, 2502, 2539, 2590, 2671, 2725, 2742, + 2786, 2852, 2893, 2909, 2931, 2955, 2967, 2974, + 2990, 3006, 3012, 3030, 3055, 3078, 3110, 3146, + 3172, 3187, 3175, 3122, 3050, 2998, 2952, 2876, + 2779, 2702, 2649, 2594, 2518, 2453, 2423, 2375, + 2289, 2205, 2122, 2041, 1980, 1915, 1848, 1793, + 1727, 1661, 1602, 1558, 1544, 1537, 1531, 1556, + 1597, 1638, 1679, 1727, 1763, 1782, 1783, 1771, + 1775, 1793, 1826, 1875, 1938, 2019, 2096, 2144, + 2174, 2207, 2230, 2232, 2226, 2229, 2232, 2235, + 2238, 2249, 2267, 2275, 2267, 2261, 2266, 2270, + 2278, 2291, 2310, 2326, 2314, 2272, 2217, 2158, + 2089, 2015, 1952, 1906, 1868, 1820, 1771, 1747, + 1731, 1670, 1566, 1474, 1385, 1287, 1202, 1122, + 1035, 976, 956, 932, 901, 904, 930, 952, + 991, 1055, 1130, 1195, 1253, 1314, 1372, 1419, + 1463, 1505, 1539, 1569, 1616, 1675, 1730, 1765, + 1786, 1802, 1815, 1814, 1802, 1780, 1758, 1764, + 1780, 1789, 1814, 1862, 1914, 1967, 2019, 2068, + 2111, 2153, 2194, 2211, 2219, 2230, 2220, 2196, + 2171, 2142, 2109, 2083, 2068, 2048, 2031, 2030, + 2039, 2044, 2040, 2048, 2071, 2099, 2123, 2159, + 2208, 2266, 2333, 2404, 2458, 2498, 2553, 2617, + 2651, 2660, 2681, 2704, 2706, 2691, 2674, 2667, + 2662, 2652, 2653, 2663, 2680, 2704, 2738, 2777, + 2833, 2895, 2936, 2970, 3020, 3065, 3101, 3148, + 3207, 3260, 3300, 3332, 3338, 3311, 3244, 3157, + 3055, 2947, 2826, 2691, 2553, 2429, 2328, 2240, + 2156, 2069, 1987, 1916, 1854, 1798, 1759, 1717, + 1672, 1653, 1667, 1676, 1669, 1679, 1708, 1740, + 1781, 1833, 1874, 1906, 1930, 1941, 1929, 1913, + 1895, 1866, 1836, 1814, 1812, 1829, 1856, 1895, + 1946, 1994, 2042, 2084, 2128, 2170, 2203, 2235, + 2266, 2292, 2311, 2320, 2325, 2338, 2348, 2342, + 2331, 2325, 2320, 2301, 2262, 2216, 2163, 2097, + 2025, 1953, 1890, 1838, 1796, 1768, 1755, 1738, + 1678, 1583, 1524, 1524, 1492, 1387, 1313, 1302, + 1264, 1200, 1181, 1187, 1175, 1151, 1115, 1105, + 1128, 1150, 1177, 1219, 1268, 1316, 1358, 1394, + 1436, 1476, 1523, 1577, 1629, 1681, 1720, 1745, + 1779, 1820, 1839, 1841, 1836, 1835, 1843, 1849, + 1852, 1870, 1909, 1941, 1944, 1944, 1968, 1999, + 2008, 2017, 2038, 2055, 2055, 2050, 2057, 2070, + 2073, 2060, 2049, 2050, 2058, 2059, 2054, 2064, + 2087, 2092, 2088, 2084, 2103, 2136, 2159, 2183, + 2222, 2267, 2310, 2349, 2391, 2434, 2465, 2475, + 2489, 2517, 2542, 2564, 2576, 2602, 2640, 2683, + 2727, 2763, 2792, 2822, 2893, 2982, 3023, 3033, + 3073, 3122, 3156, 3207, 3257, 3268, 3288, 3328, + 3359, 3391, 3399, 3342, 3235, 3125, 3034, 2927, + 2795, 2671, 2547, 2464, 2432, 2398, 2365, 2327, + 2260, 2199, 2151, 2078, 2010, 1966, 1924, 1892, + 1861, 1812, 1760, 1710, 1682, 1660, 1624, 1618, + 1643, 1664, 1687, 1723, 1746, 1744, 1728, 1693, + 1662, 1659, 1673, 1709, 1777, 1874, 1986, 2078, + 2131, 2162, 2187, 2193, 2185, 2180, 2179, 2174, + 2171, 2187, 2212, 2224, 2217, 2197, 2177, 2170, + 2173, 2182, 2197, 2213, 2218, 2200, 2168, 2126, + 2074, 2021, 1980, 1956, 1951, 1960, 1976, 1994, + 1990, 1953, 1870, 1770, 1693, 1623, 1514, 1393, + 1338, 1331, 1292, 1241, 1226, 1199, 1124, 1047, + 1013, 1026, 1043, 1046, 1072, 1135, 1198, 1244, + 1300, 1372, 1438, 1487, 1540, 1604, 1674, 1726, + 1742, 1749, 1765, 1768, 1732, 1679, 1657, 1657, + 1664, 1678, 1705, 1744, 1778, 1791, 1795, 1820, + 1856, 1881, 1907, 1952, 1996, 2032, 2074, 2104, + 2119, 2124, 2110, 2079, 2046, 2023, 2009, 1982, + 1947, 1923, 1905, 1880, 1860, 1867, 1885, 1908, + 1937, 1991, 2068, 2132, 2179, 2234, 2293, 2334, + 2370, 2401, 2419, 2438, 2479, 2513, 2518, 2531, + 2549, 2544, 2525, 2524, 2537, 2549, 2556, 2573, + 2607, 2654, 2705, 2766, 2848, 2924, 2965, 3009, + 3095, 3191, 3244, 3263, 3285, 3322, 3360, 3369, + 3358, 3366, 3377, 3362, 3309, 3223, 3100, 2971, + 2853, 2705, 2544, 2429, 2334, 2258, 2244, 2247, + 2249, 2259, 2246, 2209, 2162, 2093, 2036, 1997, + 1927, 1841, 1792, 1772, 1753, 1701, 1644, 1621, + 1614, 1607, 1606, 1603, 1600, 1609, 1609, 1587, + 1573, 1569, 1570, 1597, 1651, 1730, 1838, 1959, + 2065, 2153, 2212, 2247, 2253, 2234, 2202, 2168, + 2139, 2119, 2113, 2118, 2127, 2127, 2128, 2135, + 2136, 2143, 2153, 2172, 2190, 2190, 2179, 2166, + 2147, 2123, 2095, 2068, 2062, 2066, 2078, 2096, + 2113, 2110, 2076, 2028, 1963, 1880, 1789, 1692, + 1585, 1439, 1286, 1214, 1227, 1225, 1179, 1161, + 1195, 1237, 1278, 1329, 1359, 1366, 1356, 1329, + 1322, 1337, 1354, 1373, 1427, 1494, 1557, 1610, + 1653, 1676, 1670, 1652, 1633, 1618, 1592, 1550, + 1524, 1539, 1592, 1648, 1708, 1783, 1849, 1916, + 1987, 2036, 2066, 2101, 2110, 2080, 2044, 2026, + 2007, 1983, 1963, 1957, 1956, 1956, 1944, 1929, + 1928, 1926, 1899, 1866, 1847, 1847, 1861, 1889, + 1921, 1962, 2034, 2115, 2179, 2234, 2301, 2358, + 2384, 2393, 2392, 2381, 2362, 2343, 2330, 2339, + 2362, 2383, 2408, 2442, 2475, 2524, 2594, 2642, + 2654, 2663, 2705, 2764, 2806, 2840, 2899, 2984, + 3073, 3150, 3210, 3274, 3351, 3398, 3413, 3414, + 3426, 3448, 3427, 3394, 3394, 3422, 3435, 3389, + 3293, 3187, 3082, 2982, 2890, 2789, 2677, 2584, + 2551, 2552, 2545, 2534, 2520, 2465, 2386, 2306, + 2218, 2135, 2067, 1985, 1891, 1796, 1711, 1655, + 1602, 1532, 1459, 1434, 1451, 1476, 1514, 1567, + 1615, 1641, 1652, 1656, 1658, 1666, 1684, 1714, + 1771, 1860, 1952, 2039, 2107, 2133, 2122, 2096, + 2060, 2029, 2009, 1992, 1984, 2002, 2044, 2093, + 2131, 2166, 2195, 2222, 2254, 2291, 2333, 2381, + 2411, 2416, 2396, 2362, 2316, 2259, 2200, 2145, + 2107, 2091, 2088, 2089, 2084, 2057, 2020, 1972, + 1921, 1875, 1833, 1805, 1787, 1760, 1725, 1711, + 1724, 1723, 1665, 1582, 1539, 1528, 1519, 1470, + 1395, 1321, 1257, 1221, 1211, 1204, 1206, 1241, + 1307, 1386, 1481, 1564, 1612, 1640, 1645, 1639, + 1637, 1644, 1652, 1669, 1688, 1710, 1743, 1777, + 1792, 1785, 1773, 1763, 1752, 1748, 1750, 1751, + 1761, 1784, 1804, 1820, 1848, 1890, 1937, 1973, + 1999, 2027, 2053, 2064, 2054, 2025, 1990, 1950, + 1912, 1883, 1867, 1856, 1844, 1858, 1887, 1904, + 1929, 1966, 1997, 2011, 2021, 2044, 2090, 2135, + 2170, 2194, 2221, 2265, 2308, 2339, 2360, 2365, + 2374, 2383, 2393, 2411, 2432, 2433, 2417, 2442, + 2509, 2565, 2589, 2630, 2706, 2777, 2825, 2879, + 2951, 3017, 3067, 3106, 3145, 3206, 3269, 3305, + 3331, 3370, 3399, 3399, 3409, 3429, 3426, 3423, + 3438, 3448, 3428, 3388, 3318, 3224, 3143, 3055, + 2938, 2822, 2753, 2717, 2689, 2666, 2655, 2661, + 2657, 2613, 2524, 2431, 2341, 2221, 2102, 2012, + 1921, 1819, 1714, 1615, 1549, 1530, 1516, 1486, + 1483, 1518, 1560, 1594, 1627, 1650, 1647, 1627, + 1606, 1601, 1617, 1644, 1689, 1759, 1844, 1919, + 1969, 1991, 1983, 1960, 1934, 1899, 1879, 1887, + 1909, 1937, 1996, 2073, 2145, 2204, 2262, 2319, + 2371, 2416, 2452, 2479, 2500, 2503, 2474, 2425, + 2365, 2308, 2251, 2209, 2191, 2197, 2208, 2216, + 2229, 2240, 2232, 2203, 2160, 2115, 2081, 2062, + 2057, 2063, 2082, 2102, 2109, 2102, 2086, 2055, + 2006, 1946, 1855, 1713, 1552, 1432, 1352, 1247, + 1135, 1105, 1156, 1213, 1273, 1373, 1474, 1529, + 1555, 1553, 1526, 1488, 1435, 1396, 1396, 1421, + 1447, 1484, 1523, 1547, 1561, 1565, 1553, 1534, + 1524, 1516, 1511, 1525, 1554, 1587, 1630, 1687, + 1742, 1811, 1896, 1976, 2036, 2089, 2132, 2128, + 2082, 2033, 1984, 1932, 1874, 1837, 1834, 1856, + 1881, 1912, 1958, 2005, 2033, 2043, 2056, 2062, + 2060, 2052, 2051, 2059, 2071, 2088, 2103, 2109, + 2114, 2124, 2127, 2114, 2101, 2088, 2075, 2049, + 2015, 1989, 1971, 1978, 2007, 2040, 2083, 2137, + 2211, 2308, 2398, 2456, 2487, 2520, 2553, 2590, + 2637, 2610, 2541, 2576, 2666, 2721, 2798, 2921, + 3018, 3073, 3113, 3155, 3193, 3195, 3196, 3234, + 3295, 3344, 3386, 3442, 3477, 3483, 3516, 3567, + 3562, 3505, 3425, 3332, 3226, 3113, 3003, 2915, + 2846, 2762, 2686, 2652, 2632, 2626, 2646, 2648, + 2600, 2514, 2408, 2265, 2114, 1969, 1837, 1697, + 1544, 1430, 1392, 1388, 1372, 1366, 1399, 1443, + 1472, 1489, 1481, 1450, 1434, 1427, 1410, 1403, + 1418, 1449, 1494, 1555, 1620, 1690, 1760, 1808, + 1831, 1839, 1830, 1823, 1830, 1841, 1857, 1901, + 1974, 2050, 2131, 2226, 2331, 2429, 2521, 2589, + 2625, 2644, 2641, 2605, 2553, 2498, 2446, 2401, + 2368, 2349, 2345, 2357, 2375, 2392, 2406, 2406, + 2386, 2341, 2282, 2228, 2182, 2144, 2109, 2078, + 2060, 2044, 2018, 1989, 1961, 1934, 1897, 1845, + 1788, 1732, 1671, 1601, 1516, 1439, 1390, 1356, + 1315, 1272, 1251, 1253, 1265, 1276, 1291, 1306, + 1319, 1320, 1325, 1343, 1362, 1369, 1373, 1381, + 1393, 1409, 1439, 1474, 1514, 1554, 1591, 1634, + 1669, 1688, 1684, 1682, 1694, 1712, 1736, 1770, + 1812, 1866, 1925, 1980, 2018, 2044, 2056, 2048, + 2034, 2023, 2012, 1992, 1969, 1961, 1960, 1964, + 1961, 1956, 1950, 1952, 1952, 1947, 1946, 1939, + 1924, 1908, 1891, 1874, 1865, 1863, 1854, 1854, + 1864, 1870, 1863, 1855, 1852, 1846, 1824, 1794, + 1780, 1781, 1785, 1791, 1802, 1816, 1839, 1868, + 1903, 1943, 1974, 1996, 2020, 2039, 2066, 2101, + 2126, 2145, 2173, 2219, 2276, 2326, 2383, 2457, + 2529, 2596, 2678, 2775, 2858, 2928, 3002, 3073, + 3156, 3217, 3222, 3232, 3276, 3292, 3278, 3276, + 3286, 3298, 3326, 3372, 3409, 3426, 3448, 3477, + 3507, 3517, 3507, 3499, 3475, 3430, 3384, 3331, + 3252, 3169, 3102, 3032, 2937, 2838, 2773, 2714, + 2632, 2546, 2452, 2363, 2276, 2179, 2062, 1935, + 1831, 1751, 1652, 1538, 1472, 1461, 1462, 1453, + 1460, 1505, 1543, 1560, 1562, 1537, 1486, 1430, + 1380, 1344, 1329, 1335, 1370, 1432, 1511, 1599, + 1677, 1734, 1790, 1847, 1884, 1926, 1987, 2058, + 2126, 2195, 2258, 2320, 2373, 2411, 2448, 2487, + 2526, 2572, 2614, 2641, 2658, 2661, 2637, 2591, + 2545, 2506, 2478, 2464, 2477, 2514, 2556, 2588, + 2604, 2602, 2572, 2518, 2446, 2365, 2292, 2233, + 2181, 2132, 2089, 2049, 2002, 1947, 1891, 1842, + 1802, 1771, 1752, 1737, 1724, 1714, 1703, 1677, + 1641, 1606, 1585, 1577, 1578, 1594, 1610, 1607, + 1584, 1557, 1530, 1489, 1431, 1367, 1306, 1285, + 1323, 1372, 1373, 1384, 1451, 1526, 1581, 1625, + 1663, 1702, 1742, 1767, 1791, 1811, 1811, 1794, + 1771, 1771, 1786, 1799, 1812, 1831, 1854, 1872, + 1884, 1894, 1914, 1926, 1917, 1921, 1956, 1998, + 2021, 2032, 2043, 2061, 2074, 2051, 2014, 1986, + 1959, 1926, 1888, 1848, 1817, 1794, 1764, 1740, + 1734, 1741, 1755, 1765, 1781, 1802, 1810, 1809, + 1808, 1798, 1776, 1754, 1729, 1708, 1694, 1692, + 1680, 1667, 1657, 1655, 1647, 1641, 1651, 1658, + 1673, 1705, 1741, 1766, 1792, 1835, 1890, 1935, + 1957, 1977, 2017, 2055, 2080, 2109, 2140, 2164, + 2188, 2224, 2263, 2305, 2344, 2396, 2466, 2534, + 2617, 2713, 2807, 2896, 2988, 3086, 3178, 3240, + 3270, 3278, 3263, 3229, 3190, 3154, 3122, 3091, + 3079, 3114, 3189, 3260, 3320, 3390, 3475, 3555, + 3606, 3610, 3599, 3605, 3578, 3521, 3455, 3383, + 3306, 3208, 3112, 3042, 2970, 2890, 2812, 2744, + 2699, 2661, 2598, 2528, 2484, 2433, 2374, 2329, + 2285, 2244, 2187, 2104, 2015, 1908, 1774, 1629, + 1506, 1424, 1369, 1336, 1349, 1409, 1490, 1561, + 1624, 1652, 1664, 1676, 1661, 1644, 1666, 1708, + 1753, 1807, 1861, 1918, 1961, 1974, 1972, 1982, + 2004, 2041, 2097, 2170, 2258, 2338, 2399, 2453, + 2491, 2511, 2525, 2541, 2584, 2645, 2696, 2737, + 2767, 2767, 2730, 2658, 2561, 2472, 2398, 2340, + 2309, 2314, 2344, 2376, 2398, 2402, 2387, 2353, + 2298, 2240, 2195, 2154, 2115, 2075, 2035, 1984, + 1919, 1833, 1744, 1672, 1617, 1581, 1569, 1581, + 1606, 1630, 1642, 1640, 1628, 1607, 1581, 1567, + 1578, 1602, 1643, 1691, 1733, 1760, 1766, 1759, + 1733, 1704, 1681, 1673, 1688, 1724, 1778, 1837, + 1898, 1950, 1994, 2018, 2006, 1947, 1860, 1802, + 1808, 1852, 1877, 1871, 1876, 1905, 1928, 1927, + 1913, 1887, 1844, 1813, 1817, 1858, 1912, 1934, + 1926, 1913, 1900, 1874, 1832, 1788, 1751, 1724, + 1708, 1705, 1715, 1720, 1702, 1674, 1656, 1661, + 1676, 1684, 1686, 1701, 1723, 1732, 1718, 1693, + 1667, 1641, 1611, 1590, 1586, 1595, 1614, 1630, + 1644, 1658, 1660, 1638, 1616, 1619, 1628, 1629, + 1638, 1662, 1703, 1733, 1745, 1760, 1780, 1787, + 1779, 1769, 1774, 1787, 1798, 1794, 1791, 1788, + 1786, 1790, 1795, 1810, 1831, 1853, 1884, 1930, + 1974, 2000, 2014, 2016, 2009, 1999, 1991, 1991, + 1995, 2005, 2030, 2059, 2084, 2107, 2125, 2147, + 2175, 2207, 2246, 2290, 2337, 2392, 2451, 2507, + 2555, 2598, 2638, 2667, 2690, 2719, 2744, 2751, + 2748, 2745, 2745, 2760, 2783, 2827, 2871, 2902, + 2943, 3006, 3067, 3102, 3129, 3176, 3221, 3233, + 3258, 3285, 3304, 3307, 3285, 3257, 3210, 3162, + 3135, 3116, 3096, 3072, 3061, 3066, 3069, 3044, + 3013, 2994, 2960, 2933, 2904, 2868, 2849, 2832, + 2808, 2778, 2711, 2622, 2529, 2419, 2281, 2128, + 1981, 1840, 1737, 1683, 1663, 1682, 1732, 1810, + 1909, 2005, 2075, 2105, 2088, 2029, 1944, 1831, + 1726, 1639, 1568, 1521, 1501, 1511, 1545, 1591, + 1631, 1669, 1715, 1770, 1836, 1901, 1958, 2015, + 2062, 2089, 2103, 2105, 2089, 2074, 2069, 2074, + 2094, 2116, 2134, 2150, 2150, 2128, 2089, 2045, + 2016, 2010, 2029, 2077, 2155, 2245, 2333, 2399, + 2435, 2435, 2393, 2327, 2242, 2154, 2072, 1999, + 1945, 1904, 1870, 1845, 1828, 1820, 1829, 1846, + 1880, 1921, 1966, 2007, 2030, 2033, 2009, 1959, + 1893, 1818, 1749, 1706, 1681, 1674, 1689, 1707, + 1726, 1736, 1732, 1724, 1711, 1701, 1702, 1719, + 1750, 1792, 1844, 1893, 1928, 1950, 1957, 1952, + 1938, 1923, 1907, 1889, 1877, 1865, 1862, 1864, + 1867, 1866, 1850, 1822, 1803, 1810, 1830, 1855, + 1887, 1930, 1989, 2050, 2084, 2070, 2027, 1966, + 1895, 1822, 1755, 1707, 1691, 1694, 1722, 1770, + 1814, 1842, 1859, 1856, 1841, 1830, 1820, 1814, + 1803, 1791, 1782, 1769, 1750, 1730, 1705, 1676, + 1653, 1648, 1652, 1649, 1649, 1652, 1651, 1647, + 1635, 1625, 1628, 1632, 1641, 1667, 1695, 1713, + 1724, 1715, 1695, 1674, 1649, 1621, 1594, 1576, + 1580, 1597, 1617, 1645, 1685, 1719, 1738, 1755, + 1776, 1797, 1812, 1810, 1801, 1798, 1806, 1810, + 1805, 1790, 1780, 1790, 1806, 1817, 1832, 1843, + 1868, 1901, 1919, 1932, 1942, 1950, 1961, 1968, + 1973, 1983, 1991, 1993, 1994, 1993, 1983, 1976, + 1976, 1979, 1987, 2000, 2010, 2033, 2072, 2108, + 2148, 2196, 2244, 2299, 2353, 2397, 2440, 2468, + 2478, 2473, 2451, 2426, 2426, 2449, 2477, 2503, + 2537, 2609, 2715, 2815, 2883, 2932, 2965, 2970, + 2953, 2930, 2929, 2967, 3017, 3056, 3089, 3121, + 3185, 3277, 3343, 3378, 3378, 3376, 3385, 3349, + 3291, 3264, 3246, 3209, 3174, 3163, 3193, 3258, + 3315, 3361, 3385, 3377, 3372, 3372, 3338, 3251, + 3163, 3068, 2932, 2807, 2675, 2534, 2433, 2362, + 2322, 2314, 2331, 2364, 2376, 2350, 2292, 2214, + 2120, 2012, 1907, 1840, 1802, 1771, 1764, 1746, + 1706, 1661, 1587, 1504, 1444, 1419, 1420, 1455, + 1516, 1579, 1640, 1699, 1727, 1725, 1703, 1664, + 1628, 1624, 1655, 1699, 1741, 1783, 1822, 1836, + 1818, 1792, 1780, 1799, 1857, 1940, 2039, 2144, + 2251, 2331, 2360, 2349, 2315, 2264, 2199, 2150, + 2137, 2145, 2177, 2222, 2254, 2275, 2288, 2285, + 2271, 2257, 2249, 2257, 2272, 2281, 2286, 2269, + 2227, 2166, 2100, 2037, 1978, 1938, 1924, 1930, + 1954, 1988, 2010, 2017, 2007, 1985, 1947, 1910, + 1885, 1872, 1877, 1884, 1894, 1899, 1897, 1885, + 1866, 1840, 1814, 1807, 1810, 1823, 1842, 1870, + 1901, 1926, 1941, 1952, 1960, 1968, 1977, 1987, + 2003, 2022, 2040, 2058, 2069, 2068, 2065, 2062, + 2061, 2068, 2082, 2107, 2141, 2176, 2213, 2243, + 2261, 2262, 2234, 2179, 2126, 2097, 2086, 2073, + 2058, 2058, 2082, 2107, 2107, 2088, 2059, 2022, + 1981, 1951, 1924, 1896, 1875, 1861, 1863, 1873, + 1875, 1868, 1861, 1852, 1834, 1817, 1803, 1788, + 1766, 1729, 1687, 1655, 1637, 1615, 1587, 1579, + 1605, 1641, 1678, 1710, 1739, 1767, 1773, 1767, + 1752, 1738, 1706, 1677, 1654, 1649, 1664, 1682, + 1694, 1707, 1738, 1773, 1797, 1815, 1836, 1858, + 1880, 1882, 1877, 1879, 1877, 1869, 1852, 1843, + 1840, 1840, 1844, 1852, 1862, 1872, 1883, 1890, + 1894, 1892, 1896, 1906, 1916, 1923, 1931, 1937, + 1941, 1948, 1950, 1941, 1932, 1931, 1928, 1921, + 1916, 1910, 1905, 1913, 1931, 1961, 1990, 2008, + 2024, 2042, 2056, 2063, 2043, 2011, 1982, 1956, + 1936, 1927, 1932, 1950, 1979, 2012, 2046, 2082, + 2113, 2128, 2137, 2142, 2148, 2161, 2180, 2196, + 2213, 2248, 2299, 2350, 2405, 2460, 2499, 2530, + 2546, 2550, 2556, 2556, 2547, 2548, 2577, 2640, + 2720, 2786, 2846, 2921, 3004, 3063, 3069, 3056, + 3055, 3065, 3067, 3060, 3049, 3054, 3077, 3103, + 3126, 3137, 3145, 3161, 3187, 3206, 3211, 3231, + 3246, 3242, 3228, 3203, 3182, 3176, 3157, 3118, + 3075, 3031, 3006, 2990, 2952, 2903, 2849, 2812, + 2790, 2763, 2745, 2712, 2653, 2579, 2502, 2404, + 2267, 2098, 1929, 1827, 1771, 1732, 1734, 1804, + 1919, 2028, 2098, 2107, 2069, 1992, 1851, 1667, + 1499, 1371, 1291, 1254, 1250, 1289, 1363, 1435, + 1495, 1544, 1583, 1627, 1676, 1733, 1789, 1827, + 1845, 1849, 1833, 1798, 1746, 1692, 1667, 1686, + 1750, 1843, 1955, 2066, 2162, 2232, 2266, 2261, + 2230, 2198, 2180, 2188, 2219, 2271, 2335, 2398, + 2437, 2442, 2422, 2386, 2341, 2290, 2242, 2209, + 2207, 2215, 2226, 2232, 2230, 2232, 2228, 2219, + 2214, 2219, 2226, 2229, 2216, 2188, 2141, 2071, + 1991, 1905, 1834, 1782, 1761, 1775, 1819, 1878, + 1938, 1990, 2025, 2038, 2028, 2001, 1958, 1917, + 1876, 1841, 1811, 1792, 1783, 1781, 1782, 1793, + 1813, 1841, 1874, 1912, 1946, 1977, 1996, 2002, + 2000, 1987, 1971, 1955, 1947, 1952, 1966, 1985, + 2007, 2032, 2052, 2065, 2076, 2081, 2080, 2083, + 2090, 2103, 2120, 2139, 2159, 2181, 2201, 2211, + 2215, 2214, 2204, 2192, 2175, 2156, 2135, 2117, + 2102, 2086, 2077, 2075, 2081, 2084, 2078, 2081, + 2093, 2099, 2076, 2020, 1937, 1824, 1714, 1648, + 1607, 1576, 1560, 1579, 1647, 1740, 1800, 1814, + 1801, 1770, 1725, 1675, 1627, 1576, 1531, 1481, + 1439, 1424, 1430, 1437, 1449, 1470, 1511, 1561, + 1622, 1687, 1744, 1780, 1781, 1758, 1726, 1704, + 1679, 1638, 1611, 1619, 1643, 1675, 1713, 1751, + 1786, 1810, 1824, 1833, 1846, 1858, 1865, 1864, + 1862, 1858, 1856, 1856, 1859, 1858, 1851, 1842, + 1840, 1843, 1843, 1842, 1842, 1845, 1838, 1830, + 1827, 1836, 1849, 1863, 1877, 1888, 1902, 1916, + 1915, 1893, 1865, 1837, 1810, 1797, 1799, 1806, + 1817, 1834, 1864, 1897, 1929, 1960, 1981, 2007, + 2031, 2035, 2034, 2028, 2019, 2006, 1982, 1964, + 1965, 1983, 2006, 2033, 2067, 2104, 2144, 2179, + 2199, 2203, 2195, 2192, 2185, 2176, 2171, 2173, + 2194, 2222, 2244, 2259, 2284, 2315, 2342, 2376, + 2405, 2415, 2426, 2436, 2443, 2460, 2474, 2481, + 2488, 2505, 2544, 2598, 2652, 2706, 2760, 2798, + 2814, 2836, 2865, 2865, 2833, 2807, 2795, 2803, + 2827, 2847, 2877, 2928, 2958, 2979, 3006, 3042, + 3081, 3090, 3065, 3050, 3061, 3071, 3063, 3036, + 3006, 2987, 2962, 2932, 2920, 2919, 2895, 2866, + 2855, 2855, 2853, 2828, 2756, 2623, 2409, 2184, + 2063, 1996, 1882, 1807, 1871, 2060, 2301, 2485, + 2555, 2552, 2477, 2278, 1995, 1698, 1429, 1241, + 1139, 1114, 1204, 1368, 1522, 1640, 1719, 1756, + 1761, 1742, 1745, 1784, 1820, 1830, 1820, 1789, + 1722, 1606, 1446, 1308, 1235, 1253, 1354, 1533, + 1763, 1996, 2199, 2322, 2338, 2264, 2138, 2010, + 1902, 1827, 1805, 1859, 1970, 2091, 2185, 2220, + 2213, 2189, 2150, 2102, 2083, 2113, 2184, 2253, + 2304, 2335, 2342, 2316, 2258, 2188, 2128, 2099, + 2117, 2163, 2209, 2240, 2237, 2199, 2137, 2062, + 1982, 1911, 1879, 1900, 1971, 2061, 2149, 2224, + 2266, 2259, 2213, 2139, 2046, 1958, 1890, 1844, + 1823, 1821, 1826, 1839, 1859, 1879, 1897, 1923, + 1966, 2014, 2061, 2091, 2106, 2103, 2069, 2004, + 1927, 1856, 1808, 1787, 1785, 1809, 1867, 1943, + 2022, 2090, 2145, 2185, 2208, 2215, 2211, 2201, + 2186, 2172, 2156, 2140, 2126, 2120, 2121, 2132, + 2154, 2184, 2218, 2253, 2282, 2309, 2320, 2319, + 2308, 2289, 2271, 2258, 2243, 2230, 2231, 2233, + 2225, 2217, 2211, 2196, 2178, 2162, 2141, 2114, + 2090, 2078, 2077, 2063, 2049, 2059, 2070, 2077, + 2073, 2050, 2013, 1985, 1942, 1879, 1823, 1787, + 1762, 1756, 1764, 1774, 1792, 1795, 1793, 1805, + 1809, 1801, 1789, 1770, 1752, 1739, 1712, 1678, + 1656, 1643, 1633, 1629, 1646, 1681, 1722, 1753, + 1776, 1804, 1824, 1830, 1822, 1805, 1784, 1763, + 1740, 1727, 1731, 1745, 1762, 1776, 1805, 1843, + 1870, 1883, 1901, 1915, 1917, 1915, 1908, 1901, + 1899, 1893, 1873, 1862, 1859, 1864, 1870, 1877, + 1892, 1910, 1927, 1939, 1945, 1944, 1940, 1938, + 1932, 1922, 1911, 1904, 1908, 1915, 1919, 1923, + 1931, 1939, 1944, 1947, 1953, 1964, 1973, 1977, + 1986, 2006, 2027, 2033, 2031, 2040, 2061, 2078, + 2085, 2087, 2099, 2114, 2124, 2130, 2140, 2153, + 2165, 2178, 2196, 2223, 2250, 2268, 2279, 2292, + 2310, 2333, 2344, 2344, 2344, 2346, 2347, 2352, + 2350, 2345, 2346, 2361, 2383, 2408, 2426, 2436, + 2455, 2474, 2476, 2473, 2484, 2485, 2479, 2479, + 2477, 2470, 2467, 2461, 2456, 2464, 2470, 2482, + 2504, 2522, 2537, 2556, 2561, 2556, 2547, 2534, + 2522, 2509, 2485, 2473, 2487, 2502, 2512, 2513, + 2527, 2553, 2558, 2535, 2528, 2544, 2556, 2542, + 2518, 2513, 2521, 2527, 2520, 2500, 2497, 2511, + 2517, 2501, 2467, 2427, 2396, 2367, 2310, 2253, + 2226, 2226, 2250, 2280, 2302, 2331, 2358, 2366, + 2357, 2320, 2263, 2197, 2131, 2069, 2016, 1979, + 1949, 1933, 1934, 1943, 1951, 1964, 1982, 2007, + 2036, 2056, 2066, 2068, 2057, 2030, 1980, 1911, + 1844, 1795, 1766, 1751, 1754, 1781, 1832, 1887, + 1936, 1974, 2007, 2027, 2032, 2025, 2006, 1989, + 1976, 1963, 1948, 1934, 1918, 1915, 1914, 1919, + 1931, 1953, 1990, 2033, 2069, 2096, 2117, 2127, + 2125, 2111, 2084, 2056, 2040, 2029, 2023, 2025, + 2032, 2038, 2046, 2057, 2067, 2073, 2077, 2083, + 2095, 2107, 2113, 2121, 2123, 2122, 2121, 2117, + 2109, 2102, 2101, 2100, 2102, 2104, 2103, 2104, + 2104, 2101, 2096, 2093, 2091, 2093, 2100, 2108, + 2121, 2134, 2141, 2137, 2130, 2118, 2103, 2085, + 2068, 2055, 2047, 2042, 2046, 2052, 2059, 2069, + 2080, 2094, 2103, 2113, 2120, 2120, 2119, 2110, + 2098, 2084, 2072, 2058, 2047, 2040, 2039, 2044, + 2064, 2075, 2086, 2092, 2089, 2095, 2104, 2112, + 2113, 2104, 2082, 2056, 2033, 2026, 2027, 2025, + 2025, 2023, 2018, 2018, 2010, 1989, 1975, 1966, + 1946, 1919, 1910, 1920, 1932, 1939, 1939, 1939, + 1943, 1925, 1878, 1815, 1771, 1740, 1694, 1656, + 1659, 1689, 1722, 1751, 1766, 1779, 1792, 1791, + 1778, 1756, 1730, 1697, 1667, 1642, 1629, 1615, + 1589, 1580, 1583, 1593, 1621, 1656, 1696, 1743, + 1775, 1796, 1810, 1810, 1797, 1762, 1719, 1681, + 1649, 1632, 1627, 1640, 1670, 1702, 1741, 1785, + 1821, 1848, 1865, 1875, 1882, 1877, 1856, 1835, + 1815, 1796, 1775, 1749, 1738, 1742, 1756, 1774, + 1799, 1834, 1869, 1896, 1916, 1931, 1929, 1918, + 1905, 1888, 1869, 1852, 1842, 1849, 1860, 1872, + 1889, 1910, 1933, 1954, 1974, 1990, 2007, 2021, + 2029, 2028, 2034, 2041, 2042, 2045, 2058, 2072, + 2082, 2092, 2113, 2137, 2156, 2171, 2183, 2201, + 2225, 2242, 2248, 2260, 2279, 2300, 2322, 2337, + 2350, 2369, 2385, 2396, 2395, 2397, 2412, 2430, + 2446, 2459, 2471, 2493, 2516, 2539, 2555, 2570, + 2589, 2606, 2626, 2650, 2658, 2659, 2672, 2697, + 2709, 2714, 2721, 2737, 2762, 2772, 2768, 2775, + 2799, 2820, 2818, 2803, 2790, 2789, 2780, 2753, + 2717, 2681, 2647, 2577, 2477, 2416, 2401, 2371, + 2325, 2324, 2389, 2484, 2552, 2565, 2540, 2494, + 2418, 2288, 2121, 1974, 1863, 1782, 1728, 1721, + 1757, 1808, 1862, 1900, 1913, 1916, 1922, 1923, + 1922, 1918, 1907, 1895, 1866, 1812, 1734, 1642, + 1550, 1471, 1429, 1439, 1501, 1606, 1729, 1852, + 1956, 2028, 2050, 2026, 1979, 1920, 1854, 1789, + 1754, 1754, 1777, 1803, 1819, 1830, 1846, 1863, + 1880, 1905, 1951, 2014, 2077, 2127, 2174, 2199, + 2191, 2146, 2082, 2012, 1948, 1913, 1908, 1928, + 1967, 2013, 2062, 2107, 2139, 2153, 2149, 2143, + 2144, 2152, 2162, 2179, 2203, 2220, 2218, 2197, + 2166, 2128, 2089, 2058, 2039, 2040, 2058, 2085, + 2114, 2144, 2169, 2176, 2163, 2141, 2124, 2113, + 2099, 2085, 2077, 2071, 2061, 2044, 2021, 1995, + 1970, 1945, 1927, 1926, 1942, 1970, 2004, 2038, + 2065, 2087, 2093, 2090, 2081, 2063, 2039, 2018, + 2001, 1994, 1993, 1996, 2001, 2009, 2017, 2026, + 2039, 2057, 2080, 2107, 2130, 2151, 2170, 2180, + 2182, 2172, 2152, 2128, 2104, 2084, 2072, 2073, + 2079, 2094, 2116, 2139, 2159, 2174, 2187, 2194, + 2195, 2190, 2186, 2185, 2182, 2172, 2161, 2153, + 2139, 2125, 2116, 2109, 2103, 2101, 2104, 2118, + 2141, 2162, 2177, 2188, 2189, 2185, 2173, 2158, + 2145, 2129, 2114, 2099, 2091, 2085, 2077, 2070, + 2065, 2058, 2056, 2052, 2051, 2062, 2071, 2077, + 2080, 2079, 2072, 2059, 2042, 2019, 1997, 1981, + 1970, 1959, 1958, 1961, 1970, 1976, 1976, 1977, + 1979, 1976, 1974, 1969, 1960, 1954, 1952, 1951, + 1949, 1948, 1941, 1937, 1933, 1927, 1923, 1923, + 1927, 1930, 1931, 1932, 1920, 1892, 1884, 1894, + 1895, 1884, 1871, 1875, 1890, 1907, 1909, 1885, + 1865, 1864, 1874, 1884, 1883, 1878, 1870, 1865, + 1858, 1846, 1829, 1823, 1829, 1832, 1834, 1849, + 1874, 1902, 1917, 1920, 1920, 1929, 1941, 1948, + 1947, 1938, 1939, 1946, 1950, 1954, 1960, 1971, + 1979, 1989, 1998, 2011, 2026, 2046, 2066, 2079, + 2083, 2080, 2083, 2086, 2086, 2076, 2060, 2049, + 2052, 2060, 2067, 2076, 2081, 2089, 2101, 2114, + 2124, 2128, 2128, 2129, 2126, 2125, 2127, 2126, + 2121, 2117, 2109, 2098, 2093, 2096, 2109, 2119, + 2123, 2130, 2141, 2159, 2170, 2172, 2169, 2168, + 2175, 2172, 2163, 2165, 2168, 2170, 2170, 2169, + 2169, 2177, 2185, 2189, 2182, 2186, 2193, 2199, + 2206, 2218, 2224, 2217, 2215, 2212, 2209, 2205, + 2202, 2198, 2193, 2193, 2200, 2207, 2208, 2205, + 2208, 2208, 2205, 2207, 2209, 2208, 2208, 2212, + 2215, 2224, 2234, 2239, 2242, 2240, 2240, 2243, + 2239, 2233, 2238, 2245, 2241, 2242, 2243, 2243, + 2244, 2242, 2241, 2242, 2247, 2253, 2257, 2260, + 2268, 2274, 2271, 2262, 2258, 2256, 2252, 2244, + 2231, 2226, 2225, 2224, 2222, 2218, 2214, 2211, + 2208, 2209, 2212, 2213, 2215, 2218, 2220, 2220, + 2216, 2208, 2199, 2191, 2178, 2165, 2151, 2144, + 2140, 2137, 2131, 2127, 2128, 2127, 2123, 2118, + 2111, 2108, 2101, 2093, 2086, 2080, 2071, 2063, + 2052, 2039, 2028, 2016, 2007, 1998, 1990, 1987, + 1985, 1987, 1990, 1992, 1995, 1995, 1992, 1986, + 1979, 1973, 1966, 1955, 1945, 1938, 1929, 1926, + 1922, 1919, 1918, 1923, 1925, 1929, 1936, 1942, + 1944, 1946, 1947, 1945, 1942, 1937, 1934, 1930, + 1925, 1923, 1924, 1928, 1932, 1938, 1944, 1950, + 1959, 1969, 1974, 1979, 1984, 1985, 1983, 1983, + 1983, 1981, 1980, 1975, 1975, 1972, 1976, 1981, + 1983, 1986, 1987, 1989, 1990, 1990, 1992, 1993, + 1992, 1996, 1998, 1998, 1995, 1994, 1993, 1991, + 1988, 1982, 1977, 1973, 1970, 1968, 1965, 1963, + 1966, 1968, 1969, 1971, 1974, 1979, 1984, 1985, + 1987, 1988, 1985, 1979, 1973, 1965, 1957, 1954, + 1950, 1947, 1948, 1948, 1952, 1959, 1966, 1974, + 1980, 1986, 1990, 1992, 1993, 1994, 1992, 1987, + 1979, 1975, 1976, 1977, 1973, 1973, 1977, 1986, + 1995, 2004, 2008, 2018, 2026, 2025, 2026, 2024, + 2021, 2019, 2013, 2009, 2006, 2005, 2007, 2007, + 2011, 2018, 2028, 2038, 2047, 2056, 2063, 2074, + 2083, 2087, 2087, 2089, 2090, 2087, 2086, 2085, + 2090, 2094, 2094, 2105, 2118, 2127, 2131, 2136, + 2145, 2153, 2156, 2155, 2150, 2152, 2156, 2158, + 2155, 2154, 2158, 2165, 2167, 2165, 2166, 2170, + 2177, 2184, 2185, 2190, 2195, 2199, 2202, 2200, + 2198, 2197, 2199, 2199, 2196, 2193, 2197, 2202, + 2203, 2203, 2206, 2208, 2208, 2209, 2210, 2210, + 2210, 2212, 2213, 2214, 2214, 2215, 2215, 2214, + 2216, 2217, 2212, 2208, 2212, 2214, 2213, 2215, + 2216, 2222, 2226, 2226, 2229, 2225, 2221, 2224, + 2222, 2215, 2208, 2203, 2196, 2192, 2184, 2175, + 2170, 2165, 2163, 2159, 2154, 2150, 2146, 2142, + 2138, 2137, 2133, 2130, 2126, 2124, 2121, 2113, + 2104, 2094, 2087, 2081, 2075, 2064, 2058, 2054, + 2052, 2049, 2045, 2044, 2042, 2039, 2038, 2032, + 2028, 2025, 2022, 2020, 2015, 2008, 1999, 1993, + 1988, 1982, 1974, 1970, 1972, 1972, 1975, 1977, + 1977, 1980, 1980, 1976, 1973, 1973, 1970, 1966, + 1962, 1961, 1957, 1955, 1954, 1955, 1956, 1956, + 1958, 1961, 1969, 1975, 1978, 1981, 1983, 1984, + 1988, 1985, 1982, 1981, 1980, 1980, 1982, 1985, + 1990, 1997, 2003, 2010, 2015, 2021, 2027, 2030, + 2033, 2035, 2036, 2039, 2042, 2044, 2045, 2049, + 2050, 2050, 2052, 2055, 2056, 2058, 2061, 2066, + 2070, 2069, 2073, 2074, 2076, 2079, 2081, 2079, + 2077, 2076, 2074, 2075, 2074, 2072, 2070, 2070, + 2070, 2069, 2066, 2064, 2062, 2063, 2060, 2059, + 2060, 2061, 2061, 2057, 2055, 2053, 2049, 2043, + 2036, 2027, 2021, 2012, 2010, 1999, 1994, 1992, + 1987, 1980, 1972, 1973, 1972, 1968, 1965, 1965, + 1966, 1967, 1963, 1958, 1954, 1947, 1945, 1940, + 1935, 1933, 1930, 1929, 1931, 1933, 1933, 1933, + 1933, 1934, 1935, 1936, 1934, 1932, 1934, 1934, + 1933, 1935, 1933, 1932, 1934, 1933, 1930, 1928, + 1931, 1930, 1931, 1932, 1931, 1934, 1932, 1932, + 1932, 1934, 1937, 1936, 1937, 1940, 1943, 1942, + 1946, 1945, 1944, 1944, 1942, 1944, 1946, 1948, + 1947, 1949, 1953, 1956, 1958, 1961, 1964, 1968, + 1970, 1971, 1975, 1976, 1979, 1981, 1982, 1985, + 1988, 1990, 1992, 1997, 2002, 2009, 2013, 2018, + 2027, 2033, 2039, 2042, 2049, 2054, 2061, 2062, + 2062, 2066, 2069, 2076, 2080, 2084, 2089, 2094, + 2099, 2105, 2110, 2114, 2120, 2125, 2130, 2137, + 2141, 2146, 2152, 2159, 2164, 2168, 2172, 2177, + 2182, 2186, 2187, 2192, 2197, 2201, 2205, 2210, + 2218, 2220, 2224, 2228, 2232, 2238, 2243, 2246, + 2249, 2252, 2250, 2248, 2248, 2246, 2249, 2250, + 2252, 2252, 2252, 2258, 2262, 2264, 2268, 2271, + 2272, 2274, 2271, 2269, 2268, 2268, 2264, 2262, + 2261, 2261, 2255, 2251, 2249, 2248, 2248, 2243, + 2241, 2244, 2246, 2249, 2248, 2247, 2246, 2246, + 2245, 2240, 2238, 2237, 2241, 2240, 2240, 2239, + 2240, 2240, 2238, 2236, 2234, 2233, 2230, 2226, + 2222, 2222, 2219, 2215, 2213, 2209, 2204, 2201, + 2193, 2185, 2182, 2175, 2169, 2164, 2161, 2154, + 2150, 2143, 2134, 2132, 2127, 2122, 2114, 2109, + 2104, 2097, 2092, 2085, 2077, 2068, 2060, 2054, + 2049, 2045, 2039, 2035, 2033, 2033, 2031, 2029, + 2027, 2023, 2023, 2018, 2015, 2013, 2010, 2008, + 2008, 2005, 2001, 2002, 1997, 1996, 1993, 1991, + 1991, 1995, 1996, 1996, 1997, 1998, 1999, 1999, + 1995, 1994, 1998, 1996, 1996, 1997, 1999, 2001, + 2002, 2006, 2009, 2011, 2012, 2015, 2017, 2020, + 2023, 2031, 2035, 2039, 2041, 2042, 2047, 2049, + 2048, 2049, 2052, 2056, 2058, 2060, 2064, 2068, + 2071, 2073, 2071, 2073, 2077, 2079, 2077, 2078, + 2077, 2077, 2076, 2073, 2073, 2071, 2069, 2068, + 2069, 2066, 2068, 2070, 2069, 2070, 2068, 2070, + 2067, 2067, 2064, 2062, 2059, 2056, 2050, 2048, + 2047, 2044, 2041, 2040, 2038, 2038, 2036, 2036, + 2035, 2035, 2035, 2033, 2035, 2032, 2030, 2027, + 2024, 2019, 2015, 2014, 2013, 2011, 2011, 2011, + 2011, 2010, 2012, 2012, 2009, 2009, 2005, 2004, + 2002, 1997, 1995, 1991, 1990, 1989, 1985, 1983, + 1982, 1982, 1980, 1978, 1978, 1980, 1980, 1980, + 1984, 1986, 1984, 1984, 1986, 1987, 1987, 1986, + 1987, 1986, 1987, 1988, 1989, 1989, 1987, 1990, + 1992, 1996, 1998, 2002, 2007, 2011, 2015, 2018, + 2021, 2026, 2028, 2028, 2028, 2026, 2026, 2025, + 2024, 2024, 2024, 2025, 2027, 2033, 2033, 2034, + 2038, 2040, 2043, 2041, 2044, 2043, 2042, 2040, + 2036, 2036, 2038, 2040, 2043, 2044, 2045, 2048, + 2049, 2055, 2058, 2059, 2061, 2064, 2064, 2064, + 2064, 2064, 2063, 2064, 2064, 2064, 2065, 2066, + 2067, 2070, 2074, 2076, 2078, 2077, 2079, 2074, + 2075, 2074, 2071, 2073, 2073, 2074, 2075, 2077, + 2079, 2079, 2080, 2080, 2079, 2083, 2087, 2091, + 2093, 2093, 2097, 2098, 2100, 2105, 2108, 2107, + 2109, 2111, 2112, 2116, 2119, 2121, 2123, 2126, + 2131, 2134, 2138, 2140, 2143, 2144, 2148, 2149, + 2151, 2152, 2152, 2154, 2152, 2155, 2156, 2157, + 2158, 2162, 2165, 2165, 2167, 2169, 2171, 2170, + 2173, 2171, 2172, 2174, 2174, 2171, 2168, 2169, + 2168, 2163, 2162, 2164, 2166, 2167, 2169, 2165, + 2167, 2166, 2165, 2165, 2165, 2162, 2160, 2160, + 2159, 2156, 2153, 2152, 2152, 2146, 2143, 2141, + 2139, 2136, 2133, 2129, 2125, 2120, 2114, 2111, + 2108, 2103, 2100, 2092, 2091, 2091, 2087, 2080, + 2076, 2076, 2073, 2068, 2065, 2061, 2056, 2053, + 2050, 2044, 2039, 2036, 2032, 2028, 2024, 2024, + 2021, 2018, 2017, 2017, 2013, 2007, 2006, 2001, + 1996, 1997, 1992, 1990, 1988, 1982, 1979, 1977, + 1973, 1970, 1967, 1965, 1963, 1961, 1960, 1958, + 1954, 1955, 1951, 1949, 1947, 1941, 1937, 1935, + 1935, 1934, 1934, 1931, 1933, 1935, 1936, 1936, + 1936, 1937, 1939, 1939, 1942, 1943, 1946, 1945, + 1944, 1945, 1946, 1948, 1949, 1950, 1952, 1949, + 1948, 1948, 1947, 1946, 1946, 1949, 1949, 1949, + 1952, 1954, 1956, 1955, 1953, 1954, 1954, 1955, + 1957, 1953, 1952, 1950, 1948, 1948, 1948, 1948, + 1947, 1949, 1949, 1947, 1946, 1948, 1951, 1950, + 1951, 1953, 1953, 1952, 1955, 1955, 1953, 1951, + 1952, 1953, 1951, 1950, 1950, 1953, 1954, 1953, + 1954, 1951, 1952, 1953, 1953, 1952, 1953, 1954, + 1956, 1955, 1954, 1955, 1953, 1953, 1953, 1951, + 1951, 1951, 1950, 1954, 1955, 1956, 1956, 1957, + 1956, 1961, 1964, 1965, 1969, 1970, 1974, 1978, + 1980, 1981, 1981, 1983, 1983, 1986, 1987, 1992, + 1997, 2000, 2002, 2006, 2011, 2016, 2020, 2027, + 2031, 2033, 2039, 2044, 2046, 2049, 2053, 2058, + 2059, 2060, 2061, 2064, 2067, 2072, 2077, 2081, + 2086, 2090, 2096, 2100, 2102, 2104, 2108, 2111, + 2115, 2115, 2116, 2118, 2120, 2119, 2119, 2119, + 2118, 2119, 2119, 2120, 2120, 2120, 2124, 2128, + 2127, 2127, 2127, 2127, 2129, 2127, 2125, 2124, + 2124, 2125, 2124, 2125, 2123, 2122, 2123, 2122, + 2121, 2122, 2125, 2128, 2129, 2132, 2134, 2133, + 2134, 2136, 2135, 2137, 2136, 2134, 2137, 2137, + 2138, 2139, 2137, 2134, 2139, 2139, 2141, 2142, + 2145, 2150, 2152, 2154, 2156, 2159, 2159, 2160, + 2160, 2159, 2160, 2160, 2159, 2160, 2163, 2166, + 2166, 2166, 2165, 2166, 2168, 2169, 2171, 2174, + 2178, 2176, 2176, 2176, 2177, 2177, 2176, 2174, + 2174, 2177, 2181, 2181, 2182, 2183, 2186, 2188, + 2189, 2191, 2190, 2191, 2188, 2186, 2186, 2185, + 2183, 2185, 2186, 2184, 2183, 2183, 2182, 2183, + 2180, 2180, 2177, 2175, 2175, 2172, 2168, 2165, + 2165, 2165, 2163, 2162, 2162, 2158, 2158, 2154, + 2150, 2146, 2143, 2138, 2139, 2134, 2130, 2124, + 2122, 2117, 2116, 2109, 2104, 2099, 2097, 2089, + 2084, 2079, 2072, 2068, 2064, 2061, 2055, 2048, + 2043, 2041, 2034, 2032, 2028, 2022, 2019, 2012, + 2008, 2005, 2001, 1996, 1991, 1989, 1988, 1985, + 1982, 1978, 1974, 1972, 1970, 1967, 1964, 1960, + 1961, 1959, 1955, 1952, 1951, 1949, 1949, 1947, + 1944, 1945, 1944, 1944, 1942, 1941, 1940, 1937, + 1934, 1931, 1932, 1931, 1931, 1932, 1932, 1930, + 1929, 1927, 1926, 1926, 1928, 1931, 1933, 1935, + 1935, 1935, 1937, 1938, 1940, 1941, 1937, 1938, + 1940, 1940, 1942, 1942, 1943, 1945, 1947, 1948, + 1950, 1954, 1953, 1955, 1957, 1959, 1961, 1965, + 1965, 1965, 1966, 1968, 1971, 1971, 1972, 1972, + 1974, 1975, 1975, 1978, 1980, 1980, 1982, 1983, + 1983, 1984, 1986, 1988, 1992, 1993, 1994, 1997, + 1996, 1994, 1994, 1998, 1999, 2002, 2004, 2007, + 2009, 2010, 2012, 2013, 2017, 2020, 2022, 2024, + 2027, 2027, 2030, 2034, 2037, 2039, 2041, 2045, + 2049, 2050, 2052, 2055, 2055, 2057, 2060, 2062, + 2067, 2072, 2075, 2077, 2078, 2082, 2085, 2089, + 2090, 2094, 2095, 2098, 2099, 2103, 2107, 2108, + 2111, 2113, 2115, 2115, 2117, 2116, 2117, 2118, + 2120, 2121, 2124, 2125, 2126, 2126, 2127, 2129, + 2129, 2129, 2129, 2131, 2129, 2129, 2129, 2128, + 2128, 2126, 2127, 2127, 2128, 2128, 2126, 2126, + 2125, 2126, 2125, 2124, 2121, 2120, 2119, 2118, + 2118, 2118, 2116, 2114, 2114, 2116, 2115, 2115, + 2111, 2110, 2110, 2110, 2107, 2108, 2108, 2106, + 2109, 2109, 2110, 2110, 2109, 2108, 2107, 2103, + 2102, 2102, 2102, 2101, 2099, 2101, 2098, 2096, + 2093, 2093, 2094, 2093, 2094, 2095, 2095, 2097, + 2094, 2090, 2091, 2088, 2084, 2083, 2083, 2082, + 2079, 2076, 2076, 2076, 2076, 2073, 2073, 2071, + 2068, 2069, 2068, 2066, 2063, 2063, 2063, 2065, + 2064, 2063, 2062, 2063, 2065, 2065, 2068, 2068, + 2066, 2068, 2066, 2062, 2064, 2067, 2063, 2063, + 2063, 2063, 2064, 2061, 2060, 2062, 2061, 2061, + 2059, 2061, 2060, 2057, 2059, 2059, 2058, 2058, + 2055, 2053, 2054, 2052, 2047, 2044, 2041, 2042, + 2040, 2041, 2041, 2042, 2039, 2039, 2040, 2042, + 2042, 2040, 2040, 2036, 2036, 2037, 2035, 2034, + 2034, 2032, 2031, 2028, 2027, 2026, 2023, 2025, + 2026, 2028, 2027, 2027, 2028, 2026, 2026, 2027, + 2025, 2022, 2019, 2016, 2011, 2010, 2008, 2008, + 2004, 2001, 1999, 1998, 1996, 1997, 1994, 1992, + 1993, 1990, 1989, 1985, 1984, 1983, 1980, 1979, + 1975, 1970, 1969, 1971, 1970, 1969, 1969, 1969, + 1970, 1971, 1973, 1975, 1974, 1974, 1974, 1975, + 1972, 1974, 1974, 1974, 1976, 1972, 1973, 1973, + 1973, 1973, 1969, 1972, 1972, 1977, 1981, 1984, + 1987, 1989, 1989, 1990, 1991, 1991, 1990, 1991, + 1989, 1987, 1985, 1988, 1987, 1986, 1987, 1988, + 1989, 1988, 1992, 1993, 1992, 1994, 1995, 1995, + 1994, 1993, 1991, 1994, 1992, 1990, 1992, 1990, + 1994, 1994, 1997, 1997, 1999, 2001, 2002, 2003, + 2003, 2003, 2005, 2003, 2000, 2000, 2001, 2003, + 2004, 2004, 2002, 2002, 2003, 2002, 2002, 2002, + 2003, 2002, 2001, 2005, 2003, 2001, 2001, 2003, + 2002, 2001, 2001, 2000, 2002, 2000, 2002, 2002, + 2002, 2003, 2002, 2005, 2004, 2004, 2008, 2007, + 2008, 2010, 2013, 2018, 2019, 2020, 2021, 2022, + 2023, 2023, 2024, 2024, 2022, 2022, 2023, 2025, + 2026, 2026, 2029, 2030, 2030, 2032, 2032, 2034, + 2032, 2033, 2031, 2033, 2035, 2036, 2037, 2037, + 2036, 2035, 2038, 2040, 2040, 2040, 2039, 2039, + 2040, 2041, 2040, 2040, 2039, 2041, 2040, 2039, + 2041, 2039, 2038, 2038, 2041, 2042, 2042, 2044, + 2042, 2042, 2040, 2042, 2044, 2043, 2043, 2045, + 2045, 2044, 2047, 2048, 2048, 2049, 2050, 2049, + 2051, 2052, 2053, 2056, 2055, 2055, 2056, 2056, + 2059, 2056, 2058, 2056, 2055, 2056, 2054, 2058, + 2059, 2059, 2059, 2058, 2057, 2058, 2056, 2056, + 2059, 2060, 2060, 2062, 2064, 2064, 2063, 2065, + 2065, 2066, 2064, 2065, 2067, 2064, 2064, 2064, + 2066, 2064, 2066, 2064, 2064, 2066, 2065, 2065, + 2064, 2064, 2063, 2064, 2063, 2063, 2064, 2063, + 2064, 2066, 2066, 2068, 2068, 2063, 2062, 2062, + 2063, 2065, 2065, 2063, 2062, 2064, 2064, 2067, + 2064, 2065, 2066, 2062, 2063, 2064, 2064, 2065, + 2066, 2064, 2066, 2069, 2069, 2070, 2070, 2070, + 2068, 2069, 2071, 2073, 2074, 2077, 2076, 2079, + 2080, 2082, 2082, 2083, 2083, 2082, 2082, 2081, + 2083, 2083, 2080, 2081, 2081, 2083, 2083, 2083, + 2083, 2080, 2081, 2084, 2085, 2084, 2085, 2085, + 2083, 2082, 2080, 2081, 2080, 2080, 2078, 2079, + 2077, 2076, 2076, 2076, 2078, 2076, 2077, 2078, + 2080, 2080, 2082, 2084, 2082, 2082, 2082, 2081, + 2082, 2082, 2083, 2083, 2084, 2085, 2086, 2086, + 2084, 2085, 2086, 2087, 2087, 2089, 2088, 2085, + 2086, 2089, 2088, 2087, 2086, 2086, 2086, 2090, + 2089, 2089, 2090, 2092, 2094, 2095, 2095, 2097, + 2098, 2099, 2100, 2099, 2101, 2104, 2102, 2101, + 2101, 2101, 2103, 2102, 2099, 2096, 2097, 2098, + 2097, 2097, 2099, 2099, 2100, 2100, 2102, 2105, + 2104, 2100, 2099, 2096, 2097, 2095, 2092, 2094, + 2092, 2089, 2089, 2088, 2088, 2085, 2085, 2083, + 2082, 2081, 2080, 2081, 2082, 2082, 2080, 2080, + 2080, 2079, 2080, 2078, 2076, 2074, 2073, 2073, + 2073, 2072, 2071, 2067, 2067, 2069, 2070, 2072, + 2074, 2077, 2078, 2078, 2080, 2078, 2076, 2076, + 2073, 2073, 2071, 2070, 2071, 2069, 2069, 2069, + 2069, 2068, 2069, 2069, 2068, 2068, 2068, 2069, + 2068, 2066, 2064, 2064, 2063, 2062, 2061, 2055, + 2058, 2059, 2057, 2056, 2055, 2058, 2057, 2055, + 2054, 2055, 2056, 2055, 2055, 2055, 2052, 2053, + 2055, 2054, 2055, 2052, 2051, 2051, 2050, 2049, + 2049, 2050, 2048, 2049, 2049, 2049, 2050, 2052, + 2052, 2052, 2052, 2053, 2054, 2057, 2057, 2058, + 2058, 2058, 2061, 2061, 2062, 2064, 2065, 2066, + 2068, 2067, 2070, 2071, 2073, 2075, 2075, 2076, + 2078, 2078, 2077, 2076, 2080, 2077, 2079, 2080, + 2081, 2079, 2076, 2075, 2074, 2077, 2075, 2071, + 2071, 2070, 2070, 2073, 2073, 2076, 2074, 2071, + 2072, 2072, 2071, 2072, 2069, 2066, 2064, 2062, + 2061, 2062, 2063, 2062, 2064, 2062, 2060, 2062, + 2062, 2061, 2061, 2060, 2056, 2057, 2057, 2055, + 2056, 2056, 2055, 2056, 2057, 2057, 2058, 2059, + 2060, 2059, 2062, 2065, 2067, 2068, 2067, 2067, + 2067, 2066, 2066, 2065, 2063, 2060, 2064, 2067, + 2067, 2065, 2063, 2062, 2063, 2063, 2061, 2061, + 2060, 2060, 2059, 2059, 2061, 2060, 2064, 2064, + 2063, 2062, 2061, 2061, 2060, 2060, 2059, 2057, + 2056, 2055, 2056, 2058, 2058, 2060, 2058, 2060, + 2060, 2057, 2056, 2055, 2055, 2054, 2052, 2051, + 2052, 2048, 2048, 2050, 2051, 2046, 2044, 2043, + 2045, 2045, 2042, 2044, 2044, 2045, 2046, 2048, + 2047, 2049, 2045, 2043, 2042, 2042, 2040, 2039, + 2040, 2039, 2042, 2041, 2042, 2044, 2043, 2041, + 2040, 2039, 2036, 2038, 2039, 2040, 2042, 2043, + 2042, 2042, 2043, 2043, 2042, 2042, 2041, 2042, + 2041, 2044, 2044, 2041, 2042, 2043, 2040, 2041, + 2040, 2038, 2038, 2036, 2034, 2034, 2035, 2032, + 2032, 2031, 2032, 2031, 2029, 2030, 2029, 2029, + 2027, 2025, 2024, 2025, 2022, 2021, 2016, 2012, + 2012, 2014, 2014, 2014, 2013, 2011, 2010, 2008, + 2010, 2009, 2008, 2007, 2006, 2008, 2009, 2010, + 2011, 2008, 2009, 2011, 2010, 2012, 2012, 2011, + 2011, 2008, 2010, 2012, 2012, 2014, 2014, 2013, + 2007, 2012, 2017, 2018, 2016, 2013, 2011, 2015, + 2016, 2018, 2020, 2019, 2018, 2020, 2021, 2023, + 2024, 2023, 2026, 2024, 2025, 2027, 2027, 2026, + 2025, 2026, 2026, 2024, 2025, 2024, 2019, 2017, + 2015, 2012, 2010, 2009, 2010, 2010, 2008, 2005, + 2007, 2008, 2004, 2002, 1999, 1995, 1994, 1997, + 1997, 1997, 1996, 1995, 2000, 2001, 1998, 1998, + 1994, 1994, 1993, 1993, 1990, 1991, 1991, 1991, + 1996, 1993, 1995, 1995, 1997, 1994, 1994, 1994, + 1993, 1993, 1990, 1990, 1992, 1994, 1996, 1998, + 1998, 1998, 2000, 2002, 2001, 2001, 2000, 1998, + 2003, 2004, 2002, 2003, 2006, 2006, 2007, 2004, + 2002, 2001, 2000, 2000, 2002, 2001, 2002, 2003, + 2003, 2005, 2002, 2003, 2004, 2004, 2003, 1999, + 1996, 1998, 2000, 2001, 2001, 2000, 2001, 2003, + 2007, 2006, 2006, 2006, 2007, 2005, 2009, 2008, + 2008, 2011, 2011, 2017, 2016, 2016, 2019, 2021, + 2022, 2023, 2020, 2019, 2021, 2022, 2022, 2019, + 2020, 2021, 2022, 2021, 2025, 2027, 2025, 2025, + 2026, 2028, 2029, 2031, 2029, 2030, 2033, 2034, + 2034, 2031, 2030, 2032, 2033, 2032, 2033, 2032, + 2032, 2033, 2033, 2033, 2034, 2033, 2033, 2035, + 2034, 2032, 2033, 2034, 2030, 2028, 2026, 2026, + 2029, 2028, 2028, 2027, 2029, 2031, 2033, 2034, + 2034, 2033, 2032, 2034, 2034, 2032, 2031, 2034, + 2032, 2034, 2030, 2032, 2033, 2031, 2032, 2031, + 2030, 2031, 2031, 2030, 2029, 2028, 2027, 2028, + 2029, 2029, 2027, 2027, 2027, 2028, 2029, 2025, + 2024, 2022, 2022, 2025, 2026, 2027, 2026, 2027, + 2030, 2032, 2030, 2030, 2028, 2029, 2028, 2027, + 2028, 2030, 2032, 2030, 2032, 2033, 2032, 2031, + 2030, 2033, 2031, 2031, 2034, 2033, 2039, 2039, + 2039, 2041, 2043, 2043, 2041, 2039, 2038, 2038, + 2039, 2040, 2041, 2040, 2044, 2044, 2043, 2044, + 2044, 2047, 2049, 2045, 2046, 2046, 2044, 2046, + 2046, 2046, 2047, 2043, 2040, 2041, 2040, 2041, + 2045, 2044, 2044, 2046, 2043, 2042, 2042, 2041, + 2041, 2041, 2042, 2043, 2043, 2044, 2044, 2042, + 2042, 2044, 2044, 2044, 2046, 2045, 2046, 2046, + 2044, 2043, 2044, 2041, 2040, 2042, 2043, 2042, + 2043, 2047, 2046, 2048, 2045, 2045, 2046, 2046, + 2045, 2046, 2046, 2044, 2042, 2042, 2043, 2045, + 2047, 2046, 2046, 2048, 2048, 2049, 2050, 2049, + 2047, 2047, 2048, 2050, 2050, 2049, 2050, 2050, + 2051, 2050, 2048, 2048, 2047, 2044, 2044, 2043, + 2042, 2043, 2041, 2040, 2041, 2039, 2038, 2038, + 2038, 2038, 2039, 2036, 2034, 2034, 2031, 2031, + 2031, 2029, 2028, 2027, 2028, 2028, 2026, 2025, + 2027, 2030, 2028, 2027, 2025, 2024, 2023, 2020, + 2021, 2020, 2018, 2021, 2021, 2020, 2018, 2020, + 2019, 2021, 2026, 2027, 2027, 2027, 2028, 2027, + 2028, 2026, 2029, 2026, 2025, 2028, 2029, 2030, + 2033, 2034, 2034, 2034, 2036, 2036, 2039, 2041, + 2041, 2040, 2039, 2036, 2033, 2030, 2032, 2031, + 2029, 2034, 2039, 2044, 2048, 2051, 2054, 2055, + 2054, 2057, 2059, 2056, 2053, 2050, 2048, 2044, + 2037, 2033, 2030, 2026, 2027, 2028, 2031, 2037, + 2042, 2046, 2051, 2051, 2056, 2056, 2052, 2048, + 2044, 2037, 2029, 2023, 2014, 2007, 2003, 2002, + 2001, 1999, 1952, 1835, 1745, 1700, 1674, 1683, + 1730, 1806, 1892, 1979, 2053, 2095, 2102, 2106, + 2121, 2130, 2119, 2100, 2071, 2028, 1984, 1947, + 1918, 1900, 1904, 1935, 1979, 2022, 2068, 2117, + 2154, 2185, 2200, 2203, 2195, 2171, 2138, 2103, + 2079, 2045, 2012, 2001, 2006, 2014, 2025, 2046, + 2071, 2087, 2104, 2123, 2137, 2145, 2147, 2156, + 2150, 2130, 2105, 2082, 2044, 2005, 1982, 1967, + 1967, 1976, 1996, 1991, 1900, 1837, 1827, 1801, + 1808, 1817, 1847, 1897, 1932, 1965, 1973, 1967, + 1969, 2007, 2030, 2021, 2003, 1972, 1936, 1895, + 1870, 1845, 1822, 1827, 1856, 1892, 1915, 1937, + 1964, 1985, 2006, 2025, 2041, 2046, 2029, 2015, + 2001, 1988, 1969, 1936, 1912, 1908, 1909, 1918, + 1931, 1948, 1974, 2003, 2029, 2050, 2066, 2074, + 2075, 2065, 2045, 2027, 2012, 1990, 1967, 1957, + 1960, 1970, 1981, 1996, 2015, 2026, 2040, 2054, + 2058, 2051, 2049, 2056, 2058, 2049, 2029, 2008, + 1991, 1985, 1983, 1975, 1951, 1915, 1878, 1859, + 1850, 1841, 1846, 1863, 1891, 1923, 1957, 1977, + 1975, 1960, 1953, 1956, 1965, 1970, 1964, 1957, + 1943, 1933, 1923, 1910, 1898, 1892, 1897, 1914, + 1945, 1973, 2000, 2018, 2031, 2040, 2038, 2026, + 2002, 1975, 1954, 1945, 1942, 1938, 1941, 1951, + 1964, 1971, 1972, 1970, 1979, 1989, 1996, 2004, + 2013, 2012, 2009, 2022, 2016, 1991, 1975, 1980, + 1974, 1947, 1934, 1950, 1976, 2002, 2023, 2035, + 2041, 2047, 2053, 2046, 2030, 2021, 2017, 2011, + 2015, 2021, 2010, 1991, 1984, 1996, 2011, 2016, + 2013, 2008, 2006, 2017, 2024, 2023, 2026, 2032, + 2031, 2030, 2029, 2025, 2004, 1987, 1996, 2021, + 2041, 2042, 2035, 2033, 2031, 2026, 2011, 1998, + 1989, 1977, 1963, 1956, 1957, 1951, 1941, 1935, + 1939, 1951, 1956, 1956, 1952, 1948, 1950, 1950, + 1945, 1938, 1908, 1840, 1792, 1779, 1765, 1742, + 1726, 1745, 1771, 1801, 1839, 1877, 1904, 1924, + 1950, 1965, 1975, 1976, 1957, 1929, 1906, 1900, + 1888, 1864, 1847, 1846, 1861, 1881, 1909, 1945, + 1986, 2019, 2043, 2056, 2062, 2055, 2026, 2000, + 1988, 1976, 1954, 1935, 1934, 1950, 1972, 1984, + 1998, 2022, 2047, 2060, 2063, 2064, 2062, 2057, + 2046, 2040, 2033, 2016, 2000, 1991, 1978, 1969, + 1972, 1995, 2016, 2028, 2051, 2070, 2071, 2066, + 2059, 2044, 2023, 2007, 2003, 1999, 1984, 1970, + 1965, 1963, 1962, 1970, 1982, 1988, 1993, 1996, + 2001, 2005, 2000, 2001, 1999, 1991, 1984, 1972, + 1960, 1944, 1929, 1920, 1919, 1935, 1958, 1974, + 1980, 1991, 2005, 2018, 2015, 1997, 1984, 1971, + 1956, 1948, 1945, 1940, 1945, 1963, 1973, 1972, + 1975, 1981, 1986, 1988, 1995, 2009, 2020, 2032, + 2035, 2026, 2008, 1991, 1973, 1962, 1964, 1971, + 1981, 1999, 2025, 2050, 2063, 2068, 2062, 2052, + 2044, 2038, 2033, 2028, 2027, 2028, 2031, 2031, + 2033, 2029, 2021, 2019, 2017, 2021, 2031, 2044, + 2058, 2068, 2075, 2074, 2067, 2056, 2044, 2031, + 2015, 2002, 2000, 1997, 2001, 2010, 2012, 2025, + 2035, 2041, 2044, 2046, 2048, 2043, 2039, 2035, + 2036, 2032, 2025, 2016, 2004, 1989, 1982, 1983, + 1989, 1998, 2008, 2021, 2032, 2036, 2037, 2035, + 2031, 2021, 2012, 2011, 2008, 2002, 1999, 2000, + 2001, 2003, 2011, 2021, 2025, 2024, 2027, 2033, + 2036, 2036, 2038, 2039, 2042, 2040, 2037, 2034, + 2027, 2019, 2013, 2012, 2013, 2018, 2030, 2043, + 2057, 2067, 2074, 2075, 2069, 2060, 2051, 2044, + 2036, 2030, 2031, 2033, 2037, 2040, 2043, 2043, + 2048, 2053, 2054, 2054, 2061, 2069, 2066, 2060, + 2059, 2056, 2052, 2050, 2054, 2057, 2053, 2055, + 2055, 2059, 2060, 2063, 2067, 2069, 2068, 2070, + 2067, 2058, 2047, 2043, 2042, 2039, 2040, 2047, + 2051, 2050, 2052, 2055, 2058, 2056, 2055, 2053, + 2053, 2049, 2047, 2045, 2040, 2036, 2031, 2028, + 2026, 2026, 2032, 2039, 2047, 2053, 2058, 2061, + 2060, 2062, 2056, 2046, 2043, 2040, 2040, 2037, + 2036, 2037, 2041, 2042, 2044, 2048, 2048, 2050, + 2056, 2062, 2066, 2068, 2071, 2072, 2070, 2069, + 2066, 2057, 2048, 2044, 2044, 2047, 2050, 2055, + 2061, 2067, 2072, 2078, 2083, 2085, 2088, 2087, + 2084, 2083, 2076, 2071, 2067, 2062, 2060, 2060, + 2058, 2056, 2059, 2065, 2073, 2079, 2088, 2089, + 2093, 2097, 2097, 2092, 2084, 2078, 2074, 2067, + 2060, 2058, 2056, 2058, 2058, 2065, 2067, 2073, + 2077, 2081, 2080, 2074, 2072, 2069, 2067, 2063, + 2062, 2059, 2061, 2060, 2057, 2055, 2054, 2057, + 2061, 2065, 2067, 2065, 2063, 2063, 2061, 2058, + 2053, 2052, 2050, 2051, 2053, 2057, 2059, 2061, + 2060, 2058, 2060, 2058, 2061, 2068, 2071, 2070, + 2066, 2069, 2067, 2061, 2055, 2052, 2054, 2054, + 2055, 2056, 2061, 2063, 2065, 2066, 2071, 2076, + 2080, 2082, 2081, 2080, 2075, 2068, 2058, 2048, + 2040, 2036, 2035, 2040, 2050, 2059, 2070, 2083, + 2092, 2097, 2094, 2091, 2087, 2077, 2070, 2062, + 2054, 2049, 2048, 2048, 2046, 2044, 2051, 2058, + 2067, 2075, 2088, 2091, 2085, 2077, 2068, 2063, + 2056, 2056, 2062, 2064, 2061, 2056, 2051, 2046, + 2044, 2047, 2050, 2057, 2063, 2064, 2061, 2056, + 2057, 2059, 2063, 2068, 2068, 2068, 2063, 2054, + 2043, 2036, 2033, 2035, 2039, 2045, 2048, 2051, + 2049, 2047, 2048, 2046, 2052, 2057, 2058, 2058, + 2054, 2046, 2040, 2039, 2036, 2037, 2041, 2045, + 2049, 2052, 2049, 2042, 2030, 2022, 2020, 2022, + 2029, 2039, 2048, 2058, 2064, 2062, 2056, 2045, + 2040, 2036, 2032, 2029, 2024, 2020, 2014, 2012, + 2016, 2023, 2034, 2043, 2051, 2053, 2052, 2048, + 2041, 2034, 2030, 2028, 2027, 2024, 2016, 2008, + 2003, 2001, 2003, 2009, 2019, 2026, 2032, 2033, + 2033, 2032, 2033, 2036, 2038, 2038, 2034, 2035, + 2031, 2029, 2024, 2023, 2024, 2027, 2027, 2026, + 2020, 2017, 2018, 2022, 2026, 2031, 2038, 2039, + 2038, 2039, 2038, 2036, 2030, 2024, 2022, 2020, + 2016, 2012, 2011, 2011, 2013, 2018, 2025, 2028, + 2026, 2024, 2018, 2014, 2008, 2003, 2001, 2007, + 2014, 2025, 2029, 2026, 2019, 2008, 1999, 1990, + 1985, 1984, 1989, 1995, 2007, 2015, 2015, 2015, + 2014, 2013, 2012, 2016, 2016, 2015, 2014, 2008, + 2001, 1991, 1987, 1984, 1986, 1989, 1995, 2004, + 2009, 2011, 2010, 2006, 2000, 1996, 1997, 1996, + 2000, 2000, 1999, 2002, 2001, 2000, 1997, 1994, + 1989, 1988, 1986, 1981, 1977, 1979, 1982, 1986, + 1990, 1998, 2000, 2002, 2001, 2000, 1993, 1983, + 1977, 1970, 1963, 1960, 1963, 1962, 1965, 1966, + 1967, 1969, 1968, 1972, 1976, 1979, 1983, 1984, + 1985, 1986, 1982, 1975, 1969, 1963, 1960, 1958, + 1961, 1965, 1969, 1972, 1976, 1980, 1983, 1988, + 1989, 1990, 1991, 1990, 1986, 1984, 1983, 1980, + 1974, 1972, 1973, 1977, 1984, 1992, 1997, 2000, + 2005, 2009, 2009, 2003, 1998, 1992, 1986, 1983, + 1977, 1973, 1969, 1968, 1974, 1977, 1984, 1992, + 1998, 2004, 2001, 1996, 1990, 1986, 1984, 1982, + 1982, 1986, 1988, 1990, 1988, 1986, 1984, 1984, + 1983, 1984, 1988, 1993, 1998, 2003, 2005, 2001, + 1996, 1991, 1986, 1983, 1979, 1982, 1983, 1986, + 1991, 1992, 1990, 1986, 1984, 1980, 1982, 1982, + 1984, 1986, 1984, 1987, 1987, 1982, 1984, 1986, + 1983, 1984, 1985, 1987, 1986, 1985, 1982, 1982, + 1984, 1985, 1988, 1986, 1988, 1990, 1991, 1992, + 1993, 1992, 1991, 1991, 1988, 1987, 1990, 1991, + 1994, 1997, 2001, 2001, 1999, 1995, 1988, 1984, + 1980, 1976, 1976, 1982, 1985, 1987, 1989, 1991, + 1993, 1993, 1996, 1999, 2003, 2005, 2004, 2004, + 2002, 1998, 1994, 1989, 1986, 1984, 1983, 1984, + 1983, 1981, 1985, 1986, 1986, 1986, 1988, 1992, + 1997, 2000, 1999, 1996, 1991, 1991, 1988, 1982, + 1983, 1980, 1981, 1984, 1984, 1985, 1985, 1989, + 1991, 1994, 1999, 1996, 1994, 1989, 1988, 1988, + 1979, 1980, 1979, 1980, 1979, 1980, 1982, 1984, + 1985, 1986, 1988, 1988, 1992, 1991, 1989, 1987, + 1988, 1987, 1987, 1991, 1994, 1999, 2003, 2001, + 2000, 1999, 1996, 1991, 1990, 1990, 1991, 1990, + 1992, 1994, 1993, 1997, 1997, 2002, 2009, 2016, + 2022, 2025, 2028, 2027, 2024, 2024, 2024, 2022, + 2025, 2024, 2022, 2021, 2019, 2017, 2014, 2017, + 2020, 2023, 2026, 2030, 2034, 2036, 2033, 2032, + 2030, 2029, 2027, 2021, 2019, 2017, 2016, 2019, + 2027, 2031, 2033, 2035, 2032, 2030, 2024, 2022, + 2016, 2015, 2017, 2014, 2013, 2013, 2012, 2012, + 2014, 2017, 2023, 2029, 2033, 2036, 2037, 2034, + 2032, 2029, 2029, 2029, 2030, 2030, 2032, 2030, + 2026, 2021, 2019, 2021, 2027, 2033, 2038, 2040, + 2044, 2047, 2043, 2038, 2035, 2033, 2031, 2030, + 2030, 2030, 2031, 2033, 2038, 2039, 2038, 2037, + 2039, 2038, 2037, 2035, 2036, 2039, 2042, 2043, + 2041, 2042, 2042, 2040, 2036, 2037, 2040, 2040, + 2042, 2046, 2049, 2046, 2044, 2044, 2043, 2040, + 2036, 2039, 2042, 2045, 2048, 2043, 2040, 2037, + 2036, 2034, 2033, 2032, 2032, 2032, 2036, 2037, + 2040, 2041, 2042, 2043, 2047, 2051, 2051, 2049, + 2047, 2043, 2035, 2031, 2027, 2025, 2026, 2024, + 2030, 2034, 2036, 2038, 2039, 2045, 2052, 2054, + 2055, 2054, 2053, 2052, 2051, 2048, 2046, 2044, + 2048, 2048, 2046, 2046, 2047, 2046, 2047, 2048, + 2049, 2051, 2051, 2052, 2051, 2052, 2052, 2055, + 2062, 2064, 2067, 2068, 2066, 2068, 2067, 2066, + 2069, 2069, 2070, 2072, 2071, 2071, 2067, 2062, + 2061, 2063, 2064, 2067, 2067, 2067, 2071, 2071, + 2074, 2079, 2080, 2081, 2080, 2078, 2074, 2072, + 2068, 2062, 2060, 2061, 2064, 2065, 2069, 2073, + 2076, 2081, 2084, 2089, 2091, 2094, 2093, 2093, + 2090, 2086, 2085, 2081, 2081, 2081, 2082, 2082, + 2081, 2081, 2080, 2078, 2080, 2084, 2086, 2090, + 2096, 2095, 2095, 2093, 2091, 2085, 2086, 2088, + 2088, 2090, 2091, 2091, 2089, 2088, 2089, 2088, + 2087, 2089, 2089, 2092, 2096, 2099, 2102, 2101, + 2100, 2102, 2102, 2098, 2096, 2092, 2089, 2086, + 2084, 2086, 2093, 2097, 2105, 2111, 2115, 2116, + 2114, 2112, 2111, 2112, 2113, 2116, 2114, 2119, + 2124, 2127, 2122, 2115, 2114, 2111, 2111, 2112, + 2114, 2115, 2118, 2123, 2127, 2131, 2133, 2135, + 2136, 2135, 2131, 2130, 2130, 2131, 2130, 2129, + 2131, 2135, 2136, 2139, 2139, 2137, 2133, 2130, + 2126, 2124, 2129, 2129, 2129, 2126, 2126, 2128, + 2128, 2126, 2127, 2127, 2132, 2134, 2131, 2129, + 2126, 2124, 2122, 2119, 2115, 2112, 2110, 2111, + 2112, 2114, 2114, 2116, 2115, 2118, 2121, 2125, + 2126, 2124, 2124, 2120, 2118, 2115, 2113, 2110, + 2111, 2111, 2109, 2108, 2110, 2112, 2115, 2119, + 2121, 2123, 2123, 2121, 2121, 2120, 2123, 2124, + 2125, 2127, 2128, 2129, 2127, 2124, 2119, 2114, + 2112, 2110, 2111, 2114, 2114, 2118, 2123, 2126, + 2127, 2125, 2126, 2130, 2131, 2133, 2130, 2128, + 2125, 2120, 2118, 2117, 2116, 2119, 2129, 2132, + 2133, 2134, 2131, 2132, 2131, 2134, 2137, 2139, + 2140, 2139, 2138, 2133, 2130, 2126, 2123, 2123, + 2127, 2128, 2130, 2134, 2133, 2134, 2137, 2140, + 2142, 2144, 2144, 2141, 2136, 2133, 2128, 2121, + 2118, 2120, 2127, 2129, 2134, 2138, 2138, 2138, + 2134, 2133, 2131, 2133, 2134, 2131, 2126, 2121, + 2115, 2108, 2109, 2114, 2120, 2128, 2136, 2141, + 2142, 2142, 2143, 2139, 2139, 2139, 2137, 2135, + 2128, 2123, 2116, 2110, 2108, 2108, 2110, 2116, + 2119, 2122, 2128, 2129, 2126, 2123, 2125, 2127, + 2130, 2128, 2124, 2119, 2113, 2106, 2104, 2105, + 2107, 2110, 2115, 2118, 2118, 2118, 2118, 2115, + 2114, 2115, 2115, 2115, 2114, 2112, 2111, 2111, + 2110, 2112, 2115, 2116, 2117, 2119, 2116, 2115, + 2112, 2111, 2110, 2108, 2107, 2105, 2106, 2106, + 2106, 2106, 2106, 2106, 2107, 2108, 2108, 2107, + 2110, 2113, 2115, 2113, 2108, 2103, 2094, 2086, + 2084, 2086, 2087, 2084, 2085, 2089, 2090, 2091, + 2096, 2100, 2103, 2105, 2110, 2108, 2105, 2098, + 2093, 2091, 2087, 2089, 2094, 2099, 2101, 2101, + 2097, 2094, 2093, 2090, 2096, 2104, 2109, 2110, + 2108, 2104, 2102, 2102, 2104, 2108, 2113, 2117, + 2120, 2119, 2118, 2118, 2113, 2115, 2119, 2120, + 2125, 2126, 2121, 2117, 2111, 2108, 2110, 2112, + 2116, 2121, 2127, 2129, 2130, 2127, 2128, 2128, + 2130, 2134, 2137, 2136, 2133, 2129, 2124, 2119, + 2115, 2115, 2117, 2121, 2127, 2131, 2132, 2132, + 2131, 2131, 2135, 2138, 2140, 2138, 2136, 2130, + 2124, 2122, 2123, 2125, 2132, 2138, 2144, 2147, + 2147, 2146, 2144, 2144, 2143, 2143, 2144, 2143, + 2138, 2133, 2127, 2121, 2118, 2121, 2128, 2135, + 2143, 2151, 2154, 2152, 2151, 2147, 2143, 2142, + 2142, 2139, 2135, 2134, 2133, 2133, 2134, 2135, + 2136, 2140, 2144, 2143, 2143, 2144, 2144, 2144, + 2144, 2145, 2148, 2146, 2145, 2144, 2143, 2139, + 2139, 2138, 2139, 2140, 2141, 2144, 2149, 2152, + 2155, 2157, 2158, 2160, 2160, 2160, 2157, 2156, + 2153, 2151, 2152, 2152, 2149, 2148, 2148, 2147, + 2149, 2152, 2158, 2161, 2165, 2164, 2165, 2166, + 2166, 2164, 2161, 2163, 2163, 2163, 2160, 2157, + 2157, 2156, 2153, 2155, 2159, 2162, 2163, 2166, + 2171, 2171, 2170, 2166, 2161, 2157, 2153, 2153, + 2155, 2155, 2152, 2153, 2155, 2157, 2159, 2160, + 2165, 2168, 2167, 2167, 2161, 2156, 2154, 2152, + 2152, 2154, 2155, 2157, 2156, 2159, 2156, 2157, + 2157, 2158, 2159, 2163, 2169, 2166, 2162, 2158, + 2154, 2153, 2151, 2148, 2152, 2158, 2156, 2155, + 2157, 2159, 2156, 2154, 2154, 2157, 2156, 2158, + 2160, 2158, 2156, 2153, 2151, 2149, 2146, 2150, + 2155, 2156, 2159, 2160, 2161, 2163, 2166, 2168, + 2168, 2169, 2170, 2169, 2164, 2157, 2152, 2150, + 2150, 2148, 2150, 2155, 2162, 2165, 2170, 2172, + 2177, 2181, 2184, 2184, 2182, 2180, 2175, 2171, + 2164, 2160, 2156, 2157, 2161, 2162, 2164, 2167, + 2165, 2163, 2165, 2165, 2167, 2169, 2171, 2172, + 2172, 2171, 2170, 2170, 2173, 2176, 2172, 2171, + 2171, 2171, 2165, 2160, 2153, 2154, 2159, 2167, + 2170, 2170, 2171, 2173, 2172, 2170, 2169, 2171, + 2174, 2176, 2180, 2179, 2174, 2170, 2168, 2168, + 2167, 2167, 2168, 2169, 2171, 2169, 2169, 2171, + 2173, 2177, 2179, 2185, 2189, 2191, 2188, 2181, + 2179, 2178, 2176, 2179, 2182, 2183, 2178, 2177, + 2172, 2165, 2159, 2158, 2164, 2168, 2169, 2173, + 2173, 2170, 2173, 2175, 2177, 2179, 2185, 2189, + 2193, 2190, 2186, 2183, 2180, 2182, 2182, 2184, + 2188, 2188, 2185, 2180, 2174, 2172, 2171, 2170, + 2173, 2178, 2178, 2178, 2176, 2177, 2177, 2179, + 2184, 2188, 2194, 2199, 2200, 2198, 2193, 2188, + 2182, 2177, 2175, 2172, 2172, 2172, 2174, 2173, + 2175, 2173, 2179, 2186, 2190, 2197, 2200, 2201, + 2196, 2190, 2185, 2180, 2176, 2174, 2169, 2167, + 2164, 2162, 2158, 2157, 2158, 2162, 2169, 2177, + 2185, 2190, 2192, 2192, 2186, 2180, 2175, 2173, + 2169, 2166, 2165, 2162, 2158, 2153, 2152, 2155, + 2161, 2168, 2176, 2185, 2185, 2184, 2181, 2180, + 2176, 2174, 2175, 2177, 2181, 2185, 2185, 2179, + 2177, 2172, 2169, 2170, 2172, 2174, 2175, 2176, + 2172, 2170, 2171, 2174, 2179, 2185, 2191, 2198, + 2203, 2202, 2197, 2190, 2190, 2190, 2188, 2190, + 2188, 2183, 2178, 2173, 2168, 2167, 2166, 2173, + 2180, 2188, 2199, 2202, 2205, 2202, 2201, 2195, + 2192, 2191, 2190, 2189, 2186, 2182, 2179, 2177, + 2175, 2176, 2178, 2185, 2189, 2193, 2196, 2195, + 2197, 2195, 2192, 2193, 2194, 2196, 2196, 2189, + 2183, 2181, 2180, 2182, 2185, 2190, 2198, 2201, + 2206, 2203, 2198, 2192, 2186, 2185, 2182, 2179, + 2178, 2179, 2175, 2175, 2180, 2186, 2191, 2195, + 2199, 2201, 2199, 2196, 2190, 2190, 2185, 2184, + 2182, 2179, 2177, 2170, 2164, 2162, 2162, 2165, + 2169, 2173, 2180, 2186, 2191, 2193, 2194, 2193, + 2193, 2192, 2190, 2186, 2185, 2182, 2175, 2172, + 2171, 2171, 2172, 2174, 2179, 2180, 2182, 2188, + 2190, 2191, 2192, 2192, 2192, 2190, 2188, 2190, + 2188, 2185, 2183, 2182, 2181, 2179, 2178, 2178, + 2175, 2175, 2175, 2176, 2179, 2180, 2183, 2182, + 2179, 2179, 2178, 2177, 2179, 2180, 2187, 2188, + 2192, 2194, 2194, 2193, 2191, 2192, 2192, 2188, + 2185, 2183, 2183, 2182, 2180, 2184, 2186, 2191, + 2195, 2199, 2200, 2203, 2201, 2201, 2203, 2206, + 2208, 2207, 2209, 2205, 2198, 2193, 2186, 2185, + 2183, 2188, 2190, 2194, 2198, 2199, 2200, 2199, + 2200, 2202, 2203, 2204, 2202, 2202, 2200, 2192, + 2186, 2183, 2177, 2174, 2172, 2166, 2164, 2161, + 2160, 2158, 2158, 2160, 2161, 2167, 2169, 2169, + 2165, 2162, 2160, 2161, 2161, 2162, 2164, 2167, + 2167, 2165, 2161, 2156, 2155, 2150, 2146, 2147, + 2150, 2152, 2156, 2158, 2161, 2164, 2166, 2166, + 2165, 2165, 2163, 2163, 2161, 2159, 2158, 2157, + 2160, 2157, 2158, 2156, 2153, 2148, 2147, 2150, + 2154, 2155, 2159, 2162, 2166, 2165, 2165, 2166, + 2164, 2163, 2158, 2154, 2152, 2151, 2151, 2151, + 2148, 2147, 2147, 2147, 2148, 2149, 2154, 2158, + 2162, 2165, 2166, 2170, 2172, 2172, 2172, 2169, + 2169, 2166, 2164, 2162, 2160, 2159, 2159, 2162, + 2166, 2167, 2168, 2170, 2172, 2172, 2174, 2175, + 2177, 2178, 2183, 2185, 2181, 2179, 2176, 2174, + 2169, 2164, 2162, 2163, 2161, 2165, 2165, 2165, + 2169, 2171, 2173, 2175, 2177, 2178, 2177, 2177, + 2176, 2174, 2174, 2176, 2177, 2177, 2177, 2174, + 2173, 2170, 2167, 2167, 2170, 2173, 2179, 2182, + 2182, 2183, 2183, 2185, 2188, 2190, 2192, 2194, + 2193, 2193, 2192, 2191, 2190, 2191, 2194, 2194, + 2196, 2201, 2203, 2202, 2198, 2198, 2199, 2205, + 2208, 2214, 2218, 2220, 2218, 2220, 2218, 2219, + 2220, 2219, 2218, 2216, 2213, 2212, 2214, 2210, + 2210, 2212, 2213, 2215, 2217, 2216, 2217, 2218, + 2220, 2223, 2223, 2226, 2228, 2228, 2224, 2223, + 2220, 2219, 2218, 2219, 2218, 2216, 2216, 2218, + 2221, 2221, 2225, 2230, 2238, 2245, 2250, 2250, + 2250, 2249, 2241, 2237, 2235, 2232, 2230, 2227, + 2227, 2230, 2230, 2231, 2235, 2238, 2238, 2240, + 2244, 2246, 2244, 2243, 2244, 2246, 2247, 2246, + 2243, 2239, 2237, 2233, 2231, 2230, 2231, 2231, + 2234, 2237, 2240, 2243, 2242, 2239, 2238, 2240, + 2243, 2242, 2243, 2246, 2250, 2253, 2251, 2249, + 2251, 2250, 2249, 2249, 2249, 2247, 2247, 2247, + 2247, 2246, 2246, 2248, 2249, 2251, 2253, 2254, + 2256, 2258, 2258, 2261, 2261, 2260, 2261, 2258, + 2257, 2252, 2251, 2252, 2247, 2245, 2244, 2243, + 2245, 2241, 2239, 2239, 2241, 2241, 2242, 2243, + 2246, 2244, 2241, 2237, 2235, 2235, 2232, 2231, + 2231, 2232, 2230, 2230, 2229, 2230, 2233, 2233, + 2233, 2237, 2239, 2239, 2238, 2237, 2239, 2242, + 2244, 2244, 2245, 2243, 2236, 2232, 2227, 2223, + 2225, 2226, 2230, 2232, 2235, 2234, 2234, 2234, + 2235, 2240, 2240, 2245, 2248, 2249, 2245, 2239, + 2235, 2231, 2226, 2224, 2223, 2219, 2218, 2217, + 2217, 2217, 2221, 2223, 2227, 2230, 2232, 2233, + 2231, 2231, 2228, 2226, 2226, 2224, 2219, 2218, + 2216, 2211, 2211, 2213, 2217, 2218, 2221, 2223, + 2226, 2231, 2235, 2242, 2248, 2251, 2251, 2253, + 2254, 2259, 2259, 2254, 2255, 2254, 2250, 2246, + 2241, 2238, 2232, 2231, 2234, 2239, 2241, 2243, + 2248, 2250, 2254, 2256, 2259, 2262, 2264, 2263, + 2261, 2255, 2251, 2246, 2240, 2233, 2230, 2233, + 2232, 2228, 2224, 2223, 2222, 2221, 2223, 2227, + 2230, 2235, 2234, 2232, 2230, 2231, 2230, 2232, + 2232, 2232, 2229, 2227, 2228, 2225, 2224, 2224, + 2227, 2229, 2227, 2228, 2227, 2228, 2230, 2230, + 2229, 2231, 2233, 2233, 2231, 2226, 2226, 2223, + 2223, 2223, 2225, 2228, 2227, 2228, 2226, 2226, + 2224, 2221, 2223, 2224, 2225, 2227, 2229, 2227, + 2228, 2225, 2224, 2223, 2226, 2224, 2224, 2226, + 2225, 2226, 2226, 2226, 2225, 2224, 2225, 2227, + 2225, 2223, 2223, 2227, 2227, 2226, 2227, 2226, + 2226, 2225, 2226, 2228, 2227, 2229, 2229, 2232, + 2231, 2232, 2230, 2233, 2232, 2232, 2231, 2230, + 2231, 2230, 2230, 2231, 2231, 2233, 2234, 2235, + 2235, 2231, 2228, 2227, 2226, 2224, 2222, 2222, + 2222, 2224, 2221, 2220, 2217, 2215, 2213, 2214, + 2215, 2216, 2215, 2212, 2211, 2209, 2211, 2212, + 2209, 2211, 2212, 2210, 2206, 2203, 2199, 2197, + 2198, 2199, 2203, 2207, 2210, 2212, 2214, 2216, + 2219, 2220, 2222, 2224, 2226, 2227, 2223, 2217, + 2212, 2206, 2203, 2197, 2193, 2193, 2195, 2199, + 2203, 2209, 2213, 2216, 2218, 2223, 2225, 2227, + 2228, 2222, 2219, 2214, 2213, 2213, 2213, 2210, + 2210, 2207, 2207, 2206, 2204, 2201, 2204, 2207, + 2209, 2212, 2214, 2216, 2215, 2211, 2206, 2204, + 2203, 2199, 2200, 2198, 2199, 2202, 2200, 2199, + 2198, 2198, 2198, 2200, 2201, 2199, 2201, 2199, + 2198, 2193, 2192, 2191, 2190, 2190, 2192, 2192, + 2192, 2191, 2191, 2191, 2193, 2193, 2194, 2193, + 2192, 2192, 2188, 2185, 2182, 2181, 2177, 2177, + 2178, 2175, 2176, 2174, 2175, 2172, 2173, 2172, + 2172, 2172, 2170, 2169, 2164, 2158, 2153, 2149, + 2144, 2143, 2138, 2134, 2132, 2135, 2138, 2137, + 2138, 2140, 2144, 2147, 2148, 2149, 2150, 2147, + 2144, 2143, 2141, 2139, 2136, 2134, 2132, 2132, + 2133, 2132, 2131, 2136, 2138, 2142, 2146, 2146, + 2147, 2146, 2148, 2147, 2142, 2140, 2139, 2138, + 2138, 2133, 2130, 2126, 2122, 2121, 2123, 2124, + 2123, 2125, 2127, 2128, 2126, 2125, 2123, 2120, + 2117, 2112, 2110, 2107, 2104, 2102, 2096, 2092, + 2091, 2091, 2087, 2086, 2087, 2089, 2090, 2089, + 2087, 2086, 2088, 2090, 2094, 2095, 2095, 2093, + 2089, 2085, 2081, 2078, 2077, 2075, 2075, 2074, + 2073, 2073, 2069, 2066, 2065, 2064, 2064, 2062, + 2064, 2064, 2065, 2067, 2067, 2067, 2066, 2067, + 2065, 2064, 2064, 2062, 2059, 2055, 2053, 2053, + 2055, 2054, 2055, 2054, 2054, 2050, 2050, 2051, + 2051, 2051, 2052, 2055, 2059, 2060, 2058, 2058, + 2052, 2049, 2047, 2044, 2044, 2046, 2045, 2050, + 2051, 2052, 2051, 2052, 2055, 2053, 2055, 2056, + 2052, 2051, 2052, 2049, 2046, 2045, 2046, 2044, + 2043, 2043, 2043, 2041, 2042, 2043, 2045, 2047, + 2049, 2050, 2049, 2049, 2047, 2046, 2045, 2041, + 2042, 2041, 2041, 2038, 2039, 2038, 2036, 2036, + 2033, 2029, 2030, 2028, 2029, 2033, 2030, 2032, + 2031, 2030, 2030, 2030, 2029, 2028, 2031, 2030, + 2031, 2028, 2028, 2029, 2025, 2022, 2019, 2017, + 2013, 2011, 2010, 2009, 2011, 2012, 2013, 2016, + 2017, 2019, 2020, 2019, 2018, 2012, 2011, 2012, + 2012, 2013, 2009, 2008, 2007, 2008, 2008, 2011, + 2012, 2009, 2008, 2007, 2006, 2004, 2003, 2002, + 2003, 2001, 2001, 2001, 2002, 2002, 2005, 2004, + 2005, 2003, 2000, 2000, 1998, 1997, 1996, 1994, + 1990, 1987, 1983, 1985, 1985, 1988, 1991, 1994, + 1999, 2000, 1999, 1997, 1998, 1997, 1994, 1994, + 1993, 1990, 1988, 1985, 1979, 1977, 1977, 1977, + 1979, 1981, 1978, 1980, 1979, 1982, 1981, 1981, + 1983, 1983, 1983, 1984, 1983, 1985, 1983, 1977, + 1976, 1976, 1977, 1976, 1977, 1979, 1977, 1976, + 1971, 1966, 1965, 1963, 1962, 1965, 1968, 1967, + 1968, 1967, 1967, 1963, 1965, 1964, 1965, 1967, + 1969, 1968, 1964, 1962, 1960, 1957, 1955, 1953, + 1949, 1949, 1948, 1949, 1950, 1951, 1953, 1957, + 1963, 1964, 1963, 1965, 1960, 1959, 1957, 1951, + 1948, 1946, 1943, 1941, 1941, 1940, 1937, 1936, + 1939, 1939, 1941, 1944, 1944, 1945, 1945, 1946, + 1944, 1945, 1941, 1940, 1940, 1940, 1941, 1939, + 1935, 1936, 1936, 1934, 1933, 1934, 1935, 1937, + 1936, 1934, 1938, 1938, 1938, 1938, 1939, 1938, + 1938, 1939, 1939, 1940, 1937, 1936, 1932, 1933, + 1933, 1934, 1932, 1933, 1933, 1936, 1937, 1936, + 1941, 1944, 1946, 1948, 1952, 1954, 1953, 1950, + 1949, 1947, 1946, 1943, 1942, 1939, 1940, 1940, + 1940, 1938, 1939, 1940, 1940, 1940, 1942, 1945, + 1949, 1949, 1947, 1946, 1947, 1944, 1939, 1937, + 1938, 1936, 1936, 1939, 1937, 1938, 1937, 1935, + 1934, 1935, 1933, 1932, 1930, 1932, 1932, 1932, + 1933, 1933, 1936, 1938, 1942, 1945, 1947, 1948, + 1948, 1952, 1951, 1949, 1947, 1947, 1948, 1946, + 1945, 1945, 1945, 1946, 1944, 1945, 1948, 1952, + 1958, 1959, 1962, 1964, 1965, 1963, 1964, 1960, + 1957, 1956, 1951, 1947, 1943, 1942, 1938, 1939, + 1935, 1937, 1939, 1940, 1943, 1946, 1949, 1950, + 1948, 1947, 1948, 1948, 1947, 1943, 1938, 1939, + 1938, 1937, 1934, 1935, 1933, 1934, 1936, 1940, + 1941, 1942, 1943, 1943, 1946, 1944, 1944, 1944, + 1945, 1946, 1946, 1945, 1946, 1945, 1944, 1942, + 1939, 1936, 1937, 1935, 1935, 1936, 1935, 1937, + 1938, 1939, 1938, 1939, 1938, 1940, 1938, 1937, + 1936, 1935, 1932, 1929, 1926, 1925, 1921, 1921, + 1918, 1915, 1912, 1915, 1916, 1915, 1917, 1918, + 1921, 1925, 1927, 1924, 1921, 1918, 1920, 1918, + 1917, 1920, 1924, 1923, 1925, 1925, 1923, 1922, + 1923, 1926, 1929, 1929, 1932, 1936, 1937, 1936, + 1934, 1934, 1932, 1934, 1933, 1932, 1932, 1927, + 1926, 1926, 1926, 1927, 1925, 1924, 1923, 1923, + 1922, 1923, 1921, 1921, 1921, 1922, 1922, 1923, + 1922, 1923, 1925, 1926, 1927, 1927, 1927, 1928, + 1926, 1925, 1922, 1921, 1922, 1922, 1922, 1922, + 1920, 1921, 1921, 1918, 1919, 1919, 1923, 1924, + 1929, 1931, 1934, 1932, 1931, 1932, 1931, 1932, + 1933, 1931, 1931, 1930, 1931, 1932, 1930, 1930, + 1931, 1930, 1932, 1932, 1931, 1932, 1932, 1928, + 1928, 1930, 1931, 1932, 1932, 1933, 1932, 1930, + 1929, 1927, 1925, 1924, 1924, 1924, 1925, 1924, + 1925, 1927, 1927, 1927, 1924, 1925, 1928, 1927, + 1926, 1925, 1923, 1925, 1926, 1927, 1924, 1922, + 1921, 1919, 1921, 1918, 1917, 1918, 1921, 1922, + 1926, 1928, 1928, 1928, 1927, 1928, 1929, 1931, + 1931, 1930, 1932, 1932, 1928, 1930, 1928, 1927, + 1929, 1931, 1934, 1937, 1937, 1937, 1936, 1938, + 1938, 1939, 1937, 1938, 1937, 1937, 1936, 1933, + 1932, 1932, 1931, 1930, 1931, 1930, 1930, 1930, + 1932, 1932, 1932, 1934, 1936, 1937, 1937, 1936, + 1935, 1936, 1938, 1938, 1938, 1937, 1934, 1937, + 1934, 1928, 1930, 1928, 1930, 1930, 1932, 1934, + 1939, 1940, 1939, 1944, 1943, 1945, 1945, 1943, + 1940, 1940, 1942, 1939, 1942, 1938, 1936, 1935, + 1933, 1930, 1934, 1932, 1929, 1930, 1929, 1931, + 1929, 1927, 1928, 1926, 1925, 1923, 1920, 1920, + 1916, 1915, 1915, 1913, 1912, 1913, 1914, 1914, + 1911, 1911, 1909, 1907, 1909, 1909, 1907, 1909, + 1908, 1907, 1908, 1908, 1910, 1912, 1912, 1910, + 1910, 1913, 1912, 1915, 1916, 1913, 1914, 1911, + 1912, 1911, 1911, 1912, 1913, 1913, 1913, 1914, + 1916, 1916, 1914, 1912, 1911, 1909, 1909, 1907, + 1903, 1903, 1904, 1906, 1907, 1909, 1911, 1912, + 1913, 1912, 1913, 1913, 1912, 1914, 1913, 1913, + 1911, 1909, 1907, 1907, 1907, 1911, 1914, 1917, + 1920, 1922, 1925, 1927, 1928, 1929, 1927, 1927, + 1926, 1927, 1928, 1926, 1927, 1928, 1929, 1934, + 1937, 1938, 1939, 1940, 1941, 1940, 1938, 1937, + 1934, 1933, 1933, 1932, 1930, 1928, 1927, 1928, + 1928, 1928, 1930, 1934, 1936, 1934, 1936, 1938, + 1940, 1937, 1938, 1936, 1934, 1930, 1928, 1927, + 1929, 1928, 1925, 1928, 1930, 1932, 1936, 1940, + 1942, 1944, 1944, 1940, 1944, 1943, 1944, 1942, + 1941, 1941, 1942, 1941, 1943, 1944, 1946, 1950, + 1950, 1953, 1950, 1949, 1947, 1945, 1946, 1946, + 1946, 1948, 1950, 1948, 1946, 1946, 1947, 1946, + 1946, 1948, 1948, 1950, 1951, 1949, 1949, 1949, + 1948, 1944, 1942, 1946, 1945, 1946, 1944, 1949, + 1950, 1952, 1954, 1956, 1957, 1955, 1954, 1953, + 1952, 1949, 1948, 1949, 1950, 1951, 1955, 1956, + 1960, 1962, 1963, 1962, 1963, 1965, 1966, 1970, + 1970, 1969, 1967, 1964, 1962, 1959, 1958, 1957, + 1956, 1956, 1956, 1960, 1960, 1963, 1964, 1965, + 1965, 1966, 1964, 1963, 1962, 1960, 1959, 1958, + 1958, 1957, 1957, 1958, 1955, 1954, 1956, 1956, + 1956, 1957, 1957, 1958, 1959, 1959, 1957, 1958, + 1961, 1960, 1957, 1956, 1954, 1957, 1958, 1959, + 1958, 1957, 1961, 1961, 1963, 1959, 1960, 1963, + 1963, 1963, 1964, 1965, 1965, 1966, 1965, 1967, + 1965, 1967, 1968, 1966, 1971, 1971, 1970, 1969, + 1970, 1971, 1971, 1972, 1971, 1972, 1970, 1970, + 1969, 1967, 1967, 1966, 1967, 1971, 1972, 1974, + 1977, 1976, 1976, 1975, 1974, 1974, 1974, 1973, + 1971, 1972, 1973, 1973, 1973, 1974, 1974, 1975, + 1977, 1979, 1979, 1977, 1979, 1980, 1978, 1978, + 1976, 1976, 1975, 1975, 1974, 1973, 1971, 1974, + 1976, 1977, 1978, 1977, 1977, 1976, 1980, 1981, + 1977, 1977, 1977, 1976, 1975, 1977, 1975, 1974, + 1969, 1970, 1969, 1969, 1965, 1965, 1965, 1966, + 1968, 1967, 1970, 1971, 1972, 1973, 1974, 1973, + 1972, 1975, 1978, 1977, 1976, 1976, 1978, 1978, + 1979, 1981, 1980, 1980, 1981, 1980, 1981, 1980, + 1980, 1981, 1979, 1979, 1977, 1979, 1980, 1982, + 1983, 1984, 1985, 1987, 1992, 1994, 1996, 1997, + 1993, 1992, 1990, 1990, 1989, 1989, 1987, 1987, + 1988, 1986, 1988, 1992, 1993, 1993, 1993, 1994, + 1994, 1997, 1999, 2001, 2003, 2000, 1999, 1996, + 1997, 1996, 1996, 1995, 1996, 1996, 1994, 1994, + 1995, 1998, 1999, 2000, 2001, 2001, 2001, 2001, + 1999, 2001, 2004, 2003, 2006, 2008, 2005, 2007, + 2008, 2007, 2005, 2005, 2001, 2001, 2002, 2000, + 2001, 2002, 2000, 2001, 2003, 2001, 1997, 1994, + 1995, 1999, 2001, 2003, 2008, 2005, 2003, 2002, + 2001, 2001, 2000, 1999, 2000, 2001, 1998, 1997, + 1997, 1996, 1996, 1994, 1994, 1995, 1995, 1997, + 1996, 1996, 1999, 2001, 2001, 2003, 2006, 2004, + 2005, 2003, 2004, 2000, 1999, 1997, 1997, 1997, + 1994, 1994, 1993, 1993, 1994, 1996, 1995, 1994, + 1992, 1993, 1991, 1991, 1990, 1992, 1991, 1987, + 1986, 1986, 1985, 1984, 1986, 1982, 1980, 1979, + 1976, 1978, 1973, 1977, 1978, 1978, 1979, 1980, + 1981, 1981, 1983, 1982, 1983, 1985, 1982, 1985, + 1985, 1983, 1982, 1980, 1980, 1982, 1981, 1984, + 1986, 1986, 1986, 1986, 1984, 1982, 1984, 1987, + 1988, 1990, 1990, 1988, 1986, 1985, 1985, 1984, + 1983, 1983, 1984, 1986, 1986, 1986, 1986, 1986, + 1985, 1985, 1984, 1987, 1987, 1988, 1985, 1983, + 1981, 1979, 1980, 1976, 1974, 1977, 1978, 1979, + 1981, 1981, 1980, 1981, 1980, 1983, 1985, 1987, + 1986, 1984, 1983, 1981, 1980, 1978, 1980, 1978, + 1979, 1979, 1975, 1975, 1975, 1973, 1972, 1971, + 1971, 1969, 1971, 1970, 1970, 1969, 1966, 1964, + 1964, 1964, 1965, 1966, 1968, 1968, 1966, 1968, + 1967, 1967, 1968, 1964, 1962, 1964, 1962, 1963, + 1960, 1960, 1959, 1961, 1964, 1963, 1966, 1966, + 1968, 1969, 1971, 1968, 1967, 1969, 1969, 1969, + 1970, 1968, 1966, 1964, 1966, 1964, 1962, 1964, + 1964, 1962, 1961, 1961, 1958, 1957, 1958, 1958, + 1959, 1957, 1956, 1958, 1958, 1959, 1960, 1960, + 1961, 1960, 1961, 1958, 1958, 1956, 1955, 1954, + 1951, 1949, 1948, 1950, 1951, 1952, 1953, 1954, + 1955, 1955, 1956, 1957, 1958, 1956, 1954, 1954, + 1954, 1951, 1948, 1946, 1946, 1946, 1945, 1946, + 1946, 1946, 1946, 1946, 1946, 1946, 1945, 1943, + 1945, 1944, 1941, 1940, 1939, 1941, 1941, 1938, + 1939, 1941, 1944, 1941, 1941, 1939, 1938, 1939, + 1936, 1931, 1931, 1933, 1932, 1932, 1931, 1932, + 1933, 1933, 1934, 1934, 1936, 1937, 1934, 1935, + 1933, 1932, 1931, 1930, 1928, 1927, 1927, 1927, + 1928, 1930, 1928, 1928, 1930, 1930, 1930, 1930, + 1930, 1929, 1927, 1925, 1924, 1922, 1922, 1923, + 1918, 1917, 1915, 1916, 1917, 1916, 1916, 1915, + 1914, 1915, 1917, 1918, 1920, 1918, 1916, 1917, + 1916, 1914, 1912, 1913, 1914, 1913, 1914, 1914, + 1912, 1909, 1908, 1910, 1912, 1912, 1913, 1914, + 1914, 1913, 1912, 1914, 1914, 1915, 1914, 1913, + 1912, 1910, 1910, 1909, 1905, 1906, 1910, 1910, + 1910, 1906, 1908, 1905, 1903, 1906, 1908, 1908, + 1909, 1910, 1906, 1905, 1905, 1905, 1905, 1905, + 1907, 1907, 1908, 1910, 1911, 1911, 1909, 1910, + 1910, 1909, 1907, 1905, 1903, 1903, 1904, 1905, + 1907, 1905, 1905, 1906, 1906, 1907, 1909, 1909, + 1911, 1911, 1911, 1910, 1910, 1907, 1907, 1907, + 1906, 1905, 1903, 1902, 1905, 1903, 1906, 1907, + 1907, 1909, 1907, 1908, 1910, 1907, 1907, 1908, + 1908, 1905, 1904, 1903, 1903, 1903, 1904, 1905, + 1907, 1908, 1907, 1907, 1906, 1904, 1907, 1905, + 1905, 1906, 1903, 1902, 1901, 1901, 1901, 1898, + 1896, 1895, 1895, 1895, 1894, 1896, 1897, 1900, + 1896, 1896, 1898, 1897, 1898, 1901, 1900, 1899, + 1901, 1901, 1901, 1899, 1899, 1899, 1898, 1901, + 1903, 1904, 1904, 1905, 1906, 1905, 1903, 1903, + 1907, 1906, 1907, 1908, 1908, 1911, 1909, 1908, + 1911, 1911, 1913, 1916, 1917, 1915, 1915, 1913, + 1913, 1912, 1913, 1915, 1915, 1914, 1916, 1915, + 1917, 1918, 1916, 1918, 1920, 1920, 1922, 1921, + 1922, 1920, 1919, 1916, 1916, 1917, 1917, 1917, + 1918, 1921, 1920, 1921, 1919, 1920, 1922, 1921, + 1920, 1922, 1922, 1922, 1921, 1918, 1918, 1918, + 1919, 1919, 1919, 1919, 1919, 1920, 1920, 1925, + 1925, 1923, 1922, 1922, 1922, 1923, 1922, 1923, + 1922, 1919, 1919, 1919, 1919, 1920, 1919, 1921, + 1921, 1921, 1920, 1921, 1920, 1921, 1921, 1920, + 1921, 1924, 1924, 1923, 1922, 1923, 1921, 1923, + 1923, 1922, 1923, 1922, 1923, 1920, 1917, 1918, + 1916, 1917, 1921, 1922, 1922, 1923, 1925, 1925, + 1926, 1925, 1928, 1926, 1925, 1928, 1927, 1926, + 1926, 1925, 1925, 1925, 1922, 1923, 1923, 1925, + 1927, 1925, 1924, 1925, 1926, 1926, 1924, 1926, + 1924, 1922, 1925, 1925, 1925, 1925, 1925, 1926, + 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1926, + 1927, 1926, 1926, 1926, 1926, 1926, 1927, 1926, + 1924, 1927, 1927, 1929, 1928, 1926, 1926, 1926, + 1925, 1926, 1926, 1927, 1931, 1932, 1932, 1932, + 1933, 1931, 1931, 1931, 1929, 1928, 1928, 1930, + 1931, 1931, 1931, 1931, 1931, 1929, 1932, 1932, + 1932, 1933, 1930, 1932, 1933, 1936, 1936, 1935, + 1933, 1932, 1930, 1931, 1931, 1932, 1932, 1932, + 1935, 1934, 1934, 1937, 1937, 1937, 1938, 1935, + 1935, 1935, 1935, 1936, 1937, 1937, 1939, 1941, + 1942, 1942, 1942, 1942, 1944, 1943, 1944, 1944, + 1943, 1943, 1944, 1946, 1949, 1949, 1947, 1947, + 1945, 1945, 1946, 1943, 1942, 1947, 1944, 1943, + 1942, 1942, 1943, 1944, 1945, 1946, 1949, 1949, + 1948, 1951, 1949, 1950, 1950, 1948, 1949, 1944, + 1945, 1946, 1946, 1946, 1944, 1945, 1949, 1950, + 1953, 1953, 1954, 1954, 1954, 1953, 1954, 1957, + 1955, 1957, 1958, 1956, 1955, 1953, 1953, 1952, + 1951, 1953, 1954, 1955, 1955, 1955, 1952, 1953, + 1954, 1951, 1953, 1952, 1953, 1956, 1957, 1957, + 1955, 1954, 1957, 1950, 1948, 1950, 1949, 1951, + 1950, 1947, 1946, 1943, 1943, 1942, 1942, 1944, + 1944, 1947, 1948, 1947, 1947, 1949, 1949, 1949, + 1951, 1950, 1946, 1945, 1945, 1945, 1942, 1939, + 1943, 1943, 1943, 1943, 1944, 1947, 1945, 1943, + 1944, 1946, 1947, 1949, 1949, 1948, 1949, 1951, + 1947, 1946, 1944, 1943, 1945, 1944, 1943, 1942, + 1940, 1940, 1939, 1940, 1941, 1939, 1939, 1939, + 1942, 1943, 1943, 1942, 1943, 1944, 1947, 1946, + 1946, 1948, 1946, 1944, 1943, 1941, 1941, 1940, + 1941, 1942, 1944, 1944, 1945, 1944, 1945, 1946, + 1943, 1945, 1945, 1946, 1944, 1945, 1945, 1947, + 1947, 1946, 1942, 1942, 1940, 1938, 1937, 1936, + 1936, 1936, 1936, 1936, 1936, 1937, 1937, 1939, + 1940, 1942, 1941, 1940, 1938, 1938, 1938, 1939, + 1938, 1935, 1936, 1935, 1934, 1934, 1933, 1934, + 1934, 1934, 1933, 1932, 1933, 1933, 1933, 1929, + 1928, 1929, 1929, 1928, 1928, 1929, 1927, 1928, + 1929, 1929, 1928, 1930, 1931, 1929, 1927, 1927, + 1925, 1926, 1926, 1928, 1928, 1927, 1925, 1923, + 1923, 1924, 1925, 1924, 1927, 1929, 1930, 1928, + 1927, 1929, 1928, 1927, 1927, 1927, 1926, 1927, + 1928, 1927, 1930, 1930, 1929, 1930, 1926, 1927, + 1929, 1932, 1933, 1933, 1931, 1929, 1927, 1927, + 1925, 1926, 1928, 1928, 1928, 1925, 1926, 1927, + 1929, 1929, 1932, 1931, 1930, 1929, 1928, 1928, + 1926, 1926, 1925, 1927, 1927, 1927, 1924, 1924, + 1923, 1923, 1922, 1923, 1925, 1921, 1921, 1920, + 1922, 1923, 1921, 1921, 1921, 1918, 1918, 1916, + 1916, 1915, 1914, 1913, 1913, 1913, 1911, 1910, + 1910, 1909, 1908, 1908, 1908, 1909, 1912, 1911, + 1909, 1909, 1907, 1908, 1910, 1907, 1907, 1906, + 1907, 1906, 1905, 1902, 1902, 1900, 1899, 1900, + 1900, 1901, 1901, 1901, 1902, 1902, 1901, 1901, + 1898, 1898, 1899, 1900, 1899, 1899, 1898, 1896, + 1895, 1895, 1893, 1892, 1893, 1890, 1890, 1889, + 1889, 1891, 1891, 1893, 1894, 1897, 1898, 1898, + 1897, 1899, 1898, 1897, 1897, 1896, 1896, 1895, + 1892, 1891, 1891, 1888, 1889, 1893, 1893, 1895, + 1895, 1896, 1899, 1902, 1900, 1899, 1899, 1900, + 1901, 1901, 1901, 1900, 1901, 1901, 1903, 1900, + 1902, 1903, 1904, 1902, 1902, 1903, 1902, 1901, + 1902, 1903, 1902, 1900, 1900, 1896, 1892, 1891, + 1897, 1899, 1902, 1908, 1907, 1914, 1916, 1917, + 1918, 1918, 1917, 1912, 1904, 1898, 1891, 1886, + 1885, 1884, 1886, 1885, 1888, 1894, 1900, 1911, + 1917, 1923, 1927, 1931, 1930, 1927, 1920, 1915, + 1911, 1902, 1894, 1887, 1883, 1883, 1887, 1891, + 1894, 1900, 1906, 1915, 1922, 1925, 1930, 1931, + 1931, 1925, 1921, 1915, 1907, 1901, 1898, 1895, + 1891, 1893, 1897, 1901, 1905, 1912, 1921, 1923, + 1929, 1934, 1936, 1937, 1934, 1932, 1928, 1924, + 1918, 1915, 1910, 1908, 1908, 1910, 1910, 1910, + 1914, 1918, 1922, 1925, 1928, 1927, 1929, 1927, + 1930, 1929, 1928, 1927, 1924, 1922, 1921, 1921, + 1921, 1921, 1918, 1918, 1920, 1920, 1920, 1920, + 1922, 1927, 1931, 1930, 1932, 1933, 1933, 1937, + 1935, 1935, 1935, 1932, 1930, 1929, 1928, 1926, + 1926, 1926, 1927, 1928, 1930, 1933, 1936, 1939, + 1941, 1945, 1945, 1947, 1946, 1942, 1939, 1935, + 1932, 1929, 1928, 1928, 1927, 1929, 1931, 1935, + 1936, 1938, 1939, 1942, 1945, 1946, 1949, 1949, + 1946, 1946, 1943, 1939, 1937, 1934, 1935, 1934, + 1934, 1934, 1933, 1935, 1938, 1940, 1942, 1942, + 1944, 1943, 1944, 1943, 1944, 1944, 1943, 1943, + 1942, 1941, 1941, 1941, 1941, 1941, 1942, 1943, + 1942, 1943, 1945, 1946, 1947, 1947, 1948, 1950, + 1949, 1948, 1947, 1945, 1947, 1949, 1949, 1948, + 1950, 1952, 1948, 1950, 1954, 1952, 1952, 1955, + 1955, 1956, 1956, 1955, 1957, 1956, 1956, 1957, + 1960, 1958, 1959, 1960, 1959, 1960, 1963, 1964, + 1963, 1963, 1962, 1964, 1964, 1964, 1964, 1965, + 1967, 1967, 1966, 1964, 1965, 1962, 1961, 1961, + 1962, 1960, 1962, 1961, 1961, 1962, 1963, 1966, + 1968, 1969, 1967, 1968, 1967, 1967, 1966, 1967, + 1969, 1967, 1968, 1966, 1967, 1967, 1968, 1966, + 1966, 1969, 1970, 1973, 1972, 1974, 1978, 1976, + 1976, 1977, 1979, 1978, 1975, 1974, 1972, 1972, + 1971, 1969, 1969, 1970, 1971, 1972, 1974, 1976, + 1979, 1980, 1979, 1980, 1981, 1982, 1982, 1982, + 1980, 1978, 1980, 1980, 1978, 1976, 1977, 1979, + 1979, 1977, 1978, 1979, 1981, 1982, 1986, 1987, + 1988, 1989, 1989, 1994, 1993, 1995, 1994, 1993, + 1993, 1994, 1997, 1997, 1995, 1993, 1993, 1993, + 1995, 1995, 1997, 1996, 2000, 2002, 2001, 2001, + 2000, 2002, 2002, 2001, 2000, 2001, 2001, 2000, + 2001, 1998, 1998, 1998, 1998, 1997, 1997, 1998, + 1996, 1996, 1997, 1998, 2000, 1999, 2000, 2000, + 2000, 2003, 2002, 2001, 2001, 2002, 2004, 2005, + 2002, 2001, 2001, 2001, 2001, 1998, 2000, 1999, + 2000, 2000, 1998, 1999, 2001, 2000, 2002, 2004, + 2005, 2007, 2006, 2006, 2004, 2004, 2004, 2003, + 2003, 2001, 2001, 2000, 2000, 1999, 1999, 1998, + 1996, 1998, 1998, 1998, 1996, 1997, 1996, 1994, + 1995, 1995, 1994, 1997, 1997, 1997, 2002, 2002, + 2000, 2000, 1999, 2000, 1998, 2000, 2001, 2001, + 2001, 1999, 1998, 1998, 1999, 1999, 1999, 2000, + 2003, 2006, 2006, 2008, 2006, 2004, 2006, 2007, + 2008, 2007, 2007, 2006, 2005, 2007, 2006, 2010, + 2009, 2007, 2008, 2010, 2011, 2011, 2012, 2013, + 2012, 2014, 2011, 2012, 2014, 2013, 2015, 2013, + 2015, 2013, 2012, 2014, 2014, 2012, 2013, 2010, + 2010, 2012, 2013, 2014, 2014, 2011, 2013, 2014, + 2013, 2011, 2010, 2011, 2009, 2009, 2008, 2008, + 2007, 2006, 2005, 2005, 2004, 2005, 2005, 2004, + 2004, 2003, 2003, 2004, 2006, 2007, 2008, 2007, + 2008, 2010, 2011, 2009, 2008, 2006, 2007, 2007, + 2007, 2005, 2005, 2006, 2005, 2007, 2009, 2008, + 2008, 2008, 2008, 2007, 2006, 2004, 2004, 2005, + 2004, 2004, 2003, 2003, 2002, 2002, 2001, 2000, + 2000, 1999, 2000, 1997, 2000, 2000, 1999, 1999, + 2000, 2002, 2002, 2004, 2003, 2003, 2003, 2003, + 2002, 2003, 2006, 2007, 2007, 2009, 2007, 2006, + 2005, 2005, 2004, 2002, 2001, 2001, 2002, 2000, + 1999, 1996, 1999, 2000, 1999, 2001, 2001, 2000, + 1998, 2000, 2001, 2001, 2001, 2001, 2000, 1999, + 1998, 1998, 2000, 2000, 2000, 1999, 1998, 1996, + 1994, 1992, 1992, 1993, 1994, 1993, 1995, 1994, + 1993, 1998, 1999, 1996, 1994, 1995, 1995, 1996, + 1994, 1994, 1995, 1995, 1994, 1994, 1992, 1992, + 1993, 1992, 1992, 1993, 1994, 1994, 1994, 1996, + 1996, 1996, 1996, 1996, 1995, 1997, 1997, 1998, + 2001, 2000, 2000, 1998, 1999, 2000, 1999, 2000, + 1999, 1998, 1998, 1997, 1999, 2001, 2000, 2000, + 2001, 1998, 1998, 1997, 1998, 1998, 1998, 1998, + 1998, 1997, 1994, 1995, 1997, 1997, 1995, 1996, + 1995, 1993, 1995, 1994, 1997, 1995, 1995, 1994, + 1997, 1997, 1996, 1998, 1999, 1998, 1997, 1999, + 1999, 1999, 1999, 1998, 1997, 1995, 1998, 1999, + 1999, 1997, 1998, 1999, 1998, 1999, 2000, 2000, + 1998, 1998, 1997, 1992, 1994, 1996, 1993, 1994, + 1993, 1995, 1995, 1997, 1994, 1995, 1995, 1995, + 1994, 1993, 1993, 1992, 1991, 1993, 1992, 1993, + 1992, 1991, 1993, 1991, 1992, 1992, 1991, 1992, + 1989, 1990, 1990, 1992, 1990, 1991, 1991, 1991, + 1989, 1991, 1989, 1990, 1989, 1990, 1991, 1990, + 1990, 1990, 1990, 1990, 1991, 1993, 1991, 1991, + 1991, 1992, 1993, 1994, 1993, 1994, 1994, 1994, + 1995, 1995, 2000, 2000, 1999, 2001, 2000, 1997, + 1999, 1998, 1996, 1997, 1996, 1996, 1996, 1995, + 1997, 1997, 1997, 1996, 1995, 1997, 1997, 1999, + 1999, 2000, 1999, 1999, 2000, 2001, 2000, 2002, + 2005, 2004, 2007, 2006, 2006, 2005, 2005, 2006, + 2006, 2008, 2007, 2008, 2009, 2009, 2011, 2013, + 2013, 2013, 2017, 2017, 2019, 2020, 2019, 2021, + 2021, 2021, 2022, 2022, 2023, 2022, 2024, 2023, + 2027, 2025, 2027, 2027, 2026, 2029, 2029, 2027, + 2029, 2030, 2029, 2029, 2031, 2029, 2028, 2030, + 2029, 2033, 2032, 2035, 2032, 2031, 2032, 2027, + 2031, 2030, 2029, 2030, 2030, 2029, 2030, 2034, + 2033, 2033, 2036, 2038, 2038, 2039, 2038, 2040, + 2040, 2041, 2040, 2040, 2039, 2040, 2040, 2043, + 2044, 2044, 2044, 2044, 2045, 2047, 2045, 2047, + 2048, 2047, 2048, 2048, 2049, 2051, 2051, 2051, + 2051, 2054, 2052, 2049, 2051, 2051, 2049, 2050, + 2050, 2050, 2052, 2050, 2052, 2052, 2051, 2051, + 2051, 2050, 2051, 2050, 2052, 2053, 2053, 2052, + 2054, 2053, 2052, 2053, 2054, 2052, 2056, 2057, + 2057, 2056, 2057, 2056, 2056, 2057, 2057, 2056, + 2056, 2056, 2059, 2058, 2058, 2059, 2059, 2059, + 2059, 2061, 2059, 2059, 2059, 2062, 2062, 2061, + 2062, 2061, 2062, 2063, 2063, 2064, 2064, 2064, + 2064, 2062, 2061, 2061, 2061, 2061, 2059, 2058, + 2059, 2061, 2062, 2059, 2059, 2061, 2060, 2059, + 2060, 2060, 2062, 2062, 2064, 2067, 2064, 2066, + 2067, 2066, 2066, 2066, 2067, 2067, 2066, 2066, + 2066, 2066, 2069, 2068, 2066, 2069, 2067, 2067, + 2069, 2069, 2070, 2069, 2071, 2072, 2074, 2072, + 2071, 2073, 2073, 2073, 2071, 2073, 2076, 2073, + 2071, 2072, 2074, 2072, 2075, 2073, 2074, 2077, + 2079, 2080, 2081, 2084, 2083, 2083, 2082, 2086, + 2087, 2086, 2086, 2086, 2088, 2089, 2088, 2088, + 2088, 2088, 2090, 2090, 2090, 2090, 2093, 2093, + 2093, 2094, 2093, 2097, 2098, 2096, 2096, 2094, + 2095, 2096, 2096, 2092, 2095, 2097, 2094, 2096, + 2095, 2097, 2097, 2095, 2095, 2097, 2097, 2097, + 2095, 2094, 2097, 2097, 2098, 2097, 2096, 2096, + 2096, 2099, 2100, 2100, 2098, 2099, 2099, 2099, + 2102, 2104, 2103, 2103, 2105, 2104, 2105, 2104, + 2106, 2107, 2107, 2106, 2107, 2109, 2110, 2110, + 2111, 2113, 2115, 2113, 2114, 2116, 2114, 2116, + 2113, 2114, 2112, 2112, 2112, 2111, 2114, 2114, + 2112, 2112, 2112, 2115, 2116, 2115, 2114, 2112, + 2113, 2114, 2114, 2114, 2114, 2114, 2114, 2112, + 2113, 2115, 2113, 2115, 2114, 2115, 2117, 2115, + 2116, 2116, 2117, 2118, 2116, 2116, 2117, 2117, + 2117, 2118, 2118, 2120, 2121, 2120, 2117, 2116, + 2118, 2120, 2121, 2120, 2120, 2122, 2121, 2124, + 2122, 2120, 2123, 2121, 2121, 2123, 2121, 2121, + 2121, 2119, 2119, 2118, 2115, 2117, 2119, 2117, + 2116, 2115, 2115, 2115, 2114, 2113, 2112, 2113, + 2111, 2111, 2111, 2112, 2110, 2111, 2111, 2111, + 2111, 2111, 2112, 2111, 2111, 2112, 2111, 2110, + 2111, 2113, 2113, 2111, 2111, 2109, 2110, 2109, + 2107, 2109, 2110, 2112, 2111, 2112, 2109, 2109, + 2110, 2110, 2109, 2112, 2112, 2110, 2108, 2108, + 2108, 2109, 2107, 2108, 2112, 2111, 2109, 2108, + 2109, 2111, 2112, 2108, 2106, 2107, 2108, 2107, + 2107, 2106, 2106, 2107, 2107, 2107, 2107, 2109, + 2109, 2112, 2111, 2108, 2106, 2108, 2108, 2105, + 2106, 2107, 2106, 2107, 2105, 2104, 2105, 2105, + 2104, 2104, 2103, 2102, 2101, 2100, 2098, 2099, + 2098, 2098, 2098, 2097, 2099, 2099, 2097, 2094, + 2095, 2097, 2094, 2094, 2090, 2092, 2093, 2093, + 2094, 2094, 2094, 2093, 2094, 2094, 2094, 2093, + 2090, 2093, 2092, 2089, 2092, 2091, 2092, 2088, + 2088, 2090, 2088, 2087, 2087, 2088, 2087, 2088, + 2086, 2087, 2087, 2088, 2089, 2085, 2085, 2086, + 2088, 2087, 2086, 2088, 2087, 2085, 2085, 2086, + 2087, 2086, 2085, 2084, 2085, 2085, 2087, 2089, + 2091, 2091, 2086, 2086, 2085, 2083, 2083, 2082, + 2081, 2084, 2085, 2085, 2082, 2081, 2082, 2080, + 2082, 2084, 2082, 2082, 2082, 2079, 2080, 2080, + 2079, 2078, 2077, 2076, 2076, 2075, 2076, 2076, + 2077, 2074, 2077, 2077, 2075, 2075, 2075, 2074, + 2074, 2074, 2075, 2075, 2072, 2073, 2071, 2072, + 2072, 2070, 2070, 2068, 2070, 2068, 2069, 2068, + 2067, 2068, 2069, 2066, 2063, 2065, 2067, 2065, + 2065, 2065, 2064, 2064, 2062, 2063, 2062, 2061, + 2061, 2060, 2063, 2060, 2059, 2058, 2055, 2058, + 2059, 2059, 2061, 2058, 2057, 2057, 2058, 2058, + 2058, 2057, 2056, 2054, 2054, 2055, 2056, 2058, + 2058, 2058, 2054, 2058, 2060, 2059, 2056, 2056, + 2055, 2056, 2058, 2057, 2057, 2057, 2056, 2056, + 2057, 2058, 2058, 2058, 2058, 2058, 2058, 2058, + 2059, 2059, 2059, 2060, 2061, 2060, 2059, 2059, + 2060, 2061, 2062, 2063, 2065, 2063, 2062, 2061, + 2062, 2063, 2064, 2064, 2061, 2061, 2062, 2065, + 2067, 2065, 2068, 2065, 2066, 2066, 2066, 2067, + 2068, 2069, 2070, 2068, 2068, 2068, 2066, 2066, + 2066, 2068, 2070, 2068, 2071, 2070, 2068, 2067, + 2066, 2068, 2069, 2068, 2067, 2069, 2067, 2067, + 2070, 2069, 2068, 2067, 2066, 2066, 2068, 2069, + 2069, 2069, 2069, 2071, 2071, 2069, 2070, 2070, + 2067, 2070, 2072, 2073, 2074, 2073, 2068, 2069, + 2071, 2073, 2075, 2077, 2080, 2078, 2079, 2078, + 2078, 2078, 2078, 2077, 2076, 2078, 2076, 2079, + 2079, 2079, 2078, 2079, 2080, 2079, 2081, 2080, + 2082, 2084, 2084, 2085, 2085, 2086, 2088, 2089, + 2087, 2087, 2088, 2090, 2090, 2090, 2091, 2092, + 2093, 2093, 2092, 2094, 2093, 2095, 2093, 2093, + 2093, 2094, 2093, 2095, 2096, 2097, 2095, 2092, + 2097, 2093, 2093, 2094, 2096, 2095, 2092, 2092, + 2093, 2093, 2093, 2095, 2093, 2092, 2092, 2090, + 2090, 2091, 2091, 2092, 2094, 2095, 2096, 2094, + 2096, 2097, 2094, 2097, 2096, 2094, 2096, 2096, + 2096, 2097, 2097, 2097, 2094, 2095, 2097, 2098, + 2100, 2099, 2099, 2099, 2098, 2100, 2100, 2097, + 2099, 2100, 2101, 2100, 2100, 2102, 2102, 2100, + 2100, 2100, 2102, 2103, 2106, 2104, 2102, 2101, + 2101, 2101, 2099, 2100, 2102, 2103, 2103, 2103, + 2102, 2101, 2103, 2105, 2104, 2106, 2104, 2105, + 2105, 2105, 2105, 2102, 2101, 2102, 2103, 2103, + 2103, 2102, 2101, 2102, 2103, 2101, 2105, 2102, + 2103, 2104, 2104, 2103, 2104, 2104, 2103, 2105, + 2103, 2102, 2103, 2103, 2105, 2104, 2101, 2100, + 2099, 2099, 2100, 2101, 2101, 2099, 2100, 2100, + 2101, 2103, 2104, 2104, 2105, 2103, 2103, 2104, + 2103, 2103, 2102, 2100, 2100, 2101, 2101, 2100, + 2101, 2099, 2098, 2099, 2099, 2102, 2101, 2099, + 2099, 2098, 2100, 2103, 2103, 2104, 2107, 2106, + 2108, 2107, 2105, 2107, 2104, 2104, 2105, 2105, + 2104, 2104, 2107, 2107, 2107, 2108, 2107, 2108, + 2108, 2109, 2110, 2111, 2112, 2111, 2110, 2110, + 2111, 2110, 2111, 2112, 2113, 2114, 2114, 2112, + 2112, 2112, 2116, 2116, 2115, 2116, 2116, 2118, + 2119, 2120, 2119, 2121, 2122, 2120, 2122, 2125, + 2125, 2124, 2124, 2125, 2124, 2123, 2123, 2123, + 2121, 2122, 2122, 2125, 2124, 2123, 2124, 2126, + 2123, 2125, 2126, 2126, 2125, 2125, 2124, 2125, + 2125, 2124, 2126, 2126, 2127, 2127, 2125, 2127, + 2126, 2128, 2128, 2126, 2127, 2129, 2129, 2131, + 2131, 2131, 2131, 2132, 2130, 2130, 2132, 2132, + 2132, 2130, 2132, 2132, 2134, 2136, 2136, 2137, + 2139, 2138, 2138, 2136, 2136, 2136, 2135, 2132, + 2133, 2132, 2133, 2133, 2132, 2134, 2132, 2133, + 2136, 2131, 2132, 2133, 2133, 2135, 2134, 2134, + 2133, 2132, 2132, 2133, 2135, 2133, 2133, 2132, + 2133, 2133, 2133, 2134, 2135, 2136, 2135, 2133, + 2135, 2137, 2136, 2136, 2137, 2136, 2139, 2138, + 2137, 2138, 2137, 2139, 2138, 2138, 2139, 2139, + 2137, 2137, 2139, 2136, 2132, 2134, 2134, 2132, + 2130, 2132, 2132, 2129, 2128, 2126, 2126, 2128, + 2129, 2128, 2127, 2128, 2128, 2127, 2129, 2130, + 2130, 2128, 2128, 2128, 2129, 2129, 2131, 2132, + 2130, 2128, 2129, 2130, 2128, 2127, 2128, 2128, + 2128, 2128, 2129, 2131, 2131, 2132, 2132, 2132, + 2131, 2132, 2131, 2130, 2130, 2132, 2131, 2127, + 2130, 2127, 2127, 2127, 2128, 2124, 2123, 2124, + 2124, 2124, 2124, 2125, 2124, 2122, 2121, 2121, + 2119, 2120, 2119, 2118, 2117, 2118, 2118, 2114, + 2114, 2113, 2113, 2115, 2112, 2114, 2114, 2111, + 2111, 2111, 2111, 2109, 2110, 2110, 2109, 2108, + 2111, 2113, 2110, 2110, 2107, 2109, 2108, 2106, + 2108, 2106, 2107, 2106, 2108, 2109, 2109, 2108, + 2108, 2109, 2108, 2107, 2110, 2108, 2104, 2103, + 2105, 2106, 2104, 2104, 2103, 2103, 2102, 2102, + 2102, 2103, 2103, 2101, 2102, 2101, 2103, 2106, + 2105, 2102, 2104, 2103, 2102, 2100, 2101, 2102, + 2099, 2101, 2102, 2104, 2102, 2101, 2101, 2101, + 2103, 2102, 2103, 2105, 2103, 2104, 2102, 2102 +}; diff --git a/keyboards/planck/keymaps/synth_wavetable/config.h b/keyboards/planck/keymaps/synth_wavetable/config.h new file mode 100644 index 000000000000..6fa31cc8a76f --- /dev/null +++ b/keyboards/planck/keymaps/synth_wavetable/config.h @@ -0,0 +1,39 @@ +#pragma once + +#ifdef AUDIO_ENABLE + #define STARTUP_SONG SONG(PLANCK_SOUND) + // #define STARTUP_SONG SONG(NO_SOUND) + + #define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \ + SONG(COLEMAK_SOUND), \ + SONG(DVORAK_SOUND) \ + } +#endif + +/* + * MIDI options + */ + +/* Prevent use of disabled MIDI features in the keymap */ +//#define MIDI_ENABLE_STRICT 1 + +/* enable basic MIDI features: + - MIDI notes can be sent when in Music mode is on +*/ + +#define MIDI_BASIC + +/* enable advanced MIDI features: + - MIDI notes can be added to the keymap + - Octave shift and transpose + - Virtual sustain, portamento, and modulation wheel + - etc. +*/ +//#define MIDI_ADVANCED + +/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */ +//#define MIDI_TONE_KEYCODE_OCTAVES 2 + +// Most tactile encoders have detents every 4 stages +#define ENCODER_RESOLUTION 4 + diff --git a/keyboards/planck/keymaps/synth_wavetable/keymap.c b/keyboards/planck/keymaps/synth_wavetable/keymap.c new file mode 100644 index 000000000000..218559353dc6 --- /dev/null +++ b/keyboards/planck/keymaps/synth_wavetable/keymap.c @@ -0,0 +1,326 @@ +/* Copyright 2019 Jack Humbert + * + * 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 2 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 . + */ + +#include QMK_KEYBOARD_H +#include "audio.h" + +extern keymap_config_t keymap_config; + +enum planck_layers { + _QWERTY, + _COLEMAK, + _DVORAK, + _LOWER, + _RAISE, + _PLOVER, + _ADJUST +}; + +enum planck_keycodes { + QWERTY = SAFE_RANGE, + COLEMAK, + DVORAK, + PLOVER, + BACKLIT, + EXT_PLV +}; + +#define LOWER MO(_LOWER) +#define RAISE MO(_RAISE) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +/* Qwerty + * ,-----------------------------------------------------------------------------------. + * | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Esc | A | S | D | F | G | H | J | K | L | ; | " | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Shift| Z | X | C | V | B | N | M | , | . | / |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_QWERTY] = LAYOUT_planck_grid( + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, + KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , + BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT +), + +/* Colemak + * ,-----------------------------------------------------------------------------------. + * | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Esc | A | R | S | T | D | H | N | E | I | O | " | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Shift| Z | X | C | V | B | K | M | , | . | / |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_COLEMAK] = LAYOUT_planck_grid( + KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, + KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , + BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT +), + +/* Dvorak + * ,-----------------------------------------------------------------------------------. + * | Tab | " | , | . | P | Y | F | G | C | R | L | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Esc | A | O | E | U | I | D | H | T | N | S | / | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_DVORAK] = LAYOUT_planck_grid( + KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC, + KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH, + KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT , + BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT +), + +/* Lower + * ,-----------------------------------------------------------------------------------. + * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Del | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | Home | End | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | Next | Vol- | Vol+ | Play | + * `-----------------------------------------------------------------------------------' + */ +[_LOWER] = LAYOUT_planck_grid( + KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, + KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, + _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, S(KC_NUHS), S(KC_NUBS), KC_HOME, KC_END, _______, + _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY +), + +/* Raise + * ,-----------------------------------------------------------------------------------. + * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | Del | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / |Pg Up |Pg Dn | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | Next | Vol- | Vol+ | Play | + * `-----------------------------------------------------------------------------------' + */ +[_RAISE] = LAYOUT_planck_grid( + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, + KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, + _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, KC_PGUP, KC_PGDN, _______, + _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY +), + +/* Plover layer (http://opensteno.org) + * ,-----------------------------------------------------------------------------------. + * | # | # | # | # | # | # | # | # | # | # | # | # | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | | S | T | P | H | * | * | F | P | L | T | D | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | | S | K | W | R | * | * | R | B | G | S | Z | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Exit | | | A | O | | E | U | | | | + * `-----------------------------------------------------------------------------------' + */ +[_PLOVER] = LAYOUT_planck_grid( + KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1 , + XXXXXXX, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, + XXXXXXX, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, + EXT_PLV, XXXXXXX, XXXXXXX, KC_C, KC_V, XXXXXXX, XXXXXXX, KC_N, KC_M, XXXXXXX, XXXXXXX, XXXXXXX +), + +/* Adjust (Lower + Raise) + * ,-----------------------------------------------------------------------------------. + * | | Reset| | | | | | | | | | Del | + * |------+------+------+------+------+-------------+------+------+------+------+------| + * | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak|Plover| | + * |------+------+------+------+------+------|------+------+------+------+------+------| + * | |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof| | | | | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | | | | | | | | | | | + * `-----------------------------------------------------------------------------------' + */ +[_ADJUST] = LAYOUT_planck_grid( + _______, RESET, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL , + _______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______, + _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, TERM_ON, TERM_OFF, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ +) + +}; + +#ifdef AUDIO_ENABLE + float plover_song[][2] = SONG(PLOVER_SOUND); + float plover_gb_song[][2] = SONG(PLOVER_GOODBYE_SOUND); +#endif + +uint32_t layer_state_set_user(uint32_t state) { + return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); +} + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case QWERTY: + if (record->event.pressed) { + print("mode just switched to qwerty and this is a huge string\n"); + set_single_persistent_default_layer(_QWERTY); + } + return false; + break; + case COLEMAK: + if (record->event.pressed) { + set_single_persistent_default_layer(_COLEMAK); + } + return false; + break; + case DVORAK: + if (record->event.pressed) { + set_single_persistent_default_layer(_DVORAK); + } + return false; + break; + case BACKLIT: + if (record->event.pressed) { + register_code(KC_RSFT); + #ifdef BACKLIGHT_ENABLE + backlight_step(); + #endif + #ifdef KEYBOARD_planck_rev5 + PORTE &= ~(1<<6); + #endif + } else { + unregister_code(KC_RSFT); + #ifdef KEYBOARD_planck_rev5 + PORTE |= (1<<6); + #endif + } + return false; + break; + case PLOVER: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + stop_all_notes(); + PLAY_SONG(plover_song); + #endif + layer_off(_RAISE); + layer_off(_LOWER); + layer_off(_ADJUST); + layer_on(_PLOVER); + if (!eeconfig_is_enabled()) { + eeconfig_init(); + } + keymap_config.raw = eeconfig_read_keymap(); + keymap_config.nkro = 1; + eeconfig_update_keymap(keymap_config.raw); + } + return false; + break; + case EXT_PLV: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + PLAY_SONG(plover_gb_song); + #endif + layer_off(_PLOVER); + } + return false; + break; + } + return true; +} + +void matrix_scan_user(void) { + +} + +bool music_mask_user(uint16_t keycode) { + switch (keycode) { + case RAISE: + case LOWER: + return false; + default: + return true; + } +} + +#include "wavetable.h" + +float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; +uint8_t dac_morph = 0; +// uint8_t dac_morph_flipped = 0; +// uint16_t dac_morph_counter = 0; + +void dac_setup_note(void) { + dac_if[dac_number_of_voices()] = 0.0f; +} + +uint16_t dac_value_generate(void) { + uint16_t value = DAC_OFF_VALUE; + uint8_t working_voices = dac_number_of_voices(); + if (working_voices > DAC_VOICES_MAX) + working_voices = DAC_VOICES_MAX; + + if (working_voices > 0) { + uint16_t value_avg = 0; + for (uint8_t i = 0; i < working_voices; i++) { + dac_if[i] = dac_if[i] + ((dac_get_frequency(i) * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE); + + // Needed because % doesn't work with floats + while (dac_if[i] >= (DAC_BUFFER_SIZE)) + dac_if[i] = dac_if[i] - DAC_BUFFER_SIZE; + + // #define DAC_MORPH_SPEED 372 + // #define DAC_MORPH_SPEED_COMPUTED (DAC_SAMPLE_RATE / DAC_WAVETABLE_CUSTOM_LENGTH * (1000 / DAC_MORPH_SPEED)) + + uint16_t dac_i = (uint16_t)dac_if[i]; + // value_avg += dac_buffer_custom[dac_morph_flipped][dac_i] / working_voices / 2 * ((dac_morph >= 63) ? 6400 - dac_morph_counter : dac_morph_counter) / 6400; + // value_avg += dac_buffer_custom[dac_morph_flipped + 1][dac_i] / working_voices / 2 * ((dac_morph >= 63) ? dac_morph_counter : 6400 - dac_morph_counter) / 6400; + + // value_avg += dac_wavetable_custom[dac_morph][dac_i] / working_voices / 2 * (DAC_MORPH_SPEED_COMPUTED - dac_morph_counter) / DAC_MORPH_SPEED_COMPUTED; + // value_avg += dac_wavetable_custom[dac_morph + 1][dac_i] / working_voices / 2 * dac_morph_counter / DAC_MORPH_SPEED_COMPUTED; + value_avg += dac_wavetable_custom[dac_morph][dac_i] / working_voices; + } + value = value_avg; + + // dac_morph_counter++; + // if (dac_morph_counter >= DAC_MORPH_SPEED_COMPUTED) { + // dac_morph_counter = 0; + // dac_morph = (dac_morph + 1) % 125; + // dac_morph_flipped = ((dac_morph >= 63) ? (125 - dac_morph) : dac_morph); + // dac_morph = (dac_morph + 1) % (DAC_WAVETABLE_CUSTOM_LENGTH - 1); + // } + } + return value; +} + +void encoder_update(bool clockwise) { + if (clockwise) { + dac_morph = (dac_morph + 1) % DAC_WAVETABLE_CUSTOM_LENGTH; + } else { + if (dac_morph == 0) + dac_morph = (DAC_WAVETABLE_CUSTOM_LENGTH - 1); + else + dac_morph--; + } +} diff --git a/keyboards/planck/keymaps/synth_wavetable/rules.mk b/keyboards/planck/keymaps/synth_wavetable/rules.mk new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/keyboards/planck/keymaps/synth_wavetable/wavetable.h b/keyboards/planck/keymaps/synth_wavetable/wavetable.h new file mode 100644 index 000000000000..08e9b01bce9c --- /dev/null +++ b/keyboards/planck/keymaps/synth_wavetable/wavetable.h @@ -0,0 +1,2180 @@ +#define DAC_WAVETABLE_CUSTOM_LENGTH 64 + +static const dacsample_t dac_wavetable_custom[64][256] = { + { + 3038, 4095, 3745, 3945, 3779, 3889, 3782, 3850, + 3775, 3817, 3766, 3788, 3755, 3762, 3743, 3738, + 3729, 3716, 3715, 3695, 3700, 3676, 3683, 3658, + 3667, 3642, 3649, 3626, 3632, 3611, 3614, 3596, + 3596, 3581, 3579, 3567, 3561, 3552, 3544, 3537, + 3528, 3522, 3511, 3507, 3495, 3491, 3479, 3476, + 3464, 3460, 3449, 3444, 3433, 3428, 3419, 3412, + 3404, 3397, 3389, 3382, 3374, 3366, 3359, 3351, + 3345, 3336, 3330, 3322, 3314, 3307, 3299, 3293, + 3285, 3279, 3270, 3265, 3255, 3251, 3241, 3237, + 3227, 3223, 3213, 3208, 3200, 3194, 3187, 3179, + 3173, 3165, 3161, 3150, 3149, 3136, 3137, 3121, + 3125, 3107, 3112, 3093, 3099, 3080, 3086, 3068, + 3072, 3056, 3058, 3045, 3043, 3036, 3027, 3027, + 3010, 3019, 2992, 3013, 2974, 3007, 2955, 3002, + 2935, 2999, 2913, 2998, 2886, 3006, 2842, 3067, + 2464, 221, 205, 228, 215, 260, 231, 285, + 249, 307, 270, 326, 291, 344, 313, 359, + 335, 374, 357, 388, 378, 403, 399, 416, + 419, 431, 438, 445, 457, 460, 475, 476, + 492, 492, 509, 508, 525, 524, 540, 541, + 555, 558, 571, 574, 586, 591, 601, 607, + 616, 624, 631, 639, 647, 656, 662, 671, + 677, 687, 692, 702, 708, 718, 723, 733, + 738, 748, 753, 763, 768, 777, 783, 792, + 798, 806, 812, 820, 827, 834, 842, 848, + 857, 862, 872, 875, 887, 888, 901, 902, + 915, 915, 929, 929, 943, 942, 956, 956, + 969, 971, 981, 986, 992, 1001, 1003, 1017, + 1013, 1032, 1023, 1048, 1033, 1064, 1043, 1079, + 1054, 1093, 1065, 1106, 1078, 1118, 1092, 1127, + 1109, 1132, 1130, 1132, 1160, 1118, 1217, 1036 + }, + { + 2048, 2049, 2056, 2071, 2096, 2130, 2174, 2225, + 2280, 2337, 2392, 2444, 2490, 2529, 2559, 2581, + 2593, 2597, 2594, 2589, 2585, 2588, 2603, 2635, + 2685, 2755, 2842, 2943, 3050, 3157, 3258, 3347, + 3423, 3485, 3535, 3577, 3612, 3641, 3665, 3682, + 3692, 3694, 3692, 3689, 3690, 3700, 3724, 3761, + 3811, 3867, 3924, 3972, 4005, 4019, 4013, 3993, + 3964, 3936, 3915, 3906, 3912, 3931, 3959, 3990, + 4020, 4043, 4059, 4067, 4068, 4063, 4051, 4030, + 3997, 3946, 3875, 3782, 3671, 3546, 3419, 3299, + 3197, 3120, 3072, 3053, 3062, 3091, 3133, 3180, + 3224, 3257, 3276, 3277, 3259, 3221, 3163, 3084, + 2986, 2870, 2741, 2607, 2474, 2351, 2245, 2161, + 2102, 2069, 2058, 2067, 2091, 2124, 2160, 2195, + 2222, 2239, 2245, 2238, 2219, 2191, 2155, 2116, + 2077, 2042, 2014, 1995, 1987, 1991, 2003, 2023, + 2048, 2074, 2101, 2124, 2144, 2158, 2166, 2170, + 2172, 2175, 2181, 2195, 2221, 2260, 2315, 2384, + 2465, 2555, 2648, 2740, 2826, 2903, 2971, 3029, + 3076, 3114, 3142, 3159, 3167, 3167, 3160, 3153, + 3150, 3157, 3180, 3222, 3283, 3362, 3452, 3546, + 3636, 3715, 3777, 3823, 3854, 3874, 3889, 3905, + 3923, 3944, 3968, 3989, 4007, 4019, 4026, 4030, + 4033, 4040, 4051, 4066, 4081, 4090, 4086, 4063, + 4019, 3956, 3878, 3794, 3716, 3651, 3606, 3586, + 3589, 3612, 3647, 3688, 3728, 3760, 3781, 3787, + 3780, 3757, 3718, 3661, 3584, 3485, 3366, 3230, + 3085, 2938, 2801, 2683, 2589, 2525, 2492, 2486, + 2503, 2537, 2580, 2624, 2663, 2691, 2703, 2698, + 2674, 2633, 2574, 2500, 2415, 2322, 2228, 2139, + 2059, 1994, 1945, 1914, 1900, 1901, 1913, 1933, + 1957, 1983, 2006, 2025, 2038, 2046, 2049, 2048 + }, + { + 2048, 2053, 2074, 2119, 2191, 2291, 2416, 2559, + 2710, 2860, 3000, 3124, 3225, 3301, 3350, 3371, + 3364, 3334, 3288, 3234, 3182, 3144, 3127, 3137, + 3173, 3231, 3304, 3378, 3441, 3483, 3495, 3475, + 3423, 3344, 3243, 3128, 3002, 2867, 2726, 2581, + 2433, 2286, 2142, 2001, 1865, 1731, 1597, 1460, + 1317, 1171, 1023, 881, 750, 637, 546, 476, + 423, 380, 341, 300, 254, 205, 154, 109, + 75, 56, 55, 72, 105, 153, 217, 296, + 395, 513, 651, 806, 972, 1139, 1299, 1444, + 1572, 1680, 1772, 1855, 1935, 2018, 2110, 2212, + 2323, 2442, 2563, 2680, 2786, 2877, 2944, 2982, + 2986, 2951, 2877, 2771, 2640, 2498, 2360, 2238, + 2145, 2087, 2069, 2088, 2140, 2215, 2303, 2392, + 2469, 2524, 2550, 2543, 2505, 2437, 2346, 2241, + 2132, 2031, 1949, 1893, 1870, 1878, 1915, 1974, + 2048, 2128, 2206, 2276, 2332, 2371, 2394, 2402, + 2403, 2404, 2417, 2449, 2510, 2603, 2728, 2882, + 3056, 3236, 3410, 3564, 3690, 3783, 3842, 3868, + 3864, 3833, 3777, 3700, 3604, 3495, 3378, 3261, + 3150, 3048, 2958, 2877, 2801, 2723, 2637, 2536, + 2420, 2289, 2146, 1997, 1847, 1698, 1552, 1410, + 1271, 1133, 999, 870, 748, 637, 536, 446, + 364, 288, 216, 150, 92, 49, 29, 37, + 76, 144, 235, 339, 444, 541, 623, 689, + 741, 784, 826, 874, 933, 1009, 1101, 1209, + 1330, 1461, 1598, 1739, 1877, 2007, 2123, 2219, + 2291, 2338, 2364, 2374, 2378, 2385, 2404, 2443, + 2503, 2585, 2684, 2794, 2904, 3004, 3084, 3136, + 3154, 3133, 3070, 2965, 2823, 2650, 2458, 2261, + 2075, 1914, 1787, 1701, 1656, 1649, 1675, 1726, + 1791, 1861, 1927, 1981, 2020, 2043, 2051, 2050 + }, + { + 2048, 2051, 2065, 2095, 2144, 2212, 2298, 2397, + 2504, 2612, 2716, 2811, 2894, 2961, 3011, 3042, + 3055, 3052, 3036, 3014, 2996, 2988, 3001, 3040, + 3108, 3204, 3324, 3459, 3598, 3728, 3841, 3930, + 3992, 4029, 4045, 4045, 4032, 4009, 3975, 3930, + 3874, 3809, 3738, 3665, 3596, 3534, 3481, 3436, + 3397, 3357, 3312, 3255, 3184, 3099, 3003, 2900, + 2795, 2693, 2595, 2503, 2413, 2325, 2235, 2143, + 2048, 1950, 1850, 1750, 1651, 1554, 1460, 1370, + 1287, 1215, 1159, 1122, 1105, 1107, 1124, 1147, + 1168, 1179, 1172, 1143, 1091, 1019, 931, 836, + 741, 655, 584, 535, 510, 514, 549, 618, + 721, 856, 1019, 1201, 1388, 1569, 1730, 1862, + 1956, 2012, 2029, 2013, 1971, 1911, 1844, 1779, + 1725, 1690, 1676, 1686, 1719, 1771, 1838, 1913, + 1989, 2059, 2115, 2152, 2167, 2161, 2136, 2097, + 2048, 1994, 1942, 1894, 1856, 1829, 1813, 1805, + 1803, 1800, 1788, 1762, 1715, 1643, 1544, 1420, + 1276, 1120, 962, 811, 675, 558, 463, 390, + 337, 304, 290, 294, 316, 353, 399, 447, + 489, 517, 526, 513, 479, 430, 375, 322, + 283, 264, 269, 297, 345, 405, 473, 542, + 612, 682, 754, 829, 910, 996, 1086, 1179, + 1273, 1366, 1459, 1553, 1649, 1747, 1848, 1949, + 2048, 2141, 2227, 2305, 2375, 2440, 2505, 2574, + 2649, 2733, 2825, 2923, 3023, 3122, 3215, 3300, + 3373, 3433, 3476, 3499, 3496, 3465, 3403, 3313, + 3200, 3073, 2945, 2829, 2735, 2672, 2644, 2652, + 2691, 2756, 2836, 2921, 3000, 3062, 3101, 3111, + 3090, 3036, 2950, 2835, 2695, 2539, 2375, 2214, + 2069, 1947, 1855, 1795, 1766, 1765, 1786, 1824, + 1871, 1920, 1965, 2003, 2029, 2044, 2050, 2049 + }, + { + 2048, 2061, 2117, 2228, 2396, 2610, 2844, 3065, + 3240, 3343, 3358, 3283, 3125, 2900, 2629, 2337, + 2048, 1783, 1558, 1379, 1241, 1136, 1049, 971, + 900, 843, 815, 838, 930, 1103, 1358, 1680, + 2048, 2435, 2816, 3170, 3479, 3729, 3908, 4008, + 4025, 3959, 3819, 3616, 3364, 3076, 2757, 2413, + 2048, 1667, 1285, 922, 601, 347, 175, 92, + 93, 168, 304, 490, 722, 998, 1315, 1668, + 2048, 2437, 2818, 3173, 3483, 3736, 3919, 4021, + 4035, 3956, 3788, 3544, 3247, 2924, 2605, 2309, + 2048, 1819, 1614, 1422, 1234, 1050, 878, 733, + 633, 597, 635, 751, 939, 1186, 1471, 1768, + 2048, 2280, 2443, 2523, 2523, 2457, 2354, 2241, + 2146, 2087, 2067, 2081, 2113, 2142, 2149, 2118, + 2048, 1944, 1824, 1711, 1629, 1601, 1637, 1740, + 1896, 2080, 2261, 2404, 2481, 2478, 2394, 2243, + 2048, 1835, 1634, 1468, 1354, 1299, 1300, 1342, + 1408, 1479, 1540, 1586, 1625, 1670, 1744, 1865, + 2048, 2292, 2585, 2903, 3215, 3491, 3707, 3846, + 3899, 3864, 3745, 3550, 3296, 2999, 2682, 2360, + 2048, 1749, 1462, 1186, 917, 661, 432, 250, + 137, 112, 184, 351, 600, 912, 1268, 1651, + 2048, 2444, 2828, 3184, 3496, 3749, 3932, 4040, + 4072, 4031, 3919, 3739, 3493, 3185, 2828, 2441, + 2048, 1675, 1346, 1074, 862, 705, 592, 516, + 476, 475, 524, 632, 806, 1046, 1343, 1684, + 2048, 2412, 2755, 3051, 3279, 3421, 3468, 3421, + 3295, 3116, 2914, 2717, 2543, 2398, 2277, 2166, + 2048, 1909, 1744, 1557, 1361, 1178, 1031, 940, + 919, 975, 1102, 1284, 1497, 1708, 1886, 2004, + 2048, 2018, 1931, 1812, 1689, 1590, 1536, 1534, + 1585, 1676, 1786, 1894, 1981, 2035, 2056, 2053 + }, + { + 2048, 2072, 2162, 2326, 2531, 2717, 2808, 2744, + 2504, 2112, 1636, 1162, 781, 560, 536, 708, + 1040, 1468, 1922, 2340, 2681, 2929, 3082, 3144, + 3108, 2958, 2676, 2261, 1739, 1174, 654, 273, + 103, 179, 496, 1009, 1653, 2344, 2997, 3529, + 3874, 3994, 3882, 3563, 3082, 2497, 1866, 1246, + 698, 284, 64, 82, 347, 829, 1459, 2145, + 2795, 3334, 3712, 3900, 3885, 3668, 3262, 2702, + 2048, 1375, 770, 310, 56, 39, 261, 696, + 1287, 1952, 2594, 3120, 3458, 3578, 3497, 3260, + 2927, 2549, 2159, 1774, 1409, 1084, 836, 709, + 741, 951, 1327, 1819, 2353, 2844, 3211, 3395, + 3374, 3170, 2846, 2488, 2179, 1975, 1891, 1901, + 1956, 2008, 2027, 2015, 1996, 2006, 2073, 2203, + 2370, 2529, 2630, 2636, 2539, 2368, 2176, 2032, + 1989, 2070, 2251, 2471, 2649, 2712, 2622, 2385, + 2048, 1681, 1362, 1153, 1086, 1157, 1334, 1565, + 1803, 2019, 2207, 2378, 2545, 2706, 2837, 2892, + 2819, 2583, 2185, 1674, 1130, 653, 328, 216, + 337, 675, 1182, 1782, 2392, 2928, 3328, 3557, + 3606, 3490, 3229, 2845, 2359, 1803, 1223, 690, + 283, 77, 118, 409, 910, 1551, 2247, 2916, + 3483, 3886, 4077, 4031, 3750, 3266, 2640, 1948, + 1273, 689, 261, 35, 43, 291, 753, 1368, + 2048, 2691, 3210, 3550, 3691, 3645, 3437, 3096, + 2649, 2126, 1569, 1033, 587, 298, 216, 362, + 722, 1248, 1866, 2486, 3015, 3375, 3519, 3446, + 3200, 2855, 2490, 2166, 1911, 1723, 1584, 1478, + 1404, 1379, 1435, 1593, 1858, 2201, 2566, 2885, + 3090, 3140, 3027, 2785, 2480, 2196, 2006, 1951, + 2026, 2183, 2350, 2459, 2469, 2375, 2208, 2022, + 1871, 1793, 1798, 1865, 1955, 2028, 2061, 2057 + }, + { + 2048, 1736, 1511, 1423, 1476, 1630, 1822, 1987, + 2083, 2101, 2063, 2006, 1968, 1967, 2000, 2045, + 2073, 2061, 2011, 1944, 1899, 1908, 1981, 2099, + 2218, 2291, 2292, 2226, 2129, 2054, 2044, 2111, + 2237, 2375, 2471, 2480, 2385, 2198, 1962, 1735, + 1574, 1515, 1563, 1694, 1861, 2022, 2148, 2232, + 2282, 2305, 2299, 2254, 2154, 1996, 1798, 1599, + 1449, 1393, 1464, 1664, 1967, 2319, 2651, 2890, + 2979, 2896, 2660, 2325, 1964, 1648, 1430, 1334, + 1360, 1494, 1707, 1967, 2238, 2480, 2658, 2740, + 2709, 2561, 2310, 1987, 1639, 1327, 1114, 1056, + 1181, 1476, 1889, 2335, 2720, 2967, 3034, 2923, + 2673, 2345, 2010, 1727, 1537, 1455, 1475, 1580, + 1747, 1955, 2184, 2411, 2607, 2733, 2751, 2632, + 2378, 2025, 1643, 1320, 1132, 1123, 1287, 1573, + 1902, 2192, 2386, 2461, 2433, 2339, 2225, 2123, + 2048, 1993, 1946, 1898, 1854, 1834, 1865, 1966, + 2133, 2334, 2512, 2611, 2593, 2463, 2263, 2058, + 1913, 1862, 1902, 1996, 2088, 2130, 2099, 2001, + 1871, 1755, 1694, 1710, 1795, 1918, 2036, 2111, + 2130, 2104, 2062, 2034, 2032, 2044, 2044, 2008, + 1930, 1832, 1756, 1745, 1830, 2008, 2250, 2502, + 2700, 2790, 2741, 2556, 2273, 1955, 1672, 1483, + 1414, 1463, 1600, 1789, 1998, 2202, 2383, 2519, + 2590, 2574, 2460, 2253, 1979, 1682, 1414, 1233, + 1183, 1291, 1551, 1925, 2344, 2723, 2981, 3065, + 2964, 2707, 2356, 1983, 1656, 1424, 1315, 1335, + 1468, 1686, 1950, 2223, 2467, 2652, 2748, 2736, + 2601, 2347, 2004, 1624, 1283, 1058, 1009, 1154, + 1466, 1873, 2285, 2614, 2801, 2826, 2710, 2501, + 2259, 2036, 1862, 1751, 1697, 1692, 1733, 1822, + 1963, 2154, 2374, 2582, 2721, 2742, 2619, 2369 + }, + { + 2048, 2099, 2228, 2259, 1999, 1514, 1195, 1450, + 2280, 3163, 3424, 2780, 1605, 678, 618, 1447, + 2593, 3312, 3203, 2425, 1510, 990, 1120, 1807, + 2685, 3258, 3119, 2226, 1045, 353, 712, 2001, + 3423, 4031, 3396, 1899, 483, 41, 848, 2389, + 3692, 3949, 3033, 1544, 405, 291, 1255, 2722, + 3811, 3831, 2719, 1136, 90, 268, 1555, 3114, + 3964, 3614, 2324, 895, 183, 617, 1954, 3388, + 4020, 3424, 1949, 514, 27, 798, 2345, 3693, + 3997, 3089, 1590, 481, 425, 1338, 2538, 3274, + 3197, 2470, 1563, 978, 1033, 1728, 2698, 3356, + 3224, 2300, 1137, 500, 836, 1934, 3058, 3478, + 2986, 2018, 1282, 1194, 1621, 2108, 2314, 2242, + 2102, 2039, 2030, 2009, 2004, 2101, 2286, 2386, + 2222, 1832, 1496, 1506, 1876, 2312, 2478, 2313, + 2077, 2067, 2276, 2385, 2108, 1542, 1143, 1321, + 2048, 2836, 3127, 2729, 1951, 1338, 1247, 1633, + 2172, 2537, 2581, 2321, 1874, 1441, 1300, 1669, + 2465, 3215, 3317, 2530, 1269, 374, 507, 1646, + 3076, 3872, 3523, 2269, 928, 339, 820, 2008, + 3150, 3579, 3074, 1933, 812, 393, 1006, 2361, + 3636, 3973, 3084, 1503, 242, 106, 1176, 2779, + 3923, 3906, 2735, 1128, 88, 267, 1552, 3134, + 4033, 3701, 2345, 796, 14, 497, 1947, 3438, + 4019, 3364, 1958, 721, 380, 1054, 2279, 3324, + 3589, 2905, 1647, 566, 367, 1237, 2668, 3752, + 3780, 2721, 1257, 332, 511, 1607, 2838, 3413, + 3085, 2234, 1489, 1248, 1506, 2001, 2450, 2652, + 2503, 2030, 1460, 1167, 1432, 2176, 2932, 3161, + 2674, 1808, 1170, 1163, 1680, 2239, 2430, 2258, + 2059, 2108, 2334, 2426, 2195, 1777, 1510, 1606, + 1957, 2266, 2327, 2193, 2057, 2033, 2068, 2069 + }, + { + 2048, 2119, 2229, 2372, 2541, 2724, 2909, 3085, + 3240, 3368, 3466, 3533, 3571, 3581, 3566, 3529, + 3473, 3403, 3326, 3251, 3188, 3144, 3128, 3145, + 3195, 3276, 3382, 3503, 3628, 3747, 3850, 3932, + 3992, 4032, 4055, 4067, 4071, 4069, 4061, 4047, + 4025, 3996, 3965, 3934, 3910, 3898, 3902, 3922, + 3956, 3998, 4040, 4074, 4093, 4093, 4074, 4041, + 4002, 3964, 3935, 3920, 3921, 3936, 3961, 3991, + 4020, 4044, 4062, 4073, 4078, 4078, 4073, 4060, + 4035, 3994, 3932, 3848, 3744, 3626, 3504, 3389, + 3291, 3220, 3180, 3174, 3198, 3247, 3313, 3388, + 3462, 3527, 3577, 3607, 3615, 3598, 3553, 3479, + 3374, 3240, 3081, 2904, 2720, 2541, 2379, 2245, + 2146, 2087, 2069, 2088, 2140, 2218, 2311, 2410, + 2503, 2580, 2633, 2654, 2639, 2585, 2492, 2361, + 2199, 2014, 1817, 1619, 1435, 1273, 1142, 1045, + 984, 959, 967, 1005, 1067, 1148, 1238, 1328, + 1408, 1468, 1498, 1493, 1450, 1369, 1254, 1113, + 956, 796, 643, 508, 397, 311, 251, 214, + 196, 195, 211, 240, 283, 334, 391, 445, + 489, 515, 519, 496, 449, 380, 299, 215, + 137, 74, 31, 7, 0, 3, 10, 16, + 18, 14, 8, 2, 0, 2, 8, 16, + 23, 25, 22, 13, 4, 0, 7, 31, + 76, 139, 215, 296, 371, 432, 472, 486, + 476, 445, 398, 345, 291, 244, 207, 183, + 172, 177, 199, 241, 305, 395, 510, 648, + 800, 958, 1109, 1242, 1347, 1416, 1448, 1443, + 1404, 1338, 1255, 1164, 1077, 1002, 947, 918, + 919, 954, 1024, 1129, 1268, 1436, 1624, 1822, + 2017, 2197, 2351, 2472, 2554, 2597, 2602, 2571, + 2510, 2427, 2331, 2232, 2141, 2070, 2027, 2018 + }, + { + 2048, 2055, 2083, 2142, 2236, 2366, 2526, 2705, + 2891, 3068, 3227, 3358, 3455, 3515, 3537, 3522, + 3473, 3396, 3302, 3199, 3101, 3015, 2946, 2896, + 2859, 2827, 2789, 2734, 2652, 2541, 2399, 2232, + 2048, 1853, 1656, 1461, 1273, 1094, 929, 779, + 649, 541, 454, 384, 327, 277, 229, 182, + 139, 106, 93, 108, 158, 244, 363, 506, + 666, 832, 999, 1165, 1330, 1499, 1674, 1857, + 2048, 2243, 2440, 2635, 2825, 3005, 3173, 3324, + 3453, 3552, 3614, 3635, 3614, 3558, 3476, 3382, + 3291, 3215, 3159, 3125, 3110, 3105, 3100, 3084, + 3048, 2986, 2897, 2783, 2647, 2497, 2341, 2188, + 2048, 1931, 1846, 1799, 1790, 1815, 1863, 1922, + 1978, 2017, 2030, 2012, 1962, 1885, 1789, 1687, + 1592, 1517, 1473, 1467, 1501, 1574, 1678, 1805, + 1940, 2069, 2176, 2249, 2282, 2272, 2224, 2146, + 2048, 1941, 1837, 1745, 1672, 1623, 1598, 1591, + 1596, 1599, 1590, 1558, 1495, 1398, 1269, 1117, + 956, 802, 670, 575, 523, 516, 554, 630, + 738, 873, 1027, 1196, 1372, 1550, 1724, 1890, + 2048, 2198, 2346, 2498, 2659, 2833, 3019, 3210, + 3398, 3573, 3724, 3847, 3939, 4004, 4046, 4069, + 4078, 4071, 4048, 4005, 3939, 3852, 3743, 3618, + 3479, 3331, 3173, 3006, 2830, 2642, 2446, 2245, + 2048, 1860, 1690, 1539, 1406, 1286, 1172, 1057, + 936, 808, 676, 546, 425, 322, 242, 192, + 172, 186, 235, 319, 438, 590, 769, 965, + 1166, 1356, 1526, 1668, 1779, 1864, 1931, 1988, + 2048, 2117, 2202, 2304, 2419, 2541, 2659, 2764, + 2845, 2893, 2899, 2857, 2767, 2633, 2463, 2272, + 2078, 1899, 1750, 1642, 1579, 1563, 1587, 1643, + 1721, 1807, 1890, 1961, 2012, 2041, 2052, 2050 + }, + { + 2048, 2060, 2109, 2207, 2360, 2560, 2787, 3015, + 3217, 3368, 3451, 3458, 3391, 3257, 3067, 2840, + 2593, 2344, 2110, 1900, 1717, 1554, 1404, 1253, + 1093, 924, 753, 596, 475, 410, 418, 507, + 673, 905, 1189, 1509, 1849, 2196, 2537, 2858, + 3146, 3391, 3587, 3732, 3830, 3884, 3899, 3876, + 3811, 3695, 3524, 3294, 3012, 2689, 2345, 1999, + 1666, 1358, 1077, 824, 599, 404, 246, 133, + 75, 80, 151, 285, 478, 721, 1006, 1323, + 1660, 2000, 2324, 2612, 2847, 3019, 3127, 3181, + 3197, 3192, 3179, 3165, 3148, 3119, 3064, 2972, + 2833, 2647, 2419, 2162, 1894, 1634, 1404, 1223, + 1109, 1072, 1113, 1222, 1379, 1556, 1726, 1867, + 1965, 2019, 2035, 2029, 2021, 2027, 2060, 2127, + 2222, 2333, 2441, 2526, 2569, 2558, 2487, 2361, + 2197, 2016, 1849, 1723, 1659, 1666, 1742, 1876, + 2048, 2234, 2412, 2562, 2670, 2729, 2742, 2718, + 2674, 2627, 2591, 2574, 2575, 2583, 2581, 2548, + 2465, 2322, 2116, 1859, 1568, 1267, 977, 719, + 508, 354, 266, 245, 291, 396, 550, 737, + 945, 1165, 1394, 1634, 1891, 2170, 2472, 2790, + 3109, 3408, 3667, 3870, 4007, 4077, 4082, 4030, + 3923, 3765, 3559, 3306, 3013, 2689, 2347, 1998, + 1653, 1320, 1006, 719, 468, 266, 126, 61, + 76, 167, 322, 524, 752, 993, 1237, 1486, + 1741, 2008, 2289, 2582, 2875, 3157, 3411, 3623, + 3780, 3872, 3893, 3841, 3715, 3523, 3282, 3013, + 2740, 2489, 2276, 2107, 1979, 1879, 1791, 1699, + 1592, 1467, 1331, 1196, 1082, 1005, 980, 1015, + 1109, 1256, 1438, 1635, 1821, 1973, 2068, 2097, + 2059, 1967, 1844, 1713, 1601, 1526, 1499, 1525, + 1594, 1694, 1805, 1908, 1988, 2036, 2055, 2053 + }, + { + 2048, 2072, 2095, 2075, 2062, 2149, 2347, 2534, + 2584, 2527, 2537, 2732, 3017, 3166, 3074, 2884, + 2844, 3021, 3223, 3212, 2982, 2782, 2838, 3104, + 3321, 3317, 3206, 3252, 3548, 3896, 4028, 3910, + 3782, 3875, 4095, 4095, 4095, 3855, 3719, 3863, + 4080, 4065, 3759, 3424, 3355, 3556, 3739, 3649, + 3342, 3105, 3136, 3332, 3412, 3231, 2919, 2715, + 2707, 2768, 2724, 2551, 2362, 2259, 2219, 2157, + 2048, 1944, 1881, 1811, 1665, 1473, 1350, 1361, + 1417, 1359, 1150, 949, 947, 1145, 1329, 1300, + 1095, 955, 1044, 1254, 1316, 1103, 782, 627, + 713, 835, 759, 498, 306, 386, 653, 834, + 792, 690, 804, 1192, 1608, 1771, 1678, 1603, + 1778, 2118, 2309, 2159, 1822, 1629, 1734, 1954, + 1990, 1762, 1493, 1456, 1681, 1943, 2022, 1925, + 1847, 1930, 2119, 2249, 2238, 2153, 2095, 2080, + 2048, 1973, 1912, 1915, 1938, 1892, 1763, 1668, + 1723, 1885, 1968, 1842, 1593, 1438, 1481, 1578, + 1487, 1150, 775, 614, 689, 765, 627, 325, + 123, 191, 407, 501, 366, 185, 212, 466, + 698, 671, 436, 273, 366, 584, 630, 389, + 77, 8, 248, 539, 586, 384, 215, 329, + 667, 935, 929, 753, 682, 863, 1169, 1364, + 1361, 1292, 1331, 1505, 1700, 1812, 1863, 1934, + 2048, 2147, 2196, 2244, 2360, 2521, 2615, 2582, + 2519, 2589, 2834, 3096, 3182, 3084, 3009, 3147, + 3446, 3657, 3604, 3387, 3271, 3380, 3552, 3521, + 3228, 2893, 2770, 2865, 2939, 2800, 2540, 2436, + 2621, 2923, 3052, 2930, 2780, 2860, 3153, 3370, + 3268, 2930, 2671, 2689, 2844, 2820, 2484, 2039, + 1804, 1875, 2038, 2026, 1804, 1593, 1602, 1812, + 2013, 2049, 1961, 1906, 1958, 2053, 2091, 2066 + }, + { + 2048, 2070, 2146, 2287, 2483, 2702, 2900, 3027, + 3040, 2918, 2664, 2307, 1895, 1485, 1132, 876, + 736, 714, 794, 950, 1160, 1403, 1672, 1964, + 2279, 2614, 2955, 3279, 3551, 3731, 3784, 3687, + 3434, 3043, 2547, 1997, 1446, 948, 545, 265, + 123, 122, 252, 500, 850, 1280, 1768, 2284, + 2795, 3265, 3654, 3930, 4065, 4046, 3875, 3567, + 3152, 2664, 2143, 1626, 1146, 731, 405, 187, + 94, 136, 319, 637, 1073, 1592, 2150, 2693, + 3169, 3530, 3746, 3807, 3720, 3514, 3223, 2886, + 2537, 2196, 1875, 1578, 1306, 1063, 862, 723, + 671, 729, 908, 1201, 1584, 2009, 2421, 2763, + 2992, 3084, 3043, 2896, 2687, 2466, 2275, 2142, + 2070, 2044, 2037, 2021, 1974, 1892, 1789, 1690, + 1628, 1627, 1697, 1828, 1989, 2140, 2238, 2252, + 2173, 2016, 1819, 1633, 1508, 1484, 1577, 1776, + 2048, 2343, 2610, 2807, 2911, 2919, 2849, 2726, + 2581, 2434, 2291, 2147, 1986, 1794, 1565, 1306, + 1043, 816, 670, 645, 766, 1034, 1430, 1909, + 2417, 2895, 3293, 3576, 3726, 3744, 3643, 3442, + 3162, 2819, 2430, 2008, 1570, 1139, 742, 413, + 189, 97, 158, 374, 732, 1201, 1741, 2303, + 2842, 3316, 3692, 3947, 4067, 4047, 3887, 3596, + 3191, 2697, 2150, 1590, 1066, 621, 297, 117, + 94, 220, 475, 826, 1240, 1683, 2127, 2551, + 2937, 3270, 3535, 3711, 3780, 3723, 3531, 3209, + 2779, 2282, 1770, 1302, 930, 693, 608, 664, + 834, 1076, 1345, 1606, 1836, 2031, 2199, 2355, + 2509, 2665, 2811, 2922, 2971, 2931, 2792, 2562, + 2271, 1966, 1698, 1514, 1444, 1491, 1632, 1826, + 2020, 2164, 2228, 2200, 2097, 1953, 1809, 1705, + 1663, 1689, 1767, 1869, 1964, 2029, 2055, 2053 + }, + { + 2048, 2561, 2882, 1925, 1133, 2097, 3797, 4088, + 2776, 1767, 2291, 3280, 3257, 2487, 2059, 2126, + 2101, 1630, 1064, 1182, 1941, 2104, 1196, 546, + 1140, 2073, 2181, 1769, 1821, 2365, 2600, 2511, + 2925, 3644, 3507, 2704, 2607, 3268, 3505, 3065, + 2629, 2418, 2195, 2003, 2003, 1859, 1066, 110, + 157, 1030, 1220, 450, 80, 694, 1448, 1721, + 1786, 2100, 2633, 2799, 2270, 1758, 2203, 3394, + 4094, 3495, 2357, 2200, 3036, 3279, 2512, 2047, + 2132, 1482, 103, 0, 966, 2027, 1434, 250, + 475, 1883, 2525, 1973, 1589, 1913, 2175, 1995, + 1842, 2221, 3014, 3437, 3043, 2581, 2900, 3549, + 3502, 2694, 2013, 1982, 2001, 1505, 1262, 2009, + 2685, 2173, 1503, 2031, 3013, 2982, 2080, 1531, + 1740, 2035, 2040, 2150, 2357, 2095, 1711, 2170, + 3093, 3197, 2417, 1724, 1547, 1653, 1797, 1905, + 2048, 2242, 2334, 2300, 2332, 2628, 3225, 3649, + 3156, 2071, 1676, 2141, 2380, 2129, 2035, 2014, + 1542, 1048, 1384, 2197, 2109, 877, 120, 825, + 1656, 1357, 856, 1254, 1923, 2056, 2093, 2657, + 3405, 3542, 2994, 2621, 2942, 3334, 3120, 2552, + 2206, 2220, 2250, 1874, 1385, 1543, 1973, 1423, + 198, 29, 1125, 1695, 806, 0, 263, 1560, + 2130, 2050, 2522, 3231, 2971, 2280, 2656, 3851, + 4095, 3374, 2153, 1810, 2357, 2798, 2562, 2088, + 1879, 1846, 1581, 940, 509, 921, 1484, 1011, + 31, 79, 1132, 1898, 1978, 1988, 2205, 2327, + 2334, 2625, 3035, 2727, 1825, 1636, 2371, 2727, + 2323, 2121, 2341, 2265, 1886, 1866, 2171, 1986, + 1120, 626, 1239, 2015, 1854, 1326, 1485, 2132, + 2467, 2287, 2008, 2142, 2522, 2233, 1167, 733, + 1793, 3076, 2860, 1469, 909, 1947, 2928, 2560 + }, + { + 2048, 2504, 2795, 1937, 1211, 2093, 3713, 4049, + 2790, 1746, 2327, 3617, 3862, 2964, 2133, 1958, + 2048, 1906, 1540, 1495, 1969, 2095, 1253, 469, + 957, 2084, 2288, 1309, 413, 609, 1420, 1878, + 2048, 2416, 2641, 2415, 2445, 3116, 3618, 3425, + 3094, 3057, 2976, 2556, 2157, 2260, 2607, 2510, + 2048, 1846, 1730, 1126, 470, 562, 1118, 1256, + 707, 0, 0, 657, 1800, 2252, 1982, 1778, + 2048, 2337, 2178, 2155, 3149, 4095, 3814, 2019, + 1613, 3417, 4095, 4095, 2914, 2060, 2283, 2403, + 2048, 2008, 2319, 1963, 931, 522, 1245, 2190, + 2418, 1813, 1007, 831, 1340, 1749, 1701, 1701, + 2048, 2283, 2008, 1749, 2382, 3485, 3459, 2102, + 1281, 1916, 2557, 2061, 1334, 1451, 2031, 2222, + 2048, 2033, 2105, 1834, 1584, 1987, 2435, 1916, + 981, 920, 1695, 2348, 2505, 2404, 2271, 2175, + 2048, 1874, 1791, 1820, 1787, 1507, 926, 477, + 918, 2022, 2475, 1928, 1548, 1878, 2145, 2009, + 2048, 2386, 2390, 1952, 2002, 3023, 3848, 3333, + 2518, 3030, 4095, 4095, 2947, 2084, 2100, 2270, + 2048, 1702, 1663, 1726, 1412, 921, 893, 1364, + 1762, 1577, 771, 85, 433, 1479, 2005, 1899, + 2048, 2447, 2401, 2251, 3043, 4095, 4095, 3226, + 1627, 2142, 3851, 4095, 3076, 2212, 2305, 2408, + 2048, 1782, 2003, 2215, 1703, 660, 90, 449, + 1182, 1559, 1324, 832, 814, 1398, 1831, 1842, + 2048, 2517, 2569, 2216, 2218, 2717, 3036, 2810, + 2563, 2830, 3111, 2643, 1890, 1817, 2179, 2205, + 2048, 2021, 1715, 1061, 879, 1567, 2270, 1959, + 932, 554, 1292, 2021, 1905, 1587, 1757, 2076, + 2048, 1774, 1737, 2244, 2760, 2283, 1035, 637, + 1788, 3057, 2821, 1509, 1006, 1957, 2836, 2504 + }, + { + 2048, 2448, 2705, 1949, 1297, 2089, 3594, 3952, + 2776, 1740, 2347, 3840, 4095, 3348, 2198, 1801, + 1994, 2206, 2113, 1926, 2015, 2073, 1535, 882, + 1140, 2082, 2300, 1162, 0, 0, 565, 1339, + 1170, 960, 1385, 1871, 1992, 2142, 2460, 2617, + 2629, 2757, 2854, 2594, 2196, 2427, 3507, 4095, + 3938, 2920, 2662, 3067, 3099, 2608, 2195, 2028, + 1786, 1282, 808, 955, 1777, 2367, 1886, 688, + 1, 586, 1725, 1880, 843, 258, 1065, 2058, + 2132, 2013, 2527, 3003, 2625, 2061, 2503, 3589, + 3621, 2244, 1338, 2198, 3558, 3686, 2746, 1947, + 1842, 2145, 2321, 2155, 1950, 1904, 1660, 1024, + 593, 1060, 2140, 2565, 1577, 323, 565, 1997, + 2685, 2145, 1719, 2040, 2341, 2179, 2045, 2244, + 2355, 2087, 1946, 2350, 2626, 2116, 1633, 2182, + 3093, 3120, 2374, 1774, 1637, 1732, 1850, 1936, + 2048, 2199, 2274, 2250, 2281, 2539, 3089, 3542, + 3156, 2073, 1590, 2184, 2670, 2289, 1876, 2152, + 2553, 2428, 2091, 2069, 2066, 1520, 887, 1098, + 1656, 1132, 0, 0, 782, 1984, 1924, 1117, + 690, 1029, 1618, 1893, 1959, 2147, 2351, 2330, + 2206, 2379, 3157, 4095, 4095, 3062, 2159, 2793, + 3897, 3778, 2732, 2273, 2711, 2971, 2487, 2018, + 2130, 2013, 1044, 328, 923, 1791, 1414, 226, + 0, 708, 1938, 2310, 1670, 958, 958, 1461, + 1879, 2035, 2162, 2506, 2870, 2767, 2466, 2936, + 4064, 4095, 3409, 2348, 2278, 2767, 2907, 2584, + 2334, 2371, 2327, 2100, 2069, 2158, 1901, 1584, + 1772, 1935, 1261, 335, 403, 1472, 2281, 1965, + 1120, 944, 1561, 2033, 1989, 1946, 2085, 2015, + 1628, 1297, 1503, 2326, 2936, 2317, 964, 610, + 1793, 3007, 2766, 1557, 1113, 1967, 2741, 2447 + }, + { + 2048, 2391, 2614, 1962, 1390, 2084, 3441, 3798, + 2733, 1749, 2349, 3933, 4095, 3601, 2245, 1678, + 1949, 2480, 2673, 2383, 2069, 2045, 1963, 1657, + 1630, 2067, 2213, 1389, 126, 0, 478, 1190, + 807, 179, 564, 1450, 1580, 1095, 969, 1325, + 1647, 1798, 1949, 2078, 2078, 2176, 2736, 3459, + 3495, 2877, 2778, 3608, 4095, 3832, 3049, 2830, + 3286, 3873, 3912, 3170, 2242, 1891, 2097, 2250, + 2048, 1830, 1948, 1965, 1182, 208, 570, 2072, + 2449, 693, 0, 0, 845, 2027, 1506, 582, + 844, 1928, 2383, 1996, 1740, 1958, 2133, 2012, + 1906, 2171, 2762, 3132, 2879, 2533, 2914, 3805, + 4095, 3243, 1950, 1562, 2441, 3329, 3017, 2076, + 1754, 2015, 2102, 2047, 2244, 2409, 2068, 1514, + 1479, 1988, 2180, 1686, 1404, 1975, 2465, 1917, + 1062, 1061, 1753, 2291, 2407, 2322, 2217, 2143, + 2048, 1917, 1853, 1872, 1843, 1611, 1109, 674, + 1004, 2023, 2508, 1904, 1355, 1759, 2273, 1890, + 1114, 1014, 1626, 2105, 2060, 1990, 2239, 2366, + 2228, 2562, 3518, 3922, 3105, 2107, 2178, 3174, + 3968, 3797, 3010, 2570, 2795, 3051, 2841, 2406, + 2157, 2164, 2183, 1932, 1602, 1703, 1995, 1593, + 632, 402, 1233, 1703, 667, 0, 0, 882, + 2436, 1965, 539, 279, 1239, 1921, 1852, 1776, + 2048, 2247, 2081, 1919, 2319, 3168, 3686, 3445, + 2847, 2530, 2827, 3508, 3758, 3148, 2545, 2893, + 3591, 3482, 2690, 2150, 2095, 2087, 1943, 1859, + 1850, 1637, 1317, 1517, 2233, 2422, 1719, 1252, + 1659, 1911, 1215, 442, 674, 1620, 2200, 2001, + 1621, 1677, 1967, 2049, 2087, 2327, 2405, 1960, + 1272, 921, 1332, 2380, 3036, 2331, 957, 652, + 1807, 2930, 2695, 1612, 1229, 1978, 2645, 2391 + }, + { + 2048, 2334, 2522, 1976, 1490, 2079, 3258, 3593, + 2665, 1773, 2333, 3889, 4095, 3697, 2269, 1604, + 1919, 2679, 3113, 2768, 2118, 2017, 2415, 2552, + 2260, 2045, 2060, 1896, 1377, 998, 1204, 1514, + 1170, 558, 718, 1443, 1509, 781, 350, 647, + 1021, 1071, 1139, 1531, 1928, 1784, 1177, 880, + 1264, 1772, 1926, 2007, 2266, 2439, 2386, 2410, + 2792, 3438, 3834, 3414, 2357, 1705, 2214, 3417, + 4094, 3520, 2379, 2228, 3421, 4095, 3464, 2029, + 1806, 2675, 3147, 2715, 2168, 2047, 1957, 1561, + 1396, 1948, 2471, 1943, 827, 498, 1262, 2186, + 2411, 1809, 922, 606, 1091, 1557, 1271, 647, + 593, 1304, 2100, 2265, 1910, 1752, 1973, 2052, + 1898, 2005, 2283, 2056, 1407, 1270, 2012, 2828, + 2791, 2119, 1898, 2432, 2701, 2118, 1653, 2168, + 2934, 2918, 2303, 1839, 1742, 1817, 1905, 1968, + 2048, 2156, 2211, 2195, 2221, 2422, 2863, 3260, + 2987, 2070, 1612, 2188, 2750, 2353, 1795, 2236, + 3268, 3558, 2766, 1923, 2007, 2675, 2881, 2459, + 2139, 2121, 1934, 1615, 1678, 2021, 1977, 1347, + 690, 653, 1185, 1519, 1188, 713, 799, 1352, + 1768, 1592, 799, 53, 282, 1342, 1981, 1671, + 1281, 1501, 1912, 2039, 2186, 2693, 3057, 2588, + 1814, 2110, 3494, 4095, 3331, 2323, 2700, 3882, + 4095, 3396, 2161, 1766, 2478, 3411, 3618, 3112, + 2529, 2271, 2311, 2368, 2218, 2019, 1965, 1767, + 1212, 861, 1236, 1839, 1861, 1367, 1080, 1309, + 1542, 1252, 897, 1342, 2261, 2426, 1753, 1413, + 1772, 1963, 1600, 1328, 1568, 1949, 2059, 2054, + 2265, 2525, 2397, 2065, 2176, 2648, 2657, 1920, + 1034, 696, 1245, 2400, 3050, 2324, 1016, 763, + 1831, 2827, 2610, 1674, 1353, 1989, 2548, 2334 + }, + { + 2048, 2277, 2428, 1990, 1595, 2073, 3049, 3342, + 2572, 1810, 2299, 3712, 4095, 3626, 2267, 1589, + 1909, 2769, 3349, 2999, 2150, 1997, 2763, 3291, + 2819, 2024, 1903, 2466, 2932, 2799, 2368, 2132, + 2048, 1862, 1745, 1856, 1832, 1442, 1103, 1156, + 1308, 1252, 1212, 1508, 1905, 1682, 615, 0, + 1, 1020, 1235, 461, 0, 472, 1211, 1424, + 1100, 697, 708, 1259, 1913, 2154, 2014, 1912, + 2048, 2193, 2114, 2104, 2644, 3339, 3110, 2029, + 1740, 3127, 4095, 4095, 3180, 2068, 2650, 3863, + 3750, 2248, 1351, 2193, 3506, 3666, 2770, 1935, + 1786, 2199, 2674, 2737, 2430, 2203, 2224, 2222, + 2048, 1929, 2068, 2203, 1867, 1232, 1199, 2013, + 2590, 2151, 1589, 2033, 2980, 3075, 2091, 1155, + 1243, 1973, 2195, 1680, 1441, 1984, 2396, 1944, + 1293, 1318, 1836, 2218, 2295, 2234, 2162, 2111, + 2048, 1960, 1917, 1928, 1907, 1741, 1373, 1032, + 1249, 2028, 2432, 1921, 1395, 1755, 2298, 1853, + 727, 320, 1170, 2212, 2107, 1013, 427, 1035, + 1715, 1412, 760, 855, 1561, 2029, 2021, 1936, + 2048, 2221, 2244, 2215, 2391, 2686, 2742, 2490, + 2249, 2419, 3196, 4095, 4095, 3026, 2157, 2808, + 4050, 4086, 2953, 2398, 3348, 4095, 4095, 2977, + 1750, 2109, 3132, 3289, 2604, 2133, 2179, 2229, + 2048, 1914, 2025, 2135, 1861, 1261, 870, 1014, + 1435, 1663, 1397, 758, 436, 929, 1494, 1001, + 0, 0, 711, 1758, 1825, 1337, 1158, 1447, + 1683, 1541, 1408, 1710, 2133, 2168, 1981, 1969, + 2048, 2061, 2217, 2563, 2680, 2320, 1914, 2105, + 2836, 3225, 2727, 2076, 2234, 2841, 2792, 1901, + 951, 652, 1252, 2385, 2978, 2298, 1136, 936, + 1864, 2700, 2513, 1742, 1484, 2000, 2449, 2277 + }, + { + 2048, 2220, 2334, 2004, 1704, 2067, 2818, 3053, + 2460, 1858, 2251, 3414, 4031, 3396, 2240, 1636, + 1919, 2736, 3335, 3028, 2158, 1991, 2907, 3645, + 3117, 2011, 1802, 2860, 4086, 4095, 3365, 2704, + 2925, 3282, 2971, 2401, 2313, 2568, 2620, 2422, + 2252, 2173, 2097, 2033, 2032, 1982, 1693, 1304, + 1264, 1583, 1622, 1093, 632, 815, 1302, 1412, + 933, 196, 0, 488, 1712, 2406, 1877, 671, + 1, 568, 1709, 1859, 557, 0, 319, 2073, + 2409, 947, 0, 0, 1270, 2035, 1732, 1227, + 1396, 1984, 2220, 2022, 1893, 2003, 2090, 2030, + 1975, 2111, 2427, 2640, 2519, 2335, 2587, 3208, + 3502, 2962, 1965, 1594, 2464, 3628, 3486, 2101, + 1295, 1914, 2598, 2064, 1043, 989, 2005, 2899, + 2791, 2114, 1918, 2362, 2555, 2100, 1766, 2130, + 2640, 2614, 2210, 1917, 1860, 1907, 1962, 2000, + 2048, 2113, 2146, 2137, 2154, 2281, 2567, 2837, + 2675, 2063, 1737, 2152, 2593, 2298, 1828, 2222, + 3268, 3696, 2916, 1879, 1984, 3221, 3994, 3348, + 2509, 3013, 4095, 4095, 3169, 2103, 2157, 2910, + 3405, 3203, 2647, 2357, 2471, 2597, 2469, 2233, + 2103, 2106, 2115, 1990, 1824, 1873, 2020, 1808, + 1281, 1126, 1573, 1837, 1154, 17, 0, 1100, + 2397, 1964, 283, 0, 655, 1759, 1382, 204, + 0, 692, 1932, 2342, 1581, 491, 132, 630, + 1328, 1655, 1467, 1039, 941, 1374, 1757, 1575, + 1212, 1292, 1716, 1996, 2024, 2028, 2100, 2143, + 2148, 2260, 2435, 2338, 1942, 1826, 2252, 2573, + 2323, 2152, 2746, 3548, 3505, 2575, 1821, 2134, + 3142, 3559, 2864, 2080, 2248, 2864, 2784, 1908, + 1034, 795, 1352, 2336, 2826, 2253, 1312, 1163, + 1903, 2555, 2406, 1814, 1620, 2012, 2350, 2220 + }, + { + 2048, 2162, 2239, 2018, 1817, 2061, 2571, 2735, + 2332, 1916, 2190, 3018, 3473, 3030, 2190, 1738, + 1949, 2585, 3073, 2846, 2140, 1999, 2806, 3502, + 3055, 2012, 1798, 2909, 4095, 4095, 3680, 2913, + 3288, 3935, 3590, 2702, 2599, 3294, 3674, 3370, + 3014, 2978, 2933, 2572, 2176, 2355, 3177, 3803, + 3495, 2741, 2573, 3035, 3287, 2966, 2522, 2392, + 2561, 2764, 2748, 2454, 2116, 1994, 2064, 2115, + 2048, 1975, 2014, 2019, 1744, 1382, 1493, 2057, + 2214, 1451, 509, 482, 1366, 2035, 1658, 822, + 844, 1898, 2597, 1926, 735, 474, 1281, 2179, + 2390, 1822, 969, 628, 1067, 1516, 1146, 273, + 0, 841, 2149, 2578, 1584, 370, 585, 1996, + 2756, 2169, 1562, 2033, 2887, 2910, 2081, 1383, + 1479, 1997, 2143, 1819, 1683, 2010, 2245, 1990, + 1639, 1660, 1937, 2135, 2174, 2142, 2105, 2080, + 2048, 2004, 1982, 1987, 1976, 1890, 1695, 1508, + 1615, 2037, 2265, 1974, 1655, 1865, 2210, 1916, + 1114, 762, 1356, 2185, 2101, 1041, 329, 863, + 1613, 1105, 0, 0, 800, 1983, 1912, 910, + 127, 281, 1047, 1476, 1166, 733, 851, 1391, + 1784, 1613, 829, 23, 149, 1226, 1961, 1482, + 632, 672, 1462, 1829, 1265, 533, 635, 1534, + 2209, 2015, 1481, 1408, 1764, 2004, 1982, 1957, + 2048, 2114, 2059, 2003, 2143, 2453, 2663, 2596, + 2379, 2260, 2417, 2799, 3016, 2744, 2406, 2754, + 3591, 3831, 3101, 2291, 2248, 2738, 2991, 2750, + 2524, 2799, 3150, 2742, 1829, 1638, 2389, 2851, + 2436, 2185, 2913, 3805, 3668, 2608, 1817, 2132, + 3078, 3425, 2768, 2075, 2215, 2713, 2634, 1939, + 1272, 1106, 1533, 2258, 2607, 2193, 1531, 1433, + 1948, 2394, 2291, 1890, 1760, 2024, 2249, 2162 + }, + { + 2048, 2105, 2143, 2033, 1932, 2054, 2312, 2396, + 2192, 1980, 2121, 2551, 2793, 2565, 2123, 1882, + 1994, 2341, 2615, 2495, 2100, 2020, 2490, 2908, + 2654, 2026, 1892, 2594, 3514, 3739, 3149, 2645, + 2925, 3416, 3196, 2548, 2482, 3061, 3413, 3196, + 2917, 2917, 2909, 2579, 2184, 2389, 3368, 4095, + 3938, 3011, 2828, 3622, 4095, 3770, 3023, 2835, + 3362, 4095, 4095, 3707, 2396, 1681, 2219, 3427, + 4094, 3530, 2389, 2240, 3598, 4095, 3939, 2019, + 1621, 3410, 4095, 4095, 3221, 2068, 2626, 3750, + 3621, 2232, 1405, 2183, 3439, 3644, 2793, 1924, + 1740, 2243, 2953, 3201, 2820, 2454, 2719, 3335, + 3502, 2881, 1979, 1697, 2347, 3111, 2958, 2079, + 1621, 1976, 2331, 2056, 1572, 1565, 2029, 2411, + 2355, 2074, 1997, 2168, 2238, 2067, 1946, 2077, + 2256, 2244, 2103, 2003, 1984, 2000, 2019, 2032, + 2048, 2069, 2080, 2078, 2084, 2127, 2226, 2321, + 2268, 2053, 1935, 2086, 2252, 2144, 1961, 2118, + 2553, 2751, 2430, 1970, 2017, 2626, 3049, 2749, + 2309, 2624, 3428, 3604, 2854, 2090, 2139, 2833, + 3405, 3329, 2793, 2485, 2742, 3116, 3052, 2617, + 2285, 2453, 3232, 4095, 4062, 2961, 2148, 2746, + 3897, 3959, 2917, 2395, 3395, 4095, 4095, 3220, + 1635, 2142, 3978, 4095, 3496, 2342, 2719, 3896, + 4095, 3406, 2164, 1747, 2533, 3703, 4095, 3653, + 2897, 2533, 2807, 3457, 3716, 3158, 2579, 3029, + 4064, 4095, 3279, 2318, 2260, 2748, 2965, 2704, + 2476, 2700, 2973, 2612, 1875, 1734, 2302, 2630, + 2323, 2143, 2632, 3208, 3096, 2403, 1904, 2099, + 2667, 2862, 2468, 2063, 2143, 2420, 2372, 1988, + 1628, 1543, 1774, 2158, 2340, 2123, 1781, 1732, + 1997, 2223, 2170, 1968, 1903, 2036, 2149, 2105 + }, + { + 2048, 2081, 2108, 2062, 2033, 2108, 2213, 2231, + 2171, 2169, 2313, 2495, 2523, 2399, 2282, 2198, + 2086, 2082, 2304, 2509, 2430, 2273, 2364, 2557, + 2495, 2238, 2211, 2647, 3262, 3494, 3182, 2884, + 3081, 3340, 3015, 2465, 2546, 3166, 3465, 3191, + 2875, 2836, 2831, 2605, 2347, 2539, 3295, 3937, + 3765, 3197, 3214, 3747, 3836, 3319, 3028, 3351, + 3799, 3942, 3782, 3381, 2828, 2390, 2345, 2780, + 3431, 3666, 3188, 2747, 3186, 3917, 3676, 2669, + 2404, 3379, 4095, 4095, 3542, 2912, 2971, 3195, + 2856, 2177, 2097, 2766, 3226, 2929, 2452, 2338, + 2369, 2329, 2435, 2739, 2953, 2972, 2976, 3055, + 3070, 2820, 2318, 1989, 2255, 2794, 2819, 2258, + 1859, 1983, 2135, 1924, 1650, 1723, 2062, 2302, + 2263, 2109, 2092, 2194, 2176, 2011, 1965, 2133, + 2271, 2208, 2073, 2013, 2010, 2007, 2008, 2025, + 2048, 2062, 2073, 2093, 2113, 2126, 2178, 2283, + 2302, 2132, 1953, 2000, 2163, 2178, 2096, 2181, + 2443, 2593, 2437, 2158, 2152, 2515, 2813, 2693, + 2533, 2857, 3355, 3288, 2694, 2318, 2490, 2851, + 3034, 3022, 2962, 2951, 2919, 2748, 2575, 2643, + 2816, 2840, 2969, 3484, 3859, 3453, 2747, 2699, + 3236, 3489, 3234, 3128, 3642, 4095, 4095, 3247, + 2351, 2675, 3676, 3893, 3199, 2870, 3422, 3924, + 3615, 2867, 2387, 2435, 2850, 3295, 3533, 3569, + 3399, 2991, 2695, 2959, 3443, 3394, 2993, 3131, + 3787, 3963, 3300, 2558, 2412, 2676, 2811, 2651, + 2532, 2756, 2984, 2622, 1895, 1703, 2209, 2582, + 2419, 2303, 2653, 3027, 2911, 2454, 2158, 2257, + 2522, 2573, 2384, 2295, 2416, 2406, 2088, 1777, + 1737, 1830, 1894, 1984, 2097, 2096, 1974, 1898, + 1956, 2060, 2088, 2032, 2001, 2056, 2110, 2082 + }, + { + 2048, 1781, 1533, 1328, 1188, 1124, 1143, 1240, + 1403, 1614, 1851, 2091, 2309, 2484, 2597, 2633, + 2583, 2447, 2234, 1964, 1663, 1365, 1105, 912, + 811, 812, 918, 1116, 1384, 1696, 2022, 2334, + 2610, 2832, 2990, 3078, 3096, 3046, 2937, 2779, + 2588, 2381, 2175, 1988, 1831, 1709, 1621, 1557, + 1503, 1443, 1361, 1248, 1094, 899, 665, 395, + 95, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 166, 384, 583, 766, + 938, 1107, 1283, 1476, 1697, 1953, 2250, 2587, + 2956, 3344, 3735, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 3719, 3312, 2947, 2640, 2399, 2226, 2113, + 2048, 2012, 1986, 1950, 1884, 1773, 1608, 1389, + 1126, 836, 546, 284, 83, 0, 0, 59, + 274, 587, 976, 1413, 1868, 2312, 2719, 3070, + 3346, 3538, 3638, 3645, 3564, 3409, 3198, 2956, + 2709, 2483, 2299, 2168, 2094, 2069, 2080, 2107, + 2131, 2132, 2096, 2015, 1884, 1704, 1477, 1212, + 917, 605, 291, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 195, 562, 935, 1298, 1639, 1951, 2228, 2469, + 2677, 2855, 3015, 3168, 3329, 3511, 3729, 3991, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 3769, 3464, 3233, 3077, 2987, 2951, + 2950, 2961, 2963, 2934, 2858, 2727, 2540, 2308 + }, + { + 2048, 1952, 1949, 1768, 1386, 1123, 1378, 2211, + 3175, 3594, 3098, 1985, 1073, 1108, 2177, 3602, + 4095, 4052, 2791, 1493, 964, 1374, 2192, 2654, + 2372, 1590, 934, 876, 1388, 2030, 2357, 2278, + 2048, 1963, 2047, 2045, 1726, 1193, 892, 1244, + 2221, 3244, 3550, 2777, 1292, 0, 0, 118, + 983, 1287, 636, 0, 0, 0, 0, 779, + 1546, 1488, 916, 452, 518, 1050, 1650, 1981, + 2048, 2115, 2382, 2741, 2875, 2608, 2181, 2155, + 2966, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 3621, 2562, 2500, 3327, + 4095, 4095, 4095, 3627, 2872, 2516, 2453, 2357, + 2048, 1668, 1511, 1672, 1890, 1743, 1060, 167, + 0, 121, 1263, 2408, 2778, 2135, 981, 181, + 286, 1100, 1823, 1683, 543, 0, 0, 0, + 0, 565, 1406, 1588, 1422, 1356, 1574, 1898, + 2048, 1971, 1925, 2214, 2846, 3444, 3531, 2971, + 2159, 1763, 2181, 3173, 3984, 3916, 2897, 1582, + 883, 1282, 2447, 3481, 3584, 2644, 1282, 365, + 373, 1108, 1940, 2337, 2229, 1947, 1840, 1956, + 2048, 1886, 1553, 1420, 1810, 2663, 3513, 3854, + 3587, 3151, 3191, 3999, 4095, 4095, 4095, 4095, + 3032, 2330, 2796, 4021, 4095, 4095, 4095, 3178, + 2396, 2381, 2873, 3295, 3253, 2807, 2325, 2091, + 2048, 1899, 1453, 865, 538, 744, 1328, 1772, + 1624, 918, 212, 166, 965, 2085, 2614, 1931, + 204, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 808, 1588, 1863, 1805, 1795, + 2048, 2419, 2597, 2452, 2221, 2322, 2954, 3842, + 4095, 4095, 3540, 2958, 3201, 4095, 4095, 4095, + 4095, 4095, 3278, 2418, 2608, 3384, 3934, 3743, + 2950, 2165, 1934, 2315, 2887, 3143, 2906, 2416 + }, + { + 2048, 2249, 2630, 3002, 3260, 3501, 3941, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4049, 4012, 4008, 3770, 3277, 2720, 2299, + 2048, 1828, 1484, 998, 506, 139, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 970, 2325, 2665, 2012, 1093, + 817, 1633, 3210, 4095, 4095, 4095, 3150, 1878, + 1285, 1384, 1706, 1717, 1236, 549, 159, 400, + 1194, 2129, 2764, 2912, 2708, 2426, 2253, 2169, + 2048, 1826, 1593, 1502, 1589, 1683, 1506, 908, + 47, 0, 0, 0, 0, 102, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 276, 753, 1285, 1720, + 2048, 2395, 2870, 3414, 3810, 3864, 3601, 3308, + 3340, 3843, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 3704, 3989, 4095, + 4095, 4095, 4095, 4051, 2637, 2334, 3235, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 3282, 2286, 2136, 2589, 3105, 3255, + 2981, 2548, 2276, 2280, 2418, 2463, 2320, 2109 + }, + { + 2048, 1981, 2022, 2010, 1837, 1586, 1497, 1768, + 2349, 2925, 3133, 2858, 2376, 2189, 2660, 3701, + 4095, 4095, 4095, 3995, 3304, 3429, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 3832, 3750, 3782, 3652, 3274, 2774, 2342, + 2048, 1790, 1424, 922, 427, 127, 60, 23, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 0, 0, 0, + 0, 0, 22, 745, 854, 467, 36, 0, + 431, 1118, 1677, 1894, 1833, 1725, 1753, 1908, + 2048, 2060, 1990, 1997, 2183, 2459, 2576, 2336, + 1788, 1254, 1108, 1472, 2077, 2413, 2102, 1214, + 260, 0, 244, 1107, 1727, 1510, 430, 0, + 0, 0, 0, 788, 1040, 227, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 40, 66, 241, 660, 1203, 1688, + 2048, 2376, 2811, 3365, 3880, 4095, 4095, 4066, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 3805, 3597, 3930, 4095, 4095, + 4026, 3378, 2835, 2600, 2608, 2634, 2512, 2264 + }, + { + 2048, 1979, 2009, 1964, 1767, 1541, 1505, 1758, + 2132, 2275, 1927, 1182, 498, 415, 1153, 2399, + 3472, 3777, 3230, 2333, 1819, 2110, 2990, 3747, + 3706, 2764, 1532, 945, 1611, 3353, 4095, 4095, + 4095, 4095, 3789, 3389, 3945, 4095, 4095, 4095, + 3758, 2753, 2668, 3694, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4055, 3294, + 2817, 2815, 3125, 3395, 3363, 3026, 2587, 2249, + 2048, 1864, 1579, 1221, 950, 892, 965, 883, + 359, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 25, 0, 0, 0, + 0, 0, 272, 531, 159, 0, 0, 0, + 112, 1003, 1620, 1819, 1749, 1675, 1747, 1917, + 2048, 2087, 2137, 2350, 2744, 3124, 3204, 2846, + 2219, 1720, 1692, 2143, 2708, 2905, 2525, 1832, + 1408, 1721, 2721, 3800, 4095, 3433, 1879, 361, + 0, 227, 1372, 2263, 2247, 1378, 370, 51, + 733, 1941, 2725, 2320, 702, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 265, 688, 265, 0, 0, 0, 0, 0, + 349, 696, 720, 703, 872, 1233, 1620, 1885, + 2048, 2262, 2651, 3160, 3571, 3694, 3553, 3408, + 3559, 4089, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 3630, 3510, 3867, 4095, 4095, + 3651, 3107, 2795, 2789, 2907, 2897, 2658, 2307 + }, + { + 2048, 1872, 1766, 1689, 1616, 1562, 1560, 1621, + 1701, 1715, 1605, 1390, 1179, 1103, 1224, 1486, + 1746, 1869, 1832, 1740, 1752, 1968, 2344, 2724, + 2953, 2991, 2957, 3045, 3380, 3923, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4063, + 3723, 3511, 3391, 3280, 3110, 2869, 2590, 2314, + 2048, 1762, 1431, 1059, 683, 332, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 50, 538, 940, 1218, 1401, 1552, 1714, 1886, + 2048, 2191, 2340, 2527, 2752, 2966, 3097, 3104, + 3013, 2909, 2869, 2903, 2942, 2891, 2712, 2471, + 2305, 2325, 2529, 2785, 2913, 2805, 2509, 2198, + 2051, 2125, 2315, 2419, 2288, 1922, 1470, 1113, + 925, 814, 584, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 138, 382, 682, 1035, 1400, 1738, + 2048, 2359, 2699, 3058, 3393, 3664, 3881, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4019, 3703, 3441, 3199, 2929, 2620, 2307 + }, + { + 2048, 2324, 2624, 2954, 3284, 3568, 3796, 4005, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 3881, 3732, + 3693, 3578, 3283, 2863, 2500, 2370, 2510, 2788, + 2985, 2945, 2673, 2325, 2089, 2063, 2189, 2312, + 2292, 2097, 1816, 1580, 1463, 1441, 1421, 1321, + 1138, 950, 855, 909, 1092, 1337, 1585, 1816, + 2048, 2293, 2541, 2762, 2946, 3128, 3378, 3746, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4031, 3757, 3452, 3099, 2725, 2371, + 2048, 1733, 1398, 1043, 710, 449, 268, 119, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 62, 277, 623, 1009, 1254, 1223, 941, + 599, 434, 584, 993, 1456, 1759, 1818, 1730, + 1683, 1824, 2153, 2532, 2794, 2860, 2799, 2761, + 2873, 3137, 3439, 3623, 3604, 3411, 3161, 2970, + 2880, 2853, 2815, 2720, 2581, 2438, 2318, 2203, + 2048, 1821, 1537, 1244, 981, 748, 506, 225, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 108, 359, 569, 812, 1113, 1444, 1762 + }, + { + 2048, 2136, 2184, 2258, 2362, 2450, 2495, 2543, + 2698, 3031, 3494, 3907, 4050, 3808, 3252, 2597, + 2059, 1711, 1452, 1102, 565, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 427, + 900, 1324, 1741, 2214, 2763, 3334, 3848, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 3382, 2375, 1392, 392, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 195, 503, 850, 1247, 1656, + 2048, 2448, 2907, 3435, 3967, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 3718, 2480, 1360, + 481, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 806, 1558, 2292, 3019, 3707, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4046, 3131, 2308, 1533, 749, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 74, 551, 1028, 1482, 1838 + }, + { + 2048, 1652, 1202, 705, 224, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1214, 2449, 3595, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 3911, 3359, 2788, 2223, 1730, 1342, + 1019, 683, 285, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 236, 1269, 2189, 2856, 3287, + 3595, 3868, 4095, 4095, 4063, 3715, 3216, 2650, + 2048, 1375, 591, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 386, 1403, 2358, 3256, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 3807, 3002, 2267, 1658, 1199, + 849, 542, 257, 54, 38, 267, 673, 1087, + 1334, 1350, 1222, 1104, 1090, 1126, 1049, 726, + 188, 0, 0, 0, 282, 1093, 1794, 2245, + 2504, 2743, 3095, 3544, 3939, 4095, 4046, 3813, + 3592, 3498, 3518, 3536, 3436, 3179, 2817, 2428 + }, + { + 2048, 824, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 661, 1505, 2315, 3100, 3819, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 3826, 3648, + 3469, 3194, 2815, 2426, 2146, 2043, 2107, 2294, + 2591, 3033, 3661, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 3630, 2887, + 2048, 1109, 133, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 354, 1368, 2393, 3450, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3514, + 3057, 2966, 3065, 3137, 3087, 2988, 3006, 3240, + 3624, 3948, 4002, 3708, 3173, 2605, 2182, 1954, + 1859, 1803, 1751, 1735, 1808, 1977, 2194, 2399, + 2590, 2832, 3206, 3724, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3196 + }, + { + 2048, 1477, 923, 367, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 223, 940, 1648, 2184, 2491, 2611, + 2612, 2516, 2290, 1898, 1357, 736, 105, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 774, 1727, 2702, 3715, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4050, 2990, + 2048, 1224, 481, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 174, 807, + 1142, 1166, 1034, 944, 978, 1044, 964, 629, + 117, 0, 0, 0, 571, 1314, 1898, 2238, + 2420, 2586, 2817, 3071, 3233, 3221, 3048, 2808, + 2590, 2413, 2220, 1944, 1572, 1160, 775, 428, + 63, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 442, 1643, 2875, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 3458, 2696 + }, + { + 1987, 2084, 2164, 2206, 2261, 2413, 2694, 3034, + 3296, 3367, 3248, 3051, 2909, 2853, 2781, 2527, + 2008, 1320, 710, 426, 552, 949, 1342, 1506, + 1401, 1175, 1033, 1084, 1263, 1404, 1385, 1232, + 1112, 1214, 1614, 2226, 2867, 3375, 3694, 3867, + 3964, 4006, 3959, 3788, 3507, 3183, 2884, 2610, + 2289, 1846, 1285, 729, 350, 262, 431, 704, + 918, 1027, 1128, 1368, 1808, 2329, 2693, 2698, + 2326, 1780, 1359, 1274, 1522, 1915, 2227, 2346, + 2336, 2355, 2510, 2771, 2994, 3032, 2852, 2551, + 2286, 2163, 2180, 2259, 2327, 2370, 2421, 2501, + 2577, 2576, 2454, 2250, 2071, 2006, 2043, 2054, + 1878, 1451, 867, 332, 27, 0, 107, 208, + 231, 284, 575, 1246, 2243, 3308, 4095, 4095, + 4095, 4095, 4032, 3954, 3931, 3821, 3535, 3119, + 2706, 2412, 2246, 2115, 1902, 1565, 1157, 778, + 494, 300, 155, 42, 6, 113, 382, 742, + 1067, 1277, 1411, 1619, 2051, 2729, 3500, 4095, + 4095, 4095, 4046, 3783, 3614, 3452, 3122, 2520, + 1730, 1003, 607, 659, 1051, 1532, 1869, 1985, + 1967, 1963, 2057, 2209, 2308, 2272, 2117, 1938, + 1825, 1796, 1793, 1750, 1652, 1552, 1515, 1550, + 1597, 1579, 1488, 1407, 1460, 1699, 2044, 2314, + 2354, 2157, 1892, 1802, 2033, 2537, 3104, 3508, + 3666, 3670, 3698, 3846, 4036, 4048, 3685, 2913, + 1911, 960, 286, 0, 0, 0, 0, 0, + 0, 147, 539, 957, 1333, 1674, 2033, 2442, + 2863, 3202, 3389, 3436, 3433, 3474, 3572, 3638, + 3555, 3291, 2949, 2712, 2705, 2888, 3052, 2955, + 2488, 1760, 1030, 544, 377, 414, 461, 408, + 315, 362, 697, 1307, 2009, 2557, 2796, 2743, + 2546, 2367, 2278, 2242, 2188, 2087, 1981, 1939 + }, + { + 1039, 1027, 1033, 1037, 1091, 1279, 1630, 2072, + 2464, 2687, 2739, 2725, 2771, 2905, 3017, 2936, + 2574, 2024, 1528, 1331, 1517, 1944, 2340, 2478, + 2320, 2016, 1776, 1709, 1757, 1756, 1587, 1283, + 1014, 971, 1234, 1723, 2254, 2669, 2915, 3034, + 3099, 3131, 3097, 2959, 2732, 2482, 2273, 2105, + 1904, 1591, 1168, 753, 518, 570, 873, 1271, + 1597, 1802, 1979, 2275, 2746, 3274, 3619, 3578, + 3135, 2494, 1955, 1731, 1825, 2052, 2188, 2131, + 1946, 1798, 1799, 1925, 2035, 1988, 1752, 1429, + 1176, 1099, 1197, 1389, 1600, 1810, 2049, 2332, + 2619, 2831, 2916, 2907, 2904, 2991, 3150, 3247, + 3121, 2703, 2088, 1482, 1069, 890, 832, 736, + 544, 371, 432, 878, 1662, 2532, 3179, 3416, + 3281, 2985, 2759, 2699, 2735, 2721, 2567, 2313, + 2086, 1997, 2048, 2137, 2143, 2013, 1796, 1585, + 1442, 1357, 1286, 1211, 1176, 1247, 1446, 1704, + 1900, 1956, 1920, 1945, 2188, 2677, 3264, 3709, + 3827, 3613, 3229, 2878, 2649, 2456, 2125, 1549, + 811, 162, 0, 34, 558, 1180, 1666, 1933, + 2065, 2206, 2436, 2712, 2921, 2977, 2896, 2770, + 2689, 2670, 2656, 2579, 2427, 2254, 2126, 2054, + 1981, 1834, 1605, 1382, 1292, 1391, 1602, 1747, + 1675, 1382, 1041, 895, 1094, 1592, 2178, 2628, + 2857, 2957, 3102, 3389, 3733, 3912, 3723, 3129, + 2301, 1517, 997, 790, 788, 838, 859, 880, + 983, 1211, 1522, 1827, 2061, 2234, 2405, 2611, + 2821, 2948, 2928, 2779, 2599, 2489, 2466, 2445, + 2313, 2039, 1728, 1562, 1664, 1990, 2326, 2427, + 2176, 1673, 1173, 911, 958, 1189, 1406, 1491, + 1501, 1612, 1969, 2562, 3205, 3657, 3764, 3549, + 3166, 2782, 2476, 2220, 1948, 1639, 1342, 1132 + }, + { + 1698, 1773, 1820, 1816, 1815, 1903, 2116, 2392, + 2597, 2628, 2490, 2304, 2205, 2228, 2272, 2169, + 1833, 1355, 971, 922, 1281, 1894, 2479, 2798, + 2801, 2627, 2480, 2462, 2511, 2466, 2208, 1776, + 1348, 1125, 1199, 1500, 1857, 2122, 2250, 2295, + 2330, 2380, 2410, 2380, 2296, 2217, 2198, 2224, + 2211, 2068, 1786, 1475, 1299, 1363, 1630, 1944, + 2144, 2189, 2181, 2278, 2549, 2887, 3065, 2889, + 2353, 1666, 1131, 962, 1157, 1527, 1841, 1982, + 2007, 2066, 2260, 2552, 2792, 2830, 2629, 2287, + 1964, 1769, 1707, 1708, 1706, 1696, 1719, 1805, + 1925, 2010, 2017, 1983, 2010, 2181, 2472, 2743, + 2823, 2630, 2245, 1862, 1651, 1641, 1709, 1686, + 1512, 1300, 1266, 1568, 2165, 2818, 3229, 3226, + 2861, 2359, 1962, 1777, 1742, 1715, 1608, 1457, + 1384, 1491, 1769, 2102, 2355, 2461, 2455, 2417, + 2397, 2382, 2320, 2194, 2048, 1959, 1955, 1980, + 1926, 1730, 1454, 1267, 1336, 1700, 2220, 2658, + 2831, 2730, 2511, 2367, 2375, 2435, 2358, 2023, + 1500, 1023, 850, 1085, 1613, 2178, 2549, 2649, + 2573, 2476, 2453, 2475, 2444, 2289, 2036, 1789, + 1645, 1623, 1668, 1707, 1722, 1757, 1865, 2044, + 2221, 2309, 2288, 2232, 2258, 2417, 2627, 2712, + 2523, 2064, 1519, 1141, 1095, 1348, 1705, 1955, + 2024, 2014, 2106, 2397, 2804, 3100, 3075, 2682, + 2080, 1535, 1250, 1262, 1450, 1650, 1772, 1839, + 1932, 2093, 2286, 2428, 2466, 2419, 2361, 2343, + 2345, 2295, 2138, 1899, 1684, 1592, 1641, 1740, + 1769, 1688, 1589, 1642, 1956, 2475, 2974, 3197, + 3021, 2542, 2014, 1673, 1595, 1665, 1693, 1573, + 1374, 1286, 1466, 1913, 2451, 2843, 2941, 2767, + 2472, 2218, 2076, 2006, 1933, 1822, 1711, 1662 + }, + { + 951, 1041, 1085, 1054, 1021, 1103, 1347, 1669, + 1899, 1910, 1721, 1488, 1376, 1423, 1500, 1419, + 1094, 642, 321, 349, 753, 1341, 1831, 2037, + 1960, 1750, 1562, 1452, 1366, 1237, 1069, 945, + 951, 1087, 1258, 1350, 1327, 1264, 1269, 1380, + 1513, 1528, 1361, 1099, 939, 1036, 1369, 1732, + 1872, 1675, 1249, 858, 734, 921, 1266, 1546, + 1625, 1531, 1394, 1318, 1305, 1277, 1174, 1031, + 951, 1020, 1222, 1444, 1575, 1591, 1567, 1596, + 1677, 1700, 1527, 1134, 670, 385, 457, 862, + 1374, 1722, 1768, 1592, 1406, 1385, 1534, 1707, + 1733, 1556, 1274, 1043, 960, 994, 1037, 1015, + 951, 937, 1038, 1229, 1416, 1527, 1581, 1669, + 1851, 2065, 2134, 1893, 1335, 659, 170, 85, + 396, 890, 1303, 1500, 1536, 1575, 1725, 1943, + 2073, 1978, 1660, 1262, 960, 843, 868, 927, + 951, 961, 1025, 1167, 1326, 1408, 1377, 1312, + 1354, 1580, 1907, 2126, 2039, 1619, 1047, 603, + 477, 654, 940, 1131, 1161, 1133, 1213, 1471, + 1812, 2042, 2014, 1735, 1354, 1049, 908, 902, + 951, 1013, 1113, 1284, 1493, 1630, 1585, 1354, + 1076, 946, 1074, 1384, 1664, 1714, 1501, 1184, + 992, 1051, 1290, 1503, 1517, 1324, 1085, 997, + 1139, 1416, 1637, 1659, 1485, 1235, 1041, 957, + 951, 979, 1052, 1225, 1522, 1860, 2071, 2010, + 1671, 1215, 870, 775, 884, 1023, 1040, 933, + 855, 983, 1356, 1820, 2126, 2104, 1784, 1371, + 1096, 1056, 1176, 1291, 1286, 1169, 1031, 957, + 951, 965, 974, 1026, 1205, 1538, 1928, 2188, + 2167, 1868, 1455, 1139, 1023, 1036, 1006, 822, + 548, 389, 540, 1025, 1653, 2139, 2287, 2105, + 1769, 1482, 1334, 1279, 1213, 1092, 962, 905 + }, + { + 1705, 1810, 1851, 1793, 1729, 1803, 2071, 2426, + 2667, 2650, 2412, 2142, 2026, 2092, 2194, 2142, + 1878, 1538, 1355, 1478, 1855, 2278, 2533, 2547, + 2396, 2204, 2035, 1868, 1680, 1526, 1535, 1796, + 2245, 2669, 2834, 2657, 2271, 1930, 1811, 1898, + 2008, 1966, 1754, 1523, 1462, 1641, 1955, 2217, + 2316, 2290, 2266, 2334, 2459, 2523, 2444, 2257, + 2078, 1988, 1947, 1828, 1555, 1212, 1025, 1198, + 1745, 2444, 2971, 3109, 2878, 2489, 2168, 2005, + 1934, 1849, 1722, 1631, 1671, 1844, 2041, 2131, + 2083, 1993, 1996, 2131, 2293, 2317, 2134, 1851, + 1684, 1783, 2103, 2422, 2511, 2311, 1976, 1746, + 1770, 1998, 2247, 2350, 2274, 2104, 1943, 1812, + 1670, 1504, 1397, 1492, 1864, 2416, 2903, 3085, + 2900, 2499, 2127, 1942, 1906, 1857, 1671, 1393, + 1204, 1277, 1622, 2075, 2421, 2546, 2502, 2421, + 2390, 2384, 2319, 2163, 1991, 1920, 1988, 2095, + 2069, 1827, 1472, 1246, 1355, 1799, 2359, 2743, + 2786, 2547, 2232, 2025, 1959, 1943, 1880, 1778, + 1740, 1857, 2100, 2330, 2406, 2306, 2136, 2031, + 2025, 2022, 1899, 1644, 1407, 1399, 1716, 2238, + 2693, 2843, 2653, 2299, 2026, 1965, 2060, 2150, + 2116, 1973, 1823, 1744, 1719, 1672, 1577, 1518, + 1634, 1988, 2472, 2859, 2956, 2749, 2409, 2151, + 2067, 2064, 1966, 1691, 1341, 1139, 1254, 1663, + 2166, 2528, 2639, 2553, 2401, 2267, 2141, 1983, + 1813, 1736, 1849, 2129, 2405, 2467, 2232, 1832, + 1528, 1525, 1816, 2191, 2399, 2335, 2094, 1881, + 1829, 1916, 2015, 2029, 1982, 1987, 2122, 2343, + 2512, 2511, 2349, 2146, 2017, 1964, 1877, 1655, + 1335, 1111, 1198, 1657, 2314, 2862, 3060, 2889, + 2534, 2226, 2079, 2041, 1987, 1858, 1710, 1647 + }, + { + 1144, 1198, 1236, 1220, 1256, 1498, 1990, 2580, + 3014, 3122, 2948, 2697, 2556, 2538, 2499, 2288, + 1909, 1529, 1341, 1403, 1593, 1730, 1729, 1658, + 1647, 1748, 1886, 1951, 1934, 1974, 2238, 2746, + 3301, 3592, 3419, 2835, 2106, 1518, 1195, 1071, + 1019, 992, 1053, 1274, 1625, 1966, 2173, 2255, + 2364, 2643, 3076, 3449, 3501, 3131, 2477, 1826, + 1399, 1224, 1171, 1115, 1063, 1132, 1407, 1829, + 2218, 2417, 2426, 2383, 2429, 2573, 2682, 2623, + 2404, 2187, 2145, 2298, 2464, 2405, 2021, 1449, + 964, 779, 913, 1222, 1552, 1858, 2191, 2580, + 2940, 3119, 3034, 2771, 2536, 2481, 2566, 2577, + 2302, 1726, 1061, 603, 523, 776, 1178, 1581, + 1963, 2380, 2832, 3200, 3316, 3115, 2717, 2344, + 2153, 2114, 2064, 1872, 1576, 1354, 1362, 1583, + 1829, 1895, 1741, 1524, 1469, 1683, 2078, 2463, + 2706, 2818, 2888, 2952, 2932, 2709, 2273, 1779, + 1455, 1419, 1570, 1669, 1535, 1206, 921, 932, + 1318, 1939, 2561, 3025, 3314, 3477, 3507, 3315, + 2831, 2128, 1439, 1019, 968, 1161, 1361, 1415, + 1373, 1414, 1672, 2096, 2486, 2665, 2620, 2502, + 2475, 2571, 2672, 2636, 2436, 2180, 2004, 1932, + 1854, 1648, 1325, 1058, 1048, 1351, 1804, 2147, + 2226, 2111, 2030, 2171, 2533, 2940, 3191, 3203, + 3032, 2762, 2401, 1897, 1248, 607, 235, 329, + 867, 1593, 2194, 2507, 2599, 2661, 2815, 3011, + 3087, 2937, 2613, 2279, 2058, 1930, 1775, 1516, + 1222, 1063, 1161, 1467, 1789, 1956, 1962, 1964, + 2128, 2464, 2797, 2915, 2746, 2427, 2187, 2161, + 2286, 2380, 2302, 2060, 1775, 1545, 1360, 1148, + 909, 781, 967, 1553, 2391, 3157, 3555, 3510, + 3184, 2829, 2581, 2401, 2164, 1816, 1448, 1202 + }, + { + 1925, 1987, 2037, 2030, 2087, 2379, 2938, 3577, + 4008, 4060, 3804, 3468, 3236, 3108, 2955, 2685, + 2367, 2173, 2208, 2399, 2553, 2539, 2413, 2363, + 2529, 2862, 3172, 3307, 3296, 3312, 3486, 3756, + 3894, 3697, 3168, 2517, 1999, 1727, 1646, 1657, + 1757, 2044, 2579, 3251, 3804, 4014, 3875, 3595, + 3425, 3440, 3489, 3352, 2942, 2387, 1919, 1686, + 1669, 1770, 1951, 2282, 2827, 3495, 4031, 4095, + 3856, 3301, 2843, 2698, 2822, 2999, 3038, 2922, + 2758, 2633, 2515, 2313, 2030, 1824, 1908, 2356, + 3005, 3555, 3790, 3733, 3585, 3526, 3555, 3514, + 3265, 2837, 2405, 2130, 2020, 1959, 1854, 1773, + 1899, 2352, 3045, 3709, 4087, 4095, 3946, 3756, + 3596, 3363, 2942, 2375, 1873, 1658, 1780, 2087, + 2371, 2544, 2685, 2914, 3234, 3491, 3522, 3319, + 3071, 3005, 3182, 3441, 3524, 3300, 2864, 2435, + 2170, 2058, 1994, 1936, 1977, 2245, 2744, 3288, + 3627, 3647, 3473, 3352, 3437, 3649, 3745, 3534, + 3032, 2435, 1947, 1640, 1475, 1427, 1580, 2054, + 2846, 3729, 4095, 4095, 4095, 3589, 3154, 2933, + 2832, 2696, 2486, 2300, 2249, 2320, 2381, 2328, + 2214, 2227, 2517, 3033, 3531, 3760, 3659, 3396, + 3207, 3191, 3247, 3196, 2970, 2671, 2458, 2387, + 2361, 2244, 2030, 1884, 2007, 2447, 3035, 3516, + 3751, 3802, 3831, 3907, 3919, 3679, 3119, 2392, + 1780, 1490, 1521, 1726, 1974, 2266, 2682, 3223, + 3730, 3979, 3863, 3510, 3189, 3093, 3188, 3257, + 3105, 2732, 2320, 2068, 2025, 2094, 2168, 2258, + 2472, 2868, 3331, 3627, 3592, 3289, 2979, 2914, + 3137, 3451, 3591, 3433, 3059, 2642, 2283, 1965, + 1659, 1444, 1506, 1980, 2784, 3620, 4095, 4095, + 4031, 3737, 3527, 3366, 3117, 2724, 2293, 2000 + }, + { + 1117, 1190, 1253, 1255, 1331, 1665, 2274, 2933, + 3330, 3305, 2964, 2552, 2241, 2014, 1766, 1479, + 1282, 1326, 1599, 1899, 1996, 1843, 1635, 1631, + 1925, 2370, 2721, 2850, 2827, 2790, 2766, 2626, + 2237, 1641, 1080, 811, 903, 1198, 1477, 1667, + 1883, 2264, 2785, 3234, 3381, 3179, 2793, 2430, + 2150, 1848, 1419, 930, 618, 693, 1149, 1751, + 2236, 2511, 2678, 2865, 3054, 3086, 2829, 2351, + 1891, 1661, 1666, 1723, 1652, 1461, 1331, 1421, + 1704, 1986, 2103, 2083, 2115, 2351, 2733, 3031, + 3045, 2777, 2407, 2101, 1865, 1577, 1177, 795, + 677, 970, 1568, 2188, 2594, 2767, 2863, 3009, + 3154, 3114, 2775, 2226, 1695, 1355, 1187, 1058, + 907, 856, 1104, 1712, 2486, 3090, 3293, 3127, + 2813, 2546, 2345, 2112, 1804, 1533, 1464, 1633, + 1869, 1930, 1727, 1422, 1300, 1520, 1986, 2451, + 2733, 2842, 2898, 2949, 2891, 2584, 2038, 1467, + 1139, 1151, 1352, 1496, 1473, 1406, 1518, 1908, + 2452, 2917, 3161, 3218, 3188, 3073, 2747, 2108, + 1260, 527, 249, 531, 1175, 1844, 2318, 2594, + 2782, 2923, 2935, 2732, 2377, 2080, 2022, 2176, + 2305, 2168, 1744, 1261, 1006, 1094, 1405, 1735, + 1989, 2229, 2534, 2852, 3006, 2864, 2498, 2159, + 2059, 2181, 2288, 2137, 1700, 1186, 861, 839, + 1049, 1375, 1794, 2366, 3076, 3715, 3966, 3636, + 2834, 1923, 1265, 989, 979, 1051, 1142, 1323, + 1650, 2041, 2319, 2386, 2341, 2398, 2670, 3025, + 3174, 2917, 2326, 1687, 1277, 1163, 1220, 1308, + 1418, 1633, 1980, 2323, 2461, 2326, 2084, 2016, + 2271, 2723, 3066, 3059, 2705, 2198, 1730, 1347, + 999, 697, 596, 878, 1557, 2395, 3041, 3286, + 3189, 2978, 2823, 2694, 2448, 2022, 1538, 1203 + }, + { + 1117, 1190, 1253, 1255, 1331, 1665, 2274, 2933, + 3330, 3305, 2964, 2552, 2241, 2014, 1766, 1479, + 1282, 1326, 1599, 1899, 1996, 1843, 1635, 1631, + 1925, 2370, 2721, 2850, 2827, 2790, 2766, 2626, + 2237, 1641, 1080, 811, 903, 1198, 1477, 1667, + 1883, 2264, 2785, 3234, 3381, 3179, 2793, 2430, + 2150, 1848, 1419, 930, 618, 693, 1149, 1751, + 2236, 2511, 2678, 2865, 3054, 3086, 2829, 2351, + 1891, 1661, 1666, 1723, 1652, 1461, 1331, 1421, + 1704, 1986, 2103, 2083, 2115, 2351, 2733, 3031, + 3045, 2777, 2407, 2101, 1865, 1577, 1177, 795, + 677, 970, 1568, 2188, 2594, 2767, 2863, 3009, + 3154, 3114, 2775, 2226, 1695, 1355, 1187, 1058, + 907, 856, 1104, 1712, 2486, 3090, 3293, 3127, + 2813, 2546, 2345, 2112, 1804, 1533, 1464, 1633, + 1869, 1930, 1727, 1422, 1300, 1520, 1986, 2451, + 2733, 2842, 2898, 2949, 2891, 2584, 2038, 1467, + 1139, 1151, 1352, 1496, 1473, 1406, 1518, 1908, + 2452, 2917, 3161, 3218, 3188, 3073, 2747, 2108, + 1260, 527, 249, 531, 1175, 1844, 2318, 2594, + 2782, 2923, 2935, 2732, 2377, 2080, 2022, 2176, + 2305, 2168, 1744, 1261, 1006, 1094, 1405, 1735, + 1989, 2229, 2534, 2852, 3006, 2864, 2498, 2159, + 2059, 2181, 2288, 2137, 1700, 1186, 861, 839, + 1049, 1375, 1794, 2366, 3076, 3715, 3966, 3636, + 2834, 1923, 1265, 989, 979, 1051, 1142, 1323, + 1650, 2041, 2319, 2386, 2341, 2398, 2670, 3025, + 3174, 2917, 2326, 1687, 1277, 1163, 1220, 1308, + 1418, 1633, 1980, 2323, 2461, 2326, 2084, 2016, + 2271, 2723, 3066, 3059, 2705, 2198, 1730, 1347, + 999, 697, 596, 878, 1557, 2395, 3041, 3286, + 3189, 2978, 2823, 2694, 2448, 2022, 1538, 1203 + }, + { + 1718, 1921, 1999, 1656, 1132, 1032, 1712, 2848, + 3643, 3512, 2596, 1623, 1246, 1506, 1915, 2017, + 1844, 1803, 2145, 2612, 2653, 2019, 1111, 688, + 1190, 2308, 3242, 3398, 2864, 2229, 1969, 2022, + 1965, 1564, 1094, 1081, 1711, 2557, 2915, 2470, + 1625, 1150, 1483, 2345, 3029, 3067, 2612, 2185, + 2096, 2139, 1883, 1234, 647, 732, 1629, 2782, + 3379, 3061, 2216, 1596, 1624, 2069, 2372, 2248, + 1953, 1942, 2320, 2666, 2456, 1648, 817, 673, + 1391, 2432, 3022, 2838, 2248, 1891, 2042, 2394, + 2450, 2085, 1692, 1745, 2251, 2681, 2470, 1618, + 757, 605, 1314, 2340, 2962, 2917, 2559, 2405, + 2574, 2687, 2333, 1581, 995, 1097, 1825, 2543, + 2617, 2016, 1334, 1217, 1764, 2469, 2751, 2515, + 2186, 2209, 2546, 2708, 2296, 1481, 909, 1099, + 1922, 2684, 2761, 2163, 1491, 1343, 1761, 2265, + 2393, 2177, 2070, 2401, 2954, 3126, 2538, 1473, + 689, 746, 1508, 2285, 2490, 2151, 1804, 1902, + 2355, 2664, 2482, 2010, 1796, 2145, 2747, 2934, + 2340, 1301, 593, 739, 1553, 2355, 2620, 2417, + 2233, 2394, 2701, 2669, 2100, 1381, 1161, 1710, + 2604, 3073, 2700, 1796, 1093, 1072, 1566, 2017, + 2081, 1946, 2065, 2586, 3118, 3090, 2358, 1432, + 1049, 1496, 2335, 2804, 2518, 1780, 1244, 1274, + 1656, 1913, 1860, 1810, 2187, 2986, 3642, 3514, + 2517, 1276, 618, 874, 1639, 2210, 2240, 1983, + 1918, 2192, 2465, 2316, 1768, 1353, 1601, 2477, + 3320, 3416, 2637, 1569, 968, 1111, 1625, 1943, + 1888, 1782, 2016, 2544, 2867, 2552, 1738, 1103, + 1261, 2175, 3150, 3442, 2895, 2013, 1437, 1358, + 1450, 1342, 1089, 1143, 1827, 2881, 3588, 3398, + 2455, 1508, 1250, 1731, 2377, 2578, 2246, 1815 + }, + { + 1956, 2312, 2492, 2158, 1587, 1440, 2075, 3103, + 3686, 3310, 2251, 1289, 964, 1148, 1318, 1207, + 1102, 1470, 2337, 3132, 3196, 2466, 1596, 1370, + 1972, 2846, 3266, 3016, 2500, 2211, 2166, 1932, + 1202, 279, 0, 514, 1825, 2970, 3298, 2911, + 2460, 2438, 2721, 2794, 2395, 1846, 1708, 2128, + 2613, 2496, 1639, 644, 310, 889, 1878, 2537, + 2593, 2411, 2483, 2835, 2993, 2546, 1687, 1118, + 1375, 2266, 3014, 2986, 2268, 1526, 1315, 1565, + 1757, 1572, 1273, 1419, 2191, 3093, 3371, 2751, + 1734, 1144, 1359, 2019, 2463, 2416, 2209, 2316, + 2752, 2995, 2547, 1529, 660, 598, 1311, 2116, + 2356, 2015, 1666, 1816, 2379, 2798, 2684, 2258, + 2113, 2543, 3164, 3261, 2510, 1347, 574, 613, + 1161, 1574, 1564, 1455, 1755, 2519, 3211, 3232, + 2567, 1849, 1757, 2343, 2992, 3048, 2449, 1737, + 1454, 1580, 1619, 1216, 628, 520, 1267, 2504, + 3408, 3450, 2855, 2318, 2281, 2532, 2517, 2013, + 1407, 1298, 1822, 2459, 2530, 1902, 1140, 958, + 1517, 2286, 2609, 2356, 2002, 2057, 2485, 2743, + 2396, 1643, 1184, 1516, 2413, 3111, 3038, 2338, + 1674, 1530, 1760, 1837, 1500, 1087, 1183, 1941, + 2834, 3122, 2577, 1723, 1337, 1707, 2410, 2796, + 2657, 2373, 2410, 2734, 2807, 2177, 1045, 176, + 210, 1065, 2032, 2466, 2362, 2242, 2514, 3006, + 3170, 2727, 2032, 1745, 2140, 2771, 2886, 2175, + 1096, 437, 583, 1209, 1704, 1825, 1894, 2338, + 3102, 3601, 3299, 2321, 1415, 1285, 1930, 2673, + 2829, 2339, 1732, 1513, 1639, 1648, 1264, 805, + 906, 1822, 3065, 3773, 3486, 2550, 1755, 1582, + 1830, 1959, 1751, 1543, 1806, 2530, 3118, 2944, + 2015, 1030, 751, 1302, 2097, 2453, 2239, 1915 + }, + { + 1964, 2362, 2559, 2189, 1568, 1414, 2067, 3059, + 3526, 3046, 2033, 1276, 1149, 1327, 1288, 987, + 936, 1584, 2708, 3521, 3425, 2621, 1903, 1856, + 2309, 2599, 2335, 1808, 1611, 1918, 2247, 1998, + 1166, 443, 549, 1503, 2603, 3140, 3062, 2903, + 3077, 3364, 3157, 2203, 1000, 375, 684, 1474, + 1982, 1920, 1700, 1887, 2497, 2950, 2717, 1961, + 1425, 1673, 2496, 3112, 2972, 2281, 1721, 1683, + 1882, 1764, 1217, 782, 1086, 2110, 3112, 3324, + 2695, 1899, 1625, 1901, 2178, 2031, 1671, 1687, + 2317, 3076, 3199, 2439, 1367, 825, 1111, 1751, + 2065, 1899, 1721, 2001, 2610, 2919, 2518, 1731, + 1353, 1830, 2779, 3352, 3069, 2250, 1598, 1445, + 1472, 1203, 669, 468, 1120, 2420, 3528, 3741, + 3144, 2457, 2266, 2453, 2438, 1916, 1254, 1094, + 1614, 2272, 2351, 1722, 1001, 913, 1554, 2336, + 2649, 2506, 2458, 2890, 3503, 3576, 2750, 1475, + 615, 626, 1170, 1560, 1528, 1462, 1874, 2718, + 3334, 3129, 2236, 1437, 1396, 2018, 2602, 2606, + 2183, 1928, 2145, 2474, 2310, 1544, 781, 764, + 1596, 2598, 2979, 2593, 2012, 1853, 2129, 2320, + 2047, 1576, 1549, 2236, 3140, 3434, 2781, 1683, + 980, 1029, 1443, 1618, 1441, 1379, 1878, 2749, + 3283, 2983, 2126, 1531, 1738, 2479, 2991, 2808, + 2197, 1776, 1790, 1858, 1476, 702, 214, 644, + 1885, 3131, 3627, 3348, 2903, 2803, 2914, 2686, + 1876, 935, 595, 1104, 1936, 2317, 2009, 1510, + 1471, 1978, 2486, 2467, 2030, 1820, 2285, 3129, + 3560, 3092, 2049, 1221, 1077, 1352, 1459, 1214, + 1058, 1522, 2535, 3375, 3355, 2530, 1651, 1420, + 1826, 2259, 2233, 1913, 1866, 2338, 2895, 2850, + 2036, 1061, 736, 1277, 2114, 2503, 2272, 1916 + }, + { + 1639, 1664, 1562, 1341, 1360, 1915, 2829, 3528, + 3547, 2949, 2219, 1761, 1548, 1288, 877, 621, + 938, 1861, 2903, 3446, 3282, 2734, 2268, 2022, + 1771, 1321, 868, 873, 1570, 2635, 3406, 3454, + 2920, 2299, 1919, 1689, 1347, 896, 694, 1077, + 1938, 2737, 2992, 2720, 2385, 2390, 2662, 2769, + 2419, 1793, 1356, 1365, 1621, 1732, 1581, 1463, + 1732, 2345, 2832, 2753, 2162, 1583, 1512, 1960, + 2502, 2750, 2711, 2665, 2725, 2631, 2028, 958, + 0, 0, 496, 1736, 2834, 3458, 3723, 3841, + 3752, 3184, 2069, 822, 110, 289, 1094, 1902, + 2304, 2395, 2518, 2782, 2906, 2557, 1804, 1148, + 1076, 1597, 2255, 2598, 2593, 2554, 2689, 2805, + 2511, 1715, 836, 485, 898, 1731, 2409, 2656, + 2660, 2728, 2863, 2746, 2156, 1334, 853, 1093, + 1868, 2596, 2846, 2685, 2489, 2460, 2405, 2012, + 1304, 722, 730, 1335, 2064, 2430, 2399, 2364, + 2665, 3183, 3442, 3110, 2344, 1619, 1245, 1108, + 918, 647, 646, 1270, 2402, 3433, 3752, 3276, + 2479, 1920, 1759, 1753, 1669, 1610, 1864, 2469, + 3015, 2959, 2167, 1103, 447, 518, 1081, 1689, + 2157, 2652, 3327, 3959, 4051, 3323, 2069, 966, + 513, 658, 980, 1199, 1437, 1979, 2804, 3469, + 3484, 2808, 1918, 1372, 1319, 1472, 1526, 1535, + 1822, 2522, 3289, 3542, 3008, 2017, 1205, 958, + 1133, 1343, 1427, 1594, 2085, 2776, 3197, 2987, + 2297, 1689, 1605, 1967, 2306, 2280, 2009, 1884, + 2086, 2358, 2294, 1817, 1301, 1203, 1573, 2011, + 2103, 1872, 1753, 2114, 2839, 3420, 3451, 2996, + 2439, 2029, 1639, 1019, 242, 0, 205, 1436, + 2883, 3816, 3952, 3559, 3062, 2600, 2024, 1278, + 664, 643, 1346, 2343, 2958, 2854, 2286, 1788 + }, + { + 1664, 1710, 1621, 1407, 1442, 2003, 2873, 3465, + 3372, 2745, 2084, 1708, 1489, 1146, 713, 612, + 1202, 2315, 3312, 3633, 3266, 2647, 2153, 1768, + 1286, 760, 609, 1212, 2410, 3513, 3856, 3344, + 2445, 1678, 1182, 798, 495, 559, 1284, 2512, + 3601, 3926, 3426, 2610, 2030, 1793, 1607, 1266, + 968, 1098, 1726, 2439, 2713, 2438, 2006, 1863, + 2044, 2194, 2047, 1785, 1847, 2396, 3057, 3245, + 2741, 1890, 1225, 956, 880, 784, 811, 1334, + 2449, 3684, 4095, 4001, 3035, 2052, 1429, 1079, + 781, 592, 827, 1619, 2608, 3172, 2997, 2384, + 1932, 1937, 2162, 2183, 1912, 1690, 1855, 2317, + 2620, 2441, 1951, 1617, 1681, 1910, 1901, 1595, + 1381, 1666, 2386, 3011, 3069, 2603, 2079, 1865, + 1879, 1787, 1488, 1298, 1590, 2308, 2924, 2932, + 2348, 1676, 1389, 1493, 1645, 1637, 1660, 2042, + 2762, 3350, 3316, 2665, 1904, 1532, 1564, 1603, + 1355, 1002, 995, 1531, 2303, 2818, 2898, 2809, + 2868, 3011, 2849, 2155, 1229, 689, 883, 1548, + 2098, 2207, 2062, 2049, 2261, 2408, 2227, 1862, + 1767, 2190, 2838, 3128, 2766, 2035, 1479, 1347, + 1410, 1328, 1118, 1157, 1721, 2593, 3217, 3234, + 2828, 2472, 2390, 2340, 1956, 1257, 718, 808, + 1498, 2286, 2699, 2716, 2652, 2684, 2608, 2120, + 1299, 686, 820, 1690, 2713, 3260, 3186, 2822, + 2502, 2202, 1692, 990, 515, 722, 1593, 2569, + 3045, 2906, 2541, 2359, 2356, 2214, 1783, 1351, + 1368, 1923, 2586, 2811, 2473, 1952, 1679, 1683, + 1634, 1326, 1011, 1176, 1997, 3075, 3770, 3769, + 3287, 2713, 2162, 1452, 521, 0, 0, 704, + 2221, 3469, 3925, 3689, 3199, 2718, 2167, 1448, + 794, 672, 1285, 2261, 2912, 2846, 2291, 1798 + }, + { + 1007, 1856, 3088, 3141, 1847, 693, 1019, 2402, + 3221, 2669, 1652, 1511, 2265, 2661, 1926, 902, + 1029, 2441, 3641, 3260, 1719, 730, 1238, 2375, + 2679, 1956, 1422, 1994, 3006, 3042, 1827, 706, + 1023, 2433, 3287, 2649, 1408, 1118, 2052, 2925, + 2601, 1546, 1185, 2010, 2913, 2633, 1438, 857, + 1747, 3148, 3408, 2207, 934, 975, 2063, 2745, + 2291, 1564, 1775, 2782, 3198, 2211, 766, 519, + 1815, 3231, 3271, 2120, 1291, 1679, 2511, 2481, + 1542, 991, 1744, 3042, 3318, 2172, 930, 1040, + 2298, 3130, 2564, 1398, 1127, 2028, 2866, 2544, + 1544, 1280, 2202, 3139, 2764, 1349, 530, 1323, + 2864, 3450, 2579, 1454, 1382, 2157, 2479, 1781, + 1038, 1485, 2882, 3653, 2796, 1178, 554, 1486, + 2736, 2860, 1960, 1411, 1992, 2872, 2739, 1593, + 829, 1472, 2813, 3235, 2228, 1036, 1114, 2328, + 3157, 2624, 1479, 1185, 2020, 2769, 2363, 1324, + 1121, 2227, 3406, 3187, 1710, 604, 1030, 2335, + 2953, 2368, 1638, 1880, 2743, 2873, 1777, 620, + 857, 2375, 3534, 3105, 1716, 1022, 1666, 2595, + 2523, 1612, 1201, 1986, 3034, 2956, 1739, 846, + 1407, 2768, 3270, 2302, 1044, 990, 2114, 2978, + 2598, 1645, 1484, 2330, 2945, 2295, 996, 656, + 1854, 3341, 3494, 2243, 1092, 1233, 2166, 2501, + 1839, 1266, 1837, 3059, 3406, 2261, 808, 665, + 1934, 3095, 2878, 1764, 1266, 1962, 2817, 2600, + 1538, 1039, 1834, 2968, 2975, 1770, 819, 1333, + 2738, 3371, 2522, 1266, 1073, 1987, 2681, 2254, + 1408, 1483, 2608, 3416, 2742, 1172, 431, 1320, + 2771, 3183, 2343, 1540, 1807, 2599, 2598, 1556, + 737, 1323, 2823, 3559, 2693, 1261, 902, 1879, + 2844, 2605, 1599, 1244, 2041, 2919, 2658, 1531 + }, + { + 1940, 2558, 3310, 3167, 1867, 350, 0, 1062, + 2800, 3765, 3383, 2325, 1683, 1824, 2122, 1810, + 973, 562, 1363, 3030, 4095, 3948, 2338, 733, + 312, 1081, 2042, 2327, 2055, 2043, 2730, 3541, + 3433, 2069, 354, 0, 660, 2465, 3674, 3555, + 2627, 1952, 1980, 2174, 1778, 840, 310, 1054, + 2820, 4095, 4095, 2750, 1016, 328, 870, 1758, + 2102, 1931, 2002, 2773, 3699, 3704, 2351, 483, + 0, 332, 2127, 3511, 3617, 2819, 2147, 2119, + 2272, 1849, 837, 165, 780, 2548, 4095, 4095, + 3056, 1293, 441, 815, 1624, 1964, 1795, 1856, + 2655, 3707, 3898, 2665, 738, 0, 137, 1836, + 3299, 3559, 2871, 2228, 2206, 2400, 2025, 983, + 161, 577, 2243, 3964, 4095, 3212, 1509, 607, + 911, 1683, 1987, 1722, 1634, 2344, 3478, 3919, + 2958, 1144, 0, 179, 1657, 3024, 3299, 2677, + 2126, 2247, 2633, 2411, 1352, 294, 368, 1792, + 3522, 4095, 3306, 1795, 924, 1157, 1829, 2014, + 1589, 1330, 1958, 3199, 3921, 3260, 1583, 231, + 275, 1525, 2778, 3042, 2448, 1949, 2189, 2781, + 2774, 1790, 573, 315, 1429, 3049, 3826, 3210, + 1931, 1202, 1494, 2155, 2234, 1577, 1016, 1432, + 2711, 3741, 3497, 2102, 754, 565, 1507, 2523, + 2671, 2061, 1640, 2072, 2958, 3236, 2353, 953, + 300, 1029, 2487, 3382, 3051, 2056, 1509, 1878, + 2532, 2499, 1601, 718, 888, 2167, 3485, 3671, + 2604, 1315, 927, 1562, 2316, 2308, 1645, 1274, + 1887, 3079, 3677, 2945, 1400, 361, 677, 1927, + 2902, 2843, 2138, 1788, 2244, 2901, 2778, 1670, + 489, 408, 1648, 3195, 3762, 3008, 1804, 1276, + 1670, 2211, 2062, 1311, 912, 1616, 3052, 3976, + 3474, 1900, 566, 489, 1470, 2418, 2532, 2072 + }, + { + 2305, 1950, 1626, 1814, 2468, 2972, 2698, 1651, + 599, 493, 1629, 3299, 4095, 3750, 2036, 322, + 0, 716, 2337, 3494, 3539, 2733, 1873, 1551, + 1713, 1874, 1704, 1400, 1477, 2176, 3100, 3465, + 2796, 1444, 411, 557, 1859, 3357, 3885, 3012, + 1398, 273, 466, 1773, 3173, 3670, 3055, 1956, + 1225, 1225, 1645, 1927, 1865, 1776, 2102, 2843, + 3423, 3156, 1941, 508, 0, 771, 2528, 3975, + 4081, 2811, 1147, 304, 788, 2069, 3085, 3132, + 2367, 1558, 1356, 1763, 2238, 2291, 1965, 1758, + 2067, 2709, 3020, 2475, 1275, 311, 477, 1870, + 3595, 4095, 3648, 1838, 238, 0, 953, 2472, + 3385, 3239, 2444, 1786, 1701, 1974, 2076, 1773, + 1386, 1465, 2176, 3031, 3252, 2491, 1234, 486, + 945, 2362, 3668, 3808, 2604, 928, 25, 542, + 2045, 3415, 3744, 2992, 1892, 1252, 1307, 1669, + 1826, 1700, 1681, 2158, 2993, 3517, 3093, 1773, + 411, 53, 1073, 2800, 3984, 3764, 2346, 833, + 342, 1140, 2499, 3344, 3124, 2182, 1357, 1230, + 1687, 2150, 2196, 1957, 1926, 2378, 2991, 3078, + 2252, 913, 57, 492, 2102, 3831, 4095, 3481, + 1632, 203, 113, 1246, 2634, 3287, 2946, 2155, + 1671, 1781, 2137, 2202, 1837, 1454, 1587, 2295, + 3011, 3008, 2101, 926, 482, 1281, 2841, 3994, + 3798, 2312, 588, 0, 597, 2192, 3484, 3681, + 2895, 1901, 1409, 1511, 1759, 1733, 1500, 1531, + 2148, 3075, 3557, 3017, 1650, 404, 259, 1409, + 3036, 3917, 3390, 1883, 571, 434, 1497, 2873, + 3520, 3065, 2014, 1233, 1196, 1675, 2076, 2072, + 1891, 2018, 2606, 3204, 3117, 2089, 689, 0, + 611, 2318, 3929, 4095, 3162, 1386, 241, 446, + 1669, 2875, 3209, 2628, 1811, 1479, 1772, 2227 + }, + { + 2335, 1960, 1685, 1991, 2665, 2957, 2364, 1256, + 1187, 675, 1385, 2969, 4095, 3891, 2178, 296, + 0, 858, 2528, 3499, 3277, 2384, 1687, 1864, + 1755, 1891, 1800, 1493, 1474, 2117, 3086, 3446, + 2627, 1190, 321, 799, 2247, 3423, 3310, 3107, + 1738, 395, 255, 1464, 3033, 3737, 3149, 1995, + 1297, 1347, 1704, 1834, 1723, 1823, 2108, 2639, + 3261, 3208, 2125, 617, 0, 748, 2661, 4066, + 3914, 2447, 933, 547, 1394, 1601, 2804, 3229, + 2646, 1734, 1332, 1636, 2113, 2142, 1819, 1735, + 2218, 2881, 2971, 2189, 1720, 621, 355, 1441, + 3232, 4095, 3802, 1959, 273, 50, 1212, 2640, + 3225, 2756, 1910, 2316, 1840, 1897, 2026, 1814, + 1434, 1470, 2204, 3124, 3256, 2304, 984, 435, + 1171, 2551, 3314, 3642, 2920, 1289, 77, 298, + 1775, 3318, 3760, 2948, 1844, 1312, 1466, 1796, + 1872, 1825, 1577, 1917, 2711, 3406, 3216, 1970, + 487, 10, 1148, 2954, 3986, 3485, 1998, 851, + 972, 994, 2116, 3181, 3271, 2421, 1473, 1207, + 1641, 2110, 2109, 1863, 1914, 2408, 2823, 2479, + 2808, 1550, 347, 282, 1634, 3479, 4095, 3526, + 1607, 217, 326, 1591, 2839, 3159, 2604, 1942, + 1762, 1656, 1999, 2221, 1988, 1609, 1694, 2407, + 3070, 2862, 1756, 638, 549, 1686, 3126, 3294, + 3719, 2662, 912, 0, 407, 2032, 3459, 3612, + 2747, 1800, 1467, 1676, 1899, 1861, 1595, 1503, + 1915, 2795, 3437, 3078, 1735, 392, 309, 1631, + 3271, 3888, 3033, 1515, 651, 866, 1341, 2604, + 3487, 3253, 2196, 1262, 1125, 1617, 2009, 1977, + 1857, 2125, 2738, 3044, 2446, 2512, 1180, 155, + 433, 2025, 3791, 4095, 3137, 1246, 193, 622, + 1932, 2950, 3001, 2393, 2115, 1507, 1558, 1991 + }, + { + 2299, 1606, 1862, 2187, 2600, 3114, 2824, 819, + 742, 762, 1777, 2857, 3979, 4095, 2607, 70, + 0, 1274, 2290, 3296, 3402, 2624, 1883, 2093, + 1423, 1682, 1942, 1277, 1503, 2618, 2805, 3895, + 2249, 1512, 0, 904, 1903, 3739, 3659, 3477, + 1378, 119, 643, 1169, 2648, 4095, 3128, 2162, + 1306, 1460, 1690, 1974, 1373, 1684, 1967, 3108, + 3257, 3304, 2323, 309, 7, 529, 2826, 4095, + 3817, 2606, 606, 565, 1564, 1755, 2924, 3206, + 2565, 1884, 1147, 1262, 2231, 2237, 2195, 2100, + 1944, 2626, 3225, 1916, 1444, 924, 395, 1723, + 3132, 4095, 3586, 1748, 42, 268, 1482, 2742, + 3110, 2570, 2025, 2385, 1828, 2180, 1616, 1958, + 1380, 1703, 2019, 3249, 3581, 2116, 685, 199, + 1554, 2900, 3289, 3588, 2850, 1045, 0, 597, + 1989, 3292, 3640, 3076, 1633, 1156, 1650, 2200, + 1884, 1603, 1349, 2034, 2754, 3521, 3437, 1599, + 744, 0, 1040, 3065, 4095, 3458, 1782, 963, + 997, 977, 1824, 3559, 3467, 2488, 1558, 699, + 1750, 1983, 2306, 1793, 2240, 2704, 2237, 2629, + 2939, 1330, 530, 545, 1391, 3086, 4095, 3624, + 1583, 443, 206, 1788, 2457, 3132, 2913, 1810, + 1654, 1539, 2375, 2330, 2305, 1378, 1366, 2269, + 3182, 3207, 1447, 648, 813, 1931, 3069, 3286, + 3459, 2647, 833, 0, 589, 2201, 3797, 3585, + 2499, 1455, 1353, 2169, 2045, 1862, 1599, 1248, + 1735, 3087, 3519, 3073, 1783, 586, 403, 1230, + 3053, 4030, 3230, 1553, 814, 1012, 1239, 2409, + 3612, 3022, 2454, 988, 1344, 1690, 2015, 2311, + 1661, 1882, 2970, 3096, 2259, 2286, 1362, 415, + 382, 2202, 4077, 4095, 2592, 1052, 470, 805, + 2008, 3117, 3179, 2167, 1896, 1466, 1818, 2081 + }, + { + 1966, 2056, 2324, 2444, 1716, 1440, 1465, 1652, + 1875, 2034, 2094, 2076, 2037, 2105, 2583, 1888, + 994, 1008, 1565, 2138, 2414, 2398, 2270, 2152, + 2001, 1726, 1370, 1159, 1325, 1872, 2502, 2825, + 2599, 1908, 1177, 1358, 1754, 1897, 1956, 1973, + 1965, 1970, 2000, 2020, 1980, 1914, 1867, 1698, + 1633, 1822, 2021, 2054, 1931, 1831, 1905, 2094, + 2140, 1824, 1297, 1964, 2188, 1828, 1576, 2128, + 2255, 1961, 1600, 1533, 1823, 2209, 2347, 2115, + 1705, 1447, 1526, 1839, 2117, 2168, 2035, 1919, + 1948, 2041, 1998, 1724, 1392, 1362, 1896, 2811, + 2122, 1739, 1726, 1901, 2062, 2040, 1867, 1669, + 1531, 1527, 1740, 2238, 2702, 2377, 1984, 1563, + 1305, 1376, 1742, 2165, 2333, 2139, 1788, 1624, + 1819, 2208, 2414, 2176, 1596, 1106, 1087, 1600, + 2354, 2838, 2758, 2219, 1598, 1247, 1250, 1468, + 1734, 2029, 2451, 2851, 2030, 1593, 1481, 1600, + 1808, 1954, 2009, 2012, 1969, 1886, 1800, 1768, + 1812, 1937, 2247, 2475, 1925, 1398, 1223, 1479, + 1957, 2335, 2421, 2267, 2054, 1870, 1614, 1148, + 1402, 2051, 2361, 2381, 2151, 1806, 1621, 1674, + 1793, 1900, 1995, 2059, 2054, 1959, 1750, 1419, + 1732, 2123, 2329, 2207, 1857, 1571, 1594, 1896, + 2180, 2116, 1639, 1438, 1959, 2116, 2093, 2051, + 2049, 2037, 1956, 1739, 1214, 911, 2104, 2666, + 2618, 2292, 1979, 1758, 1557, 1351, 1268, 1485, + 2014, 2601, 2861, 2571, 1885, 1233, 989, 1278, + 1853, 2301, 2449, 2380, 2080, 1765, 1562, 1513, + 1617, 1930, 2552, 2071, 1735, 1723, 1797, 1809, + 1807, 1898, 2059, 2111, 2091, 2188, 1924, 1185, + 1048, 1869, 2546, 2656, 2239, 1647, 1338, 1500, + 1926, 2232, 2194, 1935, 1853, 1585, 1647, 1843 + }, + { + 1659, 2675, 2749, 995, 2173, 1940, 1758, 1737, + 1805, 1884, 1945, 2020, 2163, 2406, 1786, 2321, + 991, 844, 1698, 2413, 2642, 2402, 2020, 1879, + 1873, 1701, 1340, 1179, 1629, 2362, 2546, 2823, + 2611, 635, 1054, 2099, 1830, 1970, 2091, 2189, + 2174, 2003, 1706, 1379, 1301, 1802, 2504, 3525, + 1931, 631, 1107, 1894, 2188, 2207, 2261, 2251, + 1696, 718, 3108, 1636, 1614, 2164, 1962, 1527, + 2214, 2001, 1463, 1379, 1962, 2680, 2826, 2236, + 1296, 814, 1099, 1902, 2559, 2590, 2142, 1841, + 1891, 2012, 1954, 1594, 1161, 1342, 2876, 1538, + 2388, 2161, 1968, 1905, 1876, 1872, 1781, 1648, + 1622, 1774, 2024, 1808, 1350, 3460, 2891, 1498, + 1072, 1273, 1372, 1966, 2476, 2263, 1679, 1448, + 1930, 2703, 2997, 2280, 930, 682, 802, 982, + 2550, 3717, 3622, 2527, 1167, 573, 651, 1194, + 2057, 3027, 3472, 328, 2460, 2176, 1868, 1735, + 1734, 1783, 1780, 1757, 1784, 1880, 2039, 2201, + 2229, 2073, 1483, 1629, 2971, 1691, 851, 1072, + 1864, 2609, 2790, 2451, 1961, 1515, 1103, 1847, + 2014, 1647, 1888, 2020, 2063, 2184, 2102, 1878, + 1874, 1891, 1808, 1635, 1480, 1540, 2049, 3897, + 1024, 1088, 2025, 2385, 2069, 1655, 1649, 2000, + 2132, 1527, 1310, 2922, 1737, 1758, 1870, 1969, + 2088, 2176, 2080, 1699, 1295, 1033, 1600, 2820, + 2718, 2287, 1985, 1875, 1713, 1312, 1028, 1302, + 2030, 2858, 3103, 2414, 1614, 1352, 673, 1103, + 3016, 3299, 1642, 303, 1899, 2475, 2407, 2217, + 2137, 2046, 0, 2298, 2414, 2355, 2160, 1584, + 1115, 1349, 2022, 3000, 3585, 1751, 1024, 1398, + 0, 1191, 3177, 3342, 3377, 2277, 1124, 914, + 1094, 1158, 1371, 2973, 3320, 3253, 614, 540 + }, + { + 2099, 2469, 2236, 702, 2306, 2265, 1928, 1672, + 1726, 1987, 2127, 1964, 1717, 1825, 1554, 2705, + 1775, 1502, 1837, 2050, 2091, 1947, 1738, 1739, + 1928, 2072, 2002, 1816, 1805, 1889, 1699, 2154, + 2518, 1076, 1654, 2496, 1911, 1823, 1821, 1849, + 1867, 1940, 2050, 1998, 1745, 1642, 1760, 2739, + 1747, 1219, 1994, 2375, 1945, 1549, 1785, 2277, + 2037, 959, 3051, 1449, 1562, 2284, 2050, 1433, + 2072, 2097, 1863, 1753, 1851, 1981, 1988, 1929, + 1821, 1824, 1884, 1978, 2013, 1910, 1751, 1793, + 1972, 2055, 2014, 1821, 1560, 1700, 2938, 1246, + 1937, 1827, 1891, 2013, 2000, 1913, 1785, 1739, + 1875, 2124, 2270, 1727, 862, 2745, 2341, 1478, + 1641, 2081, 1896, 1913, 2030, 1912, 1750, 1767, + 1969, 2110, 2036, 1726, 1441, 2175, 2393, 1596, + 1717, 1928, 1974, 1960, 1874, 1981, 1892, 1671, + 1728, 2290, 2824, 56, 2531, 2354, 1939, 1671, + 1684, 1912, 2091, 2064, 1866, 1685, 1736, 2015, + 2225, 2101, 1361, 1380, 2857, 1977, 1503, 1703, + 2007, 2108, 1943, 1793, 1857, 1922, 1671, 2226, + 2096, 1558, 1797, 1981, 2008, 2034, 1869, 1668, + 1813, 2043, 2128, 1982, 1677, 1472, 1753, 3561, + 869, 1194, 2258, 2509, 1963, 1436, 1561, 2174, + 2442, 1702, 1200, 2655, 1589, 1862, 2067, 1960, + 1757, 1756, 1974, 2111, 2016, 1591, 1633, 2335, + 2028, 1730, 1723, 1922, 2063, 1955, 1810, 1841, + 1901, 1979, 1939, 1732, 1897, 2363, 1614, 1272, + 2407, 2579, 1525, 879, 2556, 2497, 1674, 1351, + 1926, 2700, 844, 2684, 1928, 1498, 1787, 2108, + 2115, 1928, 1585, 1766, 2412, 1472, 1850, 2833, + 998, 1559, 2529, 2010, 2009, 1560, 1460, 2158, + 2552, 1961, 1049, 1816, 2175, 2885, 1132, 1374 + }, + { + 2298, 2981, 1544, 1907, 2114, 2357, 2312, 2031, + 1922, 2051, 2257, 2329, 2136, 1889, 1951, 2330, + 2524, 1904, 1503, 2689, 2381, 1845, 1847, 2222, + 2478, 2244, 1733, 1671, 2468, 3711, 0, 2679, + 2483, 2319, 2099, 1806, 1780, 2394, 3172, 907, + 2428, 2019, 1976, 3332, 949, 2022, 2567, 2323, + 1942, 1935, 2190, 2256, 2131, 2022, 2136, 2259, + 2068, 1982, 2103, 2405, 2424, 1147, 2599, 2418, + 2080, 1906, 1999, 2236, 2336, 2151, 1935, 1952, + 2363, 2253, 1921, 2191, 2200, 1994, 1982, 2335, + 2577, 1839, 774, 4095, 1331, 2647, 760, 2895, + 2687, 1875, 1701, 2040, 2404, 2410, 2086, 1796, + 1879, 2320, 2724, 2512, 11, 3311, 3102, 1436, + 1248, 3032, 2012, 2081, 2195, 1962, 2073, 2353, + 2250, 1298, 3430, 1288, 2013, 2392, 2304, 2042, + 1870, 2446, 1774, 2216, 2566, 1933, 1739, 2235, + 2345, 2240, 2076, 1867, 2092, 2289, 2236, 2183, + 2067, 1880, 1944, 2478, 2615, 1919, 1406, 1820, + 3158, 2882, 1131, 777, 3423, 2936, 1687, 1391, + 1985, 2647, 2670, 1894, 950, 3538, 1441, 2122, + 2405, 2205, 1920, 1914, 2189, 2417, 2283, 1842, + 1983, 2034, 2172, 2886, 2024, 916, 2464, 2887, + 2448, 1253, 1916, 2446, 2377, 2219, 2125, 1761, + 1342, 3767, 1742, 1619, 2008, 2362, 2340, 2127, + 1995, 1992, 2119, 2263, 2278, 2123, 1862, 1684, + 3480, 1143, 1973, 2577, 2351, 1813, 1654, 2372, + 3429, 458, 2493, 2385, 2266, 2090, 1932, 2110, + 1759, 3261, 1250, 2307, 2104, 1810, 2959, 1710, + 1826, 2277, 2319, 2116, 2022, 2111, 2165, 2106, + 2081, 2200, 2374, 2014, 1103, 3510, 1988, 1764, + 1659, 2400, 2848, 1755, 1832, 1996, 2283, 2580, + 2140, 1399, 2388, 2249, 2290, 2145, 2045, 1628 + }, + { + 1924, 2444, 2813, 2991, 2986, 2843, 2628, 2452, + 2434, 2498, 2306, 1709, 1257, 1437, 1788, 1893, + 1862, 1859, 1900, 1934, 1937, 2067, 2535, 3037, + 2605, 1507, 2993, 4095, 2387, 1241, 1643, 1400, + 1577, 1690, 1700, 1583, 1320, 1297, 897, 4095, + 1859, 4095, 3945, 1699, 4095, 2586, 839, 274, + 2773, 861, 522, 638, 3159, 670, 3569, 3585, + 2275, 2822, 3052, 2773, 1831, 1291, 2065, 1950, + 1808, 1722, 1680, 1706, 1839, 2112, 2552, 3205, + 3077, 2986, 9, 2037, 2278, 2969, 1623, 247, + 814, 3418, 3028, 3659, 3881, 1185, 3474, 610, + 706, 1054, 1511, 1892, 2219, 2487, 2671, 2743, + 2690, 2535, 2346, 2195, 2099, 2027, 1929, 1766, + 1551, 1422, 1955, 3456, 1602, 1469, 1901, 2533, + 2937, 2774, 2129, 1705, 2157, 2768, 2283, 1411, + 1188, 1551, 2052, 2447, 2685, 2751, 2625, 2315, + 1913, 1593, 1500, 1659, 1967, 2259, 2430, 2493, + 2525, 2565, 2554, 2374, 1960, 1424, 1070, 1200, + 1881, 2674, 2940, 2849, 2779, 2370, 1681, 1327, + 1582, 2205, 2654, 2062, 1522, 2701, 2513, 2191, + 1971, 1869, 1866, 1953, 2125, 2366, 2612, 2655, + 1259, 2467, 2051, 1394, 2036, 1824, 2313, 2528, + 2549, 2764, 2979, 100, 3505, 2383, 1098, 570, + 3751, 1455, 1648, 1943, 2152, 2304, 2368, 2476, + 2677, 2783, 2720, 2510, 2188, 1792, 1355, 904, + 494, 1440, 749, 4095, 3212, 2926, 4095, 1520, + 2034, 1383, 1679, 1814, 1792, 1641, 1368, 1075, + 3968, 1321, 4081, 1908, 2868, 2153, 433, 2197, + 2089, 1958, 1946, 1979, 2098, 2196, 2320, 2614, + 2993, 3269, 3108, 2003, 630, 616, 1624, 1690, + 1185, 1322, 1960, 2600, 3081, 3429, 3627, 3562, + 3123, 2349, 1527, 976, 714, 658, 869, 1345 + }, + { + 1978, 2287, 2526, 2669, 2687, 2577, 2388, 2225, + 2197, 2323, 2481, 2505, 2388, 2223, 1976, 1694, + 1507, 1450, 1453, 1439, 1427, 1561, 2010, 2746, + 3403, 3628, 4078, 3807, 2389, 899, 1003, 1447, + 1671, 1739, 1691, 1522, 1184, 554, 648, 3083, + 3818, 3891, 3918, 3834, 3555, 2432, 1470, 767, + 771, 762, 962, 883, 941, 1513, 3249, 4000, + 3729, 3335, 2717, 2321, 2333, 2123, 1688, 1383, + 1269, 1282, 1383, 1574, 1866, 2260, 2766, 3457, + 4095, 3462, 1413, 1042, 1071, 1153, 780, 812, + 1586, 3041, 4083, 3878, 3731, 3467, 2518, 32, + 304, 967, 1415, 1780, 2103, 2382, 2594, 2715, + 2729, 2642, 2496, 2374, 2319, 2292, 2230, 2098, + 1878, 1568, 1256, 1339, 1443, 1902, 2434, 2940, + 3241, 3172, 2728, 2140, 1745, 1611, 1490, 1512, + 1766, 2091, 2349, 2503, 2567, 2543, 2416, 2195, + 1936, 1741, 1692, 1804, 2010, 2210, 2339, 2400, + 2437, 2471, 2465, 2345, 2074, 1728, 1483, 1520, + 1888, 2416, 2792, 2848, 2593, 2085, 1562, 1321, + 1470, 1907, 2449, 2909, 2959, 2629, 2217, 1945, + 1799, 1740, 1744, 1802, 1916, 2092, 2334, 2643, + 2867, 2610, 1676, 1174, 1590, 2542, 2417, 2057, + 2012, 2246, 2772, 2886, 2961, 2174, 1527, 927, + 1176, 1434, 1980, 2292, 2408, 2433, 2521, 2716, + 2869, 2872, 2728, 2479, 2159, 1797, 1417, 1020, + 551, 0, 965, 3313, 4095, 4095, 4036, 1891, + 1026, 1725, 2085, 2203, 2157, 1975, 1642, 1080, + 858, 1439, 3279, 3362, 2978, 2705, 2345, 2051, + 1614, 1552, 1722, 1899, 1989, 2034, 2174, 2497, + 2904, 3160, 3029, 2405, 1550, 993, 950, 1074, + 1350, 1848, 2358, 2732, 2971, 3126, 3193, 3108, + 2807, 2308, 1746, 1299, 1076, 1091, 1304, 1631 + }, + { + 1974, 2482, 2875, 3104, 3130, 2965, 2685, 2444, + 2398, 2432, 1941, 1529, 1311, 1281, 1417, 1638, + 1741, 1802, 1867, 1875, 1834, 1943, 2424, 3078, + 2950, 3018, 3414, 3767, 1893, 292, 1172, 1495, + 1619, 1650, 1618, 1519, 1311, 830, 542, 2902, + 3970, 3585, 3716, 4095, 3246, 2351, 1679, 1158, + 715, 432, 429, 557, 1153, 2006, 2746, 3118, + 3104, 2866, 2619, 2497, 2500, 2536, 2518, 2417, + 2251, 2029, 1729, 1335, 915, 637, 609, 848, + 1492, 2361, 3139, 3618, 3787, 3748, 3570, 3205, + 2516, 1447, 246, 0, 141, 0, 1344, 3608, + 3264, 2852, 2669, 2550, 2442, 2336, 2235, 2148, + 2085, 2047, 2016, 1955, 1850, 1735, 1654, 1631, + 1679, 1810, 2036, 2349, 2723, 2936, 2377, 1778, + 1434, 1578, 2217, 2631, 2160, 1995, 2078, 2414, + 2843, 2278, 1754, 1414, 1251, 1265, 1475, 1865, + 2337, 2726, 2890, 2798, 2540, 2262, 2057, 1923, + 1798, 1655, 1563, 1640, 1947, 2381, 2691, 2628, + 2133, 1456, 1160, 1408, 1536, 2233, 2960, 3266, + 3025, 2384, 1601, 1562, 1834, 1990, 2038, 2014, + 1962, 1916, 1895, 1901, 1924, 1944, 1932, 1833, + 1534, 1899, 2945, 3446, 3179, 2286, 1999, 2217, + 2057, 1587, 814, 1088, 1536, 1786, 1929, 2092, + 2305, 2494, 2576, 2539, 2454, 2421, 2474, 2546, + 2514, 2299, 1938, 1557, 1276, 1131, 1077, 1094, + 1249, 1656, 2360, 3211, 3866, 3997, 3421, 2169, + 772, 1352, 1724, 1879, 1916, 1860, 1692, 1325, + 485, 1603, 3374, 3302, 2657, 2380, 2388, 2362, + 1822, 1674, 1777, 1871, 1880, 1838, 1921, 2255, + 2723, 3033, 2863, 2051, 920, 840, 1432, 1622, + 1483, 1466, 2179, 2729, 3087, 3321, 3428, 3313, + 2880, 2155, 1339, 723, 458, 499, 853, 1398 + }, + { + 2279, 2196, 2046, 1841, 1621, 1468, 1478, 1682, + 1981, 2172, 2058, 1578, 1603, 1950, 2077, 2075, + 2013, 1946, 1898, 1848, 1763, 1631, 1488, 1448, + 1612, 1884, 2125, 2292, 2378, 2372, 2259, 2020, + 1630, 1020, 0, 1267, 2810, 2483, 2166, 2366, + 3306, 2194, 1046, 725, 1498, 1846, 1907, 1695, + 1498, 1747, 2090, 2433, 2596, 2448, 2018, 1500, + 1142, 1098, 1352, 1750, 2108, 2310, 2340, 2238, + 2048, 1801, 1550, 1398, 1482, 1896, 2603, 1967, + 1676, 1600, 1639, 1732, 1835, 1922, 2015, 2173, + 2124, 2066, 1991, 1537, 1367, 1433, 1626, 1856, + 2058, 2186, 2208, 2120, 1947, 1754, 1650, 1828, + 2055, 1266, 1253, 1769, 2332, 2499, 2108, 1342, + 1447, 2148, 2385, 2317, 2024, 1567, 936, 850, + 1389, 2093, 2694, 2927, 2690, 2117, 1485, 1062, + 1250, 1474, 1423, 1730, 2003, 2236, 2408, 2460, + 2333, 2031, 1654, 1353, 1243, 1334, 1540, 1754, + 1927, 2090, 2286, 2487, 2568, 2383, 1892, 1253, + 771, 729, 1201, 1984, 2690, 2961, 2668, 1948, + 1188, 1675, 1847, 1892, 1871, 1789, 1633, 1343, + 592, 1891, 3408, 2563, 2227, 1999, 1802, 1619, + 1456, 1343, 1324, 1459, 1807, 2286, 2475, 2255, + 2021, 1904, 1852, 1813, 1759, 1681, 1589, 1523, + 1555, 1773, 2269, 2057, 1921, 1968, 2072, 2100, + 2003, 1824, 1657, 1561, 1535, 1547, 1591, 1712, + 1955, 2290, 2567, 2580, 2192, 1458, 763, 1698, + 1995, 1819, 1036, 1630, 2202, 2731, 2993, 1909, + 1342, 1142, 1288, 1852, 2834, 1816, 1329, 1438, + 1885, 2275, 2331, 2041, 1606, 1686, 1699, 1684, + 1779, 1942, 2064, 2106, 2069, 1940, 1660, 1087, + 1472, 2026, 2215, 2204, 2118, 1966, 1691, 1679, + 1969, 2028, 1853, 1400, 1193, 1701, 2076, 2258 + }, + { + 2084, 2007, 2033, 2179, 2411, 2617, 2660, 2466, + 2097, 1732, 1555, 1632, 1858, 2024, 1955, 1623, + 1136, 625, 1234, 1712, 2121, 2454, 2702, 2873, + 2976, 3011, 2962, 2795, 2457, 1905, 1840, 2225, + 2377, 2208, 1524, 1695, 2066, 2151, 2080, 1907, + 1634, 1214, 462, 498, 1595, 2495, 3312, 2586, + 2206, 2032, 2016, 2142, 2357, 2511, 2491, 2398, + 2385, 2535, 2903, 2783, 2397, 2106, 1917, 1809, + 1778, 1839, 1977, 2104, 2076, 1772, 1187, 711, + 1265, 1519, 1606, 1578, 1443, 1129, 1080, 2214, + 3585, 4095, 3795, 3636, 3792, 3998, 2811, 1929, + 1447, 1217, 1030, 812, 683, 851, 1401, 2164, + 2767, 2855, 2327, 1433, 643, 374, 758, 1597, + 2511, 3177, 3493, 3554, 3493, 3321, 2894, 2032, + 1194, 1977, 2284, 2397, 2397, 2311, 2145, 1894, + 1549, 1075, 625, 1121, 1481, 1663, 1693, 1674, + 1732, 1935, 2244, 2554, 2771, 2876, 2920, 2957, + 2974, 2899, 2671, 2325, 2013, 1910, 2072, 2352, + 2441, 2048, 1087, 0, 824, 1237, 1469, 1617, + 1714, 1765, 1732, 1478, 1188, 3153, 4095, 4095, + 4095, 4095, 2770, 981, 1235, 1454, 1479, 1428, + 1319, 1132, 794, 25, 829, 2188, 2980, 3127, + 2836, 2442, 2205, 2192, 2294, 2361, 2327, 2242, + 2205, 2259, 2350, 2372, 2259, 2048, 1854, 1787, + 1878, 2061, 2231, 2314, 2296, 2191, 1991, 1659, + 1187, 672, 673, 528, 1256, 2661, 4095, 3440, + 3037, 2800, 2620, 2461, 2317, 2194, 2102, 2051, + 2043, 2043, 1976, 1822, 1654, 1532, 1474, 1475, + 1527, 1611, 1700, 1786, 1889, 2036, 2231, 2419, + 2501, 2470, 2431, 2455, 2562, 2770, 3156, 4014, + 3029, 1936, 1119, 505, 696, 858, 752, 640, + 1462, 2286, 2867, 3090, 3001, 2745, 2465, 2238 + }, + { + 2258, 2290, 2417, 2658, 2973, 3251, 3352, 3201, + 2860, 2505, 2321, 2374, 2560, 2670, 2531, 2115, + 1533, 918, 1416, 1778, 2070, 2285, 2419, 2481, + 2484, 2428, 2301, 2070, 1683, 1099, 1019, 1408, + 1581, 1450, 821, 1063, 1519, 1701, 1738, 1680, + 1529, 1233, 605, 763, 1977, 2985, 3901, 3262, + 2954, 2837, 2860, 3007, 3224, 3362, 3307, 3161, + 3080, 3146, 3416, 3186, 2682, 2266, 1948, 1710, + 1551, 1488, 1510, 1531, 1408, 1023, 374, 0, + 375, 619, 716, 717, 629, 380, 412, 1642, + 3121, 4054, 3575, 3547, 3836, 4095, 3115, 2355, + 1985, 1857, 1758, 1612, 1539, 1743, 2310, 3072, + 3653, 3701, 3115, 2145, 1264, 891, 1160, 1875, + 2659, 3193, 3376, 3306, 3120, 2831, 2298, 1343, + 426, 1147, 1410, 1497, 1491, 1418, 1284, 1084, + 807, 416, 63, 669, 1147, 1455, 1615, 1727, + 1916, 2244, 2672, 3091, 3406, 3595, 3708, 3795, + 3846, 3786, 3554, 3185, 2831, 2670, 2758, 2948, + 2936, 2432, 1352, 17, 838, 1124, 1232, 1261, + 1248, 1198, 1078, 750, 403, 2327, 4029, 3456, + 3518, 3701, 2009, 284, 617, 927, 1055, 1114, + 1122, 1056, 839, 191, 1111, 2580, 3472, 3709, + 3495, 3163, 2973, 2990, 3104, 3167, 3111, 2988, + 2897, 2881, 2890, 2819, 2605, 2285, 1977, 1794, + 1770, 1840, 1904, 1887, 1779, 1596, 1331, 949, + 441, 0, 0, 0, 537, 1988, 3802, 2902, + 2585, 2443, 2365, 2314, 2281, 2269, 2286, 2340, + 2430, 2519, 2531, 2443, 2327, 2244, 2207, 2214, + 2255, 2312, 2359, 2388, 2421, 2486, 2589, 2678, + 2654, 2515, 2366, 2282, 2284, 2393, 2689, 3468, + 2415, 1266, 411, 0, 0, 127, 46, 0, + 852, 1745, 2408, 2723, 2735, 2585, 2416, 2301 + }, + { + 2185, 2170, 2249, 2442, 2711, 2942, 2998, 2803, + 2420, 2025, 1803, 1822, 1976, 2058, 1894, 1457, + 857, 229, 718, 1076, 1368, 1587, 1730, 1806, + 1827, 1793, 1693, 1493, 1141, 595, 558, 991, + 1213, 1133, 558, 855, 1367, 1607, 1703, 1705, + 1613, 1376, 806, 1021, 2290, 3352, 4095, 3728, + 3467, 3392, 3454, 3636, 3884, 4049, 4017, 3890, + 3822, 3896, 4095, 3941, 3432, 3007, 2675, 2419, + 2238, 2150, 2142, 2130, 1971, 1548, 856, 289, + 769, 966, 1015, 968, 831, 532, 515, 1697, + 3129, 4016, 3493, 3422, 3671, 3972, 2878, 2086, + 1687, 1532, 1411, 1246, 1156, 1348, 1907, 2662, + 3242, 3290, 2708, 1746, 875, 515, 800, 1533, + 2337, 2892, 3098, 3053, 2893, 2630, 2124, 1196, + 307, 1055, 1344, 1457, 1476, 1428, 1316, 1137, + 880, 506, 170, 789, 1280, 1597, 1765, 1883, + 2074, 2404, 2832, 3249, 3559, 3741, 3847, 3925, + 3966, 3894, 3649, 3267, 2899, 2723, 2796, 2972, + 2944, 2425, 1330, 0, 789, 1062, 1158, 1176, + 1153, 1095, 966, 632, 279, 2200, 3899, 3324, + 3385, 3569, 1879, 157, 493, 808, 941, 1006, + 1021, 961, 751, 110, 1038, 2513, 3413, 3656, + 3448, 3122, 2937, 2959, 3077, 3143, 3090, 2969, + 2878, 2864, 2872, 2800, 2584, 2262, 1951, 1765, + 1737, 1804, 1864, 1844, 1732, 1545, 1277, 892, + 383, 0, 0, 0, 479, 1933, 3751, 2856, + 2546, 2411, 2343, 2302, 2281, 2282, 2313, 2383, + 2489, 2596, 2626, 2558, 2462, 2398, 2382, 2409, + 2471, 2548, 2614, 2662, 2712, 2794, 2912, 3014, + 3002, 2872, 2730, 2651, 2655, 2764, 3057, 3829, + 2767, 1607, 736, 79, 241, 388, 280, 179, + 1024, 1882, 2507, 2783, 2752, 2559, 2345, 2185 + } +}; diff --git a/util/sample_parser.py b/util/sample_parser.py new file mode 100644 index 000000000000..a1d6f6f92d84 --- /dev/null +++ b/util/sample_parser.py @@ -0,0 +1,39 @@ +#! /bin/python +# +# Copyright 2019 Jack Humbert +# +# 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 2 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 . +# + +import wave, struct, sys + +waveFile = wave.open(sys.argv[1], 'r') +# print(str(waveFile.getparams())) +# sys.exit() + +if (waveFile.getsampwidth() != 2): + raise(Exception("This script currently only works with 16bit audio files")) + +length = waveFile.getnframes() +out = "#define DAC_SAMPLE_CUSTOM_LENGTH " + str(length) + "\n\n" +out += "static const dacsample_t dac_sample_custom[" + str(length) + "] = {" +for i in range(0,length): + if (i % 8 == 0): + out += "\n " + waveData = waveFile.readframes(1) + data = struct.unpack(". +# + +import wave, struct, sys + +waveFile = wave.open(sys.argv[1], 'r') + +length = waveFile.getnframes() +out = "#define DAC_WAVETABLE_CUSTOM_LENGTH " + str(int(length / 256)) + "\n\n" +out += "static const dacsample_t dac_wavetable_custom[" + str(int(length / 256)) + "][256] = {" +for i in range(0,length): + if (i % 8 == 0): + out += "\n " + if (i % 256 == 0): + out = out[:-2] + out += "{\n " + waveData = waveFile.readframes(1) + data = struct.unpack(" Date: Sun, 16 Jun 2019 15:26:01 +0200 Subject: [PATCH 003/153] refactoring: rename audio_ to reflect their supported hardware-platform and audio-generation method: avr vs arm, and pwm vs dac --- common_features.mk | 6 +++++- quantum/audio/audio.h | 2 +- quantum/audio/{audio_avr.c => audio_avr_pwm.c} | 0 quantum/audio/{audio_chibios.c => audio_chibios_dac.c} | 0 quantum/audio/{audio_arm.h => audio_chibios_dac.h} | 0 5 files changed, 6 insertions(+), 2 deletions(-) rename quantum/audio/{audio_avr.c => audio_avr_pwm.c} (100%) rename quantum/audio/{audio_chibios.c => audio_chibios_dac.c} (100%) rename quantum/audio/{audio_arm.h => audio_chibios_dac.h} (100%) diff --git a/common_features.mk b/common_features.mk index ecb4f5576bf9..fe392d3a64e8 100644 --- a/common_features.mk +++ b/common_features.mk @@ -43,11 +43,15 @@ ifeq ($(strip $(COMMAND_ENABLE)), yes) endif ifeq ($(strip $(AUDIO_ENABLE)), yes) + AUDIO_DRIVER ?= pwm + ifeq ($(PLATFORM),CHIBIOS) + AUDIO_DRIVER ?= dac + endif OPT_DEFS += -DAUDIO_ENABLE MUSIC_ENABLE = yes SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c SRC += $(QUANTUM_DIR)/process_keycode/process_clicky.c - SRC += $(QUANTUM_DIR)/audio/audio_$(PLATFORM_KEY).c + SRC += $(QUANTUM_DIR)/audio/audio_$(PLATFORM_KEY)_$(AUDIO_DRIVER).c SRC += $(QUANTUM_DIR)/audio/voices.c SRC += $(QUANTUM_DIR)/audio/luts.c endif diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 7f0ade50378d..4894c5740035 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -28,7 +28,7 @@ #include "quantum.h" #include #if defined(PROTOCOL_CHIBIOS) - #include "audio_arm.h" + #include "audio_chibios_dac.h" #endif // Largely untested PWM audio mode (doesn't sound as good) diff --git a/quantum/audio/audio_avr.c b/quantum/audio/audio_avr_pwm.c similarity index 100% rename from quantum/audio/audio_avr.c rename to quantum/audio/audio_avr_pwm.c diff --git a/quantum/audio/audio_chibios.c b/quantum/audio/audio_chibios_dac.c similarity index 100% rename from quantum/audio/audio_chibios.c rename to quantum/audio/audio_chibios_dac.c diff --git a/quantum/audio/audio_arm.h b/quantum/audio/audio_chibios_dac.h similarity index 100% rename from quantum/audio/audio_arm.h rename to quantum/audio/audio_chibios_dac.h From 4d6e7f905fd5b6921003d55cda743c7f60712435 Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 17 Jun 2019 05:43:40 +0200 Subject: [PATCH 004/153] refactoring: deducplicate ISR code to update the pwm duty-cycle and period in the avr-pwm-implementation pulls three copies of the same code into one function which should improve readability and maintainability :-) --- quantum/audio/audio_avr_pwm.c | 354 +++++++++++----------------------- 1 file changed, 112 insertions(+), 242 deletions(-) diff --git a/quantum/audio/audio_avr_pwm.c b/quantum/audio/audio_avr_pwm.c index 1bac43bb4374..3a84ec39c6f7 100644 --- a/quantum/audio/audio_avr_pwm.c +++ b/quantum/audio/audio_avr_pwm.c @@ -130,7 +130,7 @@ bool sliding = false; float place = 0; -uint8_t* sample; +uint8_t *sample; uint16_t sample_length = 0; bool playing_notes = false; @@ -326,145 +326,102 @@ float vibrato(float average_freq) { #endif -#ifdef CPIN_AUDIO -ISR(TIMER3_AUDIO_vect) { - float freq; +/* out of a possibly polyphonic setup, retrieve the frequency for a single voice + to calculate the pwm period and duty-cycle from, relative to the cpy-frequency +*/ +float pwm_audio_get_single_voice_frequency(uint8_t voice) { + float frequency = 0.0; - if (playing_note) { - if (voices > 0) { -# ifdef BPIN_AUDIO - float freq_alt = 0; - if (voices > 1) { - if (polyphony_rate == 0) { - if (glissando) { - if (frequency_alt != 0 && frequency_alt < frequencies[voices - 2] && frequency_alt < frequencies[voices - 2] * pow(2, -440 / frequencies[voices - 2] / 12 / 2)) { - frequency_alt = frequency_alt * pow(2, 440 / frequency_alt / 12 / 2); - } else if (frequency_alt != 0 && frequency_alt > frequencies[voices - 2] && frequency_alt > frequencies[voices - 2] * pow(2, 440 / frequencies[voices - 2] / 12 / 2)) { - frequency_alt = frequency_alt * pow(2, -440 / frequency_alt / 12 / 2); - } else { - frequency_alt = frequencies[voices - 2]; - } - } else { - frequency_alt = frequencies[voices - 2]; - } - -# ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq_alt = vibrato(frequency_alt); - } else { - freq_alt = frequency_alt; - } -# else - freq_alt = frequency_alt; -# endif - } + if (voice > voices) return frequency; - if (envelope_index < 65535) { - envelope_index++; - } + if (glissando) { + if (frequency != 0 && frequency < frequencies[voices - voice] && frequency < frequencies[voices - voice] * pow(2, -440 / frequencies[voices - voice] / 12 / 2)) { + frequency = frequency * pow(2, 440 / frequency / 12 / 2); + } else if (frequency != 0 && frequency > frequencies[voices - voice] && frequency > frequencies[voices - voice] * pow(2, 440 / frequencies[voices - voice] / 12 / 2)) { + frequency = frequency * pow(2, -440 / frequency / 12 / 2); + } else { + frequency = frequencies[voices - voice]; + } + } else { + frequency = frequencies[voices - voice]; + } - freq_alt = voice_envelope(freq_alt); +#ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + frequency = vibrato(frequency); + } +#endif - if (freq_alt < 30.517578125) { - freq_alt = 30.52; - } + if (envelope_index < 65535) { + envelope_index++; + } - TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq_alt * CPU_PRESCALER)); - TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre); - } -# endif + frequency = voice_envelope(frequency); + + if (frequency < 30.517578125) { + frequency = 30.52; + } + + return frequency; +} + +void pwm_audio_timer_task(float *freq, float *freq_alt) { + if (playing_note) { + if (voices > 0) { +#ifdef BPIN_AUDIO + *freq_alt = pwm_audio_get_single_voice_frequency(2); +#else + *freq_alt = 0.0f; +#endif if (polyphony_rate > 0) { if (voices > 1) { voice_place %= voices; - if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { - voice_place = (voice_place + 1) % voices; - place = 0.0; - } + // if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { + // voice_place = (voice_place + 1) % voices; + // place = 0.0; + // } } -# ifdef VIBRATO_ENABLE +#ifdef VIBRATO_ENABLE if (vibrato_strength > 0) { - freq = vibrato(frequencies[voice_place]); + *freq = vibrato(frequencies[voice_place]); } else { - freq = frequencies[voice_place]; + *freq = frequencies[voice_place]; } -# else - freq = frequencies[voice_place]; -# endif +#else + *freq = frequencies[voice_place]; +#endif } else { - if (glissando) { - if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440 / frequencies[voices - 1] / 12 / 2)) { - frequency = frequency * pow(2, 440 / frequency / 12 / 2); - } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440 / frequencies[voices - 1] / 12 / 2)) { - frequency = frequency * pow(2, -440 / frequency / 12 / 2); - } else { - frequency = frequencies[voices - 1]; - } - } else { - frequency = frequencies[voices - 1]; - } - -# ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq = vibrato(frequency); - } else { - freq = frequency; - } -# else - freq = frequency; -# endif - } - - if (envelope_index < 65535) { - envelope_index++; + *freq = pwm_audio_get_single_voice_frequency(1); } - - freq = voice_envelope(freq); - - if (freq < 30.517578125) { - freq = 30.52; - } - - TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); - TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); } } if (playing_notes) { if (note_frequency > 0) { -# ifdef VIBRATO_ENABLE +#ifdef VIBRATO_ENABLE if (vibrato_strength > 0) { - freq = vibrato(note_frequency); + *freq = vibrato(note_frequency); } else { - freq = note_frequency; + *freq = note_frequency; } -# else - freq = note_frequency; -# endif +#else + *freq = note_frequency; +#endif if (envelope_index < 65535) { envelope_index++; } - freq = voice_envelope(freq); - - TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); - TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); - } else { - TIMER_3_PERIOD = 0; - TIMER_3_DUTY_CYCLE = 0; + *freq = voice_envelope(*freq); } note_position++; bool end_of_note = false; - if (TIMER_3_PERIOD > 0) { - if (!note_resting) - end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF - 1)); - else - end_of_note = (note_position >= (note_length)); - } else { - end_of_note = (note_position >= (note_length)); - } + if (!note_resting) + end_of_note = (note_position >= (note_length * 8 - 1)); + else + end_of_note = (note_position >= (note_length * 8)); if (end_of_note) { current_note++; @@ -472,8 +429,6 @@ ISR(TIMER3_AUDIO_vect) { if (notes_repeat) { current_note = 0; } else { - DISABLE_AUDIO_COUNTER_3_ISR; - DISABLE_AUDIO_COUNTER_3_OUTPUT; playing_notes = false; return; } @@ -497,150 +452,65 @@ ISR(TIMER3_AUDIO_vect) { note_position = 0; } - } - if (!audio_config.enable) { - playing_notes = false; - playing_note = false; + if (!audio_config.enable) { + playing_notes = false; + playing_note = false; + } } } -#endif - -#ifdef BPIN_AUDIO -ISR(TIMER1_AUDIO_vect) { -# if defined(BPIN_AUDIO) && !defined(CPIN_AUDIO) - float freq = 0; - - if (playing_note) { - if (voices > 0) { - if (polyphony_rate > 0) { - if (voices > 1) { - voice_place %= voices; - if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { - voice_place = (voice_place + 1) % voices; - place = 0.0; - } - } - -# ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq = vibrato(frequencies[voice_place]); - } else { - freq = frequencies[voice_place]; - } -# else - freq = frequencies[voice_place]; -# endif - } else { - if (glissando) { - if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440 / frequencies[voices - 1] / 12 / 2)) { - frequency = frequency * pow(2, 440 / frequency / 12 / 2); - } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440 / frequencies[voices - 1] / 12 / 2)) { - frequency = frequency * pow(2, -440 / frequency / 12 / 2); - } else { - frequency = frequencies[voices - 1]; - } - } else { - frequency = frequencies[voices - 1]; - } - -# ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq = vibrato(frequency); - } else { - freq = frequency; - } -# else - freq = frequency; -# endif - } - - if (envelope_index < 65535) { - envelope_index++; - } - freq = voice_envelope(freq); - - if (freq < 30.517578125) { - freq = 30.52; - } +#ifdef CPIN_AUDIO +ISR(TIMER3_AUDIO_vect) { + float freq, freq_alt; + pwm_audio_timer_task(&freq, &freq_alt); - TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); - TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); - } +# ifdef BPIN_AUDIO + if (freq > 0) { + TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq_alt * CPU_PRESCALER)); + TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre); + } else { + TIMER_1_PERIOD = 0; + TIMER_1_DUTY_CYCLE = 0; } +# endif - if (playing_notes) { - if (note_frequency > 0) { -# ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq = vibrato(note_frequency); - } else { - freq = note_frequency; - } -# else - freq = note_frequency; -# endif - - if (envelope_index < 65535) { - envelope_index++; - } - freq = voice_envelope(freq); - - TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); - TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); - } else { - TIMER_1_PERIOD = 0; - TIMER_1_DUTY_CYCLE = 0; - } + if (freq > 0) { + TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); + } else { + TIMER_3_PERIOD = 0; + TIMER_3_DUTY_CYCLE = 0; + } - note_position++; - bool end_of_note = false; - if (TIMER_1_PERIOD > 0) { - if (!note_resting) - end_of_note = (note_position >= (note_length / TIMER_1_PERIOD * 0xFFFF - 1)); - else - end_of_note = (note_position >= (note_length)); - } else { - end_of_note = (note_position >= (note_length)); - } + if (!playing_notes) { + DISABLE_AUDIO_COUNTER_3_ISR; + DISABLE_AUDIO_COUNTER_3_OUTPUT; +# ifdef BPIN_AUDIO + DISABLE_AUDIO_COUNTER_1_ISR; + DISABLE_AUDIO_COUNTER_1_OUTPUT; +# endif + } +} +#endif - if (end_of_note) { - current_note++; - if (current_note >= notes_count) { - if (notes_repeat) { - current_note = 0; - } else { - DISABLE_AUDIO_COUNTER_1_ISR; - DISABLE_AUDIO_COUNTER_1_OUTPUT; - playing_notes = false; - return; - } - } - if (!note_resting) { - note_resting = true; - current_note--; - if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) { - note_frequency = 0; - note_length = 1; - } else { - note_frequency = (*notes_pointer)[current_note][0]; - note_length = 1; - } - } else { - note_resting = false; - envelope_index = 0; - note_frequency = (*notes_pointer)[current_note][0]; - note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); - } +#ifdef BPIN_AUDIO +ISR(TIMER1_AUDIO_vect) { +# if defined(BPIN_AUDIO) && !defined(CPIN_AUDIO) + float freq, freq_alt; + pwm_audio_timer_task(&freq, &freq_alt); - note_position = 0; - } + if (freq > 0) { + TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); + } else { + TIMER_1_PERIOD = 0; + TIMER_1_DUTY_CYCLE = 0; } - if (!audio_config.enable) { - playing_notes = false; - playing_note = false; + if (!playing_notes) { + DISABLE_AUDIO_COUNTER_1_ISR; + DISABLE_AUDIO_COUNTER_1_OUTPUT; } # endif } From a1651dc88cebd4e99924258be39c922c093c7cb5 Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 17 Jun 2019 07:15:18 +0200 Subject: [PATCH 005/153] refactoring: move common code of arm and avr implementation into a separate/new file --- common_features.mk | 1 + quantum/audio/audio.c | 506 +++++++++++++++++++++ quantum/audio/audio.h | 8 + quantum/audio/audio_avr_pwm.c | 726 +++++++----------------------- quantum/audio/audio_chibios_dac.c | 294 +----------- 5 files changed, 687 insertions(+), 848 deletions(-) create mode 100644 quantum/audio/audio.c diff --git a/common_features.mk b/common_features.mk index fe392d3a64e8..389420fc01e1 100644 --- a/common_features.mk +++ b/common_features.mk @@ -51,6 +51,7 @@ ifeq ($(strip $(AUDIO_ENABLE)), yes) MUSIC_ENABLE = yes SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c SRC += $(QUANTUM_DIR)/process_keycode/process_clicky.c + SRC += $(QUANTUM_DIR)/audio/audio.c ## common audio code, hardware agnostic SRC += $(QUANTUM_DIR)/audio/audio_$(PLATFORM_KEY)_$(AUDIO_DRIVER).c SRC += $(QUANTUM_DIR)/audio/voices.c SRC += $(QUANTUM_DIR)/audio/luts.c diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c new file mode 100644 index 000000000000..21d68b8bd44d --- /dev/null +++ b/quantum/audio/audio.c @@ -0,0 +1,506 @@ +/* Copyright 2016-2019 Jack Humbert + * + * 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 2 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 . + */ +#include "audio.h" +#include "keymap.h" +#include "wait.h" + +#include "eeconfig.h" + +uint8_t voices = 0; +float frequencies[8] = { 0.0 }; +int volumes[8] = { 0 }; + +//float place = 0; +int voice_place = 0; +float frequency = 0; +float frequency_alt = 0; +int volume = 0; +long position = 0; + +bool playing_notes = false; +bool playing_note = false; +float note_frequency = 0; +float note_length = 0; +uint8_t note_tempo = TEMPO_DEFAULT; +float note_timbre = TIMBRE_DEFAULT; +uint32_t note_position = 0; +float (* notes_pointer)[][2]; +uint16_t notes_count; +bool notes_repeat; +bool note_resting = false; + +uint16_t current_note = 0; +uint8_t rest_counter = 0; + +#ifdef VIBRATO_ENABLE +float vibrato_counter = 0; +float vibrato_strength = .5; +float vibrato_rate = 0.125; +#endif + +float polyphony_rate = 0; + +static bool audio_initialized = false; + +audio_config_t audio_config; + +uint16_t envelope_index = 0; +bool glissando = true; + +#ifndef STARTUP_SONG + #define STARTUP_SONG SONG(STARTUP_SOUND) +#endif +#ifndef AUDIO_ON_SONG + #define AUDIO_ON_SONG SONG(AUDIO_ON_SOUND) +#endif +#ifndef AUDIO_OFF_SONG + #define AUDIO_OFF_SONG SONG(AUDIO_OFF_SOUND) +#endif +float startup_song[][2] = STARTUP_SONG; +float audio_on_song[][2] = AUDIO_ON_SONG; +float audio_off_song[][2] = AUDIO_OFF_SONG; + +void audio_init() { + + if (audio_initialized) { + return; + } + + // Check EEPROM +//TODO: avr defines? + #if defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE) + if (!eeconfig_is_enabled()) { + eeconfig_init(); + } + audio_config.raw = eeconfig_read_audio(); + #else // ARM EEPROM + audio_config.enable = true; + #ifdef AUDIO_CLICKY_ON + audio_config.clicky_enable = true; + #endif + #endif // ARM EEPROM + + + if (!audio_initialized) { + audio_initialize_hardware(); + audio_initialized = true; + } + stop_all_notes(); +} + +void audio_startup(void) { + if (audio_config.enable) { + PLAY_SONG(startup_song); + + } + +} + +void stop_all_notes() { + dprintf("audio stop all notes"); + + if (!audio_initialized) { + audio_init(); + } + voices = 0; + + audio_stop_hardware(); + + playing_notes = false; + playing_note = false; + frequency = 0; + frequency_alt = 0; + volume = 0; + + for (uint8_t i = 0; i < 8; i++) + { + frequencies[i] = 0; + volumes[i] = 0; + } +} + +void stop_note(float freq) { + dprintf("audio stop note freq=%d", (int)freq); + + if (playing_note) { + if (!audio_initialized) { + audio_init(); + } + for (int i = 7; i >= 0; i--) { + if (frequencies[i] == freq) { + frequencies[i] = 0; + volumes[i] = 0; + for (int j = i; (j < 7); j++) { + frequencies[j] = frequencies[j+1]; + frequencies[j+1] = 0; + volumes[j] = volumes[j+1]; + volumes[j+1] = 0; + } + break; + } + } + voices--; + if (voices < 0) + voices = 0; + if (voice_place >= voices) { + voice_place = 0; + } + if (voices == 0) { + playing_note = false; + + audio_stop_hardware(); + + frequency = 0; + frequency_alt = 0; + volume = 0; + playing_note = false; + } + } +} + +void play_note(float freq, int vol) { + + dprintf("audio play note freq=%d vol=%d", (int)freq, vol); + + if (!audio_initialized) { + audio_init(); + } + + if (audio_config.enable && voices < 8) { + + // Cancel notes if notes are playing + if (playing_notes) + stop_all_notes(); + + playing_note = true; + + envelope_index = 0; + + if (freq > 0) { + frequencies[voices] = freq; + volumes[voices] = vol; + voices++; + } + audio_start_hardware(); + } + +} + +void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) +{ + + if (!audio_initialized) { + audio_init(); + } + + if (audio_config.enable) { + + // Cancel note if a note is playing + if (playing_note) + stop_all_notes(); + + playing_notes = true; + + notes_pointer = np; + notes_count = n_count; + notes_repeat = n_repeat; + + current_note = 0; + + note_frequency = (*notes_pointer)[current_note][0]; + note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); + note_position = 0; + + + audio_start_hardware(); + // play_note((*notes_pointer)[current_note][0], 15); + } +} + +bool is_playing_note(void) { + return playing_note; +} + +bool is_playing_notes(void) { + return playing_notes; +} + +bool is_audio_on(void) { + return (audio_config.enable != 0); +} + +void audio_toggle(void) { + if (audio_config.enable) { + stop_all_notes(); + } + audio_config.enable ^= 1; + eeconfig_update_audio(audio_config.raw); + if (audio_config.enable) { + audio_on_user(); + } +} + +void audio_on(void) { + audio_config.enable = 1; + eeconfig_update_audio(audio_config.raw); + audio_on_user(); + PLAY_SONG(audio_on_song); +} + +void audio_off(void) { + PLAY_SONG(audio_off_song); + wait_ms(100); + stop_all_notes(); + audio_config.enable = 0; + eeconfig_update_audio(audio_config.raw); +} + +#ifdef VIBRATO_ENABLE + +float mod(float a, int b) { + float r = fmod(a, b); + return r < 0 ? r + b : r; +} + +float vibrato(float average_freq) { +#ifdef VIBRATO_STRENGTH_ENABLE + float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); +#else + float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; +#endif + vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH); + return vibrated_freq; +} + +#endif + +/* out of a possibly polyphonic setup, retrieve the frequency for a single voice + to calculate the pwm period and duty-cycle from, relative to the cpy-frequency + */ +float pwm_audio_get_single_voice_frequency( uint8_t voice ) { + float frequency = 0.0; + + if (voice > voices) + return frequency; + + if (glissando) { + if (frequency != 0 && frequency < frequencies[voices - voice] && frequency < frequencies[voices - voice] * pow(2, -440/frequencies[voices - voice]/12/2)) { + frequency = frequency * pow(2, 440/frequency/12/2); + } else if (frequency != 0 && frequency > frequencies[voices - voice] && frequency > frequencies[voices - voice] * pow(2, 440/frequencies[voices - voice]/12/2)) { + frequency = frequency * pow(2, -440/frequency/12/2); + } else { + frequency = frequencies[voices - voice]; + } + } else { + frequency = frequencies[voices - voice]; + } + +#ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + frequency = vibrato(frequency); + } +#endif + + if (envelope_index < 65535) { + envelope_index++; + } + + frequency = voice_envelope(frequency); + + if (frequency < 30.517578125) { + frequency = 30.52; + } + + return frequency; +} + +void pwm_audio_timer_task(float *freq, float *freq_alt) { + + if (playing_note) { + if (voices > 0) { + + #ifdef BPIN_AUDIO + *freq_alt = pwm_audio_get_single_voice_frequency(2); + #else + *freq_alt = 0.0f; + #endif + + if (polyphony_rate > 0) { + if (voices > 1) { + voice_place %= voices; +// if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { +// voice_place = (voice_place + 1) % voices; +// place = 0.0; +// } + } + + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + *freq = vibrato(frequencies[voice_place]); + } else { + *freq = frequencies[voice_place]; + } + #else + *freq = frequencies[voice_place]; + #endif + } else { + *freq = pwm_audio_get_single_voice_frequency(1); + } + } + } + + if (playing_notes) { + if (note_frequency > 0) { + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + *freq = vibrato(note_frequency); + } else { + *freq = note_frequency; + } + #else + *freq = note_frequency; + #endif + + if (envelope_index < 65535) { + envelope_index++; + } + *freq = voice_envelope(*freq); + } + + note_position++; + bool end_of_note = false; + if (!note_resting) + end_of_note = (note_position >= (note_length*8 - 1)); + else + end_of_note = (note_position >= (note_length*8)); + + if (end_of_note) { + current_note++; + if (current_note >= notes_count) { + if (notes_repeat) { + current_note = 0; + } else { + playing_notes = false; + return; + } + } + if (!note_resting) { + note_resting = true; + current_note--; + if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) { + note_frequency = 0; + note_length = 1; + } else { + note_frequency = (*notes_pointer)[current_note][0]; + note_length = 1; + } + } else { + note_resting = false; + envelope_index = 0; + note_frequency = (*notes_pointer)[current_note][0]; + note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); + } + + note_position = 0; + } + + if (!audio_config.enable) { + playing_notes = false; + playing_note = false; + } + } +} + + +#ifdef VIBRATO_ENABLE + +// Vibrato rate functions + +void set_vibrato_rate(float rate) { + vibrato_rate = rate; +} + +void increase_vibrato_rate(float change) { + vibrato_rate *= change; +} + +void decrease_vibrato_rate(float change) { + vibrato_rate /= change; +} + +#ifdef VIBRATO_STRENGTH_ENABLE + +void set_vibrato_strength(float strength) { + vibrato_strength = strength; +} + +void increase_vibrato_strength(float change) { + vibrato_strength *= change; +} + +void decrease_vibrato_strength(float change) { + vibrato_strength /= change; +} + +#endif /* VIBRATO_STRENGTH_ENABLE */ + +#endif /* VIBRATO_ENABLE */ + +// Polyphony functions + +void set_polyphony_rate(float rate) { + polyphony_rate = rate; +} + +void enable_polyphony(void) { + polyphony_rate = 5; +} + +void disable_polyphony(void) { + polyphony_rate = 0; +} + +void increase_polyphony_rate(float change) { + polyphony_rate *= change; +} + +void decrease_polyphony_rate(float change) { + polyphony_rate /= change; +} + +// Timbre function + +void set_timbre(float timbre) { + note_timbre = timbre; +} + +// Tempo functions + +void set_tempo(uint8_t tempo) { + note_tempo = tempo; +} + +void decrease_tempo(uint8_t tempo_change) { + note_tempo += tempo_change; +} + +void increase_tempo(uint8_t tempo_change) { + if (note_tempo - tempo_change < 10) { + note_tempo = 10; + } else { + note_tempo -= tempo_change; + } +} diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 4894c5740035..d78a64bd9d51 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -48,11 +48,19 @@ typedef union { }; } audio_config_t; +// implementation in the audio_avr/arm_* parts +void audio_initialize_hardware(void); +void audio_start_hardware(void); +void audio_stop_hardware(void); + bool is_audio_on(void); void audio_toggle(void); void audio_on(void); void audio_off(void); +float pwm_audio_get_single_voice(uint8_t voice); +void pwm_audio_timer_task(float *freq, float *freq_alt); + // Vibrato rate functions #ifdef VIBRATO_ENABLE diff --git a/quantum/audio/audio_avr_pwm.c b/quantum/audio/audio_avr_pwm.c index 3a84ec39c6f7..93736370c7dd 100644 --- a/quantum/audio/audio_avr_pwm.c +++ b/quantum/audio/audio_avr_pwm.c @@ -18,16 +18,19 @@ #include //#include #if defined(__AVR__) -# include -# include -# include + #include + #include + #include #endif #include "print.h" #include "audio.h" -#include "keymap.h" + #include "wait.h" -#include "eeconfig.h" +//TODO: move into audio-common state +extern bool playing_notes; +extern float note_timbre; +extern uint8_t voices; #define CPU_PRESCALER 8 @@ -35,80 +38,80 @@ // Timer Abstractions // ----------------------------------------------------------------------------- -// Currently we support timers 1 and 3 used at the sime time, channels A-C, -// pins PB5, PB6, PB7, PC4, PC5, and PC6 +//Currently we support timers 1 and 3 used at the sime time, channels A-C, +//pins PB5, PB6, PB7, PC4, PC5, and PC6 #if defined(C6_AUDIO) -# define CPIN_AUDIO -# define CPIN_SET_DIRECTION DDRC |= _BV(PORTC6); -# define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); -# define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A) -# define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A) -# define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1); -# define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)); -# define TIMER_3_PERIOD ICR3 -# define TIMER_3_DUTY_CYCLE OCR3A -# define TIMER3_AUDIO_vect TIMER3_COMPA_vect + #define CPIN_AUDIO + #define CPIN_SET_DIRECTION DDRC |= _BV(PORTC6); + #define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); + #define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A) + #define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A) + #define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1); + #define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)); + #define TIMER_3_PERIOD ICR3 + #define TIMER_3_DUTY_CYCLE OCR3A + #define TIMER3_AUDIO_vect TIMER3_COMPA_vect #endif #if defined(C5_AUDIO) -# define CPIN_AUDIO -# define CPIN_SET_DIRECTION DDRC |= _BV(PORTC5); -# define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3B1) | (0 << COM3B0) | (1 << WGM31) | (0 << WGM30); -# define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3B) -# define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3B) -# define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3B1); -# define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3B1) | _BV(COM3B0)); -# define TIMER_3_PERIOD ICR3 -# define TIMER_3_DUTY_CYCLE OCR3B -# define TIMER3_AUDIO_vect TIMER3_COMPB_vect + #define CPIN_AUDIO + #define CPIN_SET_DIRECTION DDRC |= _BV(PORTC5); + #define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3B1) | (0 << COM3B0) | (1 << WGM31) | (0 << WGM30); + #define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3B) + #define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3B) + #define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3B1); + #define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3B1) | _BV(COM3B0)); + #define TIMER_3_PERIOD ICR3 + #define TIMER_3_DUTY_CYCLE OCR3B + #define TIMER3_AUDIO_vect TIMER3_COMPB_vect #endif #if defined(C4_AUDIO) -# define CPIN_AUDIO -# define CPIN_SET_DIRECTION DDRC |= _BV(PORTC4); -# define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3C1) | (0 << COM3C0) | (1 << WGM31) | (0 << WGM30); -# define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3C) -# define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3C) -# define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3C1); -# define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3C1) | _BV(COM3C0)); -# define TIMER_3_PERIOD ICR3 -# define TIMER_3_DUTY_CYCLE OCR3C -# define TIMER3_AUDIO_vect TIMER3_COMPC_vect + #define CPIN_AUDIO + #define CPIN_SET_DIRECTION DDRC |= _BV(PORTC4); + #define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3C1) | (0 << COM3C0) | (1 << WGM31) | (0 << WGM30); + #define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3C) + #define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3C) + #define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3C1); + #define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3C1) | _BV(COM3C0)); + #define TIMER_3_PERIOD ICR3 + #define TIMER_3_DUTY_CYCLE OCR3C + #define TIMER3_AUDIO_vect TIMER3_COMPC_vect #endif #if defined(B5_AUDIO) -# define BPIN_AUDIO -# define BPIN_SET_DIRECTION DDRB |= _BV(PORTB5); -# define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10); -# define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1A) -# define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1A) -# define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1A1); -# define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0)); -# define TIMER_1_PERIOD ICR1 -# define TIMER_1_DUTY_CYCLE OCR1A -# define TIMER1_AUDIO_vect TIMER1_COMPA_vect + #define BPIN_AUDIO + #define BPIN_SET_DIRECTION DDRB |= _BV(PORTB5); + #define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10); + #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1A) + #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1A) + #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1A1); + #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0)); + #define TIMER_1_PERIOD ICR1 + #define TIMER_1_DUTY_CYCLE OCR1A + #define TIMER1_AUDIO_vect TIMER1_COMPA_vect #endif #if defined(B6_AUDIO) -# define BPIN_AUDIO -# define BPIN_SET_DIRECTION DDRB |= _BV(PORTB6); -# define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1B1) | (0 << COM1B0) | (1 << WGM11) | (0 << WGM10); -# define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1B) -# define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1B) -# define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1B1); -# define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1B1) | _BV(COM1B0)); -# define TIMER_1_PERIOD ICR1 -# define TIMER_1_DUTY_CYCLE OCR1B -# define TIMER1_AUDIO_vect TIMER1_COMPB_vect + #define BPIN_AUDIO + #define BPIN_SET_DIRECTION DDRB |= _BV(PORTB6); + #define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1B1) | (0 << COM1B0) | (1 << WGM11) | (0 << WGM10); + #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1B) + #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1B) + #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1B1); + #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1B1) | _BV(COM1B0)); + #define TIMER_1_PERIOD ICR1 + #define TIMER_1_DUTY_CYCLE OCR1B + #define TIMER1_AUDIO_vect TIMER1_COMPB_vect #endif #if defined(B7_AUDIO) -# define BPIN_AUDIO -# define BPIN_SET_DIRECTION DDRB |= _BV(PORTB7); -# define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1C1) | (0 << COM1C0) | (1 << WGM11) | (0 << WGM10); -# define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1C) -# define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1C) -# define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1C1); -# define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1C1) | _BV(COM1C0)); -# define TIMER_1_PERIOD ICR1 -# define TIMER_1_DUTY_CYCLE OCR1C -# define TIMER1_AUDIO_vect TIMER1_COMPC_vect + #define BPIN_AUDIO + #define BPIN_SET_DIRECTION DDRB |= _BV(PORTB7); + #define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1C1) | (0 << COM1C0) | (1 << WGM11) | (0 << WGM10); + #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1C) + #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1C) + #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1C1); + #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1C1) | _BV(COM1C0)); + #define TIMER_1_PERIOD ICR1 + #define TIMER_1_DUTY_CYCLE OCR1C + #define TIMER1_AUDIO_vect TIMER1_COMPC_vect #endif #if !defined(BPIN_AUDIO) && !defined(CPIN_AUDIO) @@ -117,116 +120,55 @@ // ----------------------------------------------------------------------------- -int voices = 0; -int voice_place = 0; -float frequency = 0; -float frequency_alt = 0; -int volume = 0; -long position = 0; -float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -bool sliding = false; float place = 0; -uint8_t *sample; -uint16_t sample_length = 0; - -bool playing_notes = false; -bool playing_note = false; -float note_frequency = 0; -float note_length = 0; -uint8_t note_tempo = TEMPO_DEFAULT; -float note_timbre = TIMBRE_DEFAULT; -uint16_t note_position = 0; -float (*notes_pointer)[][2]; -uint16_t notes_count; -bool notes_repeat; -bool note_resting = false; - -uint16_t current_note = 0; -uint8_t rest_counter = 0; - -#ifdef VIBRATO_ENABLE -float vibrato_counter = 0; -float vibrato_strength = .5; -float vibrato_rate = 0.125; -#endif - -float polyphony_rate = 0; - -static bool audio_initialized = false; - -audio_config_t audio_config; - -uint16_t envelope_index = 0; -bool glissando = true; - -#ifndef STARTUP_SONG -# define STARTUP_SONG SONG(STARTUP_SOUND) -#endif -#ifndef AUDIO_ON_SONG -# define AUDIO_ON_SONG SONG(AUDIO_ON_SOUND) -#endif -#ifndef AUDIO_OFF_SONG -# define AUDIO_OFF_SONG SONG(AUDIO_OFF_SOUND) -#endif -float startup_song[][2] = STARTUP_SONG; -float audio_on_song[][2] = AUDIO_ON_SONG; -float audio_off_song[][2] = AUDIO_OFF_SONG; - -void audio_init() { - // Check EEPROM - if (!eeconfig_is_enabled()) { - eeconfig_init(); - } - audio_config.raw = eeconfig_read_audio(); - if (!audio_initialized) { -// Set audio ports as output -#ifdef CPIN_AUDIO - CPIN_SET_DIRECTION - DISABLE_AUDIO_COUNTER_3_ISR; -#endif -#ifdef BPIN_AUDIO - BPIN_SET_DIRECTION - DISABLE_AUDIO_COUNTER_1_ISR; -#endif - -// TCCR3A / TCCR3B: Timer/Counter #3 Control Registers TCCR3A/TCCR3B, TCCR1A/TCCR1B -// Compare Output Mode (COM3An and COM1An) = 0b00 = Normal port operation -// OC3A -- PC6 -// OC3B -- PC5 -// OC3C -- PC4 -// OC1A -- PB5 -// OC1B -- PB6 -// OC1C -- PB7 - -// Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14. Period = ICR3, Duty Cycle OCR3A) -// OCR3A - PC6 -// OCR3B - PC5 -// OCR3C - PC4 -// OCR1A - PB5 -// OCR1B - PB6 -// OCR1C - PB7 - -// Clock Select (CS3n) = 0b010 = Clock / 8 -#ifdef CPIN_AUDIO - INIT_AUDIO_COUNTER_3 - TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); - TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER)); - TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre); -#endif -#ifdef BPIN_AUDIO - INIT_AUDIO_COUNTER_1 - TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10); - TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER)); - TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre); -#endif +void audio_initialize_hardware() { + + // Set audio ports as output + #ifdef CPIN_AUDIO + CPIN_SET_DIRECTION + DISABLE_AUDIO_COUNTER_3_ISR; + #endif + #ifdef BPIN_AUDIO + BPIN_SET_DIRECTION + DISABLE_AUDIO_COUNTER_1_ISR; + #endif + + // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers TCCR3A/TCCR3B, TCCR1A/TCCR1B + // Compare Output Mode (COM3An and COM1An) = 0b00 = Normal port operation + // OC3A -- PC6 + // OC3B -- PC5 + // OC3C -- PC4 + // OC1A -- PB5 + // OC1B -- PB6 + // OC1C -- PB7 + + // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14. Period = ICR3, Duty Cycle OCR3A) + // OCR3A - PC6 + // OCR3B - PC5 + // OCR3C - PC4 + // OCR1A - PB5 + // OCR1B - PB6 + // OCR1C - PB7 + + // Clock Select (CS3n) = 0b010 = Clock / 8 + #ifdef CPIN_AUDIO + INIT_AUDIO_COUNTER_3 + TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); + TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER)); + TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre); + #endif + #ifdef BPIN_AUDIO + INIT_AUDIO_COUNTER_1 + TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10); + TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER)); + TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre); + #endif audio_initialized = true; - } } void audio_startup() { @@ -235,276 +177,77 @@ void audio_startup() { } } -void stop_all_notes() { - dprintf("audio stop all notes"); - - if (!audio_initialized) { - audio_init(); - } - voices = 0; - -#ifdef CPIN_AUDIO - DISABLE_AUDIO_COUNTER_3_ISR; - DISABLE_AUDIO_COUNTER_3_OUTPUT; -#endif - -#ifdef BPIN_AUDIO - DISABLE_AUDIO_COUNTER_1_ISR; - DISABLE_AUDIO_COUNTER_1_OUTPUT; -#endif - - playing_notes = false; - playing_note = false; - frequency = 0; - frequency_alt = 0; - volume = 0; - - for (uint8_t i = 0; i < 8; i++) { - frequencies[i] = 0; - volumes[i] = 0; - } -} - -void stop_note(float freq) { - dprintf("audio stop note freq=%d", (int)freq); - - if (playing_note) { - if (!audio_initialized) { - audio_init(); - } - for (int i = 7; i >= 0; i--) { - if (frequencies[i] == freq) { - frequencies[i] = 0; - volumes[i] = 0; - for (int j = i; (j < 7); j++) { - frequencies[j] = frequencies[j + 1]; - frequencies[j + 1] = 0; - volumes[j] = volumes[j + 1]; - volumes[j + 1] = 0; - } - break; - } - } - voices--; - if (voices < 0) voices = 0; - if (voice_place >= voices) { - voice_place = 0; - } - if (voices == 0) { -#ifdef CPIN_AUDIO - DISABLE_AUDIO_COUNTER_3_ISR; - DISABLE_AUDIO_COUNTER_3_OUTPUT; -#endif -#ifdef BPIN_AUDIO - DISABLE_AUDIO_COUNTER_1_ISR; - DISABLE_AUDIO_COUNTER_1_OUTPUT; -#endif - frequency = 0; - frequency_alt = 0; - volume = 0; - playing_note = false; - } - } -} - -#ifdef VIBRATO_ENABLE - -float mod(float a, int b) { - float r = fmod(a, b); - return r < 0 ? r + b : r; -} - -float vibrato(float average_freq) { -# ifdef VIBRATO_STRENGTH_ENABLE - float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); -# else - float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; -# endif - vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0 / average_freq)), VIBRATO_LUT_LENGTH); - return vibrated_freq; -} - -#endif - -/* out of a possibly polyphonic setup, retrieve the frequency for a single voice - to calculate the pwm period and duty-cycle from, relative to the cpy-frequency -*/ -float pwm_audio_get_single_voice_frequency(uint8_t voice) { - float frequency = 0.0; - - if (voice > voices) return frequency; - - if (glissando) { - if (frequency != 0 && frequency < frequencies[voices - voice] && frequency < frequencies[voices - voice] * pow(2, -440 / frequencies[voices - voice] / 12 / 2)) { - frequency = frequency * pow(2, 440 / frequency / 12 / 2); - } else if (frequency != 0 && frequency > frequencies[voices - voice] && frequency > frequencies[voices - voice] * pow(2, 440 / frequencies[voices - voice] / 12 / 2)) { - frequency = frequency * pow(2, -440 / frequency / 12 / 2); - } else { - frequency = frequencies[voices - voice]; - } - } else { - frequency = frequencies[voices - voice]; - } +void audio_stop_hardware() { -#ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - frequency = vibrato(frequency); - } -#endif - - if (envelope_index < 65535) { - envelope_index++; - } - - frequency = voice_envelope(frequency); - - if (frequency < 30.517578125) { - frequency = 30.52; - } + #ifdef CPIN_AUDIO + DISABLE_AUDIO_COUNTER_3_ISR; + DISABLE_AUDIO_COUNTER_3_OUTPUT; + #endif - return frequency; + #ifdef BPIN_AUDIO + DISABLE_AUDIO_COUNTER_1_ISR; + DISABLE_AUDIO_COUNTER_1_OUTPUT; + #endif } -void pwm_audio_timer_task(float *freq, float *freq_alt) { - if (playing_note) { - if (voices > 0) { -#ifdef BPIN_AUDIO - *freq_alt = pwm_audio_get_single_voice_frequency(2); -#else - *freq_alt = 0.0f; -#endif - - if (polyphony_rate > 0) { - if (voices > 1) { - voice_place %= voices; - // if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { - // voice_place = (voice_place + 1) % voices; - // place = 0.0; - // } - } - -#ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - *freq = vibrato(frequencies[voice_place]); - } else { - *freq = frequencies[voice_place]; - } -#else - *freq = frequencies[voice_place]; -#endif - } else { - *freq = pwm_audio_get_single_voice_frequency(1); - } - } - } - - if (playing_notes) { - if (note_frequency > 0) { -#ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - *freq = vibrato(note_frequency); - } else { - *freq = note_frequency; - } -#else - *freq = note_frequency; -#endif - - if (envelope_index < 65535) { - envelope_index++; +void audio_start_hardware(void) { + + #ifdef CPIN_AUDIO + ENABLE_AUDIO_COUNTER_3_ISR; + ENABLE_AUDIO_COUNTER_3_OUTPUT; + #endif + #ifdef BPIN_AUDIO + #ifdef CPIN_AUDIO + if (voices > 1) { + ENABLE_AUDIO_COUNTER_1_ISR; + ENABLE_AUDIO_COUNTER_1_OUTPUT; } - *freq = voice_envelope(*freq); - } - - note_position++; - bool end_of_note = false; - if (!note_resting) - end_of_note = (note_position >= (note_length * 8 - 1)); - else - end_of_note = (note_position >= (note_length * 8)); - - if (end_of_note) { - current_note++; - if (current_note >= notes_count) { - if (notes_repeat) { - current_note = 0; - } else { - playing_notes = false; - return; - } - } - if (!note_resting) { - note_resting = true; - current_note--; - if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) { - note_frequency = 0; - note_length = 1; - } else { - note_frequency = (*notes_pointer)[current_note][0]; - note_length = 1; - } - } else { - note_resting = false; - envelope_index = 0; - note_frequency = (*notes_pointer)[current_note][0]; - note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); - } - - note_position = 0; - } - - if (!audio_config.enable) { - playing_notes = false; - playing_note = false; - } - } + #else + ENABLE_AUDIO_COUNTER_1_ISR; + ENABLE_AUDIO_COUNTER_1_OUTPUT; + #endif + #endif } #ifdef CPIN_AUDIO ISR(TIMER3_AUDIO_vect) { + float freq, freq_alt; pwm_audio_timer_task(&freq, &freq_alt); -# ifdef BPIN_AUDIO - if (freq > 0) { - TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq_alt * CPU_PRESCALER)); - TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre); - } else { - TIMER_1_PERIOD = 0; - TIMER_1_DUTY_CYCLE = 0; - } -# endif + #ifdef BPIN_AUDIO + TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq_alt * CPU_PRESCALER)); + TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre); + #endif - if (freq > 0) { - TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + if (freq>0) { + TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); } else { - TIMER_3_PERIOD = 0; + TIMER_3_PERIOD = 0; TIMER_3_DUTY_CYCLE = 0; } if (!playing_notes) { DISABLE_AUDIO_COUNTER_3_ISR; DISABLE_AUDIO_COUNTER_3_OUTPUT; -# ifdef BPIN_AUDIO - DISABLE_AUDIO_COUNTER_1_ISR; - DISABLE_AUDIO_COUNTER_1_OUTPUT; -# endif } + } #endif #ifdef BPIN_AUDIO ISR(TIMER1_AUDIO_vect) { -# if defined(BPIN_AUDIO) && !defined(CPIN_AUDIO) + + #if defined(BPIN_AUDIO) && !defined(CPIN_AUDIO) float freq, freq_alt; pwm_audio_timer_task(&freq, &freq_alt); - if (freq > 0) { - TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + if (freq>0) { + TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); } else { - TIMER_1_PERIOD = 0; + TIMER_1_PERIOD = 0; TIMER_1_DUTY_CYCLE = 0; } @@ -512,171 +255,6 @@ ISR(TIMER1_AUDIO_vect) { DISABLE_AUDIO_COUNTER_1_ISR; DISABLE_AUDIO_COUNTER_1_OUTPUT; } -# endif -} -#endif - -void play_note(float freq, int vol) { - dprintf("audio play note freq=%d vol=%d", (int)freq, vol); - - if (!audio_initialized) { - audio_init(); - } - - if (audio_config.enable && voices < 8) { -#ifdef CPIN_AUDIO - DISABLE_AUDIO_COUNTER_3_ISR; -#endif -#ifdef BPIN_AUDIO - DISABLE_AUDIO_COUNTER_1_ISR; -#endif - - // Cancel notes if notes are playing - if (playing_notes) stop_all_notes(); - - playing_note = true; - - envelope_index = 0; - - if (freq > 0) { - frequencies[voices] = freq; - volumes[voices] = vol; - voices++; - } - -#ifdef CPIN_AUDIO - ENABLE_AUDIO_COUNTER_3_ISR; - ENABLE_AUDIO_COUNTER_3_OUTPUT; -#endif -#ifdef BPIN_AUDIO -# ifdef CPIN_AUDIO - if (voices > 1) { - ENABLE_AUDIO_COUNTER_1_ISR; - ENABLE_AUDIO_COUNTER_1_OUTPUT; - } -# else - ENABLE_AUDIO_COUNTER_1_ISR; - ENABLE_AUDIO_COUNTER_1_OUTPUT; -# endif -#endif - } + #endif } - -void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) { - if (!audio_initialized) { - audio_init(); - } - - if (audio_config.enable) { -#ifdef CPIN_AUDIO - DISABLE_AUDIO_COUNTER_3_ISR; -#endif -#ifdef BPIN_AUDIO - DISABLE_AUDIO_COUNTER_1_ISR; -#endif - - // Cancel note if a note is playing - if (playing_note) stop_all_notes(); - - playing_notes = true; - - notes_pointer = np; - notes_count = n_count; - notes_repeat = n_repeat; - - place = 0; - current_note = 0; - - note_frequency = (*notes_pointer)[current_note][0]; - note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); - note_position = 0; - -#ifdef CPIN_AUDIO - ENABLE_AUDIO_COUNTER_3_ISR; - ENABLE_AUDIO_COUNTER_3_OUTPUT; -#endif -#ifdef BPIN_AUDIO -# ifndef CPIN_AUDIO - ENABLE_AUDIO_COUNTER_1_ISR; - ENABLE_AUDIO_COUNTER_1_OUTPUT; -# endif #endif - } -} - -bool is_playing_notes(void) { return playing_notes; } - -bool is_audio_on(void) { return (audio_config.enable != 0); } - -void audio_toggle(void) { - audio_config.enable ^= 1; - eeconfig_update_audio(audio_config.raw); - if (audio_config.enable) audio_on_user(); -} - -void audio_on(void) { - audio_config.enable = 1; - eeconfig_update_audio(audio_config.raw); - audio_on_user(); - PLAY_SONG(audio_on_song); -} - -void audio_off(void) { - PLAY_SONG(audio_off_song); - wait_ms(100); - stop_all_notes(); - audio_config.enable = 0; - eeconfig_update_audio(audio_config.raw); -} - -#ifdef VIBRATO_ENABLE - -// Vibrato rate functions - -void set_vibrato_rate(float rate) { vibrato_rate = rate; } - -void increase_vibrato_rate(float change) { vibrato_rate *= change; } - -void decrease_vibrato_rate(float change) { vibrato_rate /= change; } - -# ifdef VIBRATO_STRENGTH_ENABLE - -void set_vibrato_strength(float strength) { vibrato_strength = strength; } - -void increase_vibrato_strength(float change) { vibrato_strength *= change; } - -void decrease_vibrato_strength(float change) { vibrato_strength /= change; } - -# endif /* VIBRATO_STRENGTH_ENABLE */ - -#endif /* VIBRATO_ENABLE */ - -// Polyphony functions - -void set_polyphony_rate(float rate) { polyphony_rate = rate; } - -void enable_polyphony() { polyphony_rate = 5; } - -void disable_polyphony() { polyphony_rate = 0; } - -void increase_polyphony_rate(float change) { polyphony_rate *= change; } - -void decrease_polyphony_rate(float change) { polyphony_rate /= change; } - -// Timbre function - -void set_timbre(float timbre) { note_timbre = timbre; } - -// Tempo functions - -void set_tempo(uint8_t tempo) { note_tempo = tempo; } - -void decrease_tempo(uint8_t tempo_change) { note_tempo += tempo_change; } - -void increase_tempo(uint8_t tempo_change) { - if (note_tempo - tempo_change < 10) { - note_tempo = 10; - } else { - note_tempo -= tempo_change; - } -} diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index b29796e06ef0..bf5bd932cb5d 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -20,47 +20,23 @@ #include #include "print.h" -#include "keymap.h" -#include "eeconfig.h" +//TODO: move into audio-common state +extern bool playing_notes; +extern uint8_t voices; +extern float frequencies[8]; +extern uint32_t note_position; +extern float note_length; +extern float (* notes_pointer)[][2]; +extern uint16_t current_note; +extern bool notes_repeat; +extern uint16_t notes_count; +extern uint8_t note_tempo; +extern uint16_t envelope_index; // ----------------------------------------------------------------------------- -uint8_t dac_voices = 0; -float dac_frequencies[8] = { 0.0 }; - -bool playing_notes = false; -bool playing_note = false; -float note_frequency = 0; -float note_length = 0; -uint8_t note_tempo = TEMPO_DEFAULT; -float note_timbre = TIMBRE_DEFAULT; -uint32_t note_position = 0; -float (* notes_pointer)[][2]; -uint16_t notes_count; -bool notes_repeat; - -uint16_t current_note = 0; - -#ifdef VIBRATO_ENABLE -float vibrato_counter = 0; -float vibrato_strength = .5; -float vibrato_rate = 0.125; -#endif - -float polyphony_rate = 0; - -static bool audio_initialized = false; - -audio_config_t audio_config; -uint16_t envelope_index = 0; -bool glissando = true; - -#ifndef STARTUP_SONG - #define STARTUP_SONG SONG(STARTUP_SOUND) -#endif -float startup_song[][2] = STARTUP_SONG; static const dacsample_t dac_buffer_sine[DAC_BUFFER_SIZE] = { // 256 values, max 4095 @@ -151,14 +127,14 @@ static float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; __attribute__ ((weak)) uint16_t dac_value_generate(void) { uint16_t value = DAC_OFF_VALUE; - uint8_t working_voices = dac_voices; + uint8_t working_voices = voices; if (working_voices > DAC_VOICES_MAX) working_voices = DAC_VOICES_MAX; if (working_voices > 0) { uint16_t value_avg = 0; for (uint8_t i = 0; i < working_voices; i++) { - dac_if[i] = dac_if[i] + ((dac_frequencies[i] * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE); + dac_if[i] = dac_if[i] + ((frequencies[i] * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE); // Needed because % doesn't work with floats while (dac_if[i] >= (DAC_BUFFER_SIZE)) @@ -256,26 +232,10 @@ static const DACConversionGroup dac_conv_cfg = { .trigger = DAC_TRG(0b000) }; -void audio_init() { - if (audio_initialized) { - return; - } - // Check EEPROM -#ifdef EEPROM_ENABLE - if (!eeconfig_is_enabled()) { - eeconfig_init(); - } - audio_config.raw = eeconfig_read_audio(); -#else // ARM EEPROM - audio_config.enable = true; - #ifdef AUDIO_CLICKY_ON - audio_config.clicky_enable = true; - - #endif -#endif // ARM EEPROM +void audio_initialize_hardware(void) { #if defined(A4_AUDIO) palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG ); @@ -302,241 +262,27 @@ void audio_init() { stop_all_notes(); } -void audio_startup() { - if (audio_config.enable) { - PLAY_SONG(startup_song); - } -} - -void stop_all_notes() { - dprintf("audio stop all notes"); - - if (!audio_initialized) { - audio_init(); - } - dac_voices = 0; - - playing_notes = false; - playing_note = false; - for (uint8_t i = 0; i < 8; i++) { - dac_frequencies[i] = 0; - } +void audio_stop_hardware(void) { } -void stop_note(float freq) { - dprintf("audio stop note freq=%d", (int)freq); - - if (playing_note) { - if (!audio_initialized) { - audio_init(); - } - for (int i = 7; i >= 0; i--) { - if (dac_frequencies[i] == freq) { - dac_frequencies[i] = 0; - for (int j = i; (j < 7); j++) { - dac_frequencies[j] = dac_frequencies[j+1]; - dac_frequencies[j+1] = 0; - } - break; - } - } - dac_voices--; - if (dac_voices < 0) { - dac_voices = 0; - } - if (dac_voices == 0) { - playing_note = false; - } - } +void audio_start_hardware(void) { } -#ifdef VIBRATO_ENABLE -float mod(float a, int b) { - float r = fmod(a, b); - return r < 0 ? r + b : r; -} -float vibrato(float average_freq) { - #ifdef VIBRATO_STRENGTH_ENABLE - float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); - #else - float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; - #endif - vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH); - return vibrated_freq; -} - -#endif -void play_note(float freq, int vol) { - - dprintf("audio play note freq=%d vol=%d", (int)freq, vol); - - if (!audio_initialized) { - audio_init(); - } - - if (audio_config.enable && dac_voices < 8) { - playing_note = true; - if (freq > 0) { - envelope_index = 0; - dac_frequencies[dac_voices] = freq; - dac_voices++; - } - } -} __attribute__ ((weak)) void dac_setup_note(void) { - dac_if[dac_voices] = 0.0f; -} - -void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) { - - if (!audio_initialized) { - audio_init(); - } - - if (audio_config.enable) { - - playing_notes = true; - - notes_pointer = np; - notes_count = n_count; - notes_repeat = n_repeat; - - current_note = 0; - - note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); - note_position = 0; - - play_note((*notes_pointer)[current_note][0], 15); - - } -} - -bool is_playing_note(void) { - return playing_note; -} - -bool is_playing_notes(void) { - return playing_notes; -} - -bool is_audio_on(void) { - return (audio_config.enable != 0); -} - -void audio_toggle(void) { - if (audio_config.enable) { - stop_all_notes(); - } - audio_config.enable ^= 1; - eeconfig_update_audio(audio_config.raw); - if (audio_config.enable) { - audio_on_user(); - } -} - -void audio_on(void) { - audio_config.enable = 1; - eeconfig_update_audio(audio_config.raw); - audio_on_user(); -} - -void audio_off(void) { - stop_all_notes(); - audio_config.enable = 0; - eeconfig_update_audio(audio_config.raw); -} - -#ifdef VIBRATO_ENABLE - -// Vibrato rate functions - -void set_vibrato_rate(float rate) { - vibrato_rate = rate; -} - -void increase_vibrato_rate(float change) { - vibrato_rate *= change; -} - -void decrease_vibrato_rate(float change) { - vibrato_rate /= change; -} - -#ifdef VIBRATO_STRENGTH_ENABLE - -void set_vibrato_strength(float strength) { - vibrato_strength = strength; -} - -void increase_vibrato_strength(float change) { - vibrato_strength *= change; -} - -void decrease_vibrato_strength(float change) { - vibrato_strength /= change; -} - -#endif /* VIBRATO_STRENGTH_ENABLE */ - -#endif /* VIBRATO_ENABLE */ - -// Polyphony functions - -void set_polyphony_rate(float rate) { - polyphony_rate = rate; -} - -void enable_polyphony() { - polyphony_rate = 5; -} - -void disable_polyphony() { - polyphony_rate = 0; -} - -void increase_polyphony_rate(float change) { - polyphony_rate *= change; -} - -void decrease_polyphony_rate(float change) { - polyphony_rate /= change; -} - -// Timbre function - -void set_timbre(float timbre) { - note_timbre = timbre; -} - -// Tempo functions - -void set_tempo(uint8_t tempo) { - note_tempo = tempo; -} - -void decrease_tempo(uint8_t tempo_change) { - note_tempo += tempo_change; -} - -void increase_tempo(uint8_t tempo_change) { - if (note_tempo - tempo_change < 10) { - note_tempo = 10; - } else { - note_tempo -= tempo_change; - } + dac_if[voices] = 0.0f; } uint8_t dac_number_of_voices(void) { - return dac_voices; + return voices; } float dac_get_frequency(uint8_t index) { - return dac_frequencies[index]; + return frequencies[index]; } From dc81755f1b9f4a3c6f2b7a10525d416a9fdfb9d2 Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 16 Sep 2019 11:29:28 +0200 Subject: [PATCH 006/153] refactoring: audio_avr_pwm, renaming defines to decouple them from actually used timers, registers and ISRs --- docs/feature_audio.md | 14 +- quantum/audio/audio_avr_pwm.c | 236 +++++++++++++++++----------------- 2 files changed, 127 insertions(+), 123 deletions(-) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 68ba4477a52a..f289076df5a8 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -4,15 +4,19 @@ Your keyboard can make sounds! If you've got a Planck, Preonic, or basically any Up to two simultaneous audio voices are supported, one driven by timer 1 and another driven by timer 3. The following pins can be defined as audio outputs in config.h: -Timer 1: +Timer 3, on one of these pins: +`#define C4_AUDIO` +`#define C5_AUDIO` +`#define C6_AUDIO` + +Timer 1, on one of these pins: `#define B5_AUDIO` `#define B6_AUDIO` `#define B7_AUDIO` -Timer 3: -`#define C4_AUDIO` -`#define C5_AUDIO` -`#define C6_AUDIO` +for a single audio voice: set *one* out of the Cx_AUDIO or Bx_AUDIO defines +for two: set one Cx_AUDIO - which will be the primary voice - and one Bx_AUDIO, which will be the secondary + If you add `AUDIO_ENABLE = yes` to your `rules.mk`, there's a couple different sounds that will automatically be enabled without any other configuration: diff --git a/quantum/audio/audio_avr_pwm.c b/quantum/audio/audio_avr_pwm.c index 93736370c7dd..24a35e0564f7 100644 --- a/quantum/audio/audio_avr_pwm.c +++ b/quantum/audio/audio_avr_pwm.c @@ -40,78 +40,78 @@ extern uint8_t voices; //Currently we support timers 1 and 3 used at the sime time, channels A-C, //pins PB5, PB6, PB7, PC4, PC5, and PC6 -#if defined(C6_AUDIO) - #define CPIN_AUDIO - #define CPIN_SET_DIRECTION DDRC |= _BV(PORTC6); - #define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); - #define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A) - #define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A) - #define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1); - #define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)); - #define TIMER_3_PERIOD ICR3 - #define TIMER_3_DUTY_CYCLE OCR3A - #define TIMER3_AUDIO_vect TIMER3_COMPA_vect -#endif -#if defined(C5_AUDIO) - #define CPIN_AUDIO - #define CPIN_SET_DIRECTION DDRC |= _BV(PORTC5); - #define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3B1) | (0 << COM3B0) | (1 << WGM31) | (0 << WGM30); - #define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3B) - #define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3B) - #define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3B1); - #define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3B1) | _BV(COM3B0)); - #define TIMER_3_PERIOD ICR3 - #define TIMER_3_DUTY_CYCLE OCR3B - #define TIMER3_AUDIO_vect TIMER3_COMPB_vect -#endif -#if defined(C4_AUDIO) - #define CPIN_AUDIO - #define CPIN_SET_DIRECTION DDRC |= _BV(PORTC4); - #define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3C1) | (0 << COM3C0) | (1 << WGM31) | (0 << WGM30); - #define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3C) - #define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3C) - #define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3C1); - #define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3C1) | _BV(COM3C0)); - #define TIMER_3_PERIOD ICR3 - #define TIMER_3_DUTY_CYCLE OCR3C - #define TIMER3_AUDIO_vect TIMER3_COMPC_vect +#if defined(C4_AUDIO) || defined(C5_AUDIO) || defined(C6_AUDIO) + #define AUDIO_VOICE_A + #define VOICE_A_TIMER_PERIOD ICR3 + + #if defined(C6_AUDIO) + #define VOICE_A_SET_PIN_DIRECTION DDRC |= _BV(PORTC6); + #define VOICE_A_INIT_COUNTER TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); + #define VOICE_A_ENABLE_COUNTER_ISR TIMSK3 |= _BV(OCIE3A) + #define VOICE_A_DISABLE_COUNTER_ISR TIMSK3 &= ~_BV(OCIE3A) + #define VOICE_A_ENABLE_COUNTER_OUTPUT TCCR3A |= _BV(COM3A1); + #define VOICE_A_DISABLE_COUNTER_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)); + #define VOICE_A_TIMER_DUTY_CYCLE OCR3A + #define VOICE_A_TIMER_ISR_vect TIMER3_COMPA_vect + #elif defined(C5_AUDIO) + #define VOICE_A_SET_PIN_DIRECTION DDRC |= _BV(PORTC5); + #define VOICE_A_INIT_COUNTER TCCR3A = (0 << COM3B1) | (0 << COM3B0) | (1 << WGM31) | (0 << WGM30); + #define VOICE_A_ENABLE_COUNTER_ISR TIMSK3 |= _BV(OCIE3B) + #define VOICE_A_DISABLE_COUNTER_ISR TIMSK3 &= ~_BV(OCIE3B) + #define VOICE_A_ENABLE_COUNTER_OUTPUT TCCR3A |= _BV(COM3B1); + #define VOICE_A_DISABLE_COUNTER_OUTPUT TCCR3A &= ~(_BV(COM3B1) | _BV(COM3B0)); + #define VOICE_A_TIMER_DUTY_CYCLE OCR3B + #define VOICE_A_TIMER_ISR_vect TIMER3_COMPB_vect + #elif defined(C4_AUDIO) + #define VOICE_A_SET_PIN_DIRECTION DDRC |= _BV(PORTC4); + #define VOICE_A_INIT_COUNTER TCCR3A = (0 << COM3C1) | (0 << COM3C0) | (1 << WGM31) | (0 << WGM30); + #define VOICE_A_ENABLE_COUNTER_ISR TIMSK3 |= _BV(OCIE3C) + #define VOICE_A_DISABLE_COUNTER_ISR TIMSK3 &= ~_BV(OCIE3C) + #define VOICE_A_ENABLE_COUNTER_OUTPUT TCCR3A |= _BV(COM3C1); + #define VOICE_A_DISABLE_COUNTER_OUTPUT TCCR3A &= ~(_BV(COM3C1) | _BV(COM3C0)); + #define VOICE_A_TIMER_DUTY_CYCLE OCR3C + #define VOICE_A_TIMER_ISR_vect TIMER3_COMPC_vect + #endif #endif -#if defined(B5_AUDIO) - #define BPIN_AUDIO - #define BPIN_SET_DIRECTION DDRB |= _BV(PORTB5); - #define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10); - #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1A) - #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1A) - #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1A1); - #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0)); - #define TIMER_1_PERIOD ICR1 - #define TIMER_1_DUTY_CYCLE OCR1A - #define TIMER1_AUDIO_vect TIMER1_COMPA_vect -#endif -#if defined(B6_AUDIO) - #define BPIN_AUDIO - #define BPIN_SET_DIRECTION DDRB |= _BV(PORTB6); - #define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1B1) | (0 << COM1B0) | (1 << WGM11) | (0 << WGM10); - #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1B) - #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1B) - #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1B1); - #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1B1) | _BV(COM1B0)); - #define TIMER_1_PERIOD ICR1 - #define TIMER_1_DUTY_CYCLE OCR1B - #define TIMER1_AUDIO_vect TIMER1_COMPB_vect +#if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) + #define AUDIO_VOICE_B + #define VOICE_B_TIMER_PERIOD ICR1 + + #if defined(B5_AUDIO) + #define VOICE_B_SET_PIN_DIRECTION DDRB |= _BV(PORTB5); + #define VOICE_B_INIT_COUNTER TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10); + #define VOICE_B_ENABLE_COUNTER_ISR TIMSK1 |= _BV(OCIE1A) + #define VOICE_B_DISABLE_COUNTER_ISR TIMSK1 &= ~_BV(OCIE1A) + #define VOICE_B_ENABLE_COUNTER_OUTPUT TCCR1A |= _BV(COM1A1); + #define VOICE_B_DISABLE_COUNTER_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0)); + #define VOICE_B_TIMER_DUTY_CYCLE OCR1A + #define VOICE_B_TIMER_ISR_vect TIMER1_COMPA_vect + #elif defined(B6_AUDIO) + #define AUDIO_VOICE_B + #define VOICE_B_SET_PIN_DIRECTION DDRB |= _BV(PORTB6); + #define VOICE_B_INIT_COUNTER TCCR1A = (0 << COM1B1) | (0 << COM1B0) | (1 << WGM11) | (0 << WGM10); + #define VOICE_B_ENABLE_COUNTER_ISR TIMSK1 |= _BV(OCIE1B) + #define VOICE_B_DISABLE_COUNTER_ISR TIMSK1 &= ~_BV(OCIE1B) + #define VOICE_B_ENABLE_COUNTER_OUTPUT TCCR1A |= _BV(COM1B1); + #define VOICE_B_DISABLE_COUNTER_OUTPUT TCCR1A &= ~(_BV(COM1B1) | _BV(COM1B0)); + #define VOICE_B_TIMER_DUTY_CYCLE OCR1B + #define VOICE_B_TIMER_ISR_vect TIMER1_COMPB_vect + #elif defined(B7_AUDIO) + #define AUDIO_VOICE_B + #define VOICE_B_SET_PIN_DIRECTION DDRB |= _BV(PORTB7); + #define VOICE_B_INIT_COUNTER TCCR1A = (0 << COM1C1) | (0 << COM1C0) | (1 << WGM11) | (0 << WGM10); + #define VOICE_B_ENABLE_COUNTER_ISR TIMSK1 |= _BV(OCIE1C) + #define VOICE_B_DISABLE_COUNTER_ISR TIMSK1 &= ~_BV(OCIE1C) + #define VOICE_B_ENABLE_COUNTER_OUTPUT TCCR1A |= _BV(COM1C1); + #define VOICE_B_DISABLE_COUNTER_OUTPUT TCCR1A &= ~(_BV(COM1C1) | _BV(COM1C0)); + #define VOICE_B_TIMER_DUTY_CYCLE OCR1C + #define VOICE_B_TIMER_ISR_vect TIMER1_COMPC_vect + #endif #endif -#if defined(B7_AUDIO) - #define BPIN_AUDIO - #define BPIN_SET_DIRECTION DDRB |= _BV(PORTB7); - #define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1C1) | (0 << COM1C0) | (1 << WGM11) | (0 << WGM10); - #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1C) - #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1C) - #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1C1); - #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1C1) | _BV(COM1C0)); - #define TIMER_1_PERIOD ICR1 - #define TIMER_1_DUTY_CYCLE OCR1C - #define TIMER1_AUDIO_vect TIMER1_COMPC_vect + +#if !defined(AUDIO_VOICE_A) && !defined(AUDIO_VOICE_B) +#error "audio feature enabled, but no pin selected - see docs/feature_audio for defines to set" #endif #if !defined(BPIN_AUDIO) && !defined(CPIN_AUDIO) @@ -128,13 +128,13 @@ float place = 0; void audio_initialize_hardware() { // Set audio ports as output - #ifdef CPIN_AUDIO - CPIN_SET_DIRECTION - DISABLE_AUDIO_COUNTER_3_ISR; + #ifdef AUDIO_VOICE_A + VOICE_A_SET_PIN_DIRECTION + VOICE_A_DISABLE_COUNTER_ISR; #endif - #ifdef BPIN_AUDIO - BPIN_SET_DIRECTION - DISABLE_AUDIO_COUNTER_1_ISR; + #ifdef AUDIO_VOICE_B + VOICE_B_SET_PIN_DIRECTION + VOICE_B_DISABLE_COUNTER_ISR; #endif // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers TCCR3A/TCCR3B, TCCR1A/TCCR1B @@ -155,17 +155,17 @@ void audio_initialize_hardware() { // OCR1C - PB7 // Clock Select (CS3n) = 0b010 = Clock / 8 - #ifdef CPIN_AUDIO - INIT_AUDIO_COUNTER_3 + #ifdef AUDIO_VOICE_A + VOICE_A_INIT_COUNTER TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); - TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER)); - TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre); + VOICE_A_TIMER_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER)); + VOICE_A_TIMER_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre); #endif - #ifdef BPIN_AUDIO - INIT_AUDIO_COUNTER_1 + #ifdef AUDIO_VOICE_B + VOICE_B_INIT_COUNTER TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10); - TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER)); - TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre); + VOICE_B_TIMER_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER)); + VOICE_B_TIMER_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre); #endif audio_initialized = true; @@ -179,81 +179,81 @@ void audio_startup() { void audio_stop_hardware() { - #ifdef CPIN_AUDIO - DISABLE_AUDIO_COUNTER_3_ISR; - DISABLE_AUDIO_COUNTER_3_OUTPUT; + #ifdef AUDIO_VOICE_A + VOICE_A_DISABLE_COUNTER_ISR; + VOICE_A_DISABLE_COUNTER_OUTPUT; #endif - #ifdef BPIN_AUDIO - DISABLE_AUDIO_COUNTER_1_ISR; - DISABLE_AUDIO_COUNTER_1_OUTPUT; + #ifdef AUDIO_VOICE_B + VOICE_B_DISABLE_COUNTER_ISR; + VOICE_B_DISABLE_COUNTER_OUTPUT; #endif } void audio_start_hardware(void) { - #ifdef CPIN_AUDIO - ENABLE_AUDIO_COUNTER_3_ISR; - ENABLE_AUDIO_COUNTER_3_OUTPUT; + #ifdef AUDIO_VOICE_A + VOICE_A_ENABLE_COUNTER_ISR; + VOICE_A_ENABLE_COUNTER_OUTPUT; #endif - #ifdef BPIN_AUDIO - #ifdef CPIN_AUDIO + #ifdef AUDIO_VOICE_B + #ifdef AUDIO_VOICE_A if (voices > 1) { - ENABLE_AUDIO_COUNTER_1_ISR; - ENABLE_AUDIO_COUNTER_1_OUTPUT; + VOICE_B_ENABLE_COUNTER_ISR; + VOICE_B_ENABLE_COUNTER_OUTPUT; } #else - ENABLE_AUDIO_COUNTER_1_ISR; - ENABLE_AUDIO_COUNTER_1_OUTPUT; + VOICE_B_ENABLE_COUNTER_ISR; + VOICE_B_ENABLE_COUNTER_OUTPUT; #endif #endif } -#ifdef CPIN_AUDIO -ISR(TIMER3_AUDIO_vect) { +#ifdef AUDIO_VOICE_A +ISR(VOICE_A_TIMER_ISR_vect) { float freq, freq_alt; pwm_audio_timer_task(&freq, &freq_alt); - #ifdef BPIN_AUDIO - TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq_alt * CPU_PRESCALER)); - TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre); + #ifdef AUDIO_VOICE_B + VOICE_B_TIMER_PERIOD = (uint16_t)(((float)F_CPU) / (freq_alt * CPU_PRESCALER)); + VOICE_B_TIMER_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre); #endif if (freq>0) { - TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); - TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); + VOICE_A_TIMER_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + VOICE_A_TIMER_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); } else { - TIMER_3_PERIOD = 0; - TIMER_3_DUTY_CYCLE = 0; + VOICE_A_TIMER_PERIOD = 0; + VOICE_A_TIMER_DUTY_CYCLE = 0; } if (!playing_notes) { - DISABLE_AUDIO_COUNTER_3_ISR; - DISABLE_AUDIO_COUNTER_3_OUTPUT; + VOICE_A_DISABLE_COUNTER_ISR; + VOICE_A_DISABLE_COUNTER_OUTPUT; } } #endif -#ifdef BPIN_AUDIO -ISR(TIMER1_AUDIO_vect) { +#ifdef AUDIO_VOICE_B +ISR(VOICE_B_TIMER_ISR_vect) { - #if defined(BPIN_AUDIO) && !defined(CPIN_AUDIO) + #if defined(AUDIO_VOICE_B) && !defined(AUDIO_VOICE_A) float freq, freq_alt; pwm_audio_timer_task(&freq, &freq_alt); if (freq>0) { - TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); - TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); + VOICE_B_TIMER_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + VOICE_B_TIMER_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); } else { - TIMER_1_PERIOD = 0; - TIMER_1_DUTY_CYCLE = 0; + VOICE_B_TIMER_PERIOD = 0; + VOICE_B_TIMER_DUTY_CYCLE = 0; } if (!playing_notes) { - DISABLE_AUDIO_COUNTER_1_ISR; - DISABLE_AUDIO_COUNTER_1_OUTPUT; + VOICE_B_DISABLE_COUNTER_ISR; + VOICE_B_DISABLE_COUNTER_OUTPUT; } #endif } From 5ba2d157748ba0c9de82255419426c315f86a3ac Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 22 Jun 2019 02:47:38 +0200 Subject: [PATCH 007/153] refactoring: audio_avr_pwm - replacing function defines with plain register defines aligns better with other existing qmk code (and the new audio_arm_pwm) doing similar pwm thing --- quantum/audio/audio_avr_pwm.c | 370 +++++++++++++++++++--------------- 1 file changed, 211 insertions(+), 159 deletions(-) diff --git a/quantum/audio/audio_avr_pwm.c b/quantum/audio/audio_avr_pwm.c index 24a35e0564f7..4f6ce609dc2f 100644 --- a/quantum/audio/audio_avr_pwm.c +++ b/quantum/audio/audio_avr_pwm.c @@ -38,135 +38,206 @@ extern uint8_t voices; // Timer Abstractions // ----------------------------------------------------------------------------- -//Currently we support timers 1 and 3 used at the sime time, channels A-C, +//Currently we support timers 1 and 3 used at the same time, channels A-C, //pins PB5, PB6, PB7, PC4, PC5, and PC6 + +#if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) + #define AUDIO1_PIN_SET + #define AUDIO1_TIMSKx TIMSK1 + #define AUDIO1_TCCRxA TCCR1A + #define AUDIO1_TCCRxB TCCR1B + #define AUDIO1_ICRx ICR1 + #define AUDIO1_WGMx0 WGM10 + #define AUDIO1_WGMx1 WGM11 + #define AUDIO1_WGMx2 WGM12 + #define AUDIO1_WGMx3 WGM13 + #define AUDIO1_CSx0 CS10 + #define AUDIO1_CSx1 CS11 + #define AUDIO1_CSx2 CS12 + + #if defined(B5_AUDIO) + #define AUDIO1_COMxy0 COM1A0 + #define AUDIO1_COMxy1 COM1A1 + #define AUDIO1_OCIExy OCIE1A + #define AUDIO1_OCRxy OCR1A + #define AUDIO1_PIN B5 + #define AUDIO1_TIMERx_COMPy_vect TIMER1_COMPA_vect + #elif defined(B6_AUDIO) + #define AUDIO1_COMxy0 COM1B0 + #define AUDIO1_COMxy1 COM1B1 + #define AUDIO1_OCIExy OCIE1B + #define AUDIO1_OCRxy OCR1B + #define AUDIO1_PIN B6 + #define AUDIO1_TIMERx_COMPy_vect TIMER1_COMPB_vect + #elif defined(B7_AUDIO) + #define AUDIO1_COMxy0 COM1C0 + #define AUDIO1_COMxy1 COM1C1 + #define AUDIO1_OCIExy OCIE1C + #define AUDIO1_OCRxy OCR1C + #define AUDIO1_PIN B7 + #define AUDIO1_TIMERx_COMPy_vect TIMER1_COMPC_vect + #endif +#endif + #if defined(C4_AUDIO) || defined(C5_AUDIO) || defined(C6_AUDIO) - #define AUDIO_VOICE_A - #define VOICE_A_TIMER_PERIOD ICR3 + #define AUDIO2_PIN_SET + #define AUDIO2_TIMSKx TIMSK3 + #define AUDIO2_TCCRxA TCCR3A + #define AUDIO2_TCCRxB TCCR3B + #define AUDIO2_ICRx ICR3 + #define AUDIO2_WGMx0 WGM30 + #define AUDIO2_WGMx1 WGM31 + #define AUDIO2_WGMx2 WGM32 + #define AUDIO2_WGMx3 WGM33 + #define AUDIO2_CSx0 CS30 + #define AUDIO2_CSx1 CS31 + #define AUDIO2_CSx2 CS32 #if defined(C6_AUDIO) - #define VOICE_A_SET_PIN_DIRECTION DDRC |= _BV(PORTC6); - #define VOICE_A_INIT_COUNTER TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); - #define VOICE_A_ENABLE_COUNTER_ISR TIMSK3 |= _BV(OCIE3A) - #define VOICE_A_DISABLE_COUNTER_ISR TIMSK3 &= ~_BV(OCIE3A) - #define VOICE_A_ENABLE_COUNTER_OUTPUT TCCR3A |= _BV(COM3A1); - #define VOICE_A_DISABLE_COUNTER_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)); - #define VOICE_A_TIMER_DUTY_CYCLE OCR3A - #define VOICE_A_TIMER_ISR_vect TIMER3_COMPA_vect + #define AUDIO2_COMxy0 COM3A0 + #define AUDIO2_COMxy1 COM3A1 + #define AUDIO2_OCIExy OCIE3A + #define AUDIO2_OCRxy OCR3A + #define AUDIO2_PIN C6 + #define AUDIO2_TIMERx_COMPy_vect TIMER3_COMPA_vect #elif defined(C5_AUDIO) - #define VOICE_A_SET_PIN_DIRECTION DDRC |= _BV(PORTC5); - #define VOICE_A_INIT_COUNTER TCCR3A = (0 << COM3B1) | (0 << COM3B0) | (1 << WGM31) | (0 << WGM30); - #define VOICE_A_ENABLE_COUNTER_ISR TIMSK3 |= _BV(OCIE3B) - #define VOICE_A_DISABLE_COUNTER_ISR TIMSK3 &= ~_BV(OCIE3B) - #define VOICE_A_ENABLE_COUNTER_OUTPUT TCCR3A |= _BV(COM3B1); - #define VOICE_A_DISABLE_COUNTER_OUTPUT TCCR3A &= ~(_BV(COM3B1) | _BV(COM3B0)); - #define VOICE_A_TIMER_DUTY_CYCLE OCR3B - #define VOICE_A_TIMER_ISR_vect TIMER3_COMPB_vect + #define AUDIO2_COMxy0 COM3B0 + #define AUDIO2_COMxy1 COM3B1 + #define AUDIO2_OCIExy OCIE3B + #define AUDIO2_OCRxy OCR3B + #define AUDIO2_PIN C5 + #define AUDIO2_TIMERx_COMPy_vect TIMER3_COMPB_vect #elif defined(C4_AUDIO) - #define VOICE_A_SET_PIN_DIRECTION DDRC |= _BV(PORTC4); - #define VOICE_A_INIT_COUNTER TCCR3A = (0 << COM3C1) | (0 << COM3C0) | (1 << WGM31) | (0 << WGM30); - #define VOICE_A_ENABLE_COUNTER_ISR TIMSK3 |= _BV(OCIE3C) - #define VOICE_A_DISABLE_COUNTER_ISR TIMSK3 &= ~_BV(OCIE3C) - #define VOICE_A_ENABLE_COUNTER_OUTPUT TCCR3A |= _BV(COM3C1); - #define VOICE_A_DISABLE_COUNTER_OUTPUT TCCR3A &= ~(_BV(COM3C1) | _BV(COM3C0)); - #define VOICE_A_TIMER_DUTY_CYCLE OCR3C - #define VOICE_A_TIMER_ISR_vect TIMER3_COMPC_vect + #define AUDIO2_COMxy0 COM3C0 + #define AUDIO2_COMxy1 COM3C1 + #define AUDIO2_OCIExy OCIE3C + #define AUDIO2_OCRxy OCR3C + #define AUDIO2_PIN C4 + #define AUDIO2_TIMERx_COMPy_vect TIMER3_COMPC_vect #endif #endif -#if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) - #define AUDIO_VOICE_B - #define VOICE_B_TIMER_PERIOD ICR1 - #if defined(B5_AUDIO) - #define VOICE_B_SET_PIN_DIRECTION DDRB |= _BV(PORTB5); - #define VOICE_B_INIT_COUNTER TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10); - #define VOICE_B_ENABLE_COUNTER_ISR TIMSK1 |= _BV(OCIE1A) - #define VOICE_B_DISABLE_COUNTER_ISR TIMSK1 &= ~_BV(OCIE1A) - #define VOICE_B_ENABLE_COUNTER_OUTPUT TCCR1A |= _BV(COM1A1); - #define VOICE_B_DISABLE_COUNTER_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0)); - #define VOICE_B_TIMER_DUTY_CYCLE OCR1A - #define VOICE_B_TIMER_ISR_vect TIMER1_COMPA_vect - #elif defined(B6_AUDIO) - #define AUDIO_VOICE_B - #define VOICE_B_SET_PIN_DIRECTION DDRB |= _BV(PORTB6); - #define VOICE_B_INIT_COUNTER TCCR1A = (0 << COM1B1) | (0 << COM1B0) | (1 << WGM11) | (0 << WGM10); - #define VOICE_B_ENABLE_COUNTER_ISR TIMSK1 |= _BV(OCIE1B) - #define VOICE_B_DISABLE_COUNTER_ISR TIMSK1 &= ~_BV(OCIE1B) - #define VOICE_B_ENABLE_COUNTER_OUTPUT TCCR1A |= _BV(COM1B1); - #define VOICE_B_DISABLE_COUNTER_OUTPUT TCCR1A &= ~(_BV(COM1B1) | _BV(COM1B0)); - #define VOICE_B_TIMER_DUTY_CYCLE OCR1B - #define VOICE_B_TIMER_ISR_vect TIMER1_COMPB_vect - #elif defined(B7_AUDIO) - #define AUDIO_VOICE_B - #define VOICE_B_SET_PIN_DIRECTION DDRB |= _BV(PORTB7); - #define VOICE_B_INIT_COUNTER TCCR1A = (0 << COM1C1) | (0 << COM1C0) | (1 << WGM11) | (0 << WGM10); - #define VOICE_B_ENABLE_COUNTER_ISR TIMSK1 |= _BV(OCIE1C) - #define VOICE_B_DISABLE_COUNTER_ISR TIMSK1 &= ~_BV(OCIE1C) - #define VOICE_B_ENABLE_COUNTER_OUTPUT TCCR1A |= _BV(COM1C1); - #define VOICE_B_DISABLE_COUNTER_OUTPUT TCCR1A &= ~(_BV(COM1C1) | _BV(COM1C0)); - #define VOICE_B_TIMER_DUTY_CYCLE OCR1C - #define VOICE_B_TIMER_ISR_vect TIMER1_COMPC_vect - #endif +// C6 seems to be the assumed default by many existing keyboard - but sill warn the user +#if !defined(AUDIO2_PIN_SET) && !defined(AUDIO1_PIN_SET) +#pragma message "audio feature enabled, but no pin selected - see docs/feature_audio for defines to set" #endif +// ----------------------------------------------------------------------------- -#if !defined(AUDIO_VOICE_A) && !defined(AUDIO_VOICE_B) -#error "audio feature enabled, but no pin selected - see docs/feature_audio for defines to set" -#endif -#if !defined(BPIN_AUDIO) && !defined(CPIN_AUDIO) -# error "Audio feature enabled, but no suitable pin selected - see docs/feature_audio.md under the AVR settings for available options." +float place = 0; + +#ifdef AUDIO1_PIN_SET +static float channel_1_frequency = 0.0f; +void channel_1_set_frequency(float freq) { + + if (freq < 0.0f) + freq = 0.0f; + + if (freq == channel_1_frequency) + return; + + channel_1_frequency = freq; + + // set pwm period + AUDIO1_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + // and duty cycle + AUDIO1_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); +} + +float channel_1_get_frequency(void) { + return channel_1_frequency; +} + +void channel_1_start(void) { + // enable timer-counter ISR + AUDIO1_TIMSKx |= _BV(AUDIO1_OCIExy); + // enable timer-counter output + AUDIO1_TCCRxA |= _BV(AUDIO1_COMxy1); +} + +void channel_1_stop(void) { + // disable timer-counter ISR + AUDIO1_TIMSKx &= ~_BV(AUDIO1_OCIExy); + // disable timer-counter output + AUDIO1_TCCRxA &= ~(_BV(AUDIO1_COMxy1) | _BV(AUDIO1_COMxy0)); +} #endif -// ----------------------------------------------------------------------------- +#ifdef AUDIO2_PIN_SET +static float channel_2_frequency = 0.0f; +void channel_2_set_frequency(float freq) { + if (freq < 0.0f) + freq = 0.0f; + if (freq == channel_2_frequency) + return; -float place = 0; + channel_2_frequency = freq; + + AUDIO2_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + AUDIO2_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); +} + +void channel_2_start(void) { + AUDIO2_TIMSKx |= _BV(AUDIO2_OCIExy); + AUDIO2_TCCRxA |= _BV(AUDIO2_COMxy1); +} + +void channel_2_stop(void) { + AUDIO2_TIMSKx &= ~_BV(AUDIO2_OCIExy); + AUDIO2_TCCRxA &= ~(_BV(AUDIO2_COMxy1) | _BV(AUDIO2_COMxy0)); +} +#endif void audio_initialize_hardware() { - // Set audio ports as output - #ifdef AUDIO_VOICE_A - VOICE_A_SET_PIN_DIRECTION - VOICE_A_DISABLE_COUNTER_ISR; - #endif - #ifdef AUDIO_VOICE_B - VOICE_B_SET_PIN_DIRECTION - VOICE_B_DISABLE_COUNTER_ISR; - #endif +#ifdef AUDIO1_PIN_SET + channel_1_stop(); + // Set audio ports as output + setPinOutput(AUDIO1_PIN); +#endif - // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers TCCR3A/TCCR3B, TCCR1A/TCCR1B - // Compare Output Mode (COM3An and COM1An) = 0b00 = Normal port operation - // OC3A -- PC6 - // OC3B -- PC5 - // OC3C -- PC4 - // OC1A -- PB5 - // OC1B -- PB6 - // OC1C -- PB7 - - // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14. Period = ICR3, Duty Cycle OCR3A) - // OCR3A - PC6 - // OCR3B - PC5 - // OCR3C - PC4 - // OCR1A - PB5 - // OCR1B - PB6 - // OCR1C - PB7 - - // Clock Select (CS3n) = 0b010 = Clock / 8 - #ifdef AUDIO_VOICE_A - VOICE_A_INIT_COUNTER - TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); - VOICE_A_TIMER_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER)); - VOICE_A_TIMER_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre); - #endif - #ifdef AUDIO_VOICE_B - VOICE_B_INIT_COUNTER - TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10); - VOICE_B_TIMER_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER)); - VOICE_B_TIMER_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre); - #endif +#ifdef AUDIO2_PIN_SET + channel_2_stop(); + setPinOutput(AUDIO2_PIN); +#endif + + // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers TCCR3A/TCCR3B, TCCR1A/TCCR1B + // Compare Output Mode (COM3An and COM1An) = 0b00 = Normal port operation + // OC3A -- PC6 + // OC3B -- PC5 + // OC3C -- PC4 + // OC1A -- PB5 + // OC1B -- PB6 + // OC1C -- PB7 + + // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14. Period = ICR3, Duty Cycle OCR3A) + // OCR3A - PC6 + // OCR3B - PC5 + // OCR3C - PC4 + // OCR1A - PB5 + // OCR1B - PB6 + // OCR1C - PB7 + +#ifdef AUDIO1_PIN_SET + // initialize timer-counter + AUDIO1_TCCRxA = (0 << AUDIO1_COMxy1) | (0 << AUDIO1_COMxy0) | (1 << AUDIO1_WGMx1) | (0 << AUDIO1_WGMx0); + AUDIO1_TCCRxB = (1 << AUDIO1_WGMx3) | (1 << AUDIO1_WGMx2) | (0 << AUDIO1_CSx2) | (1 << AUDIO1_CSx1) | (0 << AUDIO1_CSx0); + + //channel_1_set_frequency(440); // original code set this frequency here... why? +#endif + + + // Clock Select (CS3n) = 0b010 = Clock / 8 +#ifdef AUDIO2_PIN_SET + AUDIO2_TCCRxA = (0 << AUDIO2_COMxy1) | (0 << AUDIO2_COMxy0) | (1 << AUDIO2_WGMx1) | (0 << AUDIO2_WGMx0); + AUDIO2_TCCRxB = (1 << AUDIO2_WGMx3) | (1 << AUDIO2_WGMx2) | (0 << AUDIO2_CSx2) | (1 << AUDIO2_CSx1) | (0 << AUDIO2_CSx0); + + //channel_2_set_frequency(440); // original code set this frequency here... why? +#endif audio_initialized = true; } @@ -179,82 +250,63 @@ void audio_startup() { void audio_stop_hardware() { - #ifdef AUDIO_VOICE_A - VOICE_A_DISABLE_COUNTER_ISR; - VOICE_A_DISABLE_COUNTER_OUTPUT; + #ifdef AUDIO2_PIN_SET + channel_2_stop(); #endif - #ifdef AUDIO_VOICE_B - VOICE_B_DISABLE_COUNTER_ISR; - VOICE_B_DISABLE_COUNTER_OUTPUT; + #ifdef AUDIO1_PIN_SET + channel_1_stop(); #endif } void audio_start_hardware(void) { - #ifdef AUDIO_VOICE_A - VOICE_A_ENABLE_COUNTER_ISR; - VOICE_A_ENABLE_COUNTER_OUTPUT; - #endif - #ifdef AUDIO_VOICE_B - #ifdef AUDIO_VOICE_A - if (voices > 1) { - VOICE_B_ENABLE_COUNTER_ISR; - VOICE_B_ENABLE_COUNTER_OUTPUT; - } - #else - VOICE_B_ENABLE_COUNTER_ISR; - VOICE_B_ENABLE_COUNTER_OUTPUT; - #endif + #ifdef AUDIO2_PIN_SET + channel_2_start(); + #endif + #ifdef AUDIO1_PIN_SET + #ifdef AUDIO2_PIN_SET + if (voices > 1) { + channel_1_start(); + } + #else + channel_1_start(); #endif + #endif } -#ifdef AUDIO_VOICE_A -ISR(VOICE_A_TIMER_ISR_vect) { +#ifdef AUDIO2_PIN_SET +ISR(AUDIO2_TIMERx_COMPy_vect) { float freq, freq_alt; pwm_audio_timer_task(&freq, &freq_alt); - #ifdef AUDIO_VOICE_B - VOICE_B_TIMER_PERIOD = (uint16_t)(((float)F_CPU) / (freq_alt * CPU_PRESCALER)); - VOICE_B_TIMER_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre); + // do polyphonic, if a second speaker is available + #ifdef AUDIO1_PIN_SET + if (playing_notes) + channel_1_set_frequency(freq_alt); + else + channel_1_stop(); #endif - if (freq>0) { - VOICE_A_TIMER_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); - VOICE_A_TIMER_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); - } else { - VOICE_A_TIMER_PERIOD = 0; - VOICE_A_TIMER_DUTY_CYCLE = 0; - } - - if (!playing_notes) { - VOICE_A_DISABLE_COUNTER_ISR; - VOICE_A_DISABLE_COUNTER_OUTPUT; - } - + if (playing_notes) + channel_2_set_frequency(freq); + else + channel_2_stop(); } #endif -#ifdef AUDIO_VOICE_B -ISR(VOICE_B_TIMER_ISR_vect) { +#ifdef AUDIO1_PIN_SET +ISR(AUDIO1_TIMERx_COMPy_vect) { - #if defined(AUDIO_VOICE_B) && !defined(AUDIO_VOICE_A) + #if defined(AUDIO1_PIN_SET) && !defined(AUDIO2_PIN_SET) float freq, freq_alt; pwm_audio_timer_task(&freq, &freq_alt); - if (freq>0) { - VOICE_B_TIMER_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); - VOICE_B_TIMER_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); - } else { - VOICE_B_TIMER_PERIOD = 0; - VOICE_B_TIMER_DUTY_CYCLE = 0; - } - - if (!playing_notes) { - VOICE_B_DISABLE_COUNTER_ISR; - VOICE_B_DISABLE_COUNTER_OUTPUT; - } + if (playing_notes) + channel_1_set_frequency(freq); + else + channel_1_stop(); #endif } #endif From 369e949d65342c39612db9e7891f812487a230cb Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 20 Jun 2019 00:46:27 +0200 Subject: [PATCH 008/153] add audio-arm-pwm since not all STM32 have a DAC onboard (STM32F2xx and STM32F3xx), pwm-audio is an alternative (STM32F1xx) this code works on a "BluePill" clone, with an STM32F103C8B --- common_features.mk | 6 +- docs/feature_audio.md | 28 ++++- quantum/audio/audio_chibios_pwm.c | 197 ++++++++++++++++++++++++++++++ 3 files changed, 224 insertions(+), 7 deletions(-) create mode 100644 quantum/audio/audio_chibios_pwm.c diff --git a/common_features.mk b/common_features.mk index 389420fc01e1..0f08b911f1b2 100644 --- a/common_features.mk +++ b/common_features.mk @@ -45,7 +45,11 @@ endif ifeq ($(strip $(AUDIO_ENABLE)), yes) AUDIO_DRIVER ?= pwm ifeq ($(PLATFORM),CHIBIOS) - AUDIO_DRIVER ?= dac + ifeq ($(MCU_SERIES),STM32F1xx) + AUDIO_DRIVER ?= pwm + else ## stm32f2 and f3 have a DAC unit, f1 do not + AUDIO_DRIVER ?= dac + endif endif OPT_DEFS += -DAUDIO_ENABLE MUSIC_ENABLE = yes diff --git a/docs/feature_audio.md b/docs/feature_audio.md index f289076df5a8..b48f6255516c 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -1,25 +1,41 @@ # Audio -Your keyboard can make sounds! If you've got a Planck, Preonic, or basically any AVR keyboard that allows access to certain PWM-capable pins, you can hook up a simple speaker and make it beep. You can use those beeps to indicate layer transitions, modifiers, special keys, or just to play some funky 8bit tunes. +Your keyboard can make sounds! If you've got a Planck, Preonic, or basically any keyboard that allows access to certain PWM-capable pins, you can hook up a simple speaker and make it beep. You can use those beeps to indicate layer transitions, modifiers, special keys, or just to play some funky 8bit tunes. +To activate this feature, add `AUDIO_ENABLE = yes` to your `rules.mk`. + +## AVR based boards Up to two simultaneous audio voices are supported, one driven by timer 1 and another driven by timer 3. The following pins can be defined as audio outputs in config.h: -Timer 3, on one of these pins: +the primary voice, with Timer 3 on one of these pins: `#define C4_AUDIO` `#define C5_AUDIO` `#define C6_AUDIO` -Timer 1, on one of these pins: +and *optionally*, a secondary voice, using Timer 1, on one of these pins: `#define B5_AUDIO` `#define B6_AUDIO` `#define B7_AUDIO` -for a single audio voice: set *one* out of the Cx_AUDIO or Bx_AUDIO defines -for two: set one Cx_AUDIO - which will be the primary voice - and one Bx_AUDIO, which will be the secondary +## ARM based boards +STM32F2 upwards can use the builtin DAC unit, to drive Pins A4 or A5, set either: +`#define A4_AUDIO` +OR +`#define A5_AUDIO` + +STM32F1xx have to fall back to using PWM (on the up side: with any pin you choose), either: +`#define ARM_PWM_USE_PIN_ALTERNATE 1` +which is the default. Pin PA8 will be used, which is directly connected to the hardware PWM (TIM1_CH1 = PA8) +OR +`#define ARM_PWM_USE_PIN_ALTERNATE 0` +`#define ARM_PWM_AUDIO_PORT GPIOC` +`#define ARM_PWM_AUDIO_PIN 13` +to have any other pin output a pwm signal, generated from a timer callback (e.g. toggled in software) -If you add `AUDIO_ENABLE = yes` to your `rules.mk`, there's a couple different sounds that will automatically be enabled without any other configuration: +## Songs +There's a couple different sounds that will automatically be enabled without any other configuration: ``` STARTUP_SONG // plays when the keyboard starts up (audio.c) GOODBYE_SONG // plays when you press the RESET key (quantum.c) diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c new file mode 100644 index 000000000000..6ca685d4c57f --- /dev/null +++ b/quantum/audio/audio_chibios_pwm.c @@ -0,0 +1,197 @@ +/* Copyright 2019 Jack Humbert + * + * 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 2 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 . + */ + + +/* STM32F103C Setup: +halconf.h: +#define HAL_USE_PWM TRUE +#define HAL_USE_PAL TRUE +#define HAL_USE_GPT TRUE + + mcuconf.h: +#define STM32_PWM_USE_TIM1 TRUE +#define STM32_GPT_USE_TIM3 TRUE + +used pin: PA8 (alternate0: Tim1_Ch1) +*/ +#include "audio.h" +#include "ch.h" +#include "hal.h" + + +#include +#include "print.h" + + +/* either use the direct hardware connection of Timer1-Channel1 to GPIOA.8 + via the pins alternate-function to drive a piezo speaker + OR set this define to zero and have the timer callbacks toggle your pin of choice +*/ +#ifndef ARM_PWM_USE_PIN_ALTERNATE +#define ARM_PWM_USE_PIN_ALTERNATE 1 +#endif + +#ifndef ARM_PWM_AUDIO_PORT +#define ARM_PWM_AUDIO_PORT GPIOC +#endif +#ifndef ARM_PWM_AUDIO_PIN +#define ARM_PWM_AUDIO_PIN 13 +#endif +// ----------------------------------------------------------------------------- + +#define AUDIO_PIN PAL_LINE(ARM_PWM_AUDIO_PORT, ARM_PWM_AUDIO_PIN) + +extern int voices; +extern bool playing_notes; + +#if !(ARM_PWM_USE_PIN_ALTERNATE) +static void pwm_audio_period_callback(PWMDriver *pwmp); +static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp); +#endif + +static PWMConfig pwmCFG = { + 100000,/* PWM clock frequency */ + 10,/* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ + #if ARM_PWM_USE_PIN_ALTERNATE + NULL, + #else + pwm_audio_period_callback, + #endif + { + #if ARM_PWM_USE_PIN_ALTERNATE + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* channel 0 -> TIM1-CH1 = PA8 */ + #else + /* on the STM32F104C8B: alternate function of pin */ + {PWM_OUTPUT_ACTIVE_HIGH, pwm_audio_channel_interrupt_callback}, /* channel 0 -> TIM1-CH1 = PA8 */ + #endif + {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIM1-CH2 = PA9 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 2 -> TIM1-CH3 = PA10 */ + {PWM_OUTPUT_DISABLED, NULL} /* channel 3 -> TIM1-CH4 = PA11 */ + }, + 0, /* HW dependent part.*/ + 0 +}; + + +static float channel_1_frequency = 0.0f; +void channel_1_set_frequency(float freq) { + + if (freq == channel_1_frequency) + return; + + channel_1_frequency = freq; + + pwmcnt_t period = (pwmCFG.frequency / freq); + pwmChangePeriod(&PWMD1, period); + pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 5000)); +} + +float channel_1_get_frequency(void) { + return channel_1_frequency; +} + + + +void channel_1_start(void){ + pwmStop(&PWMD1); + pwmStart(&PWMD1, &pwmCFG); + pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 5000)); + + #if !(ARM_PWM_USE_PIN_ALTERNATE) + pwmEnablePeriodicNotification(&PWMD1); // enable pwm callbacks + pwmEnableChannelNotification(&PWMD1, 0); + #endif +} + +void channel_1_stop(void){ + pwmStop(&PWMD1); +} + +#if !(ARM_PWM_USE_PIN_ALTERNATE) +static void pwm_audio_period_callback(PWMDriver *pwmp) { + (void)pwmp; + palClearLine(AUDIO_PIN); + +/* hm, using the pwm callback, instead of the gpt timer does not work :-( + float freq, freq_alt; + pwm_audio_timer_task(&freq, &freq_alt); + + if (playing_notes) + channel_1_set_frequency(freq); + else + channel_1_stop(); +*/ +} +static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { + (void)pwmp; + palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer +} +#endif + +static void gpt_cb8(GPTDriver *gptp); +GPTConfig gpt8cfg1 = { + .frequency = 10, + .callback = gpt_cb8, + .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ + .dier = 0U +}; + + + +void audio_initialize_hardware(void) +{ + pwmStart(&PWMD1, &pwmCFG); + + pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 5000)); + + #if ARM_PWM_USE_PIN_ALTERNATE + // on STM32F103C8B: PA8.alternate0 = output of TIM1-CH1 + palSetPadMode(GPIOA, 8, PAL_MODE_STM32_ALTERNATE_PUSHPULL); + #else + palSetLineMode(AUDIO_PIN, PAL_MODE_OUTPUT_OPENDRAIN); + palClearLine(AUDIO_PIN); + + pwmEnablePeriodicNotification(&PWMD1); // enable pwm callbacks + pwmEnableChannelNotification(&PWMD1, 0); + #endif + + audio_start_hardware(); +} + +void audio_start_hardware(void) { + channel_1_stop(); + channel_1_start(); + + gptStart(&GPTD3, &gpt8cfg1); + gptStartContinuous(&GPTD3, 2U); +} + +void audio_stop_hardware(void) { + channel_1_stop(); + gptStopTimer(&GPTD3); +} + +/* regular timer task, that checks the note to be currently played, updates the pwm to output that frequency + */ +static void gpt_cb8(GPTDriver *gptp) { + float freq, freq_alt; + pwm_audio_timer_task(&freq, &freq_alt); + + if (playing_notes) + channel_1_set_frequency(freq); + else + channel_1_stop(); +} From 64010622990149c01fa08f68b4adccb74c25fe9d Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 16 Sep 2019 08:20:01 +0200 Subject: [PATCH 009/153] clang-format changes on quantum/audio/* only --- quantum/audio/audio.c | 261 +++++++++++---------------- quantum/audio/audio.h | 4 +- quantum/audio/audio_avr_pwm.c | 246 ++++++++++++-------------- quantum/audio/audio_chibios_dac.c | 283 ++++++++++-------------------- quantum/audio/audio_chibios_dac.h | 32 ++-- quantum/audio/audio_chibios_pwm.c | 119 ++++++------- 6 files changed, 375 insertions(+), 570 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 21d68b8bd44d..fc28f316e2fb 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -19,36 +19,36 @@ #include "eeconfig.h" -uint8_t voices = 0; -float frequencies[8] = { 0.0 }; -int volumes[8] = { 0 }; +uint8_t voices = 0; +float frequencies[8] = {0.0}; +int volumes[8] = {0}; -//float place = 0; -int voice_place = 0; -float frequency = 0; +// float place = 0; +int voice_place = 0; +float frequency = 0; float frequency_alt = 0; -int volume = 0; -long position = 0; +int volume = 0; +long position = 0; -bool playing_notes = false; -bool playing_note = false; +bool playing_notes = false; +bool playing_note = false; float note_frequency = 0; -float note_length = 0; -uint8_t note_tempo = TEMPO_DEFAULT; -float note_timbre = TIMBRE_DEFAULT; -uint32_t note_position = 0; -float (* notes_pointer)[][2]; +float note_length = 0; +uint8_t note_tempo = TEMPO_DEFAULT; +float note_timbre = TIMBRE_DEFAULT; +uint32_t note_position = 0; +float (*notes_pointer)[][2]; uint16_t notes_count; bool notes_repeat; bool note_resting = false; uint16_t current_note = 0; -uint8_t rest_counter = 0; +uint8_t rest_counter = 0; #ifdef VIBRATO_ENABLE -float vibrato_counter = 0; +float vibrato_counter = 0; float vibrato_strength = .5; -float vibrato_rate = 0.125; +float vibrato_rate = 0.125; #endif float polyphony_rate = 0; @@ -58,41 +58,39 @@ static bool audio_initialized = false; audio_config_t audio_config; uint16_t envelope_index = 0; -bool glissando = true; +bool glissando = true; #ifndef STARTUP_SONG - #define STARTUP_SONG SONG(STARTUP_SOUND) +# define STARTUP_SONG SONG(STARTUP_SOUND) #endif #ifndef AUDIO_ON_SONG - #define AUDIO_ON_SONG SONG(AUDIO_ON_SOUND) +# define AUDIO_ON_SONG SONG(AUDIO_ON_SOUND) #endif #ifndef AUDIO_OFF_SONG - #define AUDIO_OFF_SONG SONG(AUDIO_OFF_SOUND) +# define AUDIO_OFF_SONG SONG(AUDIO_OFF_SOUND) #endif -float startup_song[][2] = STARTUP_SONG; -float audio_on_song[][2] = AUDIO_ON_SONG; +float startup_song[][2] = STARTUP_SONG; +float audio_on_song[][2] = AUDIO_ON_SONG; float audio_off_song[][2] = AUDIO_OFF_SONG; void audio_init() { - if (audio_initialized) { return; } // Check EEPROM -//TODO: avr defines? - #if defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE) + // TODO: avr defines? +#if defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE) if (!eeconfig_is_enabled()) { eeconfig_init(); } audio_config.raw = eeconfig_read_audio(); - #else // ARM EEPROM - audio_config.enable = true; - #ifdef AUDIO_CLICKY_ON +#else // ARM EEPROM + audio_config.enable = true; +# ifdef AUDIO_CLICKY_ON audio_config.clicky_enable = true; - #endif - #endif // ARM EEPROM - +# endif +#endif // ARM EEPROM if (!audio_initialized) { audio_initialize_hardware(); @@ -104,9 +102,7 @@ void audio_init() { void audio_startup(void) { if (audio_config.enable) { PLAY_SONG(startup_song); - } - } void stop_all_notes() { @@ -117,18 +113,17 @@ void stop_all_notes() { } voices = 0; - audio_stop_hardware(); + audio_stop_hardware(); playing_notes = false; - playing_note = false; - frequency = 0; + playing_note = false; + frequency = 0; frequency_alt = 0; - volume = 0; + volume = 0; - for (uint8_t i = 0; i < 8; i++) - { + for (uint8_t i = 0; i < 8; i++) { frequencies[i] = 0; - volumes[i] = 0; + volumes[i] = 0; } } @@ -142,19 +137,18 @@ void stop_note(float freq) { for (int i = 7; i >= 0; i--) { if (frequencies[i] == freq) { frequencies[i] = 0; - volumes[i] = 0; + volumes[i] = 0; for (int j = i; (j < 7); j++) { - frequencies[j] = frequencies[j+1]; - frequencies[j+1] = 0; - volumes[j] = volumes[j+1]; - volumes[j+1] = 0; + frequencies[j] = frequencies[j + 1]; + frequencies[j + 1] = 0; + volumes[j] = volumes[j + 1]; + volumes[j + 1] = 0; } break; } } voices--; - if (voices < 0) - voices = 0; + if (voices < 0) voices = 0; if (voice_place >= voices) { voice_place = 0; } @@ -163,16 +157,15 @@ void stop_note(float freq) { audio_stop_hardware(); - frequency = 0; + frequency = 0; frequency_alt = 0; - volume = 0; - playing_note = false; + volume = 0; + playing_note = false; } } } void play_note(float freq, int vol) { - dprintf("audio play note freq=%d vol=%d", (int)freq, vol); if (!audio_initialized) { @@ -180,10 +173,8 @@ void play_note(float freq, int vol) { } if (audio_config.enable && voices < 8) { - // Cancel notes if notes are playing - if (playing_notes) - stop_all_notes(); + if (playing_notes) stop_all_notes(); playing_note = true; @@ -191,56 +182,44 @@ void play_note(float freq, int vol) { if (freq > 0) { frequencies[voices] = freq; - volumes[voices] = vol; + volumes[voices] = vol; voices++; } audio_start_hardware(); } - } -void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) -{ - +void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) { if (!audio_initialized) { audio_init(); } if (audio_config.enable) { - // Cancel note if a note is playing - if (playing_note) - stop_all_notes(); + if (playing_note) stop_all_notes(); playing_notes = true; notes_pointer = np; - notes_count = n_count; - notes_repeat = n_repeat; + notes_count = n_count; + notes_repeat = n_repeat; current_note = 0; note_frequency = (*notes_pointer)[current_note][0]; - note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); - note_position = 0; - + note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); + note_position = 0; audio_start_hardware(); - // play_note((*notes_pointer)[current_note][0], 15); + // play_note((*notes_pointer)[current_note][0], 15); } } -bool is_playing_note(void) { - return playing_note; -} +bool is_playing_note(void) { return playing_note; } -bool is_playing_notes(void) { - return playing_notes; -} +bool is_playing_notes(void) { return playing_notes; } -bool is_audio_on(void) { - return (audio_config.enable != 0); -} +bool is_audio_on(void) { return (audio_config.enable != 0); } void audio_toggle(void) { if (audio_config.enable) { @@ -276,12 +255,12 @@ float mod(float a, int b) { } float vibrato(float average_freq) { -#ifdef VIBRATO_STRENGTH_ENABLE +# ifdef VIBRATO_STRENGTH_ENABLE float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); -#else +# else float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; -#endif - vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH); +# endif + vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0 / average_freq)), VIBRATO_LUT_LENGTH); return vibrated_freq; } @@ -290,17 +269,16 @@ float vibrato(float average_freq) { /* out of a possibly polyphonic setup, retrieve the frequency for a single voice to calculate the pwm period and duty-cycle from, relative to the cpy-frequency */ -float pwm_audio_get_single_voice_frequency( uint8_t voice ) { +float pwm_audio_get_single_voice_frequency(uint8_t voice) { float frequency = 0.0; - if (voice > voices) - return frequency; + if (voice > voices) return frequency; if (glissando) { - if (frequency != 0 && frequency < frequencies[voices - voice] && frequency < frequencies[voices - voice] * pow(2, -440/frequencies[voices - voice]/12/2)) { - frequency = frequency * pow(2, 440/frequency/12/2); - } else if (frequency != 0 && frequency > frequencies[voices - voice] && frequency > frequencies[voices - voice] * pow(2, 440/frequencies[voices - voice]/12/2)) { - frequency = frequency * pow(2, -440/frequency/12/2); + if (frequency != 0 && frequency < frequencies[voices - voice] && frequency < frequencies[voices - voice] * pow(2, -440 / frequencies[voices - voice] / 12 / 2)) { + frequency = frequency * pow(2, 440 / frequency / 12 / 2); + } else if (frequency != 0 && frequency > frequencies[voices - voice] && frequency > frequencies[voices - voice] * pow(2, 440 / frequencies[voices - voice] / 12 / 2)) { + frequency = frequency * pow(2, -440 / frequency / 12 / 2); } else { frequency = frequencies[voices - voice]; } @@ -328,34 +306,32 @@ float pwm_audio_get_single_voice_frequency( uint8_t voice ) { } void pwm_audio_timer_task(float *freq, float *freq_alt) { - if (playing_note) { if (voices > 0) { - - #ifdef BPIN_AUDIO +#ifdef BPIN_AUDIO *freq_alt = pwm_audio_get_single_voice_frequency(2); - #else +#else *freq_alt = 0.0f; - #endif +#endif if (polyphony_rate > 0) { if (voices > 1) { voice_place %= voices; -// if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { -// voice_place = (voice_place + 1) % voices; -// place = 0.0; -// } + // if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { + // voice_place = (voice_place + 1) % voices; + // place = 0.0; + // } } - #ifdef VIBRATO_ENABLE +#ifdef VIBRATO_ENABLE if (vibrato_strength > 0) { *freq = vibrato(frequencies[voice_place]); } else { *freq = frequencies[voice_place]; } - #else +#else *freq = frequencies[voice_place]; - #endif +#endif } else { *freq = pwm_audio_get_single_voice_frequency(1); } @@ -364,15 +340,15 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { if (playing_notes) { if (note_frequency > 0) { - #ifdef VIBRATO_ENABLE +#ifdef VIBRATO_ENABLE if (vibrato_strength > 0) { *freq = vibrato(note_frequency); } else { *freq = note_frequency; } - #else +#else *freq = note_frequency; - #endif +#endif if (envelope_index < 65535) { envelope_index++; @@ -383,9 +359,9 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { note_position++; bool end_of_note = false; if (!note_resting) - end_of_note = (note_position >= (note_length*8 - 1)); + end_of_note = (note_position >= (note_length * 8 - 1)); else - end_of_note = (note_position >= (note_length*8)); + end_of_note = (note_position >= (note_length * 8)); if (end_of_note) { current_note++; @@ -402,16 +378,16 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { current_note--; if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) { note_frequency = 0; - note_length = 1; + note_length = 1; } else { note_frequency = (*notes_pointer)[current_note][0]; - note_length = 1; + note_length = 1; } } else { - note_resting = false; + note_resting = false; envelope_index = 0; note_frequency = (*notes_pointer)[current_note][0]; - note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); + note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); } note_position = 0; @@ -419,83 +395,54 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { if (!audio_config.enable) { playing_notes = false; - playing_note = false; + playing_note = false; } } } - #ifdef VIBRATO_ENABLE // Vibrato rate functions -void set_vibrato_rate(float rate) { - vibrato_rate = rate; -} +void set_vibrato_rate(float rate) { vibrato_rate = rate; } -void increase_vibrato_rate(float change) { - vibrato_rate *= change; -} +void increase_vibrato_rate(float change) { vibrato_rate *= change; } -void decrease_vibrato_rate(float change) { - vibrato_rate /= change; -} +void decrease_vibrato_rate(float change) { vibrato_rate /= change; } -#ifdef VIBRATO_STRENGTH_ENABLE +# ifdef VIBRATO_STRENGTH_ENABLE -void set_vibrato_strength(float strength) { - vibrato_strength = strength; -} +void set_vibrato_strength(float strength) { vibrato_strength = strength; } -void increase_vibrato_strength(float change) { - vibrato_strength *= change; -} +void increase_vibrato_strength(float change) { vibrato_strength *= change; } -void decrease_vibrato_strength(float change) { - vibrato_strength /= change; -} +void decrease_vibrato_strength(float change) { vibrato_strength /= change; } -#endif /* VIBRATO_STRENGTH_ENABLE */ +# endif /* VIBRATO_STRENGTH_ENABLE */ #endif /* VIBRATO_ENABLE */ // Polyphony functions -void set_polyphony_rate(float rate) { - polyphony_rate = rate; -} +void set_polyphony_rate(float rate) { polyphony_rate = rate; } -void enable_polyphony(void) { - polyphony_rate = 5; -} +void enable_polyphony(void) { polyphony_rate = 5; } -void disable_polyphony(void) { - polyphony_rate = 0; -} +void disable_polyphony(void) { polyphony_rate = 0; } -void increase_polyphony_rate(float change) { - polyphony_rate *= change; -} +void increase_polyphony_rate(float change) { polyphony_rate *= change; } -void decrease_polyphony_rate(float change) { - polyphony_rate /= change; -} +void decrease_polyphony_rate(float change) { polyphony_rate /= change; } // Timbre function -void set_timbre(float timbre) { - note_timbre = timbre; -} +void set_timbre(float timbre) { note_timbre = timbre; } // Tempo functions -void set_tempo(uint8_t tempo) { - note_tempo = tempo; -} +void set_tempo(uint8_t tempo) { note_tempo = tempo; } -void decrease_tempo(uint8_t tempo_change) { - note_tempo += tempo_change; -} +void decrease_tempo(uint8_t tempo_change) { note_tempo += tempo_change; } void increase_tempo(uint8_t tempo_change) { if (note_tempo - tempo_change < 10) { diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index d78a64bd9d51..bb684650407e 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -28,7 +28,7 @@ #include "quantum.h" #include #if defined(PROTOCOL_CHIBIOS) - #include "audio_chibios_dac.h" +# include "audio_chibios_dac.h" #endif // Largely untested PWM audio mode (doesn't sound as good) @@ -59,7 +59,7 @@ void audio_on(void); void audio_off(void); float pwm_audio_get_single_voice(uint8_t voice); -void pwm_audio_timer_task(float *freq, float *freq_alt); +void pwm_audio_timer_task(float *freq, float *freq_alt); // Vibrato rate functions diff --git a/quantum/audio/audio_avr_pwm.c b/quantum/audio/audio_avr_pwm.c index 4f6ce609dc2f..8593731eb148 100644 --- a/quantum/audio/audio_avr_pwm.c +++ b/quantum/audio/audio_avr_pwm.c @@ -18,18 +18,18 @@ #include //#include #if defined(__AVR__) - #include - #include - #include +# include +# include +# include #endif #include "print.h" #include "audio.h" #include "wait.h" -//TODO: move into audio-common state -extern bool playing_notes; -extern float note_timbre; +// TODO: move into audio-common state +extern bool playing_notes; +extern float note_timbre; extern uint8_t voices; #define CPU_PRESCALER 8 @@ -38,104 +38,99 @@ extern uint8_t voices; // Timer Abstractions // ----------------------------------------------------------------------------- -//Currently we support timers 1 and 3 used at the same time, channels A-C, -//pins PB5, PB6, PB7, PC4, PC5, and PC6 +// Currently we support timers 1 and 3 used at the same time, channels A-C, +// pins PB5, PB6, PB7, PC4, PC5, and PC6 #if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) - #define AUDIO1_PIN_SET - #define AUDIO1_TIMSKx TIMSK1 - #define AUDIO1_TCCRxA TCCR1A - #define AUDIO1_TCCRxB TCCR1B - #define AUDIO1_ICRx ICR1 - #define AUDIO1_WGMx0 WGM10 - #define AUDIO1_WGMx1 WGM11 - #define AUDIO1_WGMx2 WGM12 - #define AUDIO1_WGMx3 WGM13 - #define AUDIO1_CSx0 CS10 - #define AUDIO1_CSx1 CS11 - #define AUDIO1_CSx2 CS12 - - #if defined(B5_AUDIO) - #define AUDIO1_COMxy0 COM1A0 - #define AUDIO1_COMxy1 COM1A1 - #define AUDIO1_OCIExy OCIE1A - #define AUDIO1_OCRxy OCR1A - #define AUDIO1_PIN B5 - #define AUDIO1_TIMERx_COMPy_vect TIMER1_COMPA_vect - #elif defined(B6_AUDIO) - #define AUDIO1_COMxy0 COM1B0 - #define AUDIO1_COMxy1 COM1B1 - #define AUDIO1_OCIExy OCIE1B - #define AUDIO1_OCRxy OCR1B - #define AUDIO1_PIN B6 - #define AUDIO1_TIMERx_COMPy_vect TIMER1_COMPB_vect - #elif defined(B7_AUDIO) - #define AUDIO1_COMxy0 COM1C0 - #define AUDIO1_COMxy1 COM1C1 - #define AUDIO1_OCIExy OCIE1C - #define AUDIO1_OCRxy OCR1C - #define AUDIO1_PIN B7 - #define AUDIO1_TIMERx_COMPy_vect TIMER1_COMPC_vect - #endif +# define AUDIO1_PIN_SET +# define AUDIO1_TIMSKx TIMSK1 +# define AUDIO1_TCCRxA TCCR1A +# define AUDIO1_TCCRxB TCCR1B +# define AUDIO1_ICRx ICR1 +# define AUDIO1_WGMx0 WGM10 +# define AUDIO1_WGMx1 WGM11 +# define AUDIO1_WGMx2 WGM12 +# define AUDIO1_WGMx3 WGM13 +# define AUDIO1_CSx0 CS10 +# define AUDIO1_CSx1 CS11 +# define AUDIO1_CSx2 CS12 + +# if defined(B5_AUDIO) +# define AUDIO1_COMxy0 COM1A0 +# define AUDIO1_COMxy1 COM1A1 +# define AUDIO1_OCIExy OCIE1A +# define AUDIO1_OCRxy OCR1A +# define AUDIO1_PIN B5 +# define AUDIO1_TIMERx_COMPy_vect TIMER1_COMPA_vect +# elif defined(B6_AUDIO) +# define AUDIO1_COMxy0 COM1B0 +# define AUDIO1_COMxy1 COM1B1 +# define AUDIO1_OCIExy OCIE1B +# define AUDIO1_OCRxy OCR1B +# define AUDIO1_PIN B6 +# define AUDIO1_TIMERx_COMPy_vect TIMER1_COMPB_vect +# elif defined(B7_AUDIO) +# define AUDIO1_COMxy0 COM1C0 +# define AUDIO1_COMxy1 COM1C1 +# define AUDIO1_OCIExy OCIE1C +# define AUDIO1_OCRxy OCR1C +# define AUDIO1_PIN B7 +# define AUDIO1_TIMERx_COMPy_vect TIMER1_COMPC_vect +# endif #endif #if defined(C4_AUDIO) || defined(C5_AUDIO) || defined(C6_AUDIO) - #define AUDIO2_PIN_SET - #define AUDIO2_TIMSKx TIMSK3 - #define AUDIO2_TCCRxA TCCR3A - #define AUDIO2_TCCRxB TCCR3B - #define AUDIO2_ICRx ICR3 - #define AUDIO2_WGMx0 WGM30 - #define AUDIO2_WGMx1 WGM31 - #define AUDIO2_WGMx2 WGM32 - #define AUDIO2_WGMx3 WGM33 - #define AUDIO2_CSx0 CS30 - #define AUDIO2_CSx1 CS31 - #define AUDIO2_CSx2 CS32 - - #if defined(C6_AUDIO) - #define AUDIO2_COMxy0 COM3A0 - #define AUDIO2_COMxy1 COM3A1 - #define AUDIO2_OCIExy OCIE3A - #define AUDIO2_OCRxy OCR3A - #define AUDIO2_PIN C6 - #define AUDIO2_TIMERx_COMPy_vect TIMER3_COMPA_vect - #elif defined(C5_AUDIO) - #define AUDIO2_COMxy0 COM3B0 - #define AUDIO2_COMxy1 COM3B1 - #define AUDIO2_OCIExy OCIE3B - #define AUDIO2_OCRxy OCR3B - #define AUDIO2_PIN C5 - #define AUDIO2_TIMERx_COMPy_vect TIMER3_COMPB_vect - #elif defined(C4_AUDIO) - #define AUDIO2_COMxy0 COM3C0 - #define AUDIO2_COMxy1 COM3C1 - #define AUDIO2_OCIExy OCIE3C - #define AUDIO2_OCRxy OCR3C - #define AUDIO2_PIN C4 - #define AUDIO2_TIMERx_COMPy_vect TIMER3_COMPC_vect - #endif +# define AUDIO2_PIN_SET +# define AUDIO2_TIMSKx TIMSK3 +# define AUDIO2_TCCRxA TCCR3A +# define AUDIO2_TCCRxB TCCR3B +# define AUDIO2_ICRx ICR3 +# define AUDIO2_WGMx0 WGM30 +# define AUDIO2_WGMx1 WGM31 +# define AUDIO2_WGMx2 WGM32 +# define AUDIO2_WGMx3 WGM33 +# define AUDIO2_CSx0 CS30 +# define AUDIO2_CSx1 CS31 +# define AUDIO2_CSx2 CS32 + +# if defined(C6_AUDIO) +# define AUDIO2_COMxy0 COM3A0 +# define AUDIO2_COMxy1 COM3A1 +# define AUDIO2_OCIExy OCIE3A +# define AUDIO2_OCRxy OCR3A +# define AUDIO2_PIN C6 +# define AUDIO2_TIMERx_COMPy_vect TIMER3_COMPA_vect +# elif defined(C5_AUDIO) +# define AUDIO2_COMxy0 COM3B0 +# define AUDIO2_COMxy1 COM3B1 +# define AUDIO2_OCIExy OCIE3B +# define AUDIO2_OCRxy OCR3B +# define AUDIO2_PIN C5 +# define AUDIO2_TIMERx_COMPy_vect TIMER3_COMPB_vect +# elif defined(C4_AUDIO) +# define AUDIO2_COMxy0 COM3C0 +# define AUDIO2_COMxy1 COM3C1 +# define AUDIO2_OCIExy OCIE3C +# define AUDIO2_OCRxy OCR3C +# define AUDIO2_PIN C4 +# define AUDIO2_TIMERx_COMPy_vect TIMER3_COMPC_vect +# endif #endif - // C6 seems to be the assumed default by many existing keyboard - but sill warn the user #if !defined(AUDIO2_PIN_SET) && !defined(AUDIO1_PIN_SET) -#pragma message "audio feature enabled, but no pin selected - see docs/feature_audio for defines to set" +# pragma message "audio feature enabled, but no pin selected - see docs/feature_audio for defines to set" #endif // ----------------------------------------------------------------------------- - float place = 0; #ifdef AUDIO1_PIN_SET static float channel_1_frequency = 0.0f; -void channel_1_set_frequency(float freq) { +void channel_1_set_frequency(float freq) { + if (freq < 0.0f) freq = 0.0f; - if (freq < 0.0f) - freq = 0.0f; - - if (freq == channel_1_frequency) - return; + if (freq == channel_1_frequency) return; channel_1_frequency = freq; @@ -145,9 +140,7 @@ void channel_1_set_frequency(float freq) { AUDIO1_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); } -float channel_1_get_frequency(void) { - return channel_1_frequency; -} +float channel_1_get_frequency(void) { return channel_1_frequency; } void channel_1_start(void) { // enable timer-counter ISR @@ -166,17 +159,14 @@ void channel_1_stop(void) { #ifdef AUDIO2_PIN_SET static float channel_2_frequency = 0.0f; -void channel_2_set_frequency(float freq) { +void channel_2_set_frequency(float freq) { + if (freq < 0.0f) freq = 0.0f; - if (freq < 0.0f) - freq = 0.0f; - - if (freq == channel_2_frequency) - return; + if (freq == channel_2_frequency) return; channel_2_frequency = freq; - AUDIO2_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + AUDIO2_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); AUDIO2_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); } @@ -191,9 +181,7 @@ void channel_2_stop(void) { } #endif - void audio_initialize_hardware() { - #ifdef AUDIO1_PIN_SET channel_1_stop(); // Set audio ports as output @@ -225,69 +213,60 @@ void audio_initialize_hardware() { #ifdef AUDIO1_PIN_SET // initialize timer-counter AUDIO1_TCCRxA = (0 << AUDIO1_COMxy1) | (0 << AUDIO1_COMxy0) | (1 << AUDIO1_WGMx1) | (0 << AUDIO1_WGMx0); - AUDIO1_TCCRxB = (1 << AUDIO1_WGMx3) | (1 << AUDIO1_WGMx2) | (0 << AUDIO1_CSx2) | (1 << AUDIO1_CSx1) | (0 << AUDIO1_CSx0); + AUDIO1_TCCRxB = (1 << AUDIO1_WGMx3) | (1 << AUDIO1_WGMx2) | (0 << AUDIO1_CSx2) | (1 << AUDIO1_CSx1) | (0 << AUDIO1_CSx0); - //channel_1_set_frequency(440); // original code set this frequency here... why? + // channel_1_set_frequency(440); // original code set this frequency here... why? #endif - // Clock Select (CS3n) = 0b010 = Clock / 8 #ifdef AUDIO2_PIN_SET AUDIO2_TCCRxA = (0 << AUDIO2_COMxy1) | (0 << AUDIO2_COMxy0) | (1 << AUDIO2_WGMx1) | (0 << AUDIO2_WGMx0); - AUDIO2_TCCRxB = (1 << AUDIO2_WGMx3) | (1 << AUDIO2_WGMx2) | (0 << AUDIO2_CSx2) | (1 << AUDIO2_CSx1) | (0 << AUDIO2_CSx0); + AUDIO2_TCCRxB = (1 << AUDIO2_WGMx3) | (1 << AUDIO2_WGMx2) | (0 << AUDIO2_CSx2) | (1 << AUDIO2_CSx1) | (0 << AUDIO2_CSx0); - //channel_2_set_frequency(440); // original code set this frequency here... why? + // channel_2_set_frequency(440); // original code set this frequency here... why? #endif audio_initialized = true; } -void audio_startup() { - if (audio_config.enable) { - PLAY_SONG(startup_song); - } -} void audio_stop_hardware() { +#ifdef AUDIO2_PIN_SET + channel_2_stop(); +#endif - #ifdef AUDIO2_PIN_SET - channel_2_stop(); - #endif - - #ifdef AUDIO1_PIN_SET - channel_1_stop(); - #endif +#ifdef AUDIO1_PIN_SET + channel_1_stop(); +#endif } void audio_start_hardware(void) { - - #ifdef AUDIO2_PIN_SET +#ifdef AUDIO2_PIN_SET channel_2_start(); - #endif - #ifdef AUDIO1_PIN_SET - #ifdef AUDIO2_PIN_SET - if (voices > 1) { - channel_1_start(); - } - #else +#endif +#ifdef AUDIO1_PIN_SET +# ifdef AUDIO2_PIN_SET + if (voices > 1) { channel_1_start(); - #endif - #endif + } +# else + channel_1_start(); +# endif +#endif } #ifdef AUDIO2_PIN_SET ISR(AUDIO2_TIMERx_COMPy_vect) { - float freq, freq_alt; pwm_audio_timer_task(&freq, &freq_alt); - // do polyphonic, if a second speaker is available - #ifdef AUDIO1_PIN_SET +// do polyphonic, if a second speaker is available +# ifdef AUDIO1_PIN_SET if (playing_notes) channel_1_set_frequency(freq_alt); else channel_1_stop(); - #endif +# endif if (playing_notes) channel_2_set_frequency(freq); @@ -298,8 +277,7 @@ ISR(AUDIO2_TIMERx_COMPy_vect) { #ifdef AUDIO1_PIN_SET ISR(AUDIO1_TIMERx_COMPy_vect) { - - #if defined(AUDIO1_PIN_SET) && !defined(AUDIO2_PIN_SET) +# if defined(AUDIO1_PIN_SET) && !defined(AUDIO2_PIN_SET) float freq, freq_alt; pwm_audio_timer_task(&freq, &freq_alt); @@ -307,6 +285,6 @@ ISR(AUDIO1_TIMERx_COMPy_vect) { channel_1_set_frequency(freq); else channel_1_stop(); - #endif +# endif } #endif diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index bf5bd932cb5d..93105afcad96 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -21,13 +21,13 @@ #include #include "print.h" -//TODO: move into audio-common state -extern bool playing_notes; -extern uint8_t voices; -extern float frequencies[8]; +// TODO: move into audio-common state +extern bool playing_notes; +extern uint8_t voices; +extern float frequencies[8]; extern uint32_t note_position; -extern float note_length; -extern float (* notes_pointer)[][2]; +extern float note_length; +extern float (*notes_pointer)[][2]; extern uint16_t current_note; extern bool notes_repeat; extern uint16_t notes_count; @@ -36,87 +36,23 @@ extern uint16_t envelope_index; // ----------------------------------------------------------------------------- - - static const dacsample_t dac_buffer_sine[DAC_BUFFER_SIZE] = { - // 256 values, max 4095 - 0x800,0x832,0x864,0x896,0x8c8,0x8fa,0x92c,0x95e, - 0x98f,0x9c0,0x9f1,0xa22,0xa52,0xa82,0xab1,0xae0, - 0xb0f,0xb3d,0xb6b,0xb98,0xbc5,0xbf1,0xc1c,0xc47, - 0xc71,0xc9a,0xcc3,0xceb,0xd12,0xd39,0xd5f,0xd83, - 0xda7,0xdca,0xded,0xe0e,0xe2e,0xe4e,0xe6c,0xe8a, - 0xea6,0xec1,0xedc,0xef5,0xf0d,0xf24,0xf3a,0xf4f, - 0xf63,0xf76,0xf87,0xf98,0xfa7,0xfb5,0xfc2,0xfcd, - 0xfd8,0xfe1,0xfe9,0xff0,0xff5,0xff9,0xffd,0xffe, - 0xfff,0xffe,0xffd,0xff9,0xff5,0xff0,0xfe9,0xfe1, - 0xfd8,0xfcd,0xfc2,0xfb5,0xfa7,0xf98,0xf87,0xf76, - 0xf63,0xf4f,0xf3a,0xf24,0xf0d,0xef5,0xedc,0xec1, - 0xea6,0xe8a,0xe6c,0xe4e,0xe2e,0xe0e,0xded,0xdca, - 0xda7,0xd83,0xd5f,0xd39,0xd12,0xceb,0xcc3,0xc9a, - 0xc71,0xc47,0xc1c,0xbf1,0xbc5,0xb98,0xb6b,0xb3d, - 0xb0f,0xae0,0xab1,0xa82,0xa52,0xa22,0x9f1,0x9c0, - 0x98f,0x95e,0x92c,0x8fa,0x8c8,0x896,0x864,0x832, - 0x800,0x7cd,0x79b,0x769,0x737,0x705,0x6d3,0x6a1, - 0x670,0x63f,0x60e,0x5dd,0x5ad,0x57d,0x54e,0x51f, - 0x4f0,0x4c2,0x494,0x467,0x43a,0x40e,0x3e3,0x3b8, - 0x38e,0x365,0x33c,0x314,0x2ed,0x2c6,0x2a0,0x27c, - 0x258,0x235,0x212,0x1f1,0x1d1,0x1b1,0x193,0x175, - 0x159,0x13e,0x123,0x10a,0xf2, 0xdb, 0xc5, 0xb0, - 0x9c, 0x89, 0x78, 0x67, 0x58, 0x4a, 0x3d, 0x32, - 0x27, 0x1e, 0x16, 0xf, 0xa, 0x6, 0x2, 0x1, - 0x0, 0x1, 0x2, 0x6, 0xa, 0xf, 0x16, 0x1e, - 0x27, 0x32, 0x3d, 0x4a, 0x58, 0x67, 0x78, 0x89, - 0x9c, 0xb0, 0xc5, 0xdb, 0xf2, 0x10a,0x123,0x13e, - 0x159,0x175,0x193,0x1b1,0x1d1,0x1f1,0x212,0x235, - 0x258,0x27c,0x2a0,0x2c6,0x2ed,0x314,0x33c,0x365, - 0x38e,0x3b8,0x3e3,0x40e,0x43a,0x467,0x494,0x4c2, - 0x4f0,0x51f,0x54e,0x57d,0x5ad,0x5dd,0x60e,0x63f, - 0x670,0x6a1,0x6d3,0x705,0x737,0x769,0x79b,0x7cd -}; + // 256 values, max 4095 + 0x800, 0x832, 0x864, 0x896, 0x8c8, 0x8fa, 0x92c, 0x95e, 0x98f, 0x9c0, 0x9f1, 0xa22, 0xa52, 0xa82, 0xab1, 0xae0, 0xb0f, 0xb3d, 0xb6b, 0xb98, 0xbc5, 0xbf1, 0xc1c, 0xc47, 0xc71, 0xc9a, 0xcc3, 0xceb, 0xd12, 0xd39, 0xd5f, 0xd83, 0xda7, 0xdca, 0xded, 0xe0e, 0xe2e, 0xe4e, 0xe6c, 0xe8a, 0xea6, 0xec1, 0xedc, 0xef5, 0xf0d, 0xf24, 0xf3a, 0xf4f, 0xf63, 0xf76, 0xf87, 0xf98, 0xfa7, 0xfb5, 0xfc2, 0xfcd, 0xfd8, 0xfe1, 0xfe9, 0xff0, 0xff5, 0xff9, 0xffd, 0xffe, 0xfff, 0xffe, 0xffd, 0xff9, 0xff5, 0xff0, 0xfe9, 0xfe1, 0xfd8, 0xfcd, 0xfc2, 0xfb5, 0xfa7, 0xf98, 0xf87, 0xf76, 0xf63, 0xf4f, 0xf3a, 0xf24, 0xf0d, 0xef5, 0xedc, 0xec1, 0xea6, 0xe8a, 0xe6c, 0xe4e, 0xe2e, 0xe0e, 0xded, 0xdca, 0xda7, 0xd83, 0xd5f, 0xd39, 0xd12, 0xceb, 0xcc3, 0xc9a, 0xc71, 0xc47, 0xc1c, 0xbf1, 0xbc5, 0xb98, 0xb6b, 0xb3d, 0xb0f, 0xae0, 0xab1, 0xa82, 0xa52, 0xa22, 0x9f1, 0x9c0, 0x98f, 0x95e, 0x92c, 0x8fa, 0x8c8, 0x896, 0x864, 0x832, + 0x800, 0x7cd, 0x79b, 0x769, 0x737, 0x705, 0x6d3, 0x6a1, 0x670, 0x63f, 0x60e, 0x5dd, 0x5ad, 0x57d, 0x54e, 0x51f, 0x4f0, 0x4c2, 0x494, 0x467, 0x43a, 0x40e, 0x3e3, 0x3b8, 0x38e, 0x365, 0x33c, 0x314, 0x2ed, 0x2c6, 0x2a0, 0x27c, 0x258, 0x235, 0x212, 0x1f1, 0x1d1, 0x1b1, 0x193, 0x175, 0x159, 0x13e, 0x123, 0x10a, 0xf2, 0xdb, 0xc5, 0xb0, 0x9c, 0x89, 0x78, 0x67, 0x58, 0x4a, 0x3d, 0x32, 0x27, 0x1e, 0x16, 0xf, 0xa, 0x6, 0x2, 0x1, 0x0, 0x1, 0x2, 0x6, 0xa, 0xf, 0x16, 0x1e, 0x27, 0x32, 0x3d, 0x4a, 0x58, 0x67, 0x78, 0x89, 0x9c, 0xb0, 0xc5, 0xdb, 0xf2, 0x10a, 0x123, 0x13e, 0x159, 0x175, 0x193, 0x1b1, 0x1d1, 0x1f1, 0x212, 0x235, 0x258, 0x27c, 0x2a0, 0x2c6, 0x2ed, 0x314, 0x33c, 0x365, 0x38e, 0x3b8, 0x3e3, 0x40e, 0x43a, 0x467, 0x494, 0x4c2, 0x4f0, 0x51f, 0x54e, 0x57d, 0x5ad, 0x5dd, 0x60e, 0x63f, 0x670, 0x6a1, 0x6d3, 0x705, 0x737, 0x769, 0x79b, 0x7cd}; static const dacsample_t dac_buffer_triangle[DAC_BUFFER_SIZE] = { - // 256 values, max 4095 - 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x100, - 0x120,0x140,0x160,0x180,0x1a0,0x1c0,0x1e0,0x200, - 0x220,0x240,0x260,0x280,0x2a0,0x2c0,0x2e0,0x300, - 0x320,0x340,0x360,0x380,0x3a0,0x3c0,0x3e0,0x400, - 0x420,0x440,0x460,0x480,0x4a0,0x4c0,0x4e0,0x500, - 0x520,0x540,0x560,0x580,0x5a0,0x5c0,0x5e0,0x600, - 0x620,0x640,0x660,0x680,0x6a0,0x6c0,0x6e0,0x700, - 0x720,0x740,0x760,0x780,0x7a0,0x7c0,0x7e0,0x800, - 0x81f,0x83f,0x85f,0x87f,0x89f,0x8bf,0x8df,0x8ff, - 0x91f,0x93f,0x95f,0x97f,0x99f,0x9bf,0x9df,0x9ff, - 0xa1f,0xa3f,0xa5f,0xa7f,0xa9f,0xabf,0xadf,0xaff, - 0xb1f,0xb3f,0xb5f,0xb7f,0xb9f,0xbbf,0xbdf,0xbff, - 0xc1f,0xc3f,0xc5f,0xc7f,0xc9f,0xcbf,0xcdf,0xcff, - 0xd1f,0xd3f,0xd5f,0xd7f,0xd9f,0xdbf,0xddf,0xdff, - 0xe1f,0xe3f,0xe5f,0xe7f,0xe9f,0xebf,0xedf,0xeff, - 0xf1f,0xf3f,0xf5f,0xf7f,0xf9f,0xfbf,0xfdf,0xfff, - 0xfdf,0xfbf,0xf9f,0xf7f,0xf5f,0xf3f,0xf1f,0xeff, - 0xedf,0xebf,0xe9f,0xe7f,0xe5f,0xe3f,0xe1f,0xdff, - 0xddf,0xdbf,0xd9f,0xd7f,0xd5f,0xd3f,0xd1f,0xcff, - 0xcdf,0xcbf,0xc9f,0xc7f,0xc5f,0xc3f,0xc1f,0xbff, - 0xbdf,0xbbf,0xb9f,0xb7f,0xb5f,0xb3f,0xb1f,0xaff, - 0xadf,0xabf,0xa9f,0xa7f,0xa5f,0xa3f,0xa1f,0x9ff, - 0x9df,0x9bf,0x99f,0x97f,0x95f,0x93f,0x91f,0x8ff, - 0x8df,0x8bf,0x89f,0x87f,0x85f,0x83f,0x81f,0x800, - 0x7e0,0x7c0,0x7a0,0x780,0x760,0x740,0x720,0x700, - 0x6e0,0x6c0,0x6a0,0x680,0x660,0x640,0x620,0x600, - 0x5e0,0x5c0,0x5a0,0x580,0x560,0x540,0x520,0x500, - 0x4e0,0x4c0,0x4a0,0x480,0x460,0x440,0x420,0x400, - 0x3e0,0x3c0,0x3a0,0x380,0x360,0x340,0x320,0x300, - 0x2e0,0x2c0,0x2a0,0x280,0x260,0x240,0x220,0x200, - 0x1e0,0x1c0,0x1a0,0x180,0x160,0x140,0x120,0x100, - 0xe0, 0xc0, 0xa0, 0x80, 0x60, 0x40, 0x20, 0x0 -}; + // 256 values, max 4095 + 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x100, 0x120, 0x140, 0x160, 0x180, 0x1a0, 0x1c0, 0x1e0, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0x400, 0x420, 0x440, 0x460, 0x480, 0x4a0, 0x4c0, 0x4e0, 0x500, 0x520, 0x540, 0x560, 0x580, 0x5a0, 0x5c0, 0x5e0, 0x600, 0x620, 0x640, 0x660, 0x680, 0x6a0, 0x6c0, 0x6e0, 0x700, 0x720, 0x740, 0x760, 0x780, 0x7a0, 0x7c0, 0x7e0, 0x800, 0x81f, 0x83f, 0x85f, 0x87f, 0x89f, 0x8bf, 0x8df, 0x8ff, 0x91f, 0x93f, 0x95f, 0x97f, 0x99f, 0x9bf, 0x9df, 0x9ff, 0xa1f, 0xa3f, 0xa5f, 0xa7f, 0xa9f, 0xabf, 0xadf, 0xaff, 0xb1f, 0xb3f, 0xb5f, 0xb7f, 0xb9f, 0xbbf, 0xbdf, 0xbff, 0xc1f, 0xc3f, 0xc5f, 0xc7f, 0xc9f, 0xcbf, 0xcdf, 0xcff, 0xd1f, 0xd3f, 0xd5f, 0xd7f, 0xd9f, 0xdbf, 0xddf, 0xdff, 0xe1f, 0xe3f, 0xe5f, 0xe7f, 0xe9f, 0xebf, 0xedf, 0xeff, 0xf1f, 0xf3f, 0xf5f, 0xf7f, 0xf9f, 0xfbf, 0xfdf, 0xfff, + 0xfdf, 0xfbf, 0xf9f, 0xf7f, 0xf5f, 0xf3f, 0xf1f, 0xeff, 0xedf, 0xebf, 0xe9f, 0xe7f, 0xe5f, 0xe3f, 0xe1f, 0xdff, 0xddf, 0xdbf, 0xd9f, 0xd7f, 0xd5f, 0xd3f, 0xd1f, 0xcff, 0xcdf, 0xcbf, 0xc9f, 0xc7f, 0xc5f, 0xc3f, 0xc1f, 0xbff, 0xbdf, 0xbbf, 0xb9f, 0xb7f, 0xb5f, 0xb3f, 0xb1f, 0xaff, 0xadf, 0xabf, 0xa9f, 0xa7f, 0xa5f, 0xa3f, 0xa1f, 0x9ff, 0x9df, 0x9bf, 0x99f, 0x97f, 0x95f, 0x93f, 0x91f, 0x8ff, 0x8df, 0x8bf, 0x89f, 0x87f, 0x85f, 0x83f, 0x81f, 0x800, 0x7e0, 0x7c0, 0x7a0, 0x780, 0x760, 0x740, 0x720, 0x700, 0x6e0, 0x6c0, 0x6a0, 0x680, 0x660, 0x640, 0x620, 0x600, 0x5e0, 0x5c0, 0x5a0, 0x580, 0x560, 0x540, 0x520, 0x500, 0x4e0, 0x4c0, 0x4a0, 0x480, 0x460, 0x440, 0x420, 0x400, 0x3e0, 0x3c0, 0x3a0, 0x380, 0x360, 0x340, 0x320, 0x300, 0x2e0, 0x2c0, 0x2a0, 0x280, 0x260, 0x240, 0x220, 0x200, 0x1e0, 0x1c0, 0x1a0, 0x180, 0x160, 0x140, 0x120, 0x100, 0xe0, 0xc0, 0xa0, 0x80, 0x60, 0x40, 0x20, 0x0}; static const dacsample_t dac_buffer_square[DAC_BUFFER_SIZE] = { - // First half is max, second half is 0 - [0 ... DAC_BUFFER_SIZE/2-1] = DAC_SAMPLE_MAX, - [DAC_BUFFER_SIZE/2 ... DAC_BUFFER_SIZE -1] = 0, + // First half is max, second half is 0 + [0 ... DAC_BUFFER_SIZE / 2 - 1] = DAC_SAMPLE_MAX, + [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = 0, }; -static dacsample_t dac_buffer_empty[DAC_BUFFER_SIZE] = { DAC_OFF_VALUE }; +static dacsample_t dac_buffer_empty[DAC_BUFFER_SIZE] = {DAC_OFF_VALUE}; static float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; @@ -124,92 +60,82 @@ static float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; * Generation of the waveform being passed to the callback. Declared weak so users * can override it with their own waveforms/noises. */ -__attribute__ ((weak)) -uint16_t dac_value_generate(void) { - uint16_t value = DAC_OFF_VALUE; - uint8_t working_voices = voices; - if (working_voices > DAC_VOICES_MAX) - working_voices = DAC_VOICES_MAX; - - if (working_voices > 0) { - uint16_t value_avg = 0; - for (uint8_t i = 0; i < working_voices; i++) { - dac_if[i] = dac_if[i] + ((frequencies[i] * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE); - - // Needed because % doesn't work with floats - while (dac_if[i] >= (DAC_BUFFER_SIZE)) - dac_if[i] = dac_if[i] - DAC_BUFFER_SIZE; - - // Wavetable generation/lookup - uint16_t dac_i = (uint16_t)dac_if[i]; - // SINE - value_avg += dac_buffer_sine[dac_i] / working_voices / 3; - // TRIANGLE - value_avg += dac_buffer_triangle[dac_i] / working_voices / 3; - // SQUARE - value_avg += dac_buffer_square[dac_i] / working_voices / 3; +__attribute__((weak)) uint16_t dac_value_generate(void) { + uint16_t value = DAC_OFF_VALUE; + uint8_t working_voices = voices; + if (working_voices > DAC_VOICES_MAX) working_voices = DAC_VOICES_MAX; + + if (working_voices > 0) { + uint16_t value_avg = 0; + for (uint8_t i = 0; i < working_voices; i++) { + dac_if[i] = dac_if[i] + ((frequencies[i] * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE); + + // Needed because % doesn't work with floats + while (dac_if[i] >= (DAC_BUFFER_SIZE)) dac_if[i] = dac_if[i] - DAC_BUFFER_SIZE; + + // Wavetable generation/lookup + uint16_t dac_i = (uint16_t)dac_if[i]; + // SINE + value_avg += dac_buffer_sine[dac_i] / working_voices / 3; + // TRIANGLE + value_avg += dac_buffer_triangle[dac_i] / working_voices / 3; + // SQUARE + value_avg += dac_buffer_square[dac_i] / working_voices / 3; + } + value = value_avg; } - value = value_avg; - } - return value; + return value; } /** * DAC streaming callback. Does all of the main computing for playing songs. */ -static void dac_end(DACDriver * dacp, dacsample_t * sample_p, size_t sample_count) { - - (void)dacp; - - for (uint8_t s = 0; s < sample_count; s++) { - sample_p[s] = dac_value_generate(); - } - - if (playing_notes) { - note_position += sample_count; - - // End of the note - 35 is arbitary here, but gets us close to AVR's timing - if ((note_position >= (note_length*DAC_SAMPLE_RATE/35))) { - stop_note((*notes_pointer)[current_note][0]); - current_note++; - if (current_note >= notes_count) { - if (notes_repeat) { - current_note = 0; - } else { - playing_notes = false; - return; +static void dac_end(DACDriver *dacp, dacsample_t *sample_p, size_t sample_count) { + (void)dacp; + + for (uint8_t s = 0; s < sample_count; s++) { + sample_p[s] = dac_value_generate(); + } + + if (playing_notes) { + note_position += sample_count; + + // End of the note - 35 is arbitary here, but gets us close to AVR's timing + if ((note_position >= (note_length * DAC_SAMPLE_RATE / 35))) { + stop_note((*notes_pointer)[current_note][0]); + current_note++; + if (current_note >= notes_count) { + if (notes_repeat) { + current_note = 0; + } else { + playing_notes = false; + return; + } + } + play_note((*notes_pointer)[current_note][0], 15); + envelope_index = 0; + note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); + + // Skip forward in the next note's length if we've over shot the last, so + // the overall length of the song is the same + note_position = note_position - (note_length * DAC_SAMPLE_RATE / 35); } - } - play_note((*notes_pointer)[current_note][0], 15); - envelope_index = 0; - note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); - - // Skip forward in the next note's length if we've over shot the last, so - // the overall length of the song is the same - note_position = note_position - (note_length*DAC_SAMPLE_RATE/35); } - } } static void dac_error(DACDriver *dacp, dacerror_t err) { + (void)dacp; + (void)err; - (void)dacp; - (void)err; - - chSysHalt("DAC failure. halp"); + chSysHalt("DAC failure. halp"); } -static const GPTConfig gpt6cfg1 = { - .frequency = DAC_SAMPLE_RATE * 3, - .callback = NULL, - .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ - .dier = 0U -}; +static const GPTConfig gpt6cfg1 = {.frequency = DAC_SAMPLE_RATE * 3, + .callback = NULL, + .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ + .dier = 0U}; -static const DACConfig dac_conf = { - .init = DAC_SAMPLE_MAX, - .datamode = DAC_DHRM_12BIT_RIGHT -}; +static const DACConfig dac_conf = {.init = DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; /** * @note The DAC_TRG(0) here selects the Timer 6 TRGO event, which is triggered @@ -225,64 +151,37 @@ static const DACConfig dac_conf = { * EXTI9 0b110 * SWTRIG 0b111 */ -static const DACConversionGroup dac_conv_cfg = { - .num_channels = 1U, - .end_cb = dac_end, - .error_cb = dac_error, - .trigger = DAC_TRG(0b000) -}; - - - +static const DACConversionGroup dac_conv_cfg = {.num_channels = 1U, .end_cb = dac_end, .error_cb = dac_error, .trigger = DAC_TRG(0b000)}; void audio_initialize_hardware(void) { - #if defined(A4_AUDIO) - palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG ); - dacStart(&DACD1, &dac_conf); - dacStartConversion(&DACD1, &dac_conv_cfg, dac_buffer_empty, DAC_BUFFER_SIZE); + palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); + dacStart(&DACD1, &dac_conf); + dacStartConversion(&DACD1, &dac_conv_cfg, dac_buffer_empty, DAC_BUFFER_SIZE); #endif #if defined(A5_AUDIO) - palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG ); - dacStart(&DACD2, &dac_conf); - dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, DAC_BUFFER_SIZE); + palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); + dacStart(&DACD2, &dac_conf); + dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, DAC_BUFFER_SIZE); #endif - gptStart(&GPTD6, &gpt6cfg1); - gptStartContinuous(&GPTD6, 2U); - /* * Start the note timer */ gptStart(&GPTD8, &gpt8cfg1); gptStartContinuous(&GPTD8, 2U); - audio_initialized = true; - - stop_all_notes(); -} - - -void audio_stop_hardware(void) { -} -void audio_start_hardware(void) { + gptStart(&GPTD6, &gpt6cfg1); + gptStartContinuous(&GPTD6, 2U); } +void audio_stop_hardware(void) {} +void audio_start_hardware(void) {} +__attribute__((weak)) void dac_setup_note(void) { dac_if[voices] = 0.0f; } +uint8_t dac_number_of_voices(void) { return voices; } - -__attribute__ ((weak)) -void dac_setup_note(void) { - dac_if[voices] = 0.0f; -} - -uint8_t dac_number_of_voices(void) { - return voices; -} - -float dac_get_frequency(uint8_t index) { - return frequencies[index]; -} +float dac_get_frequency(uint8_t index) { return frequencies[index]; } diff --git a/quantum/audio/audio_chibios_dac.h b/quantum/audio/audio_chibios_dac.h index dea6c9068d2e..ac29b2e221fd 100644 --- a/quantum/audio/audio_chibios_dac.h +++ b/quantum/audio/audio_chibios_dac.h @@ -26,7 +26,7 @@ * Highest value allowed by our 12bit DAC. */ #ifndef DAC_SAMPLE_MAX - #define DAC_SAMPLE_MAX 4095U +# define DAC_SAMPLE_MAX 4095U #endif // #define DAC_LOW_QUALITY @@ -37,23 +37,23 @@ * relationship - slightly higher sample rates may be possible. */ #ifdef DAC_VERY_LOW_QUALITY - #define DAC_SAMPLE_RATE 11025U - #define DAC_VOICES_MAX 8 +# define DAC_SAMPLE_RATE 11025U +# define DAC_VOICES_MAX 8 #endif #ifdef DAC_LOW_QUALITY - #define DAC_SAMPLE_RATE 22050U - #define DAC_VOICES_MAX 4 +# define DAC_SAMPLE_RATE 22050U +# define DAC_VOICES_MAX 4 #endif #ifdef DAC_HIGH_QUALITY - #define DAC_SAMPLE_RATE 44100U - #define DAC_VOICES_MAX 2 +# define DAC_SAMPLE_RATE 44100U +# define DAC_VOICES_MAX 2 #endif #ifdef DAC_VERY_HIGH_QUALITY - #define DAC_SAMPLE_RATE 88200U - #define DAC_VOICES_MAX 1 +# define DAC_SAMPLE_RATE 88200U +# define DAC_VOICES_MAX 1 #endif /** @@ -63,7 +63,7 @@ * sample rate is where notes become unbearable. */ #ifndef DAC_SAMPLE_RATE - #define DAC_SAMPLE_RATE 44100U +# define DAC_SAMPLE_RATE 44100U #endif /** @@ -72,7 +72,7 @@ * are being played. */ #ifndef DAC_VOICES_MAX - #define DAC_VOICES_MAX 2 +# define DAC_VOICES_MAX 2 #endif /** @@ -80,18 +80,18 @@ * setups may require a high (DAC_SAMPLE_MAX) or low (0) value here. */ #ifndef DAC_OFF_VALUE - #define DAC_OFF_VALUE DAC_SAMPLE_MAX / 2 +# define DAC_OFF_VALUE DAC_SAMPLE_MAX / 2 #endif /** * choose pins for the speaker */ #ifndef A4_AUDIO - #define A4_AUDIO +# define A4_AUDIO //#define A5_AUDIO #endif -uint8_t dac_number_of_voices(void); -float dac_get_frequency(uint8_t index); +uint8_t dac_number_of_voices(void); +float dac_get_frequency(uint8_t index); uint16_t dac_value_generate(void); -void dac_setup_note(void); +void dac_setup_note(void); diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index 6ca685d4c57f..98f39600ee3b 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -14,7 +14,6 @@ * along with this program. If not, see . */ - /* STM32F103C Setup: halconf.h: #define HAL_USE_PWM TRUE @@ -31,30 +30,28 @@ used pin: PA8 (alternate0: Tim1_Ch1) #include "ch.h" #include "hal.h" - #include #include "print.h" - /* either use the direct hardware connection of Timer1-Channel1 to GPIOA.8 via the pins alternate-function to drive a piezo speaker OR set this define to zero and have the timer callbacks toggle your pin of choice */ #ifndef ARM_PWM_USE_PIN_ALTERNATE -#define ARM_PWM_USE_PIN_ALTERNATE 1 +# define ARM_PWM_USE_PIN_ALTERNATE 1 #endif #ifndef ARM_PWM_AUDIO_PORT -#define ARM_PWM_AUDIO_PORT GPIOC +# define ARM_PWM_AUDIO_PORT GPIOC #endif #ifndef ARM_PWM_AUDIO_PIN -#define ARM_PWM_AUDIO_PIN 13 +# define ARM_PWM_AUDIO_PIN 13 #endif // ----------------------------------------------------------------------------- #define AUDIO_PIN PAL_LINE(ARM_PWM_AUDIO_PORT, ARM_PWM_AUDIO_PIN) -extern int voices; +extern int voices; extern bool playing_notes; #if !(ARM_PWM_USE_PIN_ALTERNATE) @@ -62,35 +59,30 @@ static void pwm_audio_period_callback(PWMDriver *pwmp); static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp); #endif -static PWMConfig pwmCFG = { - 100000,/* PWM clock frequency */ - 10,/* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ - #if ARM_PWM_USE_PIN_ALTERNATE - NULL, - #else - pwm_audio_period_callback, - #endif - { - #if ARM_PWM_USE_PIN_ALTERNATE - {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* channel 0 -> TIM1-CH1 = PA8 */ - #else - /* on the STM32F104C8B: alternate function of pin */ - {PWM_OUTPUT_ACTIVE_HIGH, pwm_audio_channel_interrupt_callback}, /* channel 0 -> TIM1-CH1 = PA8 */ - #endif - {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIM1-CH2 = PA9 */ - {PWM_OUTPUT_DISABLED, NULL}, /* channel 2 -> TIM1-CH3 = PA10 */ - {PWM_OUTPUT_DISABLED, NULL} /* channel 3 -> TIM1-CH4 = PA11 */ - }, - 0, /* HW dependent part.*/ - 0 -}; - +static PWMConfig pwmCFG = {100000, /* PWM clock frequency */ + 10, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ +#if ARM_PWM_USE_PIN_ALTERNATE + NULL, +#else + pwm_audio_period_callback, +#endif + { +#if ARM_PWM_USE_PIN_ALTERNATE + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* channel 0 -> TIM1-CH1 = PA8 */ +#else + /* on the STM32F104C8B: alternate function of pin */ + {PWM_OUTPUT_ACTIVE_HIGH, pwm_audio_channel_interrupt_callback}, /* channel 0 -> TIM1-CH1 = PA8 */ +#endif + {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIM1-CH2 = PA9 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 2 -> TIM1-CH3 = PA10 */ + {PWM_OUTPUT_DISABLED, NULL} /* channel 3 -> TIM1-CH4 = PA11 */ + }, + 0, /* HW dependent part.*/ + 0}; static float channel_1_frequency = 0.0f; -void channel_1_set_frequency(float freq) { - - if (freq == channel_1_frequency) - return; +void channel_1_set_frequency(float freq) { + if (freq == channel_1_frequency) return; channel_1_frequency = freq; @@ -99,74 +91,63 @@ void channel_1_set_frequency(float freq) { pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 5000)); } -float channel_1_get_frequency(void) { - return channel_1_frequency; -} - +float channel_1_get_frequency(void) { return channel_1_frequency; } - -void channel_1_start(void){ +void channel_1_start(void) { pwmStop(&PWMD1); pwmStart(&PWMD1, &pwmCFG); pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 5000)); - #if !(ARM_PWM_USE_PIN_ALTERNATE) - pwmEnablePeriodicNotification(&PWMD1); // enable pwm callbacks +#if !(ARM_PWM_USE_PIN_ALTERNATE) + pwmEnablePeriodicNotification(&PWMD1); // enable pwm callbacks pwmEnableChannelNotification(&PWMD1, 0); - #endif +#endif } -void channel_1_stop(void){ - pwmStop(&PWMD1); -} +void channel_1_stop(void) { pwmStop(&PWMD1); } #if !(ARM_PWM_USE_PIN_ALTERNATE) static void pwm_audio_period_callback(PWMDriver *pwmp) { (void)pwmp; palClearLine(AUDIO_PIN); -/* hm, using the pwm callback, instead of the gpt timer does not work :-( - float freq, freq_alt; - pwm_audio_timer_task(&freq, &freq_alt); + /* hm, using the pwm callback, instead of the gpt timer does not work :-( + float freq, freq_alt; + pwm_audio_timer_task(&freq, &freq_alt); - if (playing_notes) - channel_1_set_frequency(freq); - else - channel_1_stop(); -*/ + if (playing_notes) + channel_1_set_frequency(freq); + else + channel_1_stop(); + */ } static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { (void)pwmp; - palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer + palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer } #endif static void gpt_cb8(GPTDriver *gptp); -GPTConfig gpt8cfg1 = { - .frequency = 10, - .callback = gpt_cb8, - .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ - .dier = 0U -}; +GPTConfig gpt8cfg1 = {.frequency = 10, + .callback = gpt_cb8, + .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ + .dier = 0U}; - - -void audio_initialize_hardware(void) -{ +void audio_initialize_hardware(void) { pwmStart(&PWMD1, &pwmCFG); pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 5000)); - #if ARM_PWM_USE_PIN_ALTERNATE +#if ARM_PWM_USE_PIN_ALTERNATE // on STM32F103C8B: PA8.alternate0 = output of TIM1-CH1 palSetPadMode(GPIOA, 8, PAL_MODE_STM32_ALTERNATE_PUSHPULL); - #else +#else palSetLineMode(AUDIO_PIN, PAL_MODE_OUTPUT_OPENDRAIN); palClearLine(AUDIO_PIN); - pwmEnablePeriodicNotification(&PWMD1); // enable pwm callbacks + pwmEnablePeriodicNotification(&PWMD1); // enable pwm callbacks pwmEnableChannelNotification(&PWMD1, 0); - #endif +#endif audio_start_hardware(); } From dc2b4086b51b6031f4ac3b69015163a738c42257 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sun, 23 Feb 2020 14:12:41 +0100 Subject: [PATCH 010/153] audio_arm_dac: stopping the notes caused screeching when using the DAC audio paths --- quantum/audio/audio.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index fc28f316e2fb..a47dc1f82e3d 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -173,9 +173,6 @@ void play_note(float freq, int vol) { } if (audio_config.enable && voices < 8) { - // Cancel notes if notes are playing - if (playing_notes) stop_all_notes(); - playing_note = true; envelope_index = 0; From ed423f2d61589e3b55414de8fc4b09c7f110cd41 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sun, 23 Feb 2020 14:14:17 +0100 Subject: [PATCH 011/153] audio_arm_pwm: use pushpull on the pin; so that a piezzo can be hooked up direclty without additional components (opendrain would require an external pullup) --- quantum/audio/audio_chibios_pwm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index 98f39600ee3b..b8775c498c83 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -142,7 +142,7 @@ void audio_initialize_hardware(void) { // on STM32F103C8B: PA8.alternate0 = output of TIM1-CH1 palSetPadMode(GPIOA, 8, PAL_MODE_STM32_ALTERNATE_PUSHPULL); #else - palSetLineMode(AUDIO_PIN, PAL_MODE_OUTPUT_OPENDRAIN); + palSetLineMode(AUDIO_PIN, PAL_MODE_OUTPUT_PUSHPULL); palClearLine(AUDIO_PIN); pwmEnablePeriodicNotification(&PWMD1); // enable pwm callbacks From a8b25fe3bfd0e4ccadabfc778d9d4df881262788 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sun, 1 Mar 2020 06:48:04 +0100 Subject: [PATCH 012/153] refactoring: remove unused file from/for atmel-avr chips --- quantum/audio/audio_pwm.c | 606 -------------------------------------- 1 file changed, 606 deletions(-) delete mode 100644 quantum/audio/audio_pwm.c diff --git a/quantum/audio/audio_pwm.c b/quantum/audio/audio_pwm.c deleted file mode 100644 index d93ac4bb4081..000000000000 --- a/quantum/audio/audio_pwm.c +++ /dev/null @@ -1,606 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 2 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 . - */ -#include -#include -//#include -#include -#include -#include -#include "print.h" -#include "audio.h" -#include "keymap.h" - -#include "eeconfig.h" - -#define PI 3.14159265 - -#define CPU_PRESCALER 8 - -#ifndef STARTUP_SONG -# define STARTUP_SONG SONG(STARTUP_SOUND) -#endif -float startup_song[][2] = STARTUP_SONG; - -// Timer Abstractions - -// TIMSK3 - Timer/Counter #3 Interrupt Mask Register -// Turn on/off 3A interputs, stopping/enabling the ISR calls -#define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A) -#define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A) - -// TCCR3A: Timer/Counter #3 Control Register -// Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 -#define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1); -#define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)); - -#define NOTE_PERIOD ICR3 -#define NOTE_DUTY_CYCLE OCR3A - -#ifdef PWM_AUDIO -# include "wave.h" -# define SAMPLE_DIVIDER 39 -# define SAMPLE_RATE (2000000.0 / SAMPLE_DIVIDER / 2048) -// Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap - -float places[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint16_t place_int = 0; -bool repeat = true; -#endif - -void delay_us(int count) { - while (count--) { - _delay_us(1); - } -} - -int voices = 0; -int voice_place = 0; -float frequency = 0; -int volume = 0; -long position = 0; - -float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -bool sliding = false; - -float place = 0; - -uint8_t* sample; -uint16_t sample_length = 0; -// float freq = 0; - -bool playing_notes = false; -bool playing_note = false; -float note_frequency = 0; -float note_length = 0; -uint8_t note_tempo = TEMPO_DEFAULT; -float note_timbre = TIMBRE_DEFAULT; -uint16_t note_position = 0; -float (*notes_pointer)[][2]; -uint16_t notes_count; -bool notes_repeat; -float notes_rest; -bool note_resting = false; - -uint16_t current_note = 0; -uint8_t rest_counter = 0; - -#ifdef VIBRATO_ENABLE -float vibrato_counter = 0; -float vibrato_strength = .5; -float vibrato_rate = 0.125; -#endif - -float polyphony_rate = 0; - -static bool audio_initialized = false; - -audio_config_t audio_config; - -uint16_t envelope_index = 0; - -void audio_init() { - // Check EEPROM - if (!eeconfig_is_enabled()) { - eeconfig_init(); - } - audio_config.raw = eeconfig_read_audio(); - -#ifdef PWM_AUDIO - - PLLFRQ = _BV(PDIV2); - PLLCSR = _BV(PLLE); - while (!(PLLCSR & _BV(PLOCK))) - ; - PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */ - - /* Init a fast PWM on Timer4 */ - TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */ - TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */ - OCR4A = 0; - - /* Enable the OC4A output */ - DDRC |= _BV(PORTC6); - - DISABLE_AUDIO_COUNTER_3_ISR; // Turn off 3A interputs - - TCCR3A = 0x0; // Options not needed - TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC - OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback - -#else - - // Set port PC6 (OC3A and /OC4A) as output - DDRC |= _BV(PORTC6); - - DISABLE_AUDIO_COUNTER_3_ISR; - - // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers - // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 - // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A) - // Clock Select (CS3n) = 0b010 = Clock / 8 - TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); - TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); - -#endif - - audio_initialized = true; -} - -void audio_startup() { - if (audio_config.enable) { - PLAY_SONG(startup_song); - } -} - -void stop_all_notes() { - if (!audio_initialized) { - audio_init(); - } - voices = 0; -#ifdef PWM_AUDIO - DISABLE_AUDIO_COUNTER_3_ISR; -#else - DISABLE_AUDIO_COUNTER_3_ISR; - DISABLE_AUDIO_COUNTER_3_OUTPUT; -#endif - - playing_notes = false; - playing_note = false; - frequency = 0; - volume = 0; - - for (uint8_t i = 0; i < 8; i++) { - frequencies[i] = 0; - volumes[i] = 0; - } -} - -void stop_note(float freq) { - if (playing_note) { - if (!audio_initialized) { - audio_init(); - } -#ifdef PWM_AUDIO - freq = freq / SAMPLE_RATE; -#endif - for (int i = 7; i >= 0; i--) { - if (frequencies[i] == freq) { - frequencies[i] = 0; - volumes[i] = 0; - for (int j = i; (j < 7); j++) { - frequencies[j] = frequencies[j + 1]; - frequencies[j + 1] = 0; - volumes[j] = volumes[j + 1]; - volumes[j + 1] = 0; - } - break; - } - } - voices--; - if (voices < 0) voices = 0; - if (voice_place >= voices) { - voice_place = 0; - } - if (voices == 0) { -#ifdef PWM_AUDIO - DISABLE_AUDIO_COUNTER_3_ISR; -#else - DISABLE_AUDIO_COUNTER_3_ISR; - DISABLE_AUDIO_COUNTER_3_OUTPUT; -#endif - frequency = 0; - volume = 0; - playing_note = false; - } - } -} - -#ifdef VIBRATO_ENABLE - -float mod(float a, int b) { - float r = fmod(a, b); - return r < 0 ? r + b : r; -} - -float vibrato(float average_freq) { -# ifdef VIBRATO_STRENGTH_ENABLE - float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); -# else - float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; -# endif - vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0 / average_freq)), VIBRATO_LUT_LENGTH); - return vibrated_freq; -} - -#endif - -ISR(TIMER3_COMPA_vect) { - if (playing_note) { -#ifdef PWM_AUDIO - if (voices == 1) { - // SINE - OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 2; - - // SQUARE - // if (((int)place) >= 1024){ - // OCR4A = 0xFF >> 2; - // } else { - // OCR4A = 0x00; - // } - - // SAWTOOTH - // OCR4A = (int)place / 4; - - // TRIANGLE - // if (((int)place) >= 1024) { - // OCR4A = (int)place / 2; - // } else { - // OCR4A = 2048 - (int)place / 2; - // } - - place += frequency; - - if (place >= SINE_LENGTH) place -= SINE_LENGTH; - - } else { - int sum = 0; - for (int i = 0; i < voices; i++) { - // SINE - sum += pgm_read_byte(&sinewave[(uint16_t)places[i]]) >> 2; - - // SQUARE - // if (((int)places[i]) >= 1024){ - // sum += 0xFF >> 2; - // } else { - // sum += 0x00; - // } - - places[i] += frequencies[i]; - - if (places[i] >= SINE_LENGTH) places[i] -= SINE_LENGTH; - } - OCR4A = sum; - } -#else - if (voices > 0) { - float freq; - if (polyphony_rate > 0) { - if (voices > 1) { - voice_place %= voices; - if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { - voice_place = (voice_place + 1) % voices; - place = 0.0; - } - } -# ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq = vibrato(frequencies[voice_place]); - } else { -# else - { -# endif - freq = frequencies[voice_place]; - } - } else { - if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440 / frequencies[voices - 1] / 12 / 2)) { - frequency = frequency * pow(2, 440 / frequency / 12 / 2); - } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440 / frequencies[voices - 1] / 12 / 2)) { - frequency = frequency * pow(2, -440 / frequency / 12 / 2); - } else { - frequency = frequencies[voices - 1]; - } - -# ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq = vibrato(frequency); - } else { -# else - { -# endif - freq = frequency; - } - } - - if (envelope_index < 65535) { - envelope_index++; - } - freq = voice_envelope(freq); - - if (freq < 30.517578125) freq = 30.52; - NOTE_PERIOD = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period - NOTE_DUTY_CYCLE = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period - } -#endif - } - - // SAMPLE - // OCR4A = pgm_read_byte(&sample[(uint16_t)place_int]); - - // place_int++; - - // if (place_int >= sample_length) - // if (repeat) - // place_int -= sample_length; - // else - // DISABLE_AUDIO_COUNTER_3_ISR; - - if (playing_notes) { -#ifdef PWM_AUDIO - OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0; - - place += note_frequency; - if (place >= SINE_LENGTH) place -= SINE_LENGTH; -#else - if (note_frequency > 0) { - float freq; - -# ifdef VIBRATO_ENABLE - if (vibrato_strength > 0) { - freq = vibrato(note_frequency); - } else { -# else - { -# endif - freq = note_frequency; - } - - if (envelope_index < 65535) { - envelope_index++; - } - freq = voice_envelope(freq); - - NOTE_PERIOD = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period - NOTE_DUTY_CYCLE = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period - } else { - NOTE_PERIOD = 0; - NOTE_DUTY_CYCLE = 0; - } -#endif - - note_position++; - bool end_of_note = false; - if (NOTE_PERIOD > 0) - end_of_note = (note_position >= (note_length / NOTE_PERIOD * 0xFFFF)); - else - end_of_note = (note_position >= (note_length * 0x7FF)); - if (end_of_note) { - current_note++; - if (current_note >= notes_count) { - if (notes_repeat) { - current_note = 0; - } else { -#ifdef PWM_AUDIO - DISABLE_AUDIO_COUNTER_3_ISR; -#else - DISABLE_AUDIO_COUNTER_3_ISR; - DISABLE_AUDIO_COUNTER_3_OUTPUT; -#endif - playing_notes = false; - return; - } - } - if (!note_resting && (notes_rest > 0)) { - note_resting = true; - note_frequency = 0; - note_length = notes_rest; - current_note--; - } else { - note_resting = false; -#ifdef PWM_AUDIO - note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; - note_length = (*notes_pointer)[current_note][1] * (((float)note_tempo) / 100); -#else - envelope_index = 0; - note_frequency = (*notes_pointer)[current_note][0]; - note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); -#endif - } - note_position = 0; - } - } - - if (!audio_config.enable) { - playing_notes = false; - playing_note = false; - } -} - -void play_note(float freq, int vol) { - if (!audio_initialized) { - audio_init(); - } - - if (audio_config.enable && voices < 8) { - DISABLE_AUDIO_COUNTER_3_ISR; - - // Cancel notes if notes are playing - if (playing_notes) stop_all_notes(); - - playing_note = true; - - envelope_index = 0; - -#ifdef PWM_AUDIO - freq = freq / SAMPLE_RATE; -#endif - if (freq > 0) { - frequencies[voices] = freq; - volumes[voices] = vol; - voices++; - } - -#ifdef PWM_AUDIO - ENABLE_AUDIO_COUNTER_3_ISR; -#else - ENABLE_AUDIO_COUNTER_3_ISR; - ENABLE_AUDIO_COUNTER_3_OUTPUT; -#endif - } -} - -void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) { - if (!audio_initialized) { - audio_init(); - } - - if (audio_config.enable) { - DISABLE_AUDIO_COUNTER_3_ISR; - - // Cancel note if a note is playing - if (playing_note) stop_all_notes(); - - playing_notes = true; - - notes_pointer = np; - notes_count = n_count; - notes_repeat = n_repeat; - notes_rest = n_rest; - - place = 0; - current_note = 0; - -#ifdef PWM_AUDIO - note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; - note_length = (*notes_pointer)[current_note][1] * (((float)note_tempo) / 100); -#else - note_frequency = (*notes_pointer)[current_note][0]; - note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); -#endif - note_position = 0; - -#ifdef PWM_AUDIO - ENABLE_AUDIO_COUNTER_3_ISR; -#else - ENABLE_AUDIO_COUNTER_3_ISR; - ENABLE_AUDIO_COUNTER_3_OUTPUT; -#endif - } -} - -#ifdef PWM_AUDIO -void play_sample(uint8_t* s, uint16_t l, bool r) { - if (!audio_initialized) { - audio_init(); - } - - if (audio_config.enable) { - DISABLE_AUDIO_COUNTER_3_ISR; - stop_all_notes(); - place_int = 0; - sample = s; - sample_length = l; - repeat = r; - - ENABLE_AUDIO_COUNTER_3_ISR; - } -} -#endif - -void audio_toggle(void) { - audio_config.enable ^= 1; - eeconfig_update_audio(audio_config.raw); -} - -void audio_on(void) { - audio_config.enable = 1; - eeconfig_update_audio(audio_config.raw); -} - -void audio_off(void) { - audio_config.enable = 0; - eeconfig_update_audio(audio_config.raw); -} - -#ifdef VIBRATO_ENABLE - -// Vibrato rate functions - -void set_vibrato_rate(float rate) { vibrato_rate = rate; } - -void increase_vibrato_rate(float change) { vibrato_rate *= change; } - -void decrease_vibrato_rate(float change) { vibrato_rate /= change; } - -# ifdef VIBRATO_STRENGTH_ENABLE - -void set_vibrato_strength(float strength) { vibrato_strength = strength; } - -void increase_vibrato_strength(float change) { vibrato_strength *= change; } - -void decrease_vibrato_strength(float change) { vibrato_strength /= change; } - -# endif /* VIBRATO_STRENGTH_ENABLE */ - -#endif /* VIBRATO_ENABLE */ - -// Polyphony functions - -void set_polyphony_rate(float rate) { polyphony_rate = rate; } - -void enable_polyphony() { polyphony_rate = 5; } - -void disable_polyphony() { polyphony_rate = 0; } - -void increase_polyphony_rate(float change) { polyphony_rate *= change; } - -void decrease_polyphony_rate(float change) { polyphony_rate /= change; } - -// Timbre function - -void set_timbre(float timbre) { note_timbre = timbre; } - -// Tempo functions - -void set_tempo(uint8_t tempo) { note_tempo = tempo; } - -void decrease_tempo(uint8_t tempo_change) { note_tempo += tempo_change; } - -void increase_tempo(uint8_t tempo_change) { - if (note_tempo - tempo_change < 10) { - note_tempo = 10; - } else { - note_tempo -= tempo_change; - } -} - -//------------------------------------------------------------------------------ -// Override these functions in your keymap file to play different tunes on -// startup and bootloader jump -__attribute__((weak)) void play_startup_tone() {} - -__attribute__((weak)) void play_goodbye_tone() {} -//------------------------------------------------------------------------------ From 2ed2cc6b2012e932958d3ab7afa26305d0338da5 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 19 Mar 2020 17:41:16 +0100 Subject: [PATCH 013/153] refactoring: remove unused (avr) wavetable file --- quantum/audio/wave.h | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 quantum/audio/wave.h diff --git a/quantum/audio/wave.h b/quantum/audio/wave.h deleted file mode 100644 index 48210a944e81..000000000000 --- a/quantum/audio/wave.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 2 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 . - */ - -#include -#include -#include - -#define SINE_LENGTH 2048 - -const uint8_t sinewave[] PROGMEM = // 2048 values - {0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x83, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x87, 0x88, 0x88, 0x88, 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8b, 0x8b, 0x8c, 0x8c, 0x8c, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x91, 0x91, 0x91, 0x92, 0x92, 0x93, 0x93, 0x93, 0x94, 0x94, 0x95, 0x95, 0x95, 0x96, 0x96, 0x96, 0x97, 0x97, 0x98, 0x98, 0x98, 0x99, 0x99, 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0x9f, 0x9f, 0xa0, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa6, 0xa6, 0xa7, 0xa7, 0xa7, 0xa8, 0xa8, 0xa9, 0xa9, 0xa9, 0xaa, 0xaa, 0xaa, 0xab, 0xab, 0xac, 0xac, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xae, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xbb, - 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xc0, 0xc0, 0xc0, 0xc1, 0xc1, 0xc1, 0xc2, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc4, 0xc4, 0xc5, 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc8, 0xc8, 0xc8, 0xc9, 0xc9, 0xc9, 0xca, 0xca, 0xca, 0xcb, 0xcb, 0xcb, 0xcb, 0xcc, 0xcc, 0xcc, 0xcd, 0xcd, 0xcd, 0xce, 0xce, 0xce, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd0, 0xd0, 0xd1, 0xd1, 0xd1, 0xd2, 0xd2, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, 0xd5, 0xd5, 0xd5, 0xd5, 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe5, 0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0xe6, 0xe7, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, - 0xe9, 0xe9, 0xe9, 0xe9, 0xea, 0xea, 0xea, 0xea, 0xea, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xec, 0xec, 0xec, 0xec, 0xec, 0xed, 0xed, 0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0xee, 0xee, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, - 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, - 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf6, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xef, 0xef, 0xef, 0xef, 0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xed, 0xed, 0xed, 0xed, 0xed, 0xec, 0xec, 0xec, 0xec, 0xec, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xea, 0xea, 0xea, 0xea, 0xea, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8, 0xe7, 0xe7, 0xe7, 0xe7, 0xe6, 0xe6, 0xe6, 0xe6, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xdf, 0xde, 0xde, 0xde, 0xde, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb, 0xdb, 0xdb, 0xda, 0xda, 0xda, 0xda, 0xd9, 0xd9, 0xd9, 0xd9, 0xd8, 0xd8, 0xd8, 0xd7, 0xd7, 0xd7, 0xd7, 0xd6, 0xd6, 0xd6, 0xd5, 0xd5, 0xd5, 0xd5, 0xd4, 0xd4, 0xd4, - 0xd3, 0xd3, 0xd3, 0xd2, 0xd2, 0xd2, 0xd2, 0xd1, 0xd1, 0xd1, 0xd0, 0xd0, 0xd0, 0xcf, 0xcf, 0xcf, 0xcf, 0xce, 0xce, 0xce, 0xcd, 0xcd, 0xcd, 0xcc, 0xcc, 0xcc, 0xcb, 0xcb, 0xcb, 0xcb, 0xca, 0xca, 0xca, 0xc9, 0xc9, 0xc9, 0xc8, 0xc8, 0xc8, 0xc7, 0xc7, 0xc7, 0xc6, 0xc6, 0xc6, 0xc5, 0xc5, 0xc5, 0xc4, 0xc4, 0xc4, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xb9, 0xb9, 0xb8, 0xb8, 0xb8, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb5, 0xb5, 0xb5, 0xb4, 0xb4, 0xb4, 0xb3, 0xb3, 0xb2, 0xb2, 0xb2, 0xb1, 0xb1, 0xb1, 0xb0, 0xb0, 0xb0, 0xaf, 0xaf, 0xae, 0xae, 0xae, 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9d, - 0x9d, 0x9d, 0x9c, 0x9c, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x99, 0x99, 0x98, 0x98, 0x98, 0x97, 0x97, 0x96, 0x96, 0x96, 0x95, 0x95, 0x95, 0x94, 0x94, 0x93, 0x93, 0x93, 0x92, 0x92, 0x91, 0x91, 0x91, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x89, 0x89, 0x88, 0x88, 0x88, 0x87, 0x87, 0x87, 0x86, 0x86, 0x85, 0x85, 0x85, 0x84, 0x84, 0x83, 0x83, 0x83, 0x82, 0x82, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7b, 0x7b, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x78, 0x78, 0x78, 0x77, 0x77, 0x77, 0x76, 0x76, 0x75, 0x75, 0x75, 0x74, 0x74, 0x73, 0x73, 0x73, 0x72, 0x72, 0x71, 0x71, 0x71, 0x70, 0x70, 0x70, 0x6f, 0x6f, 0x6e, 0x6e, 0x6e, 0x6d, 0x6d, 0x6c, 0x6c, 0x6c, 0x6b, 0x6b, 0x6a, 0x6a, 0x6a, 0x69, 0x69, 0x69, 0x68, 0x68, 0x67, 0x67, 0x67, 0x66, 0x66, 0x65, 0x65, 0x65, 0x64, 0x64, 0x64, 0x63, 0x63, 0x62, 0x62, 0x62, 0x61, 0x61, 0x61, 0x60, - 0x60, 0x5f, 0x5f, 0x5f, 0x5e, 0x5e, 0x5d, 0x5d, 0x5d, 0x5c, 0x5c, 0x5c, 0x5b, 0x5b, 0x5a, 0x5a, 0x5a, 0x59, 0x59, 0x59, 0x58, 0x58, 0x58, 0x57, 0x57, 0x56, 0x56, 0x56, 0x55, 0x55, 0x55, 0x54, 0x54, 0x53, 0x53, 0x53, 0x52, 0x52, 0x52, 0x51, 0x51, 0x51, 0x50, 0x50, 0x4f, 0x4f, 0x4f, 0x4e, 0x4e, 0x4e, 0x4d, 0x4d, 0x4d, 0x4c, 0x4c, 0x4b, 0x4b, 0x4b, 0x4a, 0x4a, 0x4a, 0x49, 0x49, 0x49, 0x48, 0x48, 0x48, 0x47, 0x47, 0x47, 0x46, 0x46, 0x45, 0x45, 0x45, 0x44, 0x44, 0x44, 0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x41, 0x41, 0x41, 0x40, 0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3e, 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39, 0x39, 0x39, 0x38, 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x31, 0x31, 0x31, 0x30, 0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2e, 0x2e, 0x2e, 0x2d, 0x2d, 0x2d, 0x2d, 0x2c, 0x2c, 0x2c, 0x2b, 0x2b, 0x2b, 0x2a, 0x2a, - 0x2a, 0x2a, 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x27, 0x27, 0x27, 0x26, 0x26, 0x26, 0x26, 0x25, 0x25, 0x25, 0x25, 0x24, 0x24, 0x24, 0x23, 0x23, 0x23, 0x23, 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x1f, 0x1f, 0x1f, 0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1d, 0x1d, 0x1d, 0x1d, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1a, 0x1a, 0x1a, 0x1a, 0x19, 0x19, 0x19, 0x19, 0x18, 0x18, 0x18, 0x18, 0x17, 0x17, 0x17, 0x17, 0x17, 0x16, 0x16, 0x16, 0x16, 0x15, 0x15, 0x15, 0x15, 0x15, 0x14, 0x14, 0x14, 0x14, 0x14, 0x13, 0x13, 0x13, 0x13, 0x13, 0x12, 0x12, 0x12, 0x12, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xe, 0xe, 0xe, 0xe, 0xe, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x8, 0x8, 0x8, 0x8, 0x8, - 0x8, 0x8, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xe, 0xe, 0xe, 0xe, 0xe, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, 0x17, - 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x1a, 0x1a, 0x1a, 0x1a, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x32, 0x32, 0x32, 0x33, 0x33, 0x33, 0x34, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x36, 0x36, 0x36, 0x37, 0x37, 0x37, 0x38, 0x38, 0x38, 0x39, 0x39, 0x39, 0x3a, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3c, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3e, 0x3e, 0x3e, 0x3f, 0x3f, 0x3f, 0x40, 0x40, 0x40, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x43, 0x43, 0x43, 0x44, 0x44, 0x44, 0x45, 0x45, 0x45, 0x46, - 0x46, 0x47, 0x47, 0x47, 0x48, 0x48, 0x48, 0x49, 0x49, 0x49, 0x4a, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d, 0x4e, 0x4e, 0x4e, 0x4f, 0x4f, 0x4f, 0x50, 0x50, 0x51, 0x51, 0x51, 0x52, 0x52, 0x52, 0x53, 0x53, 0x53, 0x54, 0x54, 0x55, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0x57, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5c, 0x5c, 0x5c, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f, 0x5f, 0x60, 0x60, 0x61, 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, 0x63, 0x64, 0x64, 0x64, 0x65, 0x65, 0x65, 0x66, 0x66, 0x67, 0x67, 0x67, 0x68, 0x68, 0x69, 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x71, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x74, 0x75, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x79, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f}; From e6a5010f9ae38149affc1f94f7546f612138c077 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sun, 1 Mar 2020 17:10:35 +0100 Subject: [PATCH 014/153] audio_arm_dac: adapt dac_end callback to changed chibios DAC api the previous chibios (17.6.0) passed along a pointer into the buffer plus a sample_count (which are/already where included in the DACDrivre object) - the current chibios (19.1.0) only passes the driver object. this patch ports more or less exactly what the previous chibios ISR code did: either have the user-callback work the first or second half of the buffer (dacsample_t pointer, with half the DAC_BUFFER_SIZE samples) by adjusting the pointer and sample count --- quantum/audio/audio_chibios_dac.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index 93105afcad96..17f8fab56a4b 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -89,16 +89,23 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { /** * DAC streaming callback. Does all of the main computing for playing songs. + * + * Note: chibios calls this CB twice: during the 'half buffer event', and the 'full buffer event'. */ -static void dac_end(DACDriver *dacp, dacsample_t *sample_p, size_t sample_count) { - (void)dacp; +static void dac_end(DACDriver *dacp){ + dacsample_t *sample_p = (dacp)->samples; + + // work on the other half of the buffer + if (dacIsBufferComplete(dacp)) { + sample_p += DAC_BUFFER_SIZE/2; // 'half_index' + } - for (uint8_t s = 0; s < sample_count; s++) { + for (uint8_t s = 0; s < DAC_BUFFER_SIZE/2; s++) { sample_p[s] = dac_value_generate(); } if (playing_notes) { - note_position += sample_count; + note_position += DAC_BUFFER_SIZE/2; // End of the note - 35 is arbitary here, but gets us close to AVR's timing if ((note_position >= (note_length * DAC_SAMPLE_RATE / 35))) { From 57ee6a241bd146ec9470c3294ae1d489d841c9b8 Mon Sep 17 00:00:00 2001 From: JohSchneider Date: Thu, 5 Mar 2020 18:36:22 +0000 Subject: [PATCH 015/153] audio-arm-dac: show a compile-warning on undefined audio-pins Co-Authored-By: Drashna Jaelre --- quantum/audio/audio_chibios_dac.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/quantum/audio/audio_chibios_dac.h b/quantum/audio/audio_chibios_dac.h index ac29b2e221fd..ea2976bc8d99 100644 --- a/quantum/audio/audio_chibios_dac.h +++ b/quantum/audio/audio_chibios_dac.h @@ -86,9 +86,10 @@ /** * choose pins for the speaker */ -#ifndef A4_AUDIO -# define A4_AUDIO -//#define A5_AUDIO +#if !defined(A4_AUDIO) && !defined(A5_AUDIO) +# pragma message "Audio feature enabled, but not pin selected - see docs/feature_audio under the ARM DAC settings. Falling back to A5_AUDIO" +# define A5_AUDIO +//TODO: go through a breaking change, and add A5_AUDIO to all keyboards currently using AUDIO on STM32 based boards #endif uint8_t dac_number_of_voices(void); From 47f697e0685878e6e5d47c33e3f7b04698b7db7d Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 11 Mar 2020 15:34:09 +0100 Subject: [PATCH 016/153] audio_arm_dac: switch from exemplary wavetable generation to sine only sine+triangle+squrare is exemplary, and not realy fit for "production" use 'stairs' are usefull for debugging (hardware, with an oscilloscope) --- quantum/audio/audio_chibios_dac.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index 17f8fab56a4b..542c264bf55c 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -41,6 +41,7 @@ static const dacsample_t dac_buffer_sine[DAC_BUFFER_SIZE] = { 0x800, 0x832, 0x864, 0x896, 0x8c8, 0x8fa, 0x92c, 0x95e, 0x98f, 0x9c0, 0x9f1, 0xa22, 0xa52, 0xa82, 0xab1, 0xae0, 0xb0f, 0xb3d, 0xb6b, 0xb98, 0xbc5, 0xbf1, 0xc1c, 0xc47, 0xc71, 0xc9a, 0xcc3, 0xceb, 0xd12, 0xd39, 0xd5f, 0xd83, 0xda7, 0xdca, 0xded, 0xe0e, 0xe2e, 0xe4e, 0xe6c, 0xe8a, 0xea6, 0xec1, 0xedc, 0xef5, 0xf0d, 0xf24, 0xf3a, 0xf4f, 0xf63, 0xf76, 0xf87, 0xf98, 0xfa7, 0xfb5, 0xfc2, 0xfcd, 0xfd8, 0xfe1, 0xfe9, 0xff0, 0xff5, 0xff9, 0xffd, 0xffe, 0xfff, 0xffe, 0xffd, 0xff9, 0xff5, 0xff0, 0xfe9, 0xfe1, 0xfd8, 0xfcd, 0xfc2, 0xfb5, 0xfa7, 0xf98, 0xf87, 0xf76, 0xf63, 0xf4f, 0xf3a, 0xf24, 0xf0d, 0xef5, 0xedc, 0xec1, 0xea6, 0xe8a, 0xe6c, 0xe4e, 0xe2e, 0xe0e, 0xded, 0xdca, 0xda7, 0xd83, 0xd5f, 0xd39, 0xd12, 0xceb, 0xcc3, 0xc9a, 0xc71, 0xc47, 0xc1c, 0xbf1, 0xbc5, 0xb98, 0xb6b, 0xb3d, 0xb0f, 0xae0, 0xab1, 0xa82, 0xa52, 0xa22, 0x9f1, 0x9c0, 0x98f, 0x95e, 0x92c, 0x8fa, 0x8c8, 0x896, 0x864, 0x832, 0x800, 0x7cd, 0x79b, 0x769, 0x737, 0x705, 0x6d3, 0x6a1, 0x670, 0x63f, 0x60e, 0x5dd, 0x5ad, 0x57d, 0x54e, 0x51f, 0x4f0, 0x4c2, 0x494, 0x467, 0x43a, 0x40e, 0x3e3, 0x3b8, 0x38e, 0x365, 0x33c, 0x314, 0x2ed, 0x2c6, 0x2a0, 0x27c, 0x258, 0x235, 0x212, 0x1f1, 0x1d1, 0x1b1, 0x193, 0x175, 0x159, 0x13e, 0x123, 0x10a, 0xf2, 0xdb, 0xc5, 0xb0, 0x9c, 0x89, 0x78, 0x67, 0x58, 0x4a, 0x3d, 0x32, 0x27, 0x1e, 0x16, 0xf, 0xa, 0x6, 0x2, 0x1, 0x0, 0x1, 0x2, 0x6, 0xa, 0xf, 0x16, 0x1e, 0x27, 0x32, 0x3d, 0x4a, 0x58, 0x67, 0x78, 0x89, 0x9c, 0xb0, 0xc5, 0xdb, 0xf2, 0x10a, 0x123, 0x13e, 0x159, 0x175, 0x193, 0x1b1, 0x1d1, 0x1f1, 0x212, 0x235, 0x258, 0x27c, 0x2a0, 0x2c6, 0x2ed, 0x314, 0x33c, 0x365, 0x38e, 0x3b8, 0x3e3, 0x40e, 0x43a, 0x467, 0x494, 0x4c2, 0x4f0, 0x51f, 0x54e, 0x57d, 0x5ad, 0x5dd, 0x60e, 0x63f, 0x670, 0x6a1, 0x6d3, 0x705, 0x737, 0x769, 0x79b, 0x7cd}; +/* static const dacsample_t dac_buffer_triangle[DAC_BUFFER_SIZE] = { // 256 values, max 4095 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x100, 0x120, 0x140, 0x160, 0x180, 0x1a0, 0x1c0, 0x1e0, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0x400, 0x420, 0x440, 0x460, 0x480, 0x4a0, 0x4c0, 0x4e0, 0x500, 0x520, 0x540, 0x560, 0x580, 0x5a0, 0x5c0, 0x5e0, 0x600, 0x620, 0x640, 0x660, 0x680, 0x6a0, 0x6c0, 0x6e0, 0x700, 0x720, 0x740, 0x760, 0x780, 0x7a0, 0x7c0, 0x7e0, 0x800, 0x81f, 0x83f, 0x85f, 0x87f, 0x89f, 0x8bf, 0x8df, 0x8ff, 0x91f, 0x93f, 0x95f, 0x97f, 0x99f, 0x9bf, 0x9df, 0x9ff, 0xa1f, 0xa3f, 0xa5f, 0xa7f, 0xa9f, 0xabf, 0xadf, 0xaff, 0xb1f, 0xb3f, 0xb5f, 0xb7f, 0xb9f, 0xbbf, 0xbdf, 0xbff, 0xc1f, 0xc3f, 0xc5f, 0xc7f, 0xc9f, 0xcbf, 0xcdf, 0xcff, 0xd1f, 0xd3f, 0xd5f, 0xd7f, 0xd9f, 0xdbf, 0xddf, 0xdff, 0xe1f, 0xe3f, 0xe5f, 0xe7f, 0xe9f, 0xebf, 0xedf, 0xeff, 0xf1f, 0xf3f, 0xf5f, 0xf7f, 0xf9f, 0xfbf, 0xfdf, 0xfff, @@ -52,6 +53,15 @@ static const dacsample_t dac_buffer_square[DAC_BUFFER_SIZE] = { [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = 0, }; +// four steps: 0, 1/3, 2/3 and 1 +static const dacsample_t dac_buffer_staircase[DAC_BUFFER_SIZE] = { + [0 ... DAC_BUFFER_SIZE/3 -1 ] = 0, + [DAC_BUFFER_SIZE / 4 ... DAC_BUFFER_SIZE / 2 -1 ] = DAC_SAMPLE_MAX / 3, + [DAC_BUFFER_SIZE / 2 ... 3 * DAC_BUFFER_SIZE / 4 -1 ] = 2 * DAC_SAMPLE_MAX / 3, + [3 * DAC_BUFFER_SIZE / 4 ... DAC_BUFFER_SIZE -1 ] = DAC_SAMPLE_MAX, +} +*/ + static dacsample_t dac_buffer_empty[DAC_BUFFER_SIZE] = {DAC_OFF_VALUE}; static float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; @@ -76,11 +86,15 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { // Wavetable generation/lookup uint16_t dac_i = (uint16_t)dac_if[i]; // SINE - value_avg += dac_buffer_sine[dac_i] / working_voices / 3; + value_avg += dac_buffer_sine[dac_i] / working_voices;// / 3; // TRIANGLE - value_avg += dac_buffer_triangle[dac_i] / working_voices / 3; +// value_avg += dac_buffer_triangle[dac_i] / working_voices / 3; // SQUARE - value_avg += dac_buffer_square[dac_i] / working_voices / 3; +// value_avg += dac_buffer_square[dac_i] / working_voices / 3; + //NOTE: combination of these three waveforms is more exemplary - and doesn't sound particularly good :-P + + // STAIRS + //value_avg = dac_buffer_staircase[dac_i] / working_voices; } value = value_avg; } From 000cde6cb58ef341f655f60db174fdf53a124f3c Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 12 Mar 2020 12:56:54 +0100 Subject: [PATCH 017/153] audio_arm_dac: enable output buffers in the STM32 to drive external loads without any additional ciruitry - external opamps and such --- quantum/audio/audio_chibios_dac.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index 542c264bf55c..479e74af362e 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -186,15 +186,30 @@ void audio_initialize_hardware(void) { dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, DAC_BUFFER_SIZE); #endif + /* enable the output buffer, to directly drive external loads with no additional circuitry + * + * see: AN4566 Application note: Extending the DAC performance of STM32 microcontrollers + * Note: Buffer-Off bit -> has to be set 0 to enable the output buffer + * Note: enabling the output buffer imparts an additional dc-offset of a couple mV + * + * this is done here, reaching directly into the stm32 registers since chibios has not implemented BOFF handling yet + * (see: chibios/os/hal/ports/STM32/todo.txt '- BOFF handling in DACv1.' + */ +#if defined(A4_AUDIO) + DACD1.params->dac->CR &= ~DAC_CR_BOFF1; +#endif +#if defined(A5_AUDIO) + DACD2.params->dac->CR &= ~DAC_CR_BOFF2; +#endif + + gptStart(&GPTD6, &gpt6cfg1); + gptStartContinuous(&GPTD6, 2U); + /* * Start the note timer */ gptStart(&GPTD8, &gpt8cfg1); gptStartContinuous(&GPTD8, 2U); - - - gptStart(&GPTD6, &gpt6cfg1); - gptStartContinuous(&GPTD6, 2U); } void audio_stop_hardware(void) {} From c4a53738a5aea07c151891636e851be5eb368180 Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 16 Mar 2020 17:54:57 +0100 Subject: [PATCH 018/153] audio: prevent out-of-bounds array access --- quantum/audio/audio.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index a47dc1f82e3d..1f809fc51f0f 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -43,6 +43,7 @@ bool notes_repeat; bool note_resting = false; uint16_t current_note = 0; +uint16_t next_note = 0; uint8_t rest_counter = 0; #ifdef VIBRATO_ENABLE @@ -372,14 +373,20 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { } if (!note_resting) { note_resting = true; - current_note--; - if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) { + if (current_note == 0) { + current_note = notes_count-1; + next_note = 0; + } else { + next_note = current_note; + current_note--; + } + + if ((*notes_pointer)[current_note][0] == (*notes_pointer)[next_note][0]) { note_frequency = 0; - note_length = 1; } else { note_frequency = (*notes_pointer)[current_note][0]; - note_length = 1; } + note_length = 1; } else { note_resting = false; envelope_index = 0; From 966757fe4e9bfdb870b36cc3393539784583f294 Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 16 Mar 2020 18:00:10 +0100 Subject: [PATCH 019/153] audio_arm_dac: add output-frequency correcting factor --- quantum/audio/audio_chibios_dac.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index 479e74af362e..ef85a1149585 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -78,7 +78,9 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { if (working_voices > 0) { uint16_t value_avg = 0; for (uint8_t i = 0; i < working_voices; i++) { - dac_if[i] = dac_if[i] + ((frequencies[i] * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE); + dac_if[i] = dac_if[i] + ((frequencies[i] * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE) + * 2/3; //TODO: why is this scaling factor necessary to get accurate frequencies on the DAC output? (as measured with an oscilloscope) + // possibly: the gpt timer runs with 3*DAC_SAMPLE_RATE; and the DAC callback is called twice per conversion? // Needed because % doesn't work with floats while (dac_if[i] >= (DAC_BUFFER_SIZE)) dac_if[i] = dac_if[i] - DAC_BUFFER_SIZE; From 4e00b5162263c6580b767bf8ef0a5d7c20cb4a16 Mon Sep 17 00:00:00 2001 From: Johannes Date: Tue, 17 Mar 2020 15:25:47 +0100 Subject: [PATCH 020/153] audio_arm_pwm: get both the alternate-function and pm-callback variants back into working condition and do some code-cleanup, refine documentation, ... --- quantum/audio/audio.c | 1 - quantum/audio/audio_chibios_pwm.c | 108 +++++++++++++++++------------- 2 files changed, 60 insertions(+), 49 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 1f809fc51f0f..dc9893a599fe 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -209,7 +209,6 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) { note_position = 0; audio_start_hardware(); - // play_note((*notes_pointer)[current_note][0], 15); } } diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index b8775c498c83..88b752fc03ab 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -1,4 +1,4 @@ -/* Copyright 2019 Jack Humbert +/* Copyright 2020 Jack Humbert * * 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 @@ -20,12 +20,26 @@ halconf.h: #define HAL_USE_PAL TRUE #define HAL_USE_GPT TRUE - mcuconf.h: +mcuconf.h: #define STM32_PWM_USE_TIM1 TRUE #define STM32_GPT_USE_TIM3 TRUE used pin: PA8 (alternate0: Tim1_Ch1) + +from the datasheet for STM32F104C8B: alternate function of pin +TIM1_CH1 = PA8 +TIM1_CH2 = PA9 +TIM1_CH3 = PA10 +TIM1_CH4 = PA11 + + +to use another hardware-pwm pin: +- check the datasheet for the timer_channel and the alternate-function +- replace PWMDx with the required timer +- reorder the PCMConfig.channels to match the TIMx_CHy (the stm datasheets usually have CH1 to CH4) +- set the pin to the appropiate alternate function (beware: differences in chibios GPIOv1, v2, ...) */ + #include "audio.h" #include "ch.h" #include "hal.h" @@ -38,19 +52,14 @@ used pin: PA8 (alternate0: Tim1_Ch1) OR set this define to zero and have the timer callbacks toggle your pin of choice */ #ifndef ARM_PWM_USE_PIN_ALTERNATE -# define ARM_PWM_USE_PIN_ALTERNATE 1 +# define ARM_PWM_USE_PIN_ALTERNATE 0 #endif -#ifndef ARM_PWM_AUDIO_PORT -# define ARM_PWM_AUDIO_PORT GPIOC -#endif #ifndef ARM_PWM_AUDIO_PIN -# define ARM_PWM_AUDIO_PIN 13 +# define ARM_PWM_AUDIO_PIN A10 #endif // ----------------------------------------------------------------------------- -#define AUDIO_PIN PAL_LINE(ARM_PWM_AUDIO_PORT, ARM_PWM_AUDIO_PIN) - extern int voices; extern bool playing_notes; @@ -59,29 +68,27 @@ static void pwm_audio_period_callback(PWMDriver *pwmp); static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp); #endif -static PWMConfig pwmCFG = {100000, /* PWM clock frequency */ - 10, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ +static PWMConfig pwmCFG = {.frequency = 100000, /* PWM clock frequency */ + .period = 0, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ #if ARM_PWM_USE_PIN_ALTERNATE - NULL, + .callback = NULL, // no callback, the hardware directly toggles the pin #else - pwm_audio_period_callback, + .callback = pwm_audio_period_callback, #endif - { + .channels = { #if ARM_PWM_USE_PIN_ALTERNATE - {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* channel 0 -> TIM1-CH1 = PA8 */ + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* channel 0 -> TIM1_CH1 */ #else - /* on the STM32F104C8B: alternate function of pin */ - {PWM_OUTPUT_ACTIVE_HIGH, pwm_audio_channel_interrupt_callback}, /* channel 0 -> TIM1-CH1 = PA8 */ + {PWM_OUTPUT_ACTIVE_HIGH, pwm_audio_channel_interrupt_callback}, /* channel 0 -> TIM1_CH1 */ #endif - {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIM1-CH2 = PA9 */ - {PWM_OUTPUT_DISABLED, NULL}, /* channel 2 -> TIM1-CH3 = PA10 */ - {PWM_OUTPUT_DISABLED, NULL} /* channel 3 -> TIM1-CH4 = PA11 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIM1_CH2 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 2 -> TIM1_CH3 */ + {PWM_OUTPUT_DISABLED, NULL} /* channel 3 -> TIM1_CH4 */ }, - 0, /* HW dependent part.*/ - 0}; + }; static float channel_1_frequency = 0.0f; -void channel_1_set_frequency(float freq) { +void channel_1_set_frequency(float freq) { if (freq == channel_1_frequency) return; channel_1_frequency = freq; @@ -96,20 +103,25 @@ float channel_1_get_frequency(void) { return channel_1_frequency; } void channel_1_start(void) { pwmStop(&PWMD1); pwmStart(&PWMD1, &pwmCFG); - pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 5000)); #if !(ARM_PWM_USE_PIN_ALTERNATE) - pwmEnablePeriodicNotification(&PWMD1); // enable pwm callbacks + pwmEnablePeriodicNotification(&PWMD1); pwmEnableChannelNotification(&PWMD1, 0); #endif } -void channel_1_stop(void) { pwmStop(&PWMD1); } +void channel_1_stop(void) { + pwmStop(&PWMD1); + +#if !(ARM_PWM_USE_PIN_ALTERNATE) + palClearLine(ARM_PWM_AUDIO_PIN); // leave the line low, after last note was played +#endif +} #if !(ARM_PWM_USE_PIN_ALTERNATE) static void pwm_audio_period_callback(PWMDriver *pwmp) { (void)pwmp; - palClearLine(AUDIO_PIN); + palClearLine(ARM_PWM_AUDIO_PIN); /* hm, using the pwm callback, instead of the gpt timer does not work :-( float freq, freq_alt; @@ -119,55 +131,55 @@ static void pwm_audio_period_callback(PWMDriver *pwmp) { channel_1_set_frequency(freq); else channel_1_stop(); - */ + //*/ } static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { (void)pwmp; - palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer + palSetLine(ARM_PWM_AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer } #endif -static void gpt_cb8(GPTDriver *gptp); -GPTConfig gpt8cfg1 = {.frequency = 10, - .callback = gpt_cb8, - .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ - .dier = 0U}; +static void gpt_callback(GPTDriver *gptp); +GPTConfig gptCFG = {.frequency = 10, + .callback = gpt_callback, +}; void audio_initialize_hardware(void) { pwmStart(&PWMD1, &pwmCFG); - pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 5000)); - #if ARM_PWM_USE_PIN_ALTERNATE - // on STM32F103C8B: PA8.alternate0 = output of TIM1-CH1 - palSetPadMode(GPIOA, 8, PAL_MODE_STM32_ALTERNATE_PUSHPULL); +# ifdef PAL_MODE_STM32_ALTERNATE_PUSHPULL + //TODO: is there a better way to differentiate between chibios GPIOv1 and GPIOv2? + palSetLineMode(A8, PAL_MODE_STM32_ALTERNATE_PUSHPULL); //f103 with GPIOv1 +# else + palSetLineMode(A8, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(6) );//f303xx with GPIOV2 +# endif #else - palSetLineMode(AUDIO_PIN, PAL_MODE_OUTPUT_PUSHPULL); - palClearLine(AUDIO_PIN); + palSetLineMode(ARM_PWM_AUDIO_PIN, PAL_MODE_OUTPUT_PUSHPULL); + palClearLine(ARM_PWM_AUDIO_PIN); - pwmEnablePeriodicNotification(&PWMD1); // enable pwm callbacks + pwmEnablePeriodicNotification(&PWMD1); // enable pwm callbacks pwmEnableChannelNotification(&PWMD1, 0); #endif - audio_start_hardware(); + gptStart(&GPTD6, &gptCFG); } void audio_start_hardware(void) { channel_1_stop(); channel_1_start(); - - gptStart(&GPTD3, &gpt8cfg1); - gptStartContinuous(&GPTD3, 2U); + gptStartContinuous(&GPTD6, 3U); // interval-ticks adjusts the note playback rate (++ for slower, -- for faster) } void audio_stop_hardware(void) { channel_1_stop(); - gptStopTimer(&GPTD3); + gptStopTimer(&GPTD6); } -/* regular timer task, that checks the note to be currently played, updates the pwm to output that frequency +/* a regular timer task, that checks the note to be currently played + * and updates the pwm to output that frequency */ -static void gpt_cb8(GPTDriver *gptp) { +static void gpt_callback(GPTDriver *gptp) { float freq, freq_alt; pwm_audio_timer_task(&freq, &freq_alt); From 0f913f2583c2b1370f07b8a76cebb5b7a9f0b301 Mon Sep 17 00:00:00 2001 From: Johannes Date: Tue, 17 Mar 2020 15:26:16 +0100 Subject: [PATCH 021/153] audio_arm_pwm: increase pwm frequency for "higher fidelity" on the previous .frequency=100000 higher frequency musical notes came out wrong (frequency measured on a Tektronix TDS2014B) note | freq | arm-pwm C2 | 65.4 | 65.491 C5 | 523.25 | 523.93 C6 | 1046.5 | 1053.38 C7 | 2093 | 2129 C8 | 4186 | 4350.91 with .frequency = 500000 C8 | 4186 | 4204.6 --- quantum/audio/audio_chibios_pwm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index 88b752fc03ab..2c5fbaa4c8ea 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -68,7 +68,7 @@ static void pwm_audio_period_callback(PWMDriver *pwmp); static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp); #endif -static PWMConfig pwmCFG = {.frequency = 100000, /* PWM clock frequency */ +static PWMConfig pwmCFG = {.frequency = 500000, /* PWM clock frequency */ .period = 0, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ #if ARM_PWM_USE_PIN_ALTERNATE .callback = NULL, // no callback, the hardware directly toggles the pin From f61efd128a9bb66106dd9e366f5293e6fba80afb Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 18 Mar 2020 16:02:13 +0100 Subject: [PATCH 022/153] audio refactoring: remove unused variables --- quantum/audio/audio.c | 39 ++++++++++++++------------------------- quantum/audio/audio.h | 6 ------ 2 files changed, 14 insertions(+), 31 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index dc9893a599fe..d15f9b6f5a43 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -21,20 +21,16 @@ uint8_t voices = 0; float frequencies[8] = {0.0}; -int volumes[8] = {0}; -// float place = 0; int voice_place = 0; float frequency = 0; float frequency_alt = 0; -int volume = 0; -long position = 0; bool playing_notes = false; bool playing_note = false; -float note_frequency = 0; +float note_frequency = 0; // Hz float note_length = 0; -uint8_t note_tempo = TEMPO_DEFAULT; +uint8_t note_tempo = TEMPO_DEFAULT; // beats-per-minute float note_timbre = TIMBRE_DEFAULT; uint32_t note_position = 0; float (*notes_pointer)[][2]; @@ -44,7 +40,7 @@ bool note_resting = false; uint16_t current_note = 0; uint16_t next_note = 0; -uint8_t rest_counter = 0; + #ifdef VIBRATO_ENABLE float vibrato_counter = 0; @@ -52,14 +48,10 @@ float vibrato_strength = .5; float vibrato_rate = 0.125; #endif -float polyphony_rate = 0; - -static bool audio_initialized = false; - -audio_config_t audio_config; - uint16_t envelope_index = 0; bool glissando = true; +float polyphony_rate = 0; + #ifndef STARTUP_SONG # define STARTUP_SONG SONG(STARTUP_SOUND) @@ -74,6 +66,10 @@ float startup_song[][2] = STARTUP_SONG; float audio_on_song[][2] = AUDIO_ON_SONG; float audio_off_song[][2] = AUDIO_OFF_SONG; + +static bool audio_initialized = false; +audio_config_t audio_config; + void audio_init() { if (audio_initialized) { return; @@ -120,11 +116,9 @@ void stop_all_notes() { playing_note = false; frequency = 0; frequency_alt = 0; - volume = 0; for (uint8_t i = 0; i < 8; i++) { frequencies[i] = 0; - volumes[i] = 0; } } @@ -138,12 +132,9 @@ void stop_note(float freq) { for (int i = 7; i >= 0; i--) { if (frequencies[i] == freq) { frequencies[i] = 0; - volumes[i] = 0; for (int j = i; (j < 7); j++) { frequencies[j] = frequencies[j + 1]; frequencies[j + 1] = 0; - volumes[j] = volumes[j + 1]; - volumes[j + 1] = 0; } break; } @@ -154,20 +145,17 @@ void stop_note(float freq) { voice_place = 0; } if (voices == 0) { - playing_note = false; - audio_stop_hardware(); frequency = 0; frequency_alt = 0; - volume = 0; playing_note = false; } } } -void play_note(float freq, int vol) { - dprintf("audio play note freq=%d vol=%d", (int)freq, vol); +void play_note(float freq, int vol) { //NOTE: vol is unused + dprintf("audio play note freq=%d", (int)freq); if (!audio_initialized) { audio_init(); @@ -180,7 +168,6 @@ void play_note(float freq, int vol) { if (freq > 0) { frequencies[voices] = freq; - volumes[voices] = vol; voices++; } audio_start_hardware(); @@ -305,7 +292,9 @@ float pwm_audio_get_single_voice_frequency(uint8_t voice) { void pwm_audio_timer_task(float *freq, float *freq_alt) { if (playing_note) { if (voices > 0) { -#ifdef BPIN_AUDIO +#ifdef AUDIO1_PIN_SET + //TODO: untangle avr specific defines + // speaker for second/alternate voice is available *freq_alt = pwm_audio_get_single_voice_frequency(2); #else *freq_alt = 0.0f; diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index bb684650407e..395f1d140b94 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -31,9 +31,6 @@ # include "audio_chibios_dac.h" #endif -// Largely untested PWM audio mode (doesn't sound as good) -// #define PWM_AUDIO - // #define VIBRATO_ENABLE // Enable vibrato strength/amplitude - slows down ISR too much @@ -96,9 +93,6 @@ void decrease_tempo(uint8_t tempo_change); void audio_init(void); void audio_startup(void); -#ifdef PWM_AUDIO -void play_sample(uint8_t* s, uint16_t l, bool r); -#endif void play_note(float freq, int vol); void stop_note(float freq); void stop_all_notes(void); From 26ed37317d2c9037a038c0b440623c38dbb2d964 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 18 Mar 2020 17:49:38 +0100 Subject: [PATCH 023/153] audio_arm_dac: calibrate note tempo: with a tempo of 60beats-per-second a whole-note should last for exactly one second --- quantum/audio/audio_chibios_dac.c | 14 +++++++++----- quantum/audio/musical_notes.h | 7 ++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index ef85a1149585..7f342f43930d 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -123,8 +123,9 @@ static void dac_end(DACDriver *dacp){ if (playing_notes) { note_position += DAC_BUFFER_SIZE/2; - // End of the note - 35 is arbitary here, but gets us close to AVR's timing - if ((note_position >= (note_length * DAC_SAMPLE_RATE / 35))) { + // End of the note - 64 is the number of 'units' of a whole note, 3 comes (probably?) from the gpttimer: DAC_SAMPLE_RATE * 3; with a TEMPO set to 60 a whole note lasts exactly one second +#define EON (64*2.0f/3) + if ((note_position >= (note_length * DAC_SAMPLE_RATE / EON))) { stop_note((*notes_pointer)[current_note][0]); current_note++; if (current_note >= notes_count) { @@ -135,13 +136,16 @@ static void dac_end(DACDriver *dacp){ return; } } - play_note((*notes_pointer)[current_note][0], 15); + + + play_note((*notes_pointer)[current_note][0], 0);//Note: second parameter volume is unused envelope_index = 0; - note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); + + note_length = ((*notes_pointer)[current_note][1]) * (60.0f / note_tempo); // Skip forward in the next note's length if we've over shot the last, so // the overall length of the song is the same - note_position = note_position - (note_length * DAC_SAMPLE_RATE / 35); + note_position = note_position - (note_length * DAC_SAMPLE_RATE / EON); } } } diff --git a/quantum/audio/musical_notes.h b/quantum/audio/musical_notes.h index 0ba572c346d2..9f1ea9e80933 100644 --- a/quantum/audio/musical_notes.h +++ b/quantum/audio/musical_notes.h @@ -17,9 +17,8 @@ #pragma once // Tempo Placeholder -#ifndef TEMPO_DEFAULT -# define TEMPO_DEFAULT 100 -#endif +#define TEMPO_DEFAULT 60 +// in beats-per-minute #define SONG(notes...) \ { notes } @@ -40,6 +39,8 @@ #define QUARTER_DOT_NOTE(note) MUSICAL_NOTE(note, 16 + 8) #define EIGHTH_DOT_NOTE(note) MUSICAL_NOTE(note, 8 + 4) #define SIXTEENTH_DOT_NOTE(note) MUSICAL_NOTE(note, 4 + 2) +// duration of 64 units == one beat == one whole note +// with a tempo of 60bpm this comes to a length of one second // Note Type Shortcuts #define M__NOTE(note, duration) MUSICAL_NOTE(note, duration) From 1045acf29c59009605c4366d0acfba954f1f7f07 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 19 Mar 2020 04:35:47 +0100 Subject: [PATCH 024/153] audio: allow feature selection in rules.mk so the user can switch the audio driver between DAC and PWM on STM32 boards which support both (STM32F2 and up) or select the "pin alternate" pwm mode, for example on STM32F103 --- common_features.mk | 14 ++++++--- docs/feature_audio.md | 22 ++++++++------ quantum/audio/audio.h | 2 +- quantum/audio/audio_chibios_pwm.c | 49 ++++++++++++++----------------- 4 files changed, 46 insertions(+), 41 deletions(-) diff --git a/common_features.mk b/common_features.mk index 0f08b911f1b2..b2caae3f12cc 100644 --- a/common_features.mk +++ b/common_features.mk @@ -42,13 +42,19 @@ ifeq ($(strip $(COMMAND_ENABLE)), yes) OPT_DEFS += -DCOMMAND_ENABLE endif +AUDIO_ENABLE ?= no ifeq ($(strip $(AUDIO_ENABLE)), yes) AUDIO_DRIVER ?= pwm ifeq ($(PLATFORM),CHIBIOS) - ifeq ($(MCU_SERIES),STM32F1xx) - AUDIO_DRIVER ?= pwm - else ## stm32f2 and f3 have a DAC unit, f1 do not - AUDIO_DRIVER ?= dac + ## stm32f2 and above have a usable DAC unit, f1 do not + ifeq ($(strip $(AUDIO_DRIVER)), dac) + OPT_DEFS += -DAUDIO_DRIVER_DAC + else ifeq ($(strip $(AUDIO_DRIVER)), pwm-pin-alternate) + OPT_DEFS += -DAUDIO_DRIVER_PWM_PIN_ALTERNATE + # reset config switch, to end up with the correct filename below + AUDIO_DRIVER := pwm + else # fallback=pwm + OPT_DEFS += -DAUDIO_DRIVER_PWM endif endif OPT_DEFS += -DAUDIO_ENABLE diff --git a/docs/feature_audio.md b/docs/feature_audio.md index b48f6255516c..0965bf8218e2 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -19,19 +19,23 @@ and *optionally*, a secondary voice, using Timer 1, on one of these pins: ## ARM based boards -STM32F2 upwards can use the builtin DAC unit, to drive Pins A4 or A5, set either: +STM32F2 upwards can use the builtin DAC unit, to drive Pins A4 or A5: +add `AUDIO_DRIVER = dac` to `rules.mk` and set in `config.h` either: `#define A4_AUDIO` OR `#define A5_AUDIO` -STM32F1xx have to fall back to using PWM (on the up side: with any pin you choose), either: -`#define ARM_PWM_USE_PIN_ALTERNATE 1` -which is the default. Pin PA8 will be used, which is directly connected to the hardware PWM (TIM1_CH1 = PA8) -OR -`#define ARM_PWM_USE_PIN_ALTERNATE 0` -`#define ARM_PWM_AUDIO_PORT GPIOC` -`#define ARM_PWM_AUDIO_PIN 13` -to have any other pin output a pwm signal, generated from a timer callback (e.g. toggled in software) + +STM32F1xx have to fall back to using PWM (on the up side: with any pin you choose), + +either set: +`AUDIO_SYSTEM = pwm-pin-alternate` in `rules.mk` and +`#define AUDIO_PIN C13` in `config.h` +to have the selected pin output a pwm signal, generated from a timer callback (e.g. toggled in software) + OR +`AUDIO_DRIVER PWM_PIN_ALTERNATE` in `rules.mk` +which will use Timer 1 to directly drive pin PA8 through the PWM hardware (TIM1_CH1 = PA8). +Should you want to use the pwm-hardware on another pin and timer - be ready to dig into the STM32 datasheet and do the neccessary changes to quantum/audio/audio_arm_pwm.c. ## Songs diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 395f1d140b94..d2314154aecf 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -27,7 +27,7 @@ #include "voices.h" #include "quantum.h" #include -#if defined(PROTOCOL_CHIBIOS) +#if defined(AUDIO_DRIVER_DAC) # include "audio_chibios_dac.h" #endif diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index 2c5fbaa4c8ea..96d6e8dadd89 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -47,38 +47,33 @@ to use another hardware-pwm pin: #include #include "print.h" -/* either use the direct hardware connection of Timer1-Channel1 to GPIOA.8 - via the pins alternate-function to drive a piezo speaker - OR set this define to zero and have the timer callbacks toggle your pin of choice -*/ -#ifndef ARM_PWM_USE_PIN_ALTERNATE -# define ARM_PWM_USE_PIN_ALTERNATE 0 +#if defined (AUDIO_DRIVER_PWM) +# if !defined(AUDIO_PIN) +# error "Audio feature enabled, but not pin selected - see docs/feature_audio under the ARM PWM settings" +# endif #endif -#ifndef ARM_PWM_AUDIO_PIN -# define ARM_PWM_AUDIO_PIN A10 -#endif // ----------------------------------------------------------------------------- extern int voices; extern bool playing_notes; -#if !(ARM_PWM_USE_PIN_ALTERNATE) +#if defined(AUDIO_DRIVER_PWM) static void pwm_audio_period_callback(PWMDriver *pwmp); static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp); #endif static PWMConfig pwmCFG = {.frequency = 500000, /* PWM clock frequency */ .period = 0, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ -#if ARM_PWM_USE_PIN_ALTERNATE +#if defined(AUDIO_DRIVER_PWM_PIN_ALTERNATE) .callback = NULL, // no callback, the hardware directly toggles the pin -#else +#else // AUDIO_DRIVER_PWM .callback = pwm_audio_period_callback, #endif .channels = { -#if ARM_PWM_USE_PIN_ALTERNATE +#if AUDIO_DRIVER_PWM_PIN_ALTERNATE {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* channel 0 -> TIM1_CH1 */ -#else +#else // AUDIO_DRIVER_PWM {PWM_OUTPUT_ACTIVE_HIGH, pwm_audio_channel_interrupt_callback}, /* channel 0 -> TIM1_CH1 */ #endif {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIM1_CH2 */ @@ -104,7 +99,7 @@ void channel_1_start(void) { pwmStop(&PWMD1); pwmStart(&PWMD1, &pwmCFG); -#if !(ARM_PWM_USE_PIN_ALTERNATE) +#if defined(AUDIO_DRIVER_PWM) pwmEnablePeriodicNotification(&PWMD1); pwmEnableChannelNotification(&PWMD1, 0); #endif @@ -113,15 +108,15 @@ void channel_1_start(void) { void channel_1_stop(void) { pwmStop(&PWMD1); -#if !(ARM_PWM_USE_PIN_ALTERNATE) - palClearLine(ARM_PWM_AUDIO_PIN); // leave the line low, after last note was played +#if defined(AUDIO_DRIVER_PWM) + palClearLine(AUDIO_PIN); // leave the line low, after last note was played #endif } -#if !(ARM_PWM_USE_PIN_ALTERNATE) +#if defined(AUDIO_DRIVER_PWM) static void pwm_audio_period_callback(PWMDriver *pwmp) { (void)pwmp; - palClearLine(ARM_PWM_AUDIO_PIN); + palClearLine(AUDIO_PIN); /* hm, using the pwm callback, instead of the gpt timer does not work :-( float freq, freq_alt; @@ -135,9 +130,9 @@ static void pwm_audio_period_callback(PWMDriver *pwmp) { } static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { (void)pwmp; - palSetLine(ARM_PWM_AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer + palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer } -#endif +#endif // AUDIO_DRIVER_PWM static void gpt_callback(GPTDriver *gptp); GPTConfig gptCFG = {.frequency = 10, @@ -147,20 +142,20 @@ GPTConfig gptCFG = {.frequency = 10, void audio_initialize_hardware(void) { pwmStart(&PWMD1, &pwmCFG); -#if ARM_PWM_USE_PIN_ALTERNATE -# ifdef PAL_MODE_STM32_ALTERNATE_PUSHPULL +#if defined(AUDIO_DRIVER_PWM_PIN_ALTERNATE) +# if defined(PAL_MODE_STM32_ALTERNATE_PUSHPULL) //TODO: is there a better way to differentiate between chibios GPIOv1 and GPIOv2? palSetLineMode(A8, PAL_MODE_STM32_ALTERNATE_PUSHPULL); //f103 with GPIOv1 # else palSetLineMode(A8, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(6) );//f303xx with GPIOV2 # endif -#else - palSetLineMode(ARM_PWM_AUDIO_PIN, PAL_MODE_OUTPUT_PUSHPULL); - palClearLine(ARM_PWM_AUDIO_PIN); +#else // AUDIO_DRIVER_PWM + palSetLineMode(AUDIO_PIN, PAL_MODE_OUTPUT_PUSHPULL); + palClearLine(AUDIO_PIN); pwmEnablePeriodicNotification(&PWMD1); // enable pwm callbacks pwmEnableChannelNotification(&PWMD1, 0); -#endif +#endif // AUDIO_DRIVER_PWM gptStart(&GPTD6, &gptCFG); } From 5f76573f1ca065aeccbd578f81f677da6c280f76 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 21 Mar 2020 01:50:13 +0100 Subject: [PATCH 025/153] audio-refactoring: move codeblocks in audio.[ch] into more coherent groups and add some inline documentation --- quantum/audio/audio.c | 155 +++++++++++++++++++++++++----------------- quantum/audio/audio.h | 48 +++++++------ 2 files changed, 119 insertions(+), 84 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index d15f9b6f5a43..8ab298e44323 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -19,26 +19,38 @@ #include "eeconfig.h" -uint8_t voices = 0; -float frequencies[8] = {0.0}; +/* audio system: + * + * audio.[ch] takes care of all overall state, tracking the actively playing + * notes (as polyphonic voices); the notes a SONG consists of; + * ... + * + * audio_[avr|chibios]_[dac|pwm] take care of the lower hardware dependent parts, + * specific to each platform and the used subsystem/driver to drive + * the output pins/channels with the calculated frequencies for each + * + */ + +uint8_t voices = 0; // nuber of active polyphonic voices +float frequencies[8] = {0.0}; // frequencies of each active voice int voice_place = 0; -float frequency = 0; -float frequency_alt = 0; +float frequency = 0; // frequency of the current note (down-mixed from the polyphony?) +float frequency_alt = 0; // frequency for the second speaker -bool playing_notes = false; -bool playing_note = false; +bool playing_notes = false; // playing a SONG? +bool playing_note = false; // or multiple polyphonic float note_frequency = 0; // Hz -float note_length = 0; +float note_length = 0; // in 64 parts to a beat uint8_t note_tempo = TEMPO_DEFAULT; // beats-per-minute float note_timbre = TIMBRE_DEFAULT; -uint32_t note_position = 0; -float (*notes_pointer)[][2]; -uint16_t notes_count; -bool notes_repeat; -bool note_resting = false; +uint32_t note_position = 0; // where in time, during playback of the current_note +float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs +uint16_t notes_count; // length of the notes_pointer array +bool notes_repeat; // PLAY_SONG or PLAY_LOOP? +bool note_resting = false; //?? current note is a pause? or is this supposed to indicate a 'tie'? -uint16_t current_note = 0; +uint16_t current_note = 0; // index into the array at notes_pointer uint16_t next_note = 0; @@ -102,6 +114,34 @@ void audio_startup(void) { } } +void audio_toggle(void) { + if (audio_config.enable) { + stop_all_notes(); + } + audio_config.enable ^= 1; + eeconfig_update_audio(audio_config.raw); + if (audio_config.enable) { + audio_on_user(); + } +} + +void audio_on(void) { + audio_config.enable = 1; + eeconfig_update_audio(audio_config.raw); + audio_on_user(); + PLAY_SONG(audio_on_song); +} + +void audio_off(void) { + PLAY_SONG(audio_off_song); + wait_ms(100); + stop_all_notes(); + audio_config.enable = 0; + eeconfig_update_audio(audio_config.raw); +} + +bool is_audio_on(void) { return (audio_config.enable != 0); } + void stop_all_notes() { dprintf("audio stop all notes"); @@ -174,6 +214,10 @@ void play_note(float freq, int vol) { //NOTE: vol is unused } } +/* the two ways to feed the audio system: + play_note to add (or start) playing notes simultaniously with multiple voices + play_nots to playback a melody, which is just an array of notes (of different frequencies and durations) +*/ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) { if (!audio_initialized) { audio_init(); @@ -203,57 +247,16 @@ bool is_playing_note(void) { return playing_note; } bool is_playing_notes(void) { return playing_notes; } -bool is_audio_on(void) { return (audio_config.enable != 0); } -void audio_toggle(void) { - if (audio_config.enable) { - stop_all_notes(); - } - audio_config.enable ^= 1; - eeconfig_update_audio(audio_config.raw); - if (audio_config.enable) { - audio_on_user(); - } -} +uint8_t audio_get_number_of_active_voices(void) { return voices; } -void audio_on(void) { - audio_config.enable = 1; - eeconfig_update_audio(audio_config.raw); - audio_on_user(); - PLAY_SONG(audio_on_song); -} - -void audio_off(void) { - PLAY_SONG(audio_off_song); - wait_ms(100); - stop_all_notes(); - audio_config.enable = 0; - eeconfig_update_audio(audio_config.raw); -} - -#ifdef VIBRATO_ENABLE - -float mod(float a, int b) { - float r = fmod(a, b); - return r < 0 ? r + b : r; -} - -float vibrato(float average_freq) { -# ifdef VIBRATO_STRENGTH_ENABLE - float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); -# else - float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; -# endif - vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0 / average_freq)), VIBRATO_LUT_LENGTH); - return vibrated_freq; -} +float audio_get_frequency(uint8_t voice_index) { return frequencies[voice_index]; } -#endif /* out of a possibly polyphonic setup, retrieve the frequency for a single voice to calculate the pwm period and duty-cycle from, relative to the cpy-frequency */ -float pwm_audio_get_single_voice_frequency(uint8_t voice) { +float audio_get_single_voice_frequency(uint8_t voice) { float frequency = 0.0; if (voice > voices) return frequency; @@ -394,7 +397,20 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { #ifdef VIBRATO_ENABLE -// Vibrato rate functions +float mod(float a, int b) { + float r = fmod(a, b); + return r < 0 ? r + b : r; +} + +float vibrato(float average_freq) { +# ifdef VIBRATO_STRENGTH_ENABLE + float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); +# else + float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; +# endif + vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0 / average_freq)), VIBRATO_LUT_LENGTH); + return vibrated_freq; +} void set_vibrato_rate(float rate) { vibrato_rate = rate; } @@ -432,14 +448,25 @@ void set_timbre(float timbre) { note_timbre = timbre; } // Tempo functions -void set_tempo(uint8_t tempo) { note_tempo = tempo; } - -void decrease_tempo(uint8_t tempo_change) { note_tempo += tempo_change; } +void set_tempo(uint8_t tempo) { + if (tempo < 10) + note_tempo = 10; +// else if (tempo > 250) +// note_tempo = 250; + else + note_tempo = tempo; +} void increase_tempo(uint8_t tempo_change) { - if (note_tempo - tempo_change < 10) { + if (tempo_change > 255-note_tempo) + note_tempo = 255; + else + note_tempo += tempo_change; +} + +void decrease_tempo(uint8_t tempo_change) { + if (tempo_change >= note_tempo-10) note_tempo = 10; - } else { + else note_tempo -= tempo_change; - } } diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index d2314154aecf..8f9cb98ddf9f 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -31,11 +31,6 @@ # include "audio_chibios_dac.h" #endif -// #define VIBRATO_ENABLE - -// Enable vibrato strength/amplitude - slows down ISR too much -// #define VIBRATO_STRENGTH_ENABLE - typedef union { uint8_t raw; struct { @@ -45,21 +40,41 @@ typedef union { }; } audio_config_t; -// implementation in the audio_avr/arm_* parts +// implementation in the audio_avr/arm_* drivers void audio_initialize_hardware(void); void audio_start_hardware(void); void audio_stop_hardware(void); -bool is_audio_on(void); +void audio_init(void); +void audio_startup(void); +) void audio_toggle(void); void audio_on(void); void audio_off(void); +bool is_audio_on(void); + +void play_note(float freq, int vol); +void stop_note(float freq); +void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat); +void stop_all_notes(void); + +bool is_playing_note(void); +bool is_playing_notes(void); + +uint8_t audio_get_number_of_active_voices(void); +float audio_get_frequency(uint8_t voice_index); + +float audio_get_single_voice_frequency(uint8_t voice); -float pwm_audio_get_single_voice(uint8_t voice); void pwm_audio_timer_task(float *freq, float *freq_alt); // Vibrato rate functions +// #define VIBRATO_ENABLE + +// Enable vibrato strength/amplitude - slows down ISR too much (TODO: from/for/on avr only?) +// #define VIBRATO_STRENGTH_ENABLE + #ifdef VIBRATO_ENABLE void set_vibrato_rate(float rate); @@ -84,20 +99,16 @@ void disable_polyphony(void); void increase_polyphony_rate(float change); void decrease_polyphony_rate(float change); +// Timbre function + void set_timbre(float timbre); -void set_tempo(uint8_t tempo); +// Tempo functions + +void set_tempo(uint8_t tempo); void increase_tempo(uint8_t tempo_change); void decrease_tempo(uint8_t tempo_change); -void audio_init(void); -void audio_startup(void); - -void play_note(float freq, int vol); -void stop_note(float freq); -void stop_all_notes(void); -void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat); - #define SCALE \ (int8_t[]) { 0 + (12 * 0), 2 + (12 * 0), 4 + (12 * 0), 5 + (12 * 0), 7 + (12 * 0), 9 + (12 * 0), 11 + (12 * 0), 0 + (12 * 1), 2 + (12 * 1), 4 + (12 * 1), 5 + (12 * 1), 7 + (12 * 1), 9 + (12 * 1), 11 + (12 * 1), 0 + (12 * 2), 2 + (12 * 2), 4 + (12 * 2), 5 + (12 * 2), 7 + (12 * 2), 9 + (12 * 2), 11 + (12 * 2), 0 + (12 * 3), 2 + (12 * 3), 4 + (12 * 3), 5 + (12 * 3), 7 + (12 * 3), 9 + (12 * 3), 11 + (12 * 3), 0 + (12 * 4), 2 + (12 * 4), 4 + (12 * 4), 5 + (12 * 4), 7 + (12 * 4), 9 + (12 * 4), 11 + (12 * 4), } @@ -107,6 +118,3 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat); #define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) #define PLAY_SONG(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), false) #define PLAY_LOOP(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), true) - -bool is_playing_note(void); -bool is_playing_notes(void); From c88052b04592f8d8b6c8515ad1849dd80b0d3196 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 21 Mar 2020 12:50:34 +0100 Subject: [PATCH 026/153] audio-refactoring: cleanup and streamline common code between audio_arm_[dac|pwm] untangeling the relation between audio.c and the two drivers and adding more documenting comments :-) --- quantum/audio/audio.c | 68 ++++++++++++++++++++++++--- quantum/audio/audio.h | 3 ++ quantum/audio/audio_chibios_dac.c | 76 ++++++++++--------------------- quantum/audio/audio_chibios_pwm.c | 50 ++++++++++++-------- 4 files changed, 119 insertions(+), 78 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 8ab298e44323..759fad5ad31e 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -206,6 +206,7 @@ void play_note(float freq, int vol) { //NOTE: vol is unused envelope_index = 0; + //TODO: handle pause/rest; freq==0 but with a valid duration if (freq > 0) { frequencies[voices] = freq; voices++; @@ -236,7 +237,7 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) { current_note = 0; note_frequency = (*notes_pointer)[current_note][0]; - note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); + note_length = ((*notes_pointer)[current_note][1]) * (60.0f / note_tempo); note_position = 0; audio_start_hardware(); @@ -262,15 +263,18 @@ float audio_get_single_voice_frequency(uint8_t voice) { if (voice > voices) return frequency; if (glissando) { - if (frequency != 0 && frequency < frequencies[voices - voice] && frequency < frequencies[voices - voice] * pow(2, -440 / frequencies[voices - voice] / 12 / 2)) { + if (frequency != 0 && frequency < frequencies[voices - voice] + && frequency < frequencies[voices - voice] * pow(2, -440 / frequencies[voices - voice] / 12 / 2)) { frequency = frequency * pow(2, 440 / frequency / 12 / 2); - } else if (frequency != 0 && frequency > frequencies[voices - voice] && frequency > frequencies[voices - voice] * pow(2, 440 / frequencies[voices - voice] / 12 / 2)) { + } else if (frequency != 0 && frequency > frequencies[voices - voice] + && frequency > frequencies[voices - voice] * pow(2, 440 / frequencies[voices - voice] / 12 / 2)) { frequency = frequency * pow(2, -440 / frequency / 12 / 2); } else { frequency = frequencies[voices - voice]; } } else { - frequency = frequencies[voices - voice]; + frequency = frequencies[voices - voice]; //TODO: why not frequencies[voice]? + // -> new voices are appended at the end, so the most recent/current is MAX-0 } #ifdef VIBRATO_ENABLE @@ -292,13 +296,14 @@ float audio_get_single_voice_frequency(uint8_t voice) { return frequency; } +// TODO: remove... AVR specific, and clusterfuck-ish void pwm_audio_timer_task(float *freq, float *freq_alt) { if (playing_note) { if (voices > 0) { #ifdef AUDIO1_PIN_SET //TODO: untangle avr specific defines // speaker for second/alternate voice is available - *freq_alt = pwm_audio_get_single_voice_frequency(2); + *freq_alt = audio_get_single_voice_frequency(2); #else *freq_alt = 0.0f; #endif @@ -322,7 +327,7 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { *freq = frequencies[voice_place]; #endif } else { - *freq = pwm_audio_get_single_voice_frequency(1); + *freq = audio_get_single_voice_frequency(1); } } } @@ -395,6 +400,57 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { } } +/* called by the timer of the audio-driver, which ticks regularly while playing a song = play_notes + + @param step: arbitrary step value, audio.c keeps track of for the audio-driver + @param end: scaling factor multiplied to the note_length. has to match step so that audio.c can determine when a note has finished playing + */ +void audio_advance_note(uint32_t step, float end) { + if (playing_notes) { + note_position += step; + + if (note_position == (note_length * end)) { + palToggleLine(D4);//yellow + } + + if (note_position >= (note_length * end)) { + stop_note((*notes_pointer)[current_note][0]); + current_note++; + +palToggleLine(D3);//orange + + if (current_note >= notes_count) { + if (notes_repeat) { + current_note = 0; + } else { + playing_notes = false; + return; + } + } + + play_note( + (*notes_pointer)[current_note][0], // frequency only; the duration is handled by calling this function regularly and advancing the note_position + 0xff);// volume TODO: second parameter is unused... refactor! + + envelope_index = 0; + + // Skip forward in the next note's length if we've over shot the last, so + // the overall length of the song is the same + note_position = note_position - (note_length * end); + + note_length = ((*notes_pointer)[current_note][1]) * (60.0f / note_tempo); + } + } + //* + else + stop_all_notes(); + //TODO: trigger a stop of the hardware or just a stop_note on the last frequency? + //*/ +} + + +// Vibrato functions + #ifdef VIBRATO_ENABLE float mod(float a, int b) { diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 8f9cb98ddf9f..17371f56e25e 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -68,6 +68,9 @@ float audio_get_single_voice_frequency(uint8_t voice); void pwm_audio_timer_task(float *freq, float *freq_alt); +void audio_advance_note(uint32_t step, float end); + + // Vibrato rate functions // #define VIBRATO_ENABLE diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index 7f342f43930d..8acce43970c9 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -21,20 +21,13 @@ #include #include "print.h" -// TODO: move into audio-common state -extern bool playing_notes; -extern uint8_t voices; -extern float frequencies[8]; -extern uint32_t note_position; -extern float note_length; -extern float (*notes_pointer)[][2]; -extern uint16_t current_note; -extern bool notes_repeat; -extern uint16_t notes_count; -extern uint8_t note_tempo; -extern uint16_t envelope_index; - -// ----------------------------------------------------------------------------- +/* + Audio Driver: DAC + + which utilizes the dac unit many STM32 are equipped with to output a modulated sinewave from samples stored in the dac_buffer_sine array and are passed to the hardware through DMA + + it ia also possible to have a custom sample-LUT by implementing/overwriding 'dac_value_generate' +*/ static const dacsample_t dac_buffer_sine[DAC_BUFFER_SIZE] = { // 256 values, max 4095 @@ -72,15 +65,19 @@ static float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; */ __attribute__((weak)) uint16_t dac_value_generate(void) { uint16_t value = DAC_OFF_VALUE; - uint8_t working_voices = voices; + uint8_t working_voices = audio_get_number_of_active_voices(); if (working_voices > DAC_VOICES_MAX) working_voices = DAC_VOICES_MAX; if (working_voices > 0) { uint16_t value_avg = 0; for (uint8_t i = 0; i < working_voices; i++) { - dac_if[i] = dac_if[i] + ((frequencies[i] * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE) - * 2/3; //TODO: why is this scaling factor necessary to get accurate frequencies on the DAC output? (as measured with an oscilloscope) - // possibly: the gpt timer runs with 3*DAC_SAMPLE_RATE; and the DAC callback is called twice per conversion? + dac_if[i] = dac_if[i] + + ((audio_get_frequency(i) //TODO: replace by glissando+vibrator+.. variant + * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE) + * 2/3; /*Note: necessary to get the correct frequencies on the + DAC output (as measured with an oscilloscope), since + the gpt timer runs with 3*DAC_SAMPLE_RATE; and the DAC + callback is called twice per conversion.*/ // Needed because % doesn't work with floats while (dac_if[i] >= (DAC_BUFFER_SIZE)) dac_if[i] = dac_if[i] - DAC_BUFFER_SIZE; @@ -120,34 +117,15 @@ static void dac_end(DACDriver *dacp){ sample_p[s] = dac_value_generate(); } - if (playing_notes) { - note_position += DAC_BUFFER_SIZE/2; - - // End of the note - 64 is the number of 'units' of a whole note, 3 comes (probably?) from the gpttimer: DAC_SAMPLE_RATE * 3; with a TEMPO set to 60 a whole note lasts exactly one second -#define EON (64*2.0f/3) - if ((note_position >= (note_length * DAC_SAMPLE_RATE / EON))) { - stop_note((*notes_pointer)[current_note][0]); - current_note++; - if (current_note >= notes_count) { - if (notes_repeat) { - current_note = 0; - } else { - playing_notes = false; - return; - } - } - - - play_note((*notes_pointer)[current_note][0], 0);//Note: second parameter volume is unused - envelope_index = 0; - - note_length = ((*notes_pointer)[current_note][1]) * (60.0f / note_tempo); - - // Skip forward in the next note's length if we've over shot the last, so - // the overall length of the song is the same - note_position = note_position - (note_length * DAC_SAMPLE_RATE / EON); - } - } + // update audio internal state (note position, current_note, voices, ...) + audio_advance_note( + DAC_BUFFER_SIZE/2, + DAC_SAMPLE_RATE/ (64*2.0f/3) + /* End of the note: 64 is the number of 'units' of a whole note, 3 comes + from the gpttimer: DAC_SAMPLE_RATE * 3; 2 from the callback beeing + called twice per sample conversion. + with a TEMPO set to 60 a whole note lasts exactly one second */ + ); } static void dac_error(DACDriver *dacp, dacerror_t err) { @@ -221,9 +199,3 @@ void audio_initialize_hardware(void) { void audio_stop_hardware(void) {} void audio_start_hardware(void) {} - -__attribute__((weak)) void dac_setup_note(void) { dac_if[voices] = 0.0f; } - -uint8_t dac_number_of_voices(void) { return voices; } - -float dac_get_frequency(uint8_t index) { return frequencies[index]; } diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index 96d6e8dadd89..7f41263fb3f8 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -14,6 +14,17 @@ * along with this program. If not, see . */ +/* +Audio Driver: PWM + +the duty-cycle is always kept at 50%, and the pwm-period is adjusted to match the frequency of a note to be played back. + +this driver uses the chibios-PWM system to produce a squarewave on a given output pin. +Either in software through a pwm callback and set/clear; or through the pwm hardware which directly toggles the pin via its alternate function. see your MCUs datasheet for pin can be driven by a timers T/IMx_CHy. + + */ + + /* STM32F103C Setup: halconf.h: #define HAL_USE_PWM TRUE @@ -114,19 +125,10 @@ void channel_1_stop(void) { } #if defined(AUDIO_DRIVER_PWM) +// generate a PWM signal on any pin, not neccessarily the one connected to the timer static void pwm_audio_period_callback(PWMDriver *pwmp) { (void)pwmp; palClearLine(AUDIO_PIN); - - /* hm, using the pwm callback, instead of the gpt timer does not work :-( - float freq, freq_alt; - pwm_audio_timer_task(&freq, &freq_alt); - - if (playing_notes) - channel_1_set_frequency(freq); - else - channel_1_stop(); - //*/ } static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { (void)pwmp; @@ -135,8 +137,17 @@ static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { #endif // AUDIO_DRIVER_PWM static void gpt_callback(GPTDriver *gptp); -GPTConfig gptCFG = {.frequency = 10, - .callback = gpt_callback, +GPTConfig gptCFG = { + /* a whole note is one beat, which is - per definition in musical_notes.h - set to 64 + the longest note is BREAVE_DOT=128+64=192, the shortest SIXTEENTH=4 + the tempo (which might vary!) is in bpm (beats per minute) + therefore: if the timer ticks away at .frequency = (60*64)Hz, + and the .intervall counts from 64 downwards - all we need to do is increment the + note_position on each callback, and have the note_lengt = duration*tempo compare + against that; hence: audio_advance_note(step=1, end=1) + */ + .frequency = 60 * 64, + .callback = gpt_callback, }; void audio_initialize_hardware(void) { @@ -144,7 +155,7 @@ void audio_initialize_hardware(void) { #if defined(AUDIO_DRIVER_PWM_PIN_ALTERNATE) # if defined(PAL_MODE_STM32_ALTERNATE_PUSHPULL) - //TODO: is there a better way to differentiate between chibios GPIOv1 and GPIOv2? + //TODO: is there a better way to differentiate between chibios GPIOv1 and GPIOv2? palSetLineMode(A8, PAL_MODE_STM32_ALTERNATE_PUSHPULL); //f103 with GPIOv1 # else palSetLineMode(A8, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(6) );//f303xx with GPIOV2 @@ -163,7 +174,7 @@ void audio_initialize_hardware(void) { void audio_start_hardware(void) { channel_1_stop(); channel_1_start(); - gptStartContinuous(&GPTD6, 3U); // interval-ticks adjusts the note playback rate (++ for slower, -- for faster) + gptStartContinuous(&GPTD6, 64); } void audio_stop_hardware(void) { @@ -175,11 +186,10 @@ void audio_stop_hardware(void) { * and updates the pwm to output that frequency */ static void gpt_callback(GPTDriver *gptp) { - float freq, freq_alt; - pwm_audio_timer_task(&freq, &freq_alt); + float freq;// TODO: freq_alt + + freq = audio_get_single_voice_frequency(1); // freq_alt would be voice=2 - if (playing_notes) - channel_1_set_frequency(freq); - else - channel_1_stop(); + channel_1_set_frequency(freq); + audio_advance_note(1, 1); } From 2c38c18a518f4d3f27aa3087473034a4acdbf82d Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 21 Mar 2020 19:14:07 +0100 Subject: [PATCH 027/153] audio_avr_pwm: getting it back into working condition, and cleanup+refactor --- quantum/audio/audio.c | 13 +- quantum/audio/audio_avr_pwm.c | 224 +++++++++++++++++----------------- quantum/audio/musical_notes.h | 3 + 3 files changed, 123 insertions(+), 117 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 759fad5ad31e..f180fcfea3ab 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -367,6 +367,7 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { return; } } + if (!note_resting) { note_resting = true; if (current_note == 0) { @@ -378,7 +379,7 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { } if ((*notes_pointer)[current_note][0] == (*notes_pointer)[next_note][0]) { - note_frequency = 0; + note_frequency = 0; //why? this disables the output frequency and makes the next note a 'rest' } else { note_frequency = (*notes_pointer)[current_note][0]; } @@ -406,19 +407,17 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { @param end: scaling factor multiplied to the note_length. has to match step so that audio.c can determine when a note has finished playing */ void audio_advance_note(uint32_t step, float end) { + if (playing_note) { + //TODO! + } + if (playing_notes) { note_position += step; - if (note_position == (note_length * end)) { - palToggleLine(D4);//yellow - } - if (note_position >= (note_length * end)) { stop_note((*notes_pointer)[current_note][0]); current_note++; -palToggleLine(D3);//orange - if (current_note >= notes_count) { if (notes_repeat) { current_note = 0; diff --git a/quantum/audio/audio_avr_pwm.c b/quantum/audio/audio_avr_pwm.c index 8593731eb148..5c1be04372b4 100644 --- a/quantum/audio/audio_avr_pwm.c +++ b/quantum/audio/audio_avr_pwm.c @@ -30,101 +30,102 @@ // TODO: move into audio-common state extern bool playing_notes; extern float note_timbre; -extern uint8_t voices; #define CPU_PRESCALER 8 -// ----------------------------------------------------------------------------- -// Timer Abstractions -// ----------------------------------------------------------------------------- +/* + Audio Driver: PWM -// Currently we support timers 1 and 3 used at the same time, channels A-C, -// pins PB5, PB6, PB7, PC4, PC5, and PC6 + drive up to two speakers, with the primary channel_1 on either pin PC4 PC5 or PC6 (the later beeing used by most AVR based keyboards) with a PMW signal generated by timer3 in hardware -#if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) -# define AUDIO1_PIN_SET -# define AUDIO1_TIMSKx TIMSK1 -# define AUDIO1_TCCRxA TCCR1A -# define AUDIO1_TCCRxB TCCR1B -# define AUDIO1_ICRx ICR1 -# define AUDIO1_WGMx0 WGM10 -# define AUDIO1_WGMx1 WGM11 -# define AUDIO1_WGMx2 WGM12 -# define AUDIO1_WGMx3 WGM13 -# define AUDIO1_CSx0 CS10 -# define AUDIO1_CSx1 CS11 -# define AUDIO1_CSx2 CS12 + and an optional secondary channel_2 on either pin PB5, PB6 or PB7, with a PWM signal from timer1 -# if defined(B5_AUDIO) -# define AUDIO1_COMxy0 COM1A0 -# define AUDIO1_COMxy1 COM1A1 -# define AUDIO1_OCIExy OCIE1A -# define AUDIO1_OCRxy OCR1A -# define AUDIO1_PIN B5 -# define AUDIO1_TIMERx_COMPy_vect TIMER1_COMPA_vect -# elif defined(B6_AUDIO) -# define AUDIO1_COMxy0 COM1B0 -# define AUDIO1_COMxy1 COM1B1 -# define AUDIO1_OCIExy OCIE1B -# define AUDIO1_OCRxy OCR1B -# define AUDIO1_PIN B6 -# define AUDIO1_TIMERx_COMPy_vect TIMER1_COMPB_vect -# elif defined(B7_AUDIO) -# define AUDIO1_COMxy0 COM1C0 -# define AUDIO1_COMxy1 COM1C1 -# define AUDIO1_OCIExy OCIE1C -# define AUDIO1_OCRxy OCR1C -# define AUDIO1_PIN B7 -# define AUDIO1_TIMERx_COMPy_vect TIMER1_COMPC_vect -# endif -#endif + in a pinch with only one of the PB pins available as speaker output, they can be used as the primary channel too - by only setting the Bx_AUDIO define, and *none* of the Cx_AUDIO defines +*/ #if defined(C4_AUDIO) || defined(C5_AUDIO) || defined(C6_AUDIO) -# define AUDIO2_PIN_SET -# define AUDIO2_TIMSKx TIMSK3 -# define AUDIO2_TCCRxA TCCR3A -# define AUDIO2_TCCRxB TCCR3B -# define AUDIO2_ICRx ICR3 -# define AUDIO2_WGMx0 WGM30 -# define AUDIO2_WGMx1 WGM31 -# define AUDIO2_WGMx2 WGM32 -# define AUDIO2_WGMx3 WGM33 -# define AUDIO2_CSx0 CS30 -# define AUDIO2_CSx1 CS31 -# define AUDIO2_CSx2 CS32 +# define AUDIO1_PIN_SET +# define AUDIO1_TIMSKx TIMSK3 +# define AUDIO1_TCCRxA TCCR3A +# define AUDIO1_TCCRxB TCCR3B +# define AUDIO1_ICRx ICR3 +# define AUDIO1_WGMx0 WGM30 +# define AUDIO1_WGMx1 WGM31 +# define AUDIO1_WGMx2 WGM32 +# define AUDIO1_WGMx3 WGM33 +# define AUDIO1_CSx0 CS30 +# define AUDIO1_CSx1 CS31 +# define AUDIO1_CSx2 CS32 # if defined(C6_AUDIO) -# define AUDIO2_COMxy0 COM3A0 -# define AUDIO2_COMxy1 COM3A1 -# define AUDIO2_OCIExy OCIE3A -# define AUDIO2_OCRxy OCR3A -# define AUDIO2_PIN C6 -# define AUDIO2_TIMERx_COMPy_vect TIMER3_COMPA_vect +# define AUDIO1_COMxy0 COM3A0 +# define AUDIO1_COMxy1 COM3A1 +# define AUDIO1_OCIExy OCIE3A +# define AUDIO1_OCRxy OCR3A +# define AUDIO1_PIN C6 +# define AUDIO1_TIMERx_COMPy_vect TIMER3_COMPA_vect # elif defined(C5_AUDIO) -# define AUDIO2_COMxy0 COM3B0 -# define AUDIO2_COMxy1 COM3B1 -# define AUDIO2_OCIExy OCIE3B -# define AUDIO2_OCRxy OCR3B -# define AUDIO2_PIN C5 -# define AUDIO2_TIMERx_COMPy_vect TIMER3_COMPB_vect +# define AUDIO1_COMxy0 COM3B0 +# define AUDIO1_COMxy1 COM3B1 +# define AUDIO1_OCIExy OCIE3B +# define AUDIO1_OCRxy OCR3B +# define AUDIO1_PIN C5 +# define AUDIO1_TIMERx_COMPy_vect TIMER3_COMPB_vect # elif defined(C4_AUDIO) -# define AUDIO2_COMxy0 COM3C0 -# define AUDIO2_COMxy1 COM3C1 -# define AUDIO2_OCIExy OCIE3C -# define AUDIO2_OCRxy OCR3C -# define AUDIO2_PIN C4 -# define AUDIO2_TIMERx_COMPy_vect TIMER3_COMPC_vect +# define AUDIO1_COMxy0 COM3C0 +# define AUDIO1_COMxy1 COM3C1 +# define AUDIO1_OCIExy OCIE3C +# define AUDIO1_OCRxy OCR3C +# define AUDIO1_PIN C4 +# define AUDIO1_TIMERx_COMPy_vect TIMER3_COMPC_vect +# endif +#endif + + +#if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) +# define AUDIO2_PIN_SET +# define AUDIO2_TIMSKx TIMSK1 +# define AUDIO2_TCCRxA TCCR1A +# define AUDIO2_TCCRxB TCCR1B +# define AUDIO2_ICRx ICR1 +# define AUDIO2_WGMx0 WGM10 +# define AUDIO2_WGMx1 WGM11 +# define AUDIO2_WGMx2 WGM12 +# define AUDIO2_WGMx3 WGM13 +# define AUDIO2_CSx0 CS10 +# define AUDIO2_CSx1 CS11 +# define AUDIO2_CSx2 CS12 + +# if defined(B5_AUDIO) +# define AUDIO2_COMxy0 COM1A0 +# define AUDIO2_COMxy1 COM1A1 +# define AUDIO2_OCIExy OCIE1A +# define AUDIO2_OCRxy OCR1A +# define AUDIO2_PIN B5 +# define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPA_vect +# elif defined(B6_AUDIO) +# define AUDIO2_COMxy0 COM1B0 +# define AUDIO2_COMxy1 COM1B1 +# define AUDIO2_OCIExy OCIE1B +# define AUDIO2_OCRxy OCR1B +# define AUDIO2_PIN B6 +# define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPB_vect +# elif defined(B7_AUDIO) +# define AUDIO2_COMxy0 COM1C0 +# define AUDIO2_COMxy1 COM1C1 +# define AUDIO2_OCIExy OCIE1C +# define AUDIO2_OCRxy OCR1C +# define AUDIO2_PIN B7 +# define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPC_vect # endif #endif // C6 seems to be the assumed default by many existing keyboard - but sill warn the user -#if !defined(AUDIO2_PIN_SET) && !defined(AUDIO1_PIN_SET) +#if !defined(AUDIO1_PIN_SET) && !defined(AUDIO2_PIN_SET) # pragma message "audio feature enabled, but no pin selected - see docs/feature_audio for defines to set" #endif // ----------------------------------------------------------------------------- -float place = 0; - #ifdef AUDIO1_PIN_SET static float channel_1_frequency = 0.0f; void channel_1_set_frequency(float freq) { @@ -135,13 +136,11 @@ void channel_1_set_frequency(float freq) { channel_1_frequency = freq; // set pwm period - AUDIO1_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + AUDIO1_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); // and duty cycle AUDIO1_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); } -float channel_1_get_frequency(void) { return channel_1_frequency; } - void channel_1_start(void) { // enable timer-counter ISR AUDIO1_TIMSKx |= _BV(AUDIO1_OCIExy); @@ -157,6 +156,7 @@ void channel_1_stop(void) { } #endif + #ifdef AUDIO2_PIN_SET static float channel_2_frequency = 0.0f; void channel_2_set_frequency(float freq) { @@ -166,10 +166,12 @@ void channel_2_set_frequency(float freq) { channel_2_frequency = freq; - AUDIO2_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + AUDIO2_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); AUDIO2_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); } +float channel_2_get_frequency(void) { return channel_2_frequency; } + void channel_2_start(void) { AUDIO2_TIMSKx |= _BV(AUDIO2_OCIExy); AUDIO2_TCCRxA |= _BV(AUDIO2_COMxy1); @@ -184,7 +186,6 @@ void channel_2_stop(void) { void audio_initialize_hardware() { #ifdef AUDIO1_PIN_SET channel_1_stop(); - // Set audio ports as output setPinOutput(AUDIO1_PIN); #endif @@ -210,6 +211,7 @@ void audio_initialize_hardware() { // OCR1B - PB6 // OCR1C - PB7 + // Clock Select (CS3n) = 0b010 = Clock / 8 #ifdef AUDIO1_PIN_SET // initialize timer-counter AUDIO1_TCCRxA = (0 << AUDIO1_COMxy1) | (0 << AUDIO1_COMxy0) | (1 << AUDIO1_WGMx1) | (0 << AUDIO1_WGMx0); @@ -218,7 +220,6 @@ void audio_initialize_hardware() { // channel_1_set_frequency(440); // original code set this frequency here... why? #endif - // Clock Select (CS3n) = 0b010 = Clock / 8 #ifdef AUDIO2_PIN_SET AUDIO2_TCCRxA = (0 << AUDIO2_COMxy1) | (0 << AUDIO2_COMxy0) | (1 << AUDIO2_WGMx1) | (0 << AUDIO2_WGMx0); AUDIO2_TCCRxB = (1 << AUDIO2_WGMx3) | (1 << AUDIO2_WGMx2) | (0 << AUDIO2_CSx2) | (1 << AUDIO2_CSx1) | (0 << AUDIO2_CSx0); @@ -226,65 +227,68 @@ void audio_initialize_hardware() { // channel_2_set_frequency(440); // original code set this frequency here... why? #endif - audio_initialized = true; } void audio_stop_hardware() { -#ifdef AUDIO2_PIN_SET - channel_2_stop(); -#endif - #ifdef AUDIO1_PIN_SET channel_1_stop(); #endif -} -void audio_start_hardware(void) { #ifdef AUDIO2_PIN_SET - channel_2_start(); + channel_2_stop(); #endif +} + +void audio_start_hardware(void) { #ifdef AUDIO1_PIN_SET -# ifdef AUDIO2_PIN_SET - if (voices > 1) { - channel_1_start(); + channel_1_start(); +#endif +#ifdef AUDIO2_PIN_SET +# ifdef AUDIO1_PIN_SET + if (audio_get_number_of_active_voices() > 1) { + channel_2_start(); } # else - channel_1_start(); + channel_2_start(); # endif #endif } -#ifdef AUDIO2_PIN_SET -ISR(AUDIO2_TIMERx_COMPy_vect) { - float freq, freq_alt; - pwm_audio_timer_task(&freq, &freq_alt); +#ifdef AUDIO1_PIN_SET +ISR(AUDIO1_TIMERx_COMPy_vect) { + + audio_advance_note(1,channel_1_frequency/CPU_PRESCALER/8); -// do polyphonic, if a second speaker is available -# ifdef AUDIO1_PIN_SET if (playing_notes) - channel_1_set_frequency(freq_alt); + channel_1_set_frequency( + audio_get_single_voice_frequency(1) + ); else channel_1_stop(); -# endif +// do polyphonic, if a second speaker is available +# ifdef AUDIO2_PIN_SET if (playing_notes) - channel_2_set_frequency(freq); + channel_2_set_frequency( + audio_get_single_voice_frequency(2) + ); else channel_2_stop(); +# endif } #endif -#ifdef AUDIO1_PIN_SET -ISR(AUDIO1_TIMERx_COMPy_vect) { -# if defined(AUDIO1_PIN_SET) && !defined(AUDIO2_PIN_SET) - float freq, freq_alt; - pwm_audio_timer_task(&freq, &freq_alt); +#if !defined(AUDIO1_PIN_SET) && defined(AUDIO2_PIN_SET) +ISR(AUDIO2_TIMERx_COMPy_vect) { + + audio_advance_note(1,channel_2_frequency/CPU_PRESCALER/8); if (playing_notes) - channel_1_set_frequency(freq); + channel_2_set_frequency( + audio_get_single_voice_frequency(1) + ); else - channel_1_stop(); -# endif + channel_2_stop(); } #endif diff --git a/quantum/audio/musical_notes.h b/quantum/audio/musical_notes.h index 9f1ea9e80933..1f1821771167 100644 --- a/quantum/audio/musical_notes.h +++ b/quantum/audio/musical_notes.h @@ -68,11 +68,14 @@ #endif // Notes - # = Octave +/*TODO: huh?? #ifdef __arm__ # define NOTE_REST 1.00f #else # define NOTE_REST 0.00f #endif +*/ +#define NOTE_REST 0.00f /* These notes are currently bugged #define NOTE_C0 16.35f From 1290f0a218b1e78354a36a8c3f04ef725b507061 Mon Sep 17 00:00:00 2001 From: JohSchneider Date: Sun, 22 Mar 2020 14:50:24 +0000 Subject: [PATCH 028/153] audio-refactoring: documentation and typo fixes Co-Authored-By: Nick Brassel --- docs/feature_audio.md | 5 ++--- quantum/audio/audio_chibios_dac.c | 2 +- quantum/audio/audio_chibios_pwm.c | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 0965bf8218e2..69cb028eda5e 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -19,8 +19,7 @@ and *optionally*, a secondary voice, using Timer 1, on one of these pins: ## ARM based boards -STM32F2 upwards can use the builtin DAC unit, to drive Pins A4 or A5: -add `AUDIO_DRIVER = dac` to `rules.mk` and set in `config.h` either: +Most STM32 MCUs have DAC peripherals, with a notable exception of the STM32F1xx series. Generally, the DAC peripheral drives pins A4 or A5. To enable DAC-based audio output on STM32 devices, add `AUDIO_DRIVER = dac` to `rules.mk` and set in `config.h` either: `#define A4_AUDIO` OR `#define A5_AUDIO` @@ -39,7 +38,7 @@ Should you want to use the pwm-hardware on another pin and timer - be ready to d ## Songs -There's a couple different sounds that will automatically be enabled without any other configuration: +There's a couple of different sounds that will automatically be enabled without any other configuration: ``` STARTUP_SONG // plays when the keyboard starts up (audio.c) GOODBYE_SONG // plays when you press the RESET key (quantum.c) diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index 8acce43970c9..789edab5c1a3 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -26,7 +26,7 @@ which utilizes the dac unit many STM32 are equipped with to output a modulated sinewave from samples stored in the dac_buffer_sine array and are passed to the hardware through DMA - it ia also possible to have a custom sample-LUT by implementing/overwriding 'dac_value_generate' + it ia also possible to have a custom sample-LUT by implementing/overriding 'dac_value_generate' */ static const dacsample_t dac_buffer_sine[DAC_BUFFER_SIZE] = { diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index 7f41263fb3f8..4f2eb2150a52 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -37,7 +37,7 @@ mcuconf.h: used pin: PA8 (alternate0: Tim1_Ch1) -from the datasheet for STM32F104C8B: alternate function of pin +from the datasheet for STM32F103C8: alternate function of pin TIM1_CH1 = PA8 TIM1_CH2 = PA9 TIM1_CH3 = PA10 @@ -60,7 +60,7 @@ to use another hardware-pwm pin: #if defined (AUDIO_DRIVER_PWM) # if !defined(AUDIO_PIN) -# error "Audio feature enabled, but not pin selected - see docs/feature_audio under the ARM PWM settings" +# error "Audio feature enabled, but no pin selected - see docs/feature_audio under the ARM PWM settings" # endif #endif From 363bacb1e2b84557a17c763f2094a8670867fa0c Mon Sep 17 00:00:00 2001 From: Johannes Date: Sun, 22 Mar 2020 17:18:08 +0100 Subject: [PATCH 029/153] audio-refactoring: cleanup defines, inludes and remove debug-prints --- quantum/audio/audio.c | 7 ------- quantum/audio/audio.h | 1 - quantum/audio/audio_avr_pwm.c | 5 ----- quantum/audio/audio_chibios_dac.c | 3 --- quantum/audio/audio_chibios_pwm.c | 9 +++------ 5 files changed, 3 insertions(+), 22 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index f180fcfea3ab..e338beb9a771 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -14,7 +14,6 @@ * along with this program. If not, see . */ #include "audio.h" -#include "keymap.h" #include "wait.h" #include "eeconfig.h" @@ -143,8 +142,6 @@ void audio_off(void) { bool is_audio_on(void) { return (audio_config.enable != 0); } void stop_all_notes() { - dprintf("audio stop all notes"); - if (!audio_initialized) { audio_init(); } @@ -163,8 +160,6 @@ void stop_all_notes() { } void stop_note(float freq) { - dprintf("audio stop note freq=%d", (int)freq); - if (playing_note) { if (!audio_initialized) { audio_init(); @@ -195,8 +190,6 @@ void stop_note(float freq) { } void play_note(float freq, int vol) { //NOTE: vol is unused - dprintf("audio play note freq=%d", (int)freq); - if (!audio_initialized) { audio_init(); } diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 17371f56e25e..2f5077b3e21f 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -21,7 +21,6 @@ #if defined(__AVR__) # include #endif -#include "wait.h" #include "musical_notes.h" #include "song_list.h" #include "voices.h" diff --git a/quantum/audio/audio_avr_pwm.c b/quantum/audio/audio_avr_pwm.c index 5c1be04372b4..7024f35a8bbe 100644 --- a/quantum/audio/audio_avr_pwm.c +++ b/quantum/audio/audio_avr_pwm.c @@ -14,18 +14,13 @@ * along with this program. If not, see . */ -#include -#include -//#include #if defined(__AVR__) # include # include # include #endif -#include "print.h" #include "audio.h" -#include "wait.h" // TODO: move into audio-common state extern bool playing_notes; diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index 789edab5c1a3..75085b716a23 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -18,9 +18,6 @@ #include #include -#include -#include "print.h" - /* Audio Driver: DAC diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index 4f2eb2150a52..91241567db2f 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -55,8 +55,6 @@ to use another hardware-pwm pin: #include "ch.h" #include "hal.h" -#include -#include "print.h" #if defined (AUDIO_DRIVER_PWM) # if !defined(AUDIO_PIN) @@ -138,7 +136,7 @@ static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { static void gpt_callback(GPTDriver *gptp); GPTConfig gptCFG = { - /* a whole note is one beat, which is - per definition in musical_notes.h - set to 64 + /* a whole note is one beat, which is - per definition in musical_notes.h - set to 64 the longest note is BREAVE_DOT=128+64=192, the shortest SIXTEENTH=4 the tempo (which might vary!) is in bpm (beats per minute) therefore: if the timer ticks away at .frequency = (60*64)Hz, @@ -154,10 +152,9 @@ void audio_initialize_hardware(void) { pwmStart(&PWMD1, &pwmCFG); #if defined(AUDIO_DRIVER_PWM_PIN_ALTERNATE) -# if defined(PAL_MODE_STM32_ALTERNATE_PUSHPULL) - //TODO: is there a better way to differentiate between chibios GPIOv1 and GPIOv2? +# if defined(USE_GPIOV1) palSetLineMode(A8, PAL_MODE_STM32_ALTERNATE_PUSHPULL); //f103 with GPIOv1 -# else +# else // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command) palSetLineMode(A8, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(6) );//f303xx with GPIOV2 # endif #else // AUDIO_DRIVER_PWM From 5548bf44f25ec3728e5cd15cbbc85205ba066aa7 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 25 Mar 2020 15:35:33 +0100 Subject: [PATCH 030/153] audio_chibios_dac: define&use a minimal sampling rate, based on the available tone-range to ease up on the cpu-load, while still rendering the higher notes/tones sufficiently also reenable the lower tones, since with the new implementation there is no evidence of them still beeing 'bugged' --- quantum/audio/audio.c | 7 ++--- quantum/audio/audio_chibios_dac.c | 1 + quantum/audio/audio_chibios_dac.h | 30 +++++++++++++++---- quantum/audio/musical_notes.h | 49 +++++++++++++++---------------- 4 files changed, 52 insertions(+), 35 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index e338beb9a771..b6f2ff451e3b 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -401,7 +401,7 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { */ void audio_advance_note(uint32_t step, float end) { if (playing_note) { - //TODO! + //TODO? playing_note is stopped 'manually'... so no need/sense in 'advanceing' them? } if (playing_notes) { @@ -433,11 +433,10 @@ void audio_advance_note(uint32_t step, float end) { note_length = ((*notes_pointer)[current_note][1]) * (60.0f / note_tempo); } } - //* - else + + if (!playing_note && !playing_notes ) stop_all_notes(); //TODO: trigger a stop of the hardware or just a stop_note on the last frequency? - //*/ } diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index 75085b716a23..2b507f78d0d3 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -54,6 +54,7 @@ static const dacsample_t dac_buffer_staircase[DAC_BUFFER_SIZE] = { static dacsample_t dac_buffer_empty[DAC_BUFFER_SIZE] = {DAC_OFF_VALUE}; +/* keep track of the sample position for for each voice/frequency */ static float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; /** diff --git a/quantum/audio/audio_chibios_dac.h b/quantum/audio/audio_chibios_dac.h index ea2976bc8d99..237ff976292a 100644 --- a/quantum/audio/audio_chibios_dac.h +++ b/quantum/audio/audio_chibios_dac.h @@ -29,33 +29,53 @@ # define DAC_SAMPLE_MAX 4095U #endif -// #define DAC_LOW_QUALITY +#if !defined(DAC_QUALITY_VERY_LOW) && !defined(DAC_QUALITY_LOW) && !defined(DAC_QUALITY_HIGH) && !defined(DAC_QUALITY_VERY_HIGH) +# define DAC_QUALITY_SANE_MINIMUM +#endif /** * These presets allow you to quickly switch between quality/voice settings for * the DAC. The sample rate and number of voices roughly has an inverse * relationship - slightly higher sample rates may be possible. + * + * NOTE: a high samplerate results in a higher cpu-load, which might lead to + * (audible) discontinuities and/or starve other processes of cpu-time + * (like RGB-led backlighting, ...) */ -#ifdef DAC_VERY_LOW_QUALITY +#ifdef DAC_QUALITY_VERY_LOW # define DAC_SAMPLE_RATE 11025U # define DAC_VOICES_MAX 8 #endif -#ifdef DAC_LOW_QUALITY +#ifdef DAC_QUALITY_LOW # define DAC_SAMPLE_RATE 22050U # define DAC_VOICES_MAX 4 #endif -#ifdef DAC_HIGH_QUALITY +#ifdef DAC_QUALITY_HIGH # define DAC_SAMPLE_RATE 44100U # define DAC_VOICES_MAX 2 #endif -#ifdef DAC_VERY_HIGH_QUALITY +#ifdef DAC_QUALITY_VERY_HIGH # define DAC_SAMPLE_RATE 88200U # define DAC_VOICES_MAX 1 #endif +#ifdef DAC_QUALITY_SANE_MINIMUM +/* a sane-minimum config: with a tradeoff between cpu-load and tone-range + * + * the (currently) highest defined note is NOTE_B8 with 7902Hz; if we now + * aim for an even even multiple of the buffersize, we end up with: + * ( roundUptoPow2(highest note / DAC_BUFFER_SIZE) * nyquist-rate * DAC_BUFFER_SIZE) + * 7902/256 = 30.867 * 2 * 256 ~= 16384 + * which works out (but the 'scope shows some sampling artifacts with lower harmonics :-P) + */ +# define DAC_SAMPLE_RATE 16384U +# define DAC_VOICES_MAX 8 +#endif + + /** * Effective bitrate of the DAC. 44.1khz is the standard for most audio - any * lower will sacrifice perceptible audio quality. Any higher will limit the diff --git a/quantum/audio/musical_notes.h b/quantum/audio/musical_notes.h index 1f1821771167..14e9e20c950a 100644 --- a/quantum/audio/musical_notes.h +++ b/quantum/audio/musical_notes.h @@ -77,32 +77,29 @@ */ #define NOTE_REST 0.00f -/* These notes are currently bugged -#define NOTE_C0 16.35f -#define NOTE_CS0 17.32f -#define NOTE_D0 18.35f -#define NOTE_DS0 19.45f -#define NOTE_E0 20.60f -#define NOTE_F0 21.83f -#define NOTE_FS0 23.12f -#define NOTE_G0 24.50f -#define NOTE_GS0 25.96f -#define NOTE_A0 27.50f -#define NOTE_AS0 29.14f -#define NOTE_B0 30.87f -#define NOTE_C1 32.70f -#define NOTE_CS1 34.65f -#define NOTE_D1 36.71f -#define NOTE_DS1 38.89f -#define NOTE_E1 41.20f -#define NOTE_F1 43.65f -#define NOTE_FS1 46.25f -#define NOTE_G1 49.00f -#define NOTE_GS1 51.91f -#define NOTE_A1 55.00f -#define NOTE_AS1 58.27f -*/ - +#define NOTE_C0 16.35f +#define NOTE_CS0 17.32f +#define NOTE_D0 18.35f +#define NOTE_DS0 19.45f +#define NOTE_E0 20.60f +#define NOTE_F0 21.83f +#define NOTE_FS0 23.12f +#define NOTE_G0 24.50f +#define NOTE_GS0 25.96f +#define NOTE_A0 27.50f +#define NOTE_AS0 29.14f +#define NOTE_B0 30.87f +#define NOTE_C1 32.70f +#define NOTE_CS1 34.65f +#define NOTE_D1 36.71f +#define NOTE_DS1 38.89f +#define NOTE_E1 41.20f +#define NOTE_F1 43.65f +#define NOTE_FS1 46.25f +#define NOTE_G1 49.00f +#define NOTE_GS1 51.91f +#define NOTE_A1 55.00f +#define NOTE_AS1 58.27f #define NOTE_B1 61.74f #define NOTE_C2 65.41f #define NOTE_CS2 69.30f From 6f3fed5b18de2e3ed24c48c1233fbd0b5f7eb94e Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 25 Mar 2020 15:36:15 +0100 Subject: [PATCH 031/153] audio-refactoring: one common AUDIO_MAX_VOICES define for all audio-drivers --- quantum/audio/audio.c | 13 ++++++----- quantum/audio/audio.h | 13 ++++++++--- quantum/audio/audio_avr_pwm.c | 1 + quantum/audio/audio_avr_pwm.h | 18 +++++++++++++++ quantum/audio/audio_chibios_dac.c | 2 +- quantum/audio/audio_chibios_dac.h | 16 ++++++------- quantum/audio/audio_chibios_pwm.c | 3 ++- quantum/audio/audio_chibios_pwm.h | 37 +++++++++++++++++++++++++++++++ 8 files changed, 84 insertions(+), 19 deletions(-) create mode 100644 quantum/audio/audio_avr_pwm.h create mode 100644 quantum/audio/audio_chibios_pwm.h diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index b6f2ff451e3b..ebd20b8ca48c 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -30,8 +30,11 @@ * */ +#ifndef AUDIO_VOICES_MAX +# define AUDIO_VOICES_MAX 8 +#endif uint8_t voices = 0; // nuber of active polyphonic voices -float frequencies[8] = {0.0}; // frequencies of each active voice +float frequencies[AUDIO_VOICES_MAX] = {0.0}; // frequencies of each active voice int voice_place = 0; float frequency = 0; // frequency of the current note (down-mixed from the polyphony?) @@ -154,7 +157,7 @@ void stop_all_notes() { frequency = 0; frequency_alt = 0; - for (uint8_t i = 0; i < 8; i++) { + for (uint8_t i = 0; i < AUDIO_VOICES_MAX; i++) { frequencies[i] = 0; } } @@ -164,10 +167,10 @@ void stop_note(float freq) { if (!audio_initialized) { audio_init(); } - for (int i = 7; i >= 0; i--) { + for (int i = AUDIO_VOICES_MAX-1; i >= 0; i--) { if (frequencies[i] == freq) { frequencies[i] = 0; - for (int j = i; (j < 7); j++) { + for (int j = i; (j < AUDIO_VOICES_MAX-1); j++) { frequencies[j] = frequencies[j + 1]; frequencies[j + 1] = 0; } @@ -194,7 +197,7 @@ void play_note(float freq, int vol) { //NOTE: vol is unused audio_init(); } - if (audio_config.enable && voices < 8) { + if (voices < AUDIO_VOICES_MAX) { playing_note = true; envelope_index = 0; diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 2f5077b3e21f..5632edc27510 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -18,18 +18,25 @@ #include #include -#if defined(__AVR__) -# include -#endif #include "musical_notes.h" #include "song_list.h" #include "voices.h" #include "quantum.h" #include + +#if defined(__AVR__) +# include +# include "audio_avr_pwm.h" +#endif + +#if defined(AUDIO_DRIVER_PWM) || defined(AUDIO_DRIVER_PWM_PIN_ALTERNATE) +# include "audio_chibios_pwm.h" +#endif #if defined(AUDIO_DRIVER_DAC) # include "audio_chibios_dac.h" #endif + typedef union { uint8_t raw; struct { diff --git a/quantum/audio/audio_avr_pwm.c b/quantum/audio/audio_avr_pwm.c index 7024f35a8bbe..f6a2ce36b24e 100644 --- a/quantum/audio/audio_avr_pwm.c +++ b/quantum/audio/audio_avr_pwm.c @@ -19,6 +19,7 @@ # include # include #endif + #include "audio.h" diff --git a/quantum/audio/audio_avr_pwm.h b/quantum/audio/audio_avr_pwm.h new file mode 100644 index 000000000000..c3edd42160d1 --- /dev/null +++ b/quantum/audio/audio_avr_pwm.h @@ -0,0 +1,18 @@ +/* Copyright 2020 Jack Humbert + * + * 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 2 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 . + */ +#pragma once + +#define AUDIO_VOICES_MAX 2 diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index 2b507f78d0d3..16c7e3d6661e 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -64,7 +64,7 @@ static float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; __attribute__((weak)) uint16_t dac_value_generate(void) { uint16_t value = DAC_OFF_VALUE; uint8_t working_voices = audio_get_number_of_active_voices(); - if (working_voices > DAC_VOICES_MAX) working_voices = DAC_VOICES_MAX; + if (working_voices > AUDIO_VOICES_MAX) working_voices = AUDIO_VOICES_MAX; if (working_voices > 0) { uint16_t value_avg = 0; diff --git a/quantum/audio/audio_chibios_dac.h b/quantum/audio/audio_chibios_dac.h index 237ff976292a..d2c0884370e5 100644 --- a/quantum/audio/audio_chibios_dac.h +++ b/quantum/audio/audio_chibios_dac.h @@ -15,8 +15,6 @@ */ #pragma once -#include "ch.h" - /** * Size of the dac_buffer arrays. All must be the same size. */ @@ -44,22 +42,22 @@ */ #ifdef DAC_QUALITY_VERY_LOW # define DAC_SAMPLE_RATE 11025U -# define DAC_VOICES_MAX 8 +# define AUDIO_VOICES_MAX 8 #endif #ifdef DAC_QUALITY_LOW # define DAC_SAMPLE_RATE 22050U -# define DAC_VOICES_MAX 4 +# define AUDIO_VOICES_MAX 4 #endif #ifdef DAC_QUALITY_HIGH # define DAC_SAMPLE_RATE 44100U -# define DAC_VOICES_MAX 2 +# define AUDIO_VOICES_MAX 2 #endif #ifdef DAC_QUALITY_VERY_HIGH # define DAC_SAMPLE_RATE 88200U -# define DAC_VOICES_MAX 1 +# define AUDIO_VOICES_MAX 1 #endif #ifdef DAC_QUALITY_SANE_MINIMUM @@ -72,7 +70,7 @@ * which works out (but the 'scope shows some sampling artifacts with lower harmonics :-P) */ # define DAC_SAMPLE_RATE 16384U -# define DAC_VOICES_MAX 8 +# define AUDIO_VOICES_MAX 8 #endif @@ -91,8 +89,8 @@ * is used here, the keyboard will freeze and glitch-out when that many voices * are being played. */ -#ifndef DAC_VOICES_MAX -# define DAC_VOICES_MAX 2 +#ifndef AUDIO_VOICES_MAX +# define AUDIO_VOICES_MAX 2 #endif /** diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index 91241567db2f..33d88f839dd1 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -20,7 +20,7 @@ Audio Driver: PWM the duty-cycle is always kept at 50%, and the pwm-period is adjusted to match the frequency of a note to be played back. this driver uses the chibios-PWM system to produce a squarewave on a given output pin. -Either in software through a pwm callback and set/clear; or through the pwm hardware which directly toggles the pin via its alternate function. see your MCUs datasheet for pin can be driven by a timers T/IMx_CHy. +Either in software through a pwm callback and set/clear; or through the pwm hardware which directly toggles the pin via its alternate function. see your MCUs datasheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function. */ @@ -64,6 +64,7 @@ to use another hardware-pwm pin: // ----------------------------------------------------------------------------- + extern int voices; extern bool playing_notes; diff --git a/quantum/audio/audio_chibios_pwm.h b/quantum/audio/audio_chibios_pwm.h new file mode 100644 index 000000000000..9c2d0140807a --- /dev/null +++ b/quantum/audio/audio_chibios_pwm.h @@ -0,0 +1,37 @@ +/* Copyright 2020 Jack Humbert + * + * 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 2 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 . + */ +#pragma once + +// with one pwm channel only one voice is possible (TODO: unless we start cycling through all frequencies[]) +#define AUDIO_VOICES_MAX 1 + + +#if !defined(AUDIO_PWM_PINALTERNATE_TIMER) +//NOTE: Timer2 seems to be used otherwise in QMK, otherwise we could default to A5 (= TIM2_CH1, with PWMD2 and alternate-function(1)) +# define AUDIO_PWM_PINALTERNATE_TIMER 1 +#endif + +#if !defined(AUDIO_PWM_PINALTERNATE_TIMERCHANNEL) +//NOTE: sticking to the STM datasheet numbering: TIMxCH1 to TIMxCH4 +// default: STM32F303CC PA8+TIM1_CH1 -> 1 +# define AUDIO_PWM_PINALTERNATE_TIMERCHANNEL 1 +#endif + +#if !defined(AUDIO_PWM_PINALTERNATE_FUNCTION) +// pin-alternate function: see the datasheet for which pin needs what AF to connect to TIMx_CHy +// default: STM32F303CC PA8+TIM1_CH1 -> 6 +# define AUDIO_PWM_PINALTERNATE_FUNCTION 6 +#endif From 981ad17205f626ce88224b2d1d7070673d4416c8 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 25 Mar 2020 15:37:10 +0100 Subject: [PATCH 032/153] audio-chibios-pwm: pwm-pin-allternate: make the the timer, timer-channel and alternate function user-#definable --- quantum/audio/audio_chibios_pwm.c | 90 ++++++++++++++++++++----------- 1 file changed, 59 insertions(+), 31 deletions(-) diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index 33d88f839dd1..8806e4518dc4 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -25,7 +25,7 @@ Either in software through a pwm callback and set/clear; or through the pwm hard */ -/* STM32F103C Setup: +/* STM32F103C8 Setup: halconf.h: #define HAL_USE_PWM TRUE #define HAL_USE_PAL TRUE @@ -35,20 +35,18 @@ mcuconf.h: #define STM32_PWM_USE_TIM1 TRUE #define STM32_GPT_USE_TIM3 TRUE -used pin: PA8 (alternate0: Tim1_Ch1) +used pin: PA8 (alternate0: TIM1_CH1) from the datasheet for STM32F103C8: alternate function of pin -TIM1_CH1 = PA8 +TIM1_CH1 = PA8 <- TIM1_CH2 = PA9 TIM1_CH3 = PA10 TIM1_CH4 = PA11 - -to use another hardware-pwm pin: -- check the datasheet for the timer_channel and the alternate-function -- replace PWMDx with the required timer -- reorder the PCMConfig.channels to match the TIMx_CHy (the stm datasheets usually have CH1 to CH4) -- set the pin to the appropiate alternate function (beware: differences in chibios GPIOv1, v2, ...) +so adding to config.h: +#define AUDIO_PIN A8 +#define AUDIO_PWM_PINALTERNATE_TIMER 1 +#define AUDIO_PWM_PINALTERNATE_TIMERCHANNEL 1 */ #include "audio.h" @@ -62,8 +60,11 @@ to use another hardware-pwm pin: # endif #endif -// ----------------------------------------------------------------------------- +// some preprocessor trickery to get the corresponding chibios-PWMDriver +#define TO_CHIBIOS_PWMD_PASTE(t) (PWMD##t) +#define TO_CHIBIOS_PWMD_EVAL(t) TO_CHIBIOS_PWMD_PASTE(t) +#define PWMD TO_CHIBIOS_PWMD_EVAL(AUDIO_PWM_PINALTERNATE_TIMER) extern int voices; extern bool playing_notes; @@ -71,7 +72,7 @@ extern bool playing_notes; #if defined(AUDIO_DRIVER_PWM) static void pwm_audio_period_callback(PWMDriver *pwmp); static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp); -#endif +#endif // AUDIO_DRIVER_PWM static PWMConfig pwmCFG = {.frequency = 500000, /* PWM clock frequency */ .period = 0, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ @@ -82,41 +83,68 @@ static PWMConfig pwmCFG = {.frequency = 500000, /* PWM clock frequency */ #endif .channels = { #if AUDIO_DRIVER_PWM_PIN_ALTERNATE - {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* channel 0 -> TIM1_CH1 */ +# if AUDIO_PWM_PINALTERNATE_TIMERCHANNEL == 4 + {PWM_OUTPUT_DISABLED, NULL}, /* channel 0 -> TIMx_CH1 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIMx_CH2 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 2 -> TIMx_CH3 */ + {PWM_OUTPUT_ACTIVE_HIGH, NULL} /* channel 3 -> TIMx_CH4 */ +# elif AUDIO_PWM_PINALTERNATE_TIMERCHANNEL == 3 + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH3 */ + {PWM_OUTPUT_DISABLED, NULL} +# elif AUDIO_PWM_PINALTERNATE_TIMERCHANNEL == 2 + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH2 */ + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_DISABLED, NULL} +# else /*fallback to CH1 */ + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH1 */ + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_DISABLED, NULL} +# endif // AUDIO_DRIVER_PWM_PIN_ALTERNATE_CHANNEL #else // AUDIO_DRIVER_PWM - {PWM_OUTPUT_ACTIVE_HIGH, pwm_audio_channel_interrupt_callback}, /* channel 0 -> TIM1_CH1 */ + // software-PWM just needs another callback on any channel + {PWM_OUTPUT_ACTIVE_HIGH, pwm_audio_channel_interrupt_callback}, /* channel 0 -> TIMx_CH1 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIMx_CH2 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 2 -> TIMx_CH3 */ + {PWM_OUTPUT_DISABLED, NULL} /* channel 3 -> TIMx_CH4 */ #endif - {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIM1_CH2 */ - {PWM_OUTPUT_DISABLED, NULL}, /* channel 2 -> TIM1_CH3 */ - {PWM_OUTPUT_DISABLED, NULL} /* channel 3 -> TIM1_CH4 */ }, - }; + }; + static float channel_1_frequency = 0.0f; void channel_1_set_frequency(float freq) { - if (freq == channel_1_frequency) return; +// if (freq == channel_1_frequency) return; + //TODO: interrupt same-frequency notes? channel_1_frequency = freq; pwmcnt_t period = (pwmCFG.frequency / freq); - pwmChangePeriod(&PWMD1, period); - pwmEnableChannel(&PWMD1, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD1, 5000)); + pwmChangePeriod(&PWMD, period); + pwmEnableChannel( + &PWMD, + AUDIO_PWM_PINALTERNATE_TIMERCHANNEL -1, + PWM_PERCENTAGE_TO_WIDTH(&PWMD, 5000) /*TODO: adjust by timbre */ + ); } float channel_1_get_frequency(void) { return channel_1_frequency; } void channel_1_start(void) { - pwmStop(&PWMD1); - pwmStart(&PWMD1, &pwmCFG); + pwmStop(&PWMD); + pwmStart(&PWMD, &pwmCFG); #if defined(AUDIO_DRIVER_PWM) - pwmEnablePeriodicNotification(&PWMD1); - pwmEnableChannelNotification(&PWMD1, 0); + pwmEnablePeriodicNotification(&PWMD); + pwmEnableChannelNotification(&PWMD, AUDIO_PWM_PINALTERNATE_TIMERCHANNEL-1); #endif } void channel_1_stop(void) { - pwmStop(&PWMD1); + pwmStop(&PWMD); #if defined(AUDIO_DRIVER_PWM) palClearLine(AUDIO_PIN); // leave the line low, after last note was played @@ -150,20 +178,20 @@ GPTConfig gptCFG = { }; void audio_initialize_hardware(void) { - pwmStart(&PWMD1, &pwmCFG); + pwmStart(&PWMD, &pwmCFG); #if defined(AUDIO_DRIVER_PWM_PIN_ALTERNATE) -# if defined(USE_GPIOV1) - palSetLineMode(A8, PAL_MODE_STM32_ALTERNATE_PUSHPULL); //f103 with GPIOv1 +# if defined(USE_GPIOV1) // STM32F103C8 + palSetLineMode(AUDIO_PIN, PAL_MODE_STM32_ALTERNATE_PUSHPULL); # else // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command) - palSetLineMode(A8, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(6) );//f303xx with GPIOV2 + palSetLineMode(AUDIO_PIN, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(AUDIO_PWM_PINALTERNATE_FUNCTION)); # endif #else // AUDIO_DRIVER_PWM palSetLineMode(AUDIO_PIN, PAL_MODE_OUTPUT_PUSHPULL); palClearLine(AUDIO_PIN); - pwmEnablePeriodicNotification(&PWMD1); // enable pwm callbacks - pwmEnableChannelNotification(&PWMD1, 0); + pwmEnablePeriodicNotification(&PWMD); // enable pwm callbacks + pwmEnableChannelNotification(&PWMD, AUDIO_PWM_PINALTERNATE_TIMERCHANNEL-1); #endif // AUDIO_DRIVER_PWM gptStart(&GPTD6, &gptCFG); From 2c80f4e2af3aa395e8af704103c6e3e7cfb1c893 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 25 Mar 2020 18:07:20 +0100 Subject: [PATCH 033/153] audio_chibios_dac: math.h has fmod for this --- quantum/audio/audio_chibios_dac.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index 16c7e3d6661e..a11f856fe44f 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -77,8 +77,7 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { the gpt timer runs with 3*DAC_SAMPLE_RATE; and the DAC callback is called twice per conversion.*/ - // Needed because % doesn't work with floats - while (dac_if[i] >= (DAC_BUFFER_SIZE)) dac_if[i] = dac_if[i] - DAC_BUFFER_SIZE; + dac_if[i] = fmod(dac_if[i], DAC_BUFFER_SIZE); // Wavetable generation/lookup uint16_t dac_i = (uint16_t)dac_if[i]; From e7c84d6375626cce95d0d002605b98c90c663975 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 25 Mar 2020 23:50:35 +0100 Subject: [PATCH 034/153] Redo Arm DAC implementation for additive, wavetable synthesis, sample playback update Jack Humberts dac-example keymaps for the slight changes in the audio-dac interface --- keyboards/planck/keymaps/synth_wavetable/keymap.c | 15 ++++++--------- keyboards/planck/keymaps/synth_wavetable/rules.mk | 3 +++ quantum/audio/audio_chibios_dac.h | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/keyboards/planck/keymaps/synth_wavetable/keymap.c b/keyboards/planck/keymaps/synth_wavetable/keymap.c index 218559353dc6..6684f02c6595 100644 --- a/keyboards/planck/keymaps/synth_wavetable/keymap.c +++ b/keyboards/planck/keymaps/synth_wavetable/keymap.c @@ -268,23 +268,20 @@ bool music_mask_user(uint16_t keycode) { float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; uint8_t dac_morph = 0; -// uint8_t dac_morph_flipped = 0; -// uint16_t dac_morph_counter = 0; -void dac_setup_note(void) { - dac_if[dac_number_of_voices()] = 0.0f; -} uint16_t dac_value_generate(void) { uint16_t value = DAC_OFF_VALUE; - uint8_t working_voices = dac_number_of_voices(); - if (working_voices > DAC_VOICES_MAX) - working_voices = DAC_VOICES_MAX; + uint8_t working_voices = audio_get_number_of_active_voices(); + if (working_voices > AUDIO_VOICES_MAX) + working_voices = AUDIO_VOICES_MAX; if (working_voices > 0) { uint16_t value_avg = 0; for (uint8_t i = 0; i < working_voices; i++) { - dac_if[i] = dac_if[i] + ((dac_get_frequency(i) * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE); + dac_if[i] = dac_if[i] + + ((audio_get_frequency(i) * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE) + * 2/3; // necessary to adjust for the gpt-timer frequency (three times the sample rate) and the dac-conversion beeing called twice per sample // Needed because % doesn't work with floats while (dac_if[i] >= (DAC_BUFFER_SIZE)) diff --git a/keyboards/planck/keymaps/synth_wavetable/rules.mk b/keyboards/planck/keymaps/synth_wavetable/rules.mk index e69de29bb2d1..39a472b63152 100644 --- a/keyboards/planck/keymaps/synth_wavetable/rules.mk +++ b/keyboards/planck/keymaps/synth_wavetable/rules.mk @@ -0,0 +1,3 @@ +AUDIO_ENABLE = yes +AUDIO_DRIVER = dac +AUDIO_PIN = A5 diff --git a/quantum/audio/audio_chibios_dac.h b/quantum/audio/audio_chibios_dac.h index d2c0884370e5..2da103db66c7 100644 --- a/quantum/audio/audio_chibios_dac.h +++ b/quantum/audio/audio_chibios_dac.h @@ -110,7 +110,7 @@ //TODO: go through a breaking change, and add A5_AUDIO to all keyboards currently using AUDIO on STM32 based boards #endif -uint8_t dac_number_of_voices(void); -float dac_get_frequency(uint8_t index); +/** + *user overridable sample generation/processing + */ uint16_t dac_value_generate(void); -void dac_setup_note(void); From 1008d5adbc8ca83b534175cf27cdd4f0d7e7f008 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 26 Mar 2020 05:23:43 +0100 Subject: [PATCH 035/153] audio-refactoring: use a common AUDIO_PIN configuration switch instead of defines have the user select a pin by configuration in rules.mk instead of a define in config.h has the advantage of beeing in a common form/pattern across all audio-driver implementations --- common_features.mk | 6 +++++ docs/feature_audio.md | 39 +++++++++++++++++-------------- quantum/audio/audio.h | 37 +++++++++++++++++++++++++++++ quantum/audio/audio_avr_pwm.c | 29 ++++++++++++----------- quantum/audio/audio_chibios_dac.c | 11 +++++---- quantum/audio/audio_chibios_dac.h | 8 +++---- 6 files changed, 91 insertions(+), 39 deletions(-) diff --git a/common_features.mk b/common_features.mk index b2caae3f12cc..3644f3336ccf 100644 --- a/common_features.mk +++ b/common_features.mk @@ -57,6 +57,12 @@ ifeq ($(strip $(AUDIO_ENABLE)), yes) OPT_DEFS += -DAUDIO_DRIVER_PWM endif endif + ifdef AUDIO_PIN + OPT_DEFS += -DAUDIO_PIN=$(AUDIO_PIN) -DAUDIO_PIN_$(AUDIO_PIN) + endif + ifdef AUDIO_PIN_ALT + OPT_DEFS += -DAUDIO_PIN_ALT=$(AUDIO_PIN) -DAUDIO_PIN_ALT_$(AUDIO_PIN) + endif OPT_DEFS += -DAUDIO_ENABLE MUSIC_ENABLE = yes SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 69cb028eda5e..3d1867a4e517 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -5,36 +5,41 @@ Your keyboard can make sounds! If you've got a Planck, Preonic, or basically any To activate this feature, add `AUDIO_ENABLE = yes` to your `rules.mk`. ## AVR based boards -Up to two simultaneous audio voices are supported, one driven by timer 1 and another driven by timer 3. The following pins can be defined as audio outputs in config.h: +Up to two simultaneous audio voices are supported, one driven by timer 1 and another driven by timer 3. The following pins can be configured as audio outputs in `rules.mk`: -the primary voice, with Timer 3 on one of these pins: -`#define C4_AUDIO` -`#define C5_AUDIO` -`#define C6_AUDIO` +for the primary voice, with Timer 3, pick ONE these pins: +`AUDIO_PIN = C4` +`AUDIO_PIN = C5` +`AUDIO_PIN = C6` -and *optionally*, a secondary voice, using Timer 1, on one of these pins: -`#define B5_AUDIO` -`#define B6_AUDIO` -`#define B7_AUDIO` +and *optionally*, a secondary voice, using Timer 1, on ONE of these pins: +`AUDIO_PIN_ALT = B5` +`AUDIO_PIN_ALT = B6` +`AUDIO_PIN_ALT = B7` ## ARM based boards -Most STM32 MCUs have DAC peripherals, with a notable exception of the STM32F1xx series. Generally, the DAC peripheral drives pins A4 or A5. To enable DAC-based audio output on STM32 devices, add `AUDIO_DRIVER = dac` to `rules.mk` and set in `config.h` either: -`#define A4_AUDIO` +Most STM32 MCUs have DAC peripherals, with a notable exception of the STM32F1xx series. Generally, the DAC peripheral drives pins A4 or A5. To enable DAC-based audio output on STM32 devices, add `AUDIO_DRIVER = dac` to `rules.mk` and set either:` +`AUDIO_PIN = A4` OR -`#define A5_AUDIO` +`AUDIO_PIN = A5` STM32F1xx have to fall back to using PWM (on the up side: with any pin you choose), -either set: -`AUDIO_SYSTEM = pwm-pin-alternate` in `rules.mk` and -`#define AUDIO_PIN C13` in `config.h` +Either: +set in `rules.mk`: +`AUDIO_SYSTEM = pwm` and +`AUDIO_PIN = C13` (can be any pin) to have the selected pin output a pwm signal, generated from a timer callback (e.g. toggled in software) OR -`AUDIO_DRIVER PWM_PIN_ALTERNATE` in `rules.mk` +`AUDIO_SYSTEM = pwm-pin-alternate` in `rules.mk` and in `config.h`: +`#define AUDIO_PIN A8` +`#define AUDIO_PWM_PINALTERNATE_TIMER 1` +`#define AUDIO_PWM_PINALTERNATE_TIMERCHANNEL 1` +(as well as `#define AUDIO_PWM_PINALTERNATE_FUNCTION 42` if you are on STM32F2 or larger) which will use Timer 1 to directly drive pin PA8 through the PWM hardware (TIM1_CH1 = PA8). -Should you want to use the pwm-hardware on another pin and timer - be ready to dig into the STM32 datasheet and do the neccessary changes to quantum/audio/audio_arm_pwm.c. +Should you want to use the pwm-hardware on another pin and timer - be ready to dig into the STM32 datasheet to pick the right TIMx_CHy and pin-alternate function. ## Songs diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 5632edc27510..715cb7252764 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -127,3 +127,40 @@ void decrease_tempo(uint8_t tempo_change); #define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) #define PLAY_SONG(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), false) #define PLAY_LOOP(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), true) + + + + +// LEGACY defines - TODO: remove and replace these in all keyboards using them +#ifdef A4_AUDIO +# define AUDIO_PIN_A4 +# define AUDIO_PIN A4 +#endif +#ifdef A5_AUDIO +# define AUDIO_PIN_A5 +# define AUDIO_PIN A5 +#endif +#ifdef B5_AUDIO +# define AUDIO_PIN_ALT_B5 +# define AUDIO_PIN_ALT B5 +#endif +#ifdef B6_AUDIO +# define AUDIO_PIN_ALT_B6 +# define AUDIO_PIN_ALT B6 +#endif +#ifdef B7_AUDIO +# define AUDIO_PIN_ALT_B7 +# define AUDIO_PIN_ALT B7 +#endif +#ifdef C4_AUDIO +# define AUDIO_PIN_C4 +# define AUDIO_PIN C4 +#endif +#ifdef C5_AUDIO +# define AUDIO_PIN_C5 +# define AUDIO_PIN C5 +#endif +#ifdef C6_AUDIO +# define AUDIO_PIN_C6 +# define AUDIO_PIN C6 +#endif diff --git a/quantum/audio/audio_avr_pwm.c b/quantum/audio/audio_avr_pwm.c index f6a2ce36b24e..70f233788053 100644 --- a/quantum/audio/audio_avr_pwm.c +++ b/quantum/audio/audio_avr_pwm.c @@ -36,10 +36,17 @@ extern float note_timbre; and an optional secondary channel_2 on either pin PB5, PB6 or PB7, with a PWM signal from timer1 - in a pinch with only one of the PB pins available as speaker output, they can be used as the primary channel too - by only setting the Bx_AUDIO define, and *none* of the Cx_AUDIO defines + in a pinch with only one of the PB pins available as speaker output, they can be used as the primary channel too - by only setting the AUDIO_PIN_ALT_Bx define, and *none* of the AUDIO_PIN_Cx defines */ -#if defined(C4_AUDIO) || defined(C5_AUDIO) || defined(C6_AUDIO) +// C6 seems to be the assumed default by many existing keyboard - but sill warn the user +#if !defined(AUDIO1_PIN_SET) && !defined(AUDIO2_PIN_SET) +# pragma message "Audio feature enabled, but no pin selected - see docs/feature_audio under the AVR settings for available options. Falling back to C6" +# define AUDIO_PIN_C6 +//TODO: make this an error - go through the breaking-change-process and change all keyboards to the new define +#endif + +#if defined(AUDIO_PIN_C4) || defined(AUDIO_PIN_C5) || defined(AUDIO_PIN_C6) # define AUDIO1_PIN_SET # define AUDIO1_TIMSKx TIMSK3 # define AUDIO1_TCCRxA TCCR3A @@ -53,21 +60,21 @@ extern float note_timbre; # define AUDIO1_CSx1 CS31 # define AUDIO1_CSx2 CS32 -# if defined(C6_AUDIO) +# if defined(AUDIO_PIN_C6) # define AUDIO1_COMxy0 COM3A0 # define AUDIO1_COMxy1 COM3A1 # define AUDIO1_OCIExy OCIE3A # define AUDIO1_OCRxy OCR3A # define AUDIO1_PIN C6 # define AUDIO1_TIMERx_COMPy_vect TIMER3_COMPA_vect -# elif defined(C5_AUDIO) +# elif defined(AUDIO_PIN_C5) # define AUDIO1_COMxy0 COM3B0 # define AUDIO1_COMxy1 COM3B1 # define AUDIO1_OCIExy OCIE3B # define AUDIO1_OCRxy OCR3B # define AUDIO1_PIN C5 # define AUDIO1_TIMERx_COMPy_vect TIMER3_COMPB_vect -# elif defined(C4_AUDIO) +# elif defined(AUDIO_PIN_C4) # define AUDIO1_COMxy0 COM3C0 # define AUDIO1_COMxy1 COM3C1 # define AUDIO1_OCIExy OCIE3C @@ -78,7 +85,7 @@ extern float note_timbre; #endif -#if defined(B5_AUDIO) || defined(B6_AUDIO) || defined(B7_AUDIO) +#if defined(AUDIO_PIN_ALT_B5) || defined(AUDIO_PIN_ALT_B6) || defined(AUDIO_PIN_ALT_B7) # define AUDIO2_PIN_SET # define AUDIO2_TIMSKx TIMSK1 # define AUDIO2_TCCRxA TCCR1A @@ -92,21 +99,21 @@ extern float note_timbre; # define AUDIO2_CSx1 CS11 # define AUDIO2_CSx2 CS12 -# if defined(B5_AUDIO) +# if defined(AUDIO_PIN_ALT_B5) # define AUDIO2_COMxy0 COM1A0 # define AUDIO2_COMxy1 COM1A1 # define AUDIO2_OCIExy OCIE1A # define AUDIO2_OCRxy OCR1A # define AUDIO2_PIN B5 # define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPA_vect -# elif defined(B6_AUDIO) +# elif defined(AUDIO_PIN_ALT_B6) # define AUDIO2_COMxy0 COM1B0 # define AUDIO2_COMxy1 COM1B1 # define AUDIO2_OCIExy OCIE1B # define AUDIO2_OCRxy OCR1B # define AUDIO2_PIN B6 # define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPB_vect -# elif defined(B7_AUDIO) +# elif defined(AUDIO_PIN_ALT_B7) # define AUDIO2_COMxy0 COM1C0 # define AUDIO2_COMxy1 COM1C1 # define AUDIO2_OCIExy OCIE1C @@ -116,10 +123,6 @@ extern float note_timbre; # endif #endif -// C6 seems to be the assumed default by many existing keyboard - but sill warn the user -#if !defined(AUDIO1_PIN_SET) && !defined(AUDIO2_PIN_SET) -# pragma message "audio feature enabled, but no pin selected - see docs/feature_audio for defines to set" -#endif // ----------------------------------------------------------------------------- #ifdef AUDIO1_PIN_SET diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index a11f856fe44f..db365e1f728f 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -155,13 +155,14 @@ static const DACConfig dac_conf = {.init = DAC_SAMPLE_MAX, .datamode = DAC_DHRM_ */ static const DACConversionGroup dac_conv_cfg = {.num_channels = 1U, .end_cb = dac_end, .error_cb = dac_error, .trigger = DAC_TRG(0b000)}; -void audio_initialize_hardware(void) { -#if defined(A4_AUDIO) + +void audio_initialize_hardware() { +#if defined(AUDIO_PIN_A4) palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); dacStart(&DACD1, &dac_conf); dacStartConversion(&DACD1, &dac_conv_cfg, dac_buffer_empty, DAC_BUFFER_SIZE); #endif -#if defined(A5_AUDIO) +#if defined(AUDIO_PIN_A5) palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); dacStart(&DACD2, &dac_conf); dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, DAC_BUFFER_SIZE); @@ -176,10 +177,10 @@ void audio_initialize_hardware(void) { * this is done here, reaching directly into the stm32 registers since chibios has not implemented BOFF handling yet * (see: chibios/os/hal/ports/STM32/todo.txt '- BOFF handling in DACv1.' */ -#if defined(A4_AUDIO) +#if defined(AUDIO_PIN_A4) DACD1.params->dac->CR &= ~DAC_CR_BOFF1; #endif -#if defined(A5_AUDIO) +#if defined(AUDIO_PIN_A5) DACD2.params->dac->CR &= ~DAC_CR_BOFF2; #endif diff --git a/quantum/audio/audio_chibios_dac.h b/quantum/audio/audio_chibios_dac.h index 2da103db66c7..1caa09b4828f 100644 --- a/quantum/audio/audio_chibios_dac.h +++ b/quantum/audio/audio_chibios_dac.h @@ -104,10 +104,10 @@ /** * choose pins for the speaker */ -#if !defined(A4_AUDIO) && !defined(A5_AUDIO) -# pragma message "Audio feature enabled, but not pin selected - see docs/feature_audio under the ARM DAC settings. Falling back to A5_AUDIO" -# define A5_AUDIO -//TODO: go through a breaking change, and add A5_AUDIO to all keyboards currently using AUDIO on STM32 based boards +#if !defined(AUDIO_PIN_A4) && !defined(AUDIO_PIN_A5) +# pragma message "Audio feature enabled, but no pin selected - see docs/feature_audio under the ARM DAC settings for available options. Falling back to A5" +# define AUDIO_PIN_A5 +//TODO: go through a breaking change, and add AUDIO_PIN=A5 to all keyboards currently using AUDIO on STM32 based boards #endif /** From 768f540476ffd3e80269182e11b553cbbdac7ba2 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 26 Mar 2020 16:05:12 +0100 Subject: [PATCH 036/153] audio-refactoring: switch backlight_avr.c to the new AUDIO_PIN defines --- quantum/backlight/backlight_avr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quantum/backlight/backlight_avr.c b/quantum/backlight/backlight_avr.c index 2ecdd4f2c428..18fb8cf43808 100644 --- a/quantum/backlight/backlight_avr.c +++ b/quantum/backlight/backlight_avr.c @@ -126,7 +126,7 @@ # define COMxx1 COM1B1 # define OCRxx OCR1B # endif -#elif !defined(B5_AUDIO) && !defined(B6_AUDIO) && !defined(B7_AUDIO) +#elif !defined(AUDIO_PIN_ALT_B5) && !defined(AUDIO_PIN_ALT_B6) && !defined(AUDIO_PIN_ALT_B7) // Timer 1 is not in use by Audio feature, Backlight can use it # pragma message "Using hardware timer 1 with software PWM" # define HARDWARE_PWM @@ -145,7 +145,7 @@ # define OCIExA OCIE1A # define OCRxx OCR1A -#elif !defined(C6_AUDIO) && !defined(C5_AUDIO) && !defined(C4_AUDIO) +#elif !defined(AUDIO_PIN_C6) && !defined(AUDIO_PIN_C5) && !defined(AUDIO_PIN_C4) # pragma message "Using hardware timer 3 with software PWM" // Timer 3 is not in use by Audio feature, Backlight can use it # define HARDWARE_PWM From f1c8c644966b726d5a268bd230f01dc1ca4834ae Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 26 Mar 2020 05:34:21 +0100 Subject: [PATCH 037/153] audio-common: have advance_note return a boolean if the note changed, to the next one in the melody beeing played --- quantum/audio/audio.c | 11 ++++++++--- quantum/audio/audio.h | 2 +- quantum/audio/audio_chibios_pwm.c | 8 ++++---- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index ebd20b8ca48c..c3a4106a3dcd 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -401,8 +401,10 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { @param step: arbitrary step value, audio.c keeps track of for the audio-driver @param end: scaling factor multiplied to the note_length. has to match step so that audio.c can determine when a note has finished playing + @return: true if the melody advanced to its next note, which the driver might need to react to */ -void audio_advance_note(uint32_t step, float end) { +bool audio_advance_note(uint32_t step, float end) { + bool goto_next_note = false; if (playing_note) { //TODO? playing_note is stopped 'manually'... so no need/sense in 'advanceing' them? } @@ -410,7 +412,8 @@ void audio_advance_note(uint32_t step, float end) { if (playing_notes) { note_position += step; - if (note_position >= (note_length * end)) { + goto_next_note = note_position >= (note_length * end); + if (goto_next_note) { stop_note((*notes_pointer)[current_note][0]); current_note++; @@ -419,7 +422,7 @@ void audio_advance_note(uint32_t step, float end) { current_note = 0; } else { playing_notes = false; - return; + return goto_next_note; } } @@ -440,6 +443,8 @@ void audio_advance_note(uint32_t step, float end) { if (!playing_note && !playing_notes ) stop_all_notes(); //TODO: trigger a stop of the hardware or just a stop_note on the last frequency? + + return goto_next_note; } diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 715cb7252764..f63c607975e6 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -74,7 +74,7 @@ float audio_get_single_voice_frequency(uint8_t voice); void pwm_audio_timer_task(float *freq, float *freq_alt); -void audio_advance_note(uint32_t step, float end); +bool audio_advance_note(uint32_t step, float end); // Vibrato rate functions diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index 8806e4518dc4..e8a17af94d46 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -214,8 +214,8 @@ void audio_stop_hardware(void) { static void gpt_callback(GPTDriver *gptp) { float freq;// TODO: freq_alt - freq = audio_get_single_voice_frequency(1); // freq_alt would be voice=2 - - channel_1_set_frequency(freq); - audio_advance_note(1, 1); + if (audio_advance_note(1, 1)) { + freq = audio_get_single_voice_frequency(1); // freq_alt would be voice=2 + channel_1_set_frequency(freq); + } } From 5c41d516fcff064b3e79dd9bb81ef359b67ef296 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 26 Mar 2020 16:14:45 +0100 Subject: [PATCH 038/153] audio-chibios-pwm: fix issue with ~130ms silence between note/frequency changes while playing a SONG through trial,error and a scope/logic analyzer figured out Chibios-PWMDriver (at least in the current version) misbehaves if the initial period is set to zero (or one; two seems to work); when thats the case subsequent calls to 'pwmChhangePeriod' + pwmEnableChannel took ~135ms of silence, before the PWM continued with the new frequency... --- quantum/audio/audio_chibios_pwm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index e8a17af94d46..472f5f5f5290 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -74,8 +74,9 @@ static void pwm_audio_period_callback(PWMDriver *pwmp); static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp); #endif // AUDIO_DRIVER_PWM -static PWMConfig pwmCFG = {.frequency = 500000, /* PWM clock frequency */ - .period = 0, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ +static PWMConfig pwmCFG = {.frequency = 100000, /* PWM clock frequency */ + //CHIBIOS-BUG? can't set the initial period to <2, or the pwm (hard or software) takes ~130ms with .frequency=500000 for a pwmChangePeriod to take effect; with no ouput=silence in the meantime + .period = 2, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ #if defined(AUDIO_DRIVER_PWM_PIN_ALTERNATE) .callback = NULL, // no callback, the hardware directly toggles the pin #else // AUDIO_DRIVER_PWM @@ -159,7 +160,8 @@ static void pwm_audio_period_callback(PWMDriver *pwmp) { } static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { (void)pwmp; - palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer + if (channel_1_frequency > 0) + palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer } #endif // AUDIO_DRIVER_PWM From da47af6a9910490703fbf0855d717c05b27136a5 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 26 Mar 2020 16:39:24 +0100 Subject: [PATCH 039/153] audio-refactoring: get 'play_note' working again with a limited number of available voices (say AUDIO_VOICES_MAX=1) allow new frequencies to be played, by discarding the oldest one in the 'frequencies' queue --- quantum/audio/audio.c | 71 +++++++++++++++++++++++-------- quantum/audio/audio_chibios_dac.c | 3 ++ quantum/audio/audio_chibios_pwm.c | 11 ++++- 3 files changed, 66 insertions(+), 19 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index c3a4106a3dcd..162bb94199a6 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -167,8 +167,10 @@ void stop_note(float freq) { if (!audio_initialized) { audio_init(); } + bool found = false; for (int i = AUDIO_VOICES_MAX-1; i >= 0; i--) { - if (frequencies[i] == freq) { + found = (frequencies[i] == freq); + if (found) { frequencies[i] = 0; for (int j = i; (j < AUDIO_VOICES_MAX-1); j++) { frequencies[j] = frequencies[j + 1]; @@ -177,6 +179,9 @@ void stop_note(float freq) { break; } } + if (!found) + return; + voices--; if (voices < 0) voices = 0; if (voice_place >= voices) { @@ -192,23 +197,48 @@ void stop_note(float freq) { } } +//TODO: rename to play_frequency; since a "note" is the combination of freq+duration (?) void play_note(float freq, int vol) { //NOTE: vol is unused + if (!audio_config.enable) + return; + if (!audio_initialized) { audio_init(); } - if (voices < AUDIO_VOICES_MAX) { - playing_note = true; - - envelope_index = 0; + // roundrobin: shifting out old voices, keeping only uniquie voices + if (freq<=0) + return; + // if the new frequency is already amongst the active voices, shift it to the end + bool found = false; + for (int i = voices-1; i >= 0; i--) { + found = (frequencies[i] == freq); + if (found) { + for (int j = i; (j < voices-1); j++) { + frequencies[j] = frequencies[j + 1]; + frequencies[j + 1] = freq; + } + break; + } + } + if (found) // since this frequency played already, the hardware was already started + return; - //TODO: handle pause/rest; freq==0 but with a valid duration - if (freq > 0) { - frequencies[voices] = freq; - voices++; + // frequency/voice is actually new, so we queue it to the end + voices++; + if (voices > AUDIO_VOICES_MAX) { + voices = AUDIO_VOICES_MAX; + // shift out the oldest voice to make room + for (int i=0; i voices) return frequency; + if ((voice > voices) || (voice == 0)) return 0.0f; if (glissando) { if (frequency != 0 && frequency < frequencies[voices - voice] @@ -270,7 +303,7 @@ float audio_get_single_voice_frequency(uint8_t voice) { } } else { frequency = frequencies[voices - voice]; //TODO: why not frequencies[voice]? - // -> new voices are appended at the end, so the most recent/current is MAX-0 + // -> new voices are appended at the end, so the most recent/current is MAX-1 } #ifdef VIBRATO_ENABLE @@ -285,9 +318,11 @@ float audio_get_single_voice_frequency(uint8_t voice) { frequency = voice_envelope(frequency); + /*TODO: why the cutoff? if (frequency < 30.517578125) { frequency = 30.52; } + */ return frequency; } @@ -306,7 +341,8 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { if (polyphony_rate > 0) { if (voices > 1) { - voice_place %= voices; + voice_place %= voices; ///2020-03-26: hm, is the voice_place (plus the polythony_rate?) intended to be used to cycle through active voices, if the number of available hardware channels is insufficient? (like with avr/arm pwm?) + // if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { // voice_place = (voice_place + 1) % voices; // place = 0.0; @@ -405,9 +441,8 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { */ bool audio_advance_note(uint32_t step, float end) { bool goto_next_note = false; - if (playing_note) { - //TODO? playing_note is stopped 'manually'... so no need/sense in 'advanceing' them? - } + + //'playing_note' is stopped manually, so no need to keep track of it here if (playing_notes) { note_position += step; diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index db365e1f728f..8b2c8182ca16 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -66,6 +66,9 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { uint8_t working_voices = audio_get_number_of_active_voices(); if (working_voices > AUDIO_VOICES_MAX) working_voices = AUDIO_VOICES_MAX; + /* doing additive wave synthesis over all currently playing voices = adding up + * sine-wave-samples for each frequency, scaled by the number of active voices + */ if (working_voices > 0) { uint16_t value_avg = 0; for (uint8_t i = 0; i < working_voices; i++) { diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index 472f5f5f5290..b4091c139208 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -67,6 +67,7 @@ so adding to config.h: #define PWMD TO_CHIBIOS_PWMD_EVAL(AUDIO_PWM_PINALTERNATE_TIMER) extern int voices; +extern bool playing_note; extern bool playing_notes; #if defined(AUDIO_DRIVER_PWM) @@ -200,9 +201,17 @@ void audio_initialize_hardware(void) { } void audio_start_hardware(void) { + float freq;// TODO: freq_alt channel_1_stop(); channel_1_start(); - gptStartContinuous(&GPTD6, 64); + + if (playing_note) { + freq = audio_get_single_voice_frequency(1); + channel_1_set_frequency(freq); + } + if (playing_notes) { + gptStartContinuous(&GPTD6, 64); + } } void audio_stop_hardware(void) { From d0f6f509f5c57ddcfd88b20ac032d929430b2e73 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 26 Mar 2020 18:35:25 +0100 Subject: [PATCH 040/153] audio: set the fallback driver to DAC for chibios and PWM for all others (==avr at the moment) --- common_features.mk | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common_features.mk b/common_features.mk index 3644f3336ccf..2ffae5d81a52 100644 --- a/common_features.mk +++ b/common_features.mk @@ -44,8 +44,8 @@ endif AUDIO_ENABLE ?= no ifeq ($(strip $(AUDIO_ENABLE)), yes) - AUDIO_DRIVER ?= pwm ifeq ($(PLATFORM),CHIBIOS) + AUDIO_DRIVER ?= dac ## stm32f2 and above have a usable DAC unit, f1 do not ifeq ($(strip $(AUDIO_DRIVER)), dac) OPT_DEFS += -DAUDIO_DRIVER_DAC @@ -56,6 +56,9 @@ ifeq ($(strip $(AUDIO_ENABLE)), yes) else # fallback=pwm OPT_DEFS += -DAUDIO_DRIVER_PWM endif + else + # fallback for all other platforms is pwm + AUDIO_DRIVER ?= pwm endif ifdef AUDIO_PIN OPT_DEFS += -DAUDIO_PIN=$(AUDIO_PIN) -DAUDIO_PIN_$(AUDIO_PIN) From e33bb3ed530d92f5dd8acc40d9b834b09ce3a746 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 27 Mar 2020 14:45:01 +0100 Subject: [PATCH 041/153] audio-refactoring: moore documentation and some cleanup --- quantum/audio/audio.c | 103 +++++++++--------- quantum/audio/audio.h | 169 ++++++++++++++++++++++++------ quantum/audio/audio_avr_pwm.c | 6 +- quantum/audio/audio_chibios_pwm.c | 4 +- 4 files changed, 192 insertions(+), 90 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 162bb94199a6..5f9667a52544 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -1,4 +1,4 @@ -/* Copyright 2016-2019 Jack Humbert +/* Copyright 2016-2020 Jack Humbert * * 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 @@ -21,42 +21,45 @@ /* audio system: * * audio.[ch] takes care of all overall state, tracking the actively playing - * notes (as polyphonic voices); the notes a SONG consists of; + * notes/tones (as voices); the notes a SONG consists of; * ... * * audio_[avr|chibios]_[dac|pwm] take care of the lower hardware dependent parts, * specific to each platform and the used subsystem/driver to drive * the output pins/channels with the calculated frequencies for each - * + * avtive voice */ #ifndef AUDIO_VOICES_MAX # define AUDIO_VOICES_MAX 8 #endif -uint8_t voices = 0; // nuber of active polyphonic voices -float frequencies[AUDIO_VOICES_MAX] = {0.0}; // frequencies of each active voice - -int voice_place = 0; -float frequency = 0; // frequency of the current note (down-mixed from the polyphony?) -float frequency_alt = 0; // frequency for the second speaker +uint8_t voices = 0; // nuber of active/playing frequencies = voices +float frequencies[AUDIO_VOICES_MAX] = {0.0}; // frequencies of each active voice bool playing_notes = false; // playing a SONG? bool playing_note = false; // or multiple polyphonic -float note_frequency = 0; // Hz + +float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs +uint16_t notes_count; // length of the notes_pointer array +bool notes_repeat; // PLAY_SONG or PLAY_LOOP? float note_length = 0; // in 64 parts to a beat uint8_t note_tempo = TEMPO_DEFAULT; // beats-per-minute -float note_timbre = TIMBRE_DEFAULT; +uint16_t current_note = 0; // index into the array at notes_pointer +uint16_t next_note = 0; uint32_t note_position = 0; // where in time, during playback of the current_note -float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs -uint16_t notes_count; // length of the notes_pointer array -bool notes_repeat; // PLAY_SONG or PLAY_LOOP? + + +//TODO/REFACTORING: check below variables if/where they are still used +#ifdef AUDIO_ENABLE_POLYPHONY +int voice_place = 0; +#endif +float note_frequency = 0; // Hz +float note_timbre = TIMBRE_DEFAULT; bool note_resting = false; //?? current note is a pause? or is this supposed to indicate a 'tie'? -uint16_t current_note = 0; // index into the array at notes_pointer -uint16_t next_note = 0; -#ifdef VIBRATO_ENABLE +#ifdef AUDIO_ENABLE_VIBRATO float vibrato_counter = 0; float vibrato_strength = .5; float vibrato_rate = 0.125; @@ -154,8 +157,6 @@ void stop_all_notes() { playing_notes = false; playing_note = false; - frequency = 0; - frequency_alt = 0; for (uint8_t i = 0; i < AUDIO_VOICES_MAX; i++) { frequencies[i] = 0; @@ -184,14 +185,14 @@ void stop_note(float freq) { voices--; if (voices < 0) voices = 0; +#ifdef AUDIO_ENABLE_POLYPHONY if (voice_place >= voices) { voice_place = 0; } +#endif if (voices == 0) { audio_stop_hardware(); - frequency = 0; - frequency_alt = 0; playing_note = false; } } @@ -280,13 +281,17 @@ bool is_playing_notes(void) { return playing_notes; } uint8_t audio_get_number_of_active_voices(void) { return voices; } -float audio_get_frequency(uint8_t voice_index) { return frequencies[voice_index]; } +float audio_get_frequency(uint8_t index) { + if (index >= voices) + return 0.0f; + return frequencies[index]; +} /* out of a possibly polyphonic setup, retrieve the frequency for a single voice to calculate the pwm period and duty-cycle from, relative to the cpy-frequency */ -float audio_get_single_voice_frequency(uint8_t voice) { +float audio_get_voice(uint8_t voice) { float frequency = 0.0; if ((voice > voices) || (voice == 0)) return 0.0f; @@ -306,7 +311,7 @@ float audio_get_single_voice_frequency(uint8_t voice) { // -> new voices are appended at the end, so the most recent/current is MAX-1 } -#ifdef VIBRATO_ENABLE +#ifdef AUDIO_ENABLE_VIBRATO if (vibrato_strength > 0) { frequency = vibrato(frequency); } @@ -327,14 +332,20 @@ float audio_get_single_voice_frequency(uint8_t voice) { return frequency; } -// TODO: remove... AVR specific, and clusterfuck-ish +/* REMOVEME + the following code block is a leftover of the audio-refactoring, which deduplicated code among the different implementations at the time - boiled down to this function, which was to be called by an avr ISR to do single/dual channel pwm + + there are lots of avr hardware specifica in there, but also some features still that could/should? be refactored into the "new" audio system - like "software polyphonic" audio, which cycles through/time multiplexes the currently active voices, avoiding the hardware limit of one or two pwm outputs/speakers; which by themselve can only render one frequency at a time (unlike the arm-dac implementation, which can do wave-synthesis to combine multiple frequencies) + + most of the logic has been refactored and moved into the different parts of the current implementation though + void pwm_audio_timer_task(float *freq, float *freq_alt) { if (playing_note) { if (voices > 0) { #ifdef AUDIO1_PIN_SET //TODO: untangle avr specific defines // speaker for second/alternate voice is available - *freq_alt = audio_get_single_voice_frequency(2); + *freq_alt = audio_get_voice(2); #else *freq_alt = 0.0f; #endif @@ -349,7 +360,7 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { // } } -#ifdef VIBRATO_ENABLE +#ifdef AUDIO_ENABLE_VIBRATO if (vibrato_strength > 0) { *freq = vibrato(frequencies[voice_place]); } else { @@ -359,14 +370,14 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { *freq = frequencies[voice_place]; #endif } else { - *freq = audio_get_single_voice_frequency(1); + *freq = audio_get_voice(1); } } } if (playing_notes) { if (note_frequency > 0) { -#ifdef VIBRATO_ENABLE +#ifdef AUDIO_ENABLE_VIBRATO if (vibrato_strength > 0) { *freq = vibrato(note_frequency); } else { @@ -388,7 +399,7 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { end_of_note = (note_position >= (note_length * 8 - 1)); else end_of_note = (note_position >= (note_length * 8)); - +// hm... maybe the whole point of the note_resting related parts is to have a slight gap/pause between two consecutive musical_notes with the same frequency. so they can bei distinguished? if (end_of_note) { current_note++; if (current_note >= notes_count) { @@ -432,13 +443,9 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { } } } +*/ -/* called by the timer of the audio-driver, which ticks regularly while playing a song = play_notes - @param step: arbitrary step value, audio.c keeps track of for the audio-driver - @param end: scaling factor multiplied to the note_length. has to match step so that audio.c can determine when a note has finished playing - @return: true if the melody advanced to its next note, which the driver might need to react to - */ bool audio_advance_note(uint32_t step, float end) { bool goto_next_note = false; @@ -484,8 +491,7 @@ bool audio_advance_note(uint32_t step, float end) { // Vibrato functions - -#ifdef VIBRATO_ENABLE +#ifdef AUDIO_ENABLE_VIBRATO float mod(float a, int b) { float r = fmod(a, b); @@ -493,7 +499,7 @@ float mod(float a, int b) { } float vibrato(float average_freq) { -# ifdef VIBRATO_STRENGTH_ENABLE +# ifdef AUDIO_ENABLE_VIBRATO_STRENGTH float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); # else float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; @@ -503,34 +509,23 @@ float vibrato(float average_freq) { } void set_vibrato_rate(float rate) { vibrato_rate = rate; } - void increase_vibrato_rate(float change) { vibrato_rate *= change; } - void decrease_vibrato_rate(float change) { vibrato_rate /= change; } - -# ifdef VIBRATO_STRENGTH_ENABLE - +# ifdef AUDIO_ENABLE_VIBRATO_STRENGTH void set_vibrato_strength(float strength) { vibrato_strength = strength; } - void increase_vibrato_strength(float change) { vibrato_strength *= change; } - void decrease_vibrato_strength(float change) { vibrato_strength /= change; } - -# endif /* VIBRATO_STRENGTH_ENABLE */ - -#endif /* VIBRATO_ENABLE */ +# endif /* AUDIO_ENABLE_VIBRATO_STRENGTH */ +#endif /* AUDIO_ENABLE_VIBRATO */ // Polyphony functions - +#ifdef AUDIO_ENABLE_POLYPHONY void set_polyphony_rate(float rate) { polyphony_rate = rate; } - void enable_polyphony(void) { polyphony_rate = 5; } - void disable_polyphony(void) { polyphony_rate = 0; } - void increase_polyphony_rate(float change) { polyphony_rate *= change; } - void decrease_polyphony_rate(float change) { polyphony_rate /= change; } +#endif // Timbre function diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index f63c607975e6..6f60f68ac884 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -1,4 +1,4 @@ -/* Copyright 2016 Jack Humbert +/* Copyright 2016-2020 Jack Humbert * * 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 @@ -46,35 +46,95 @@ typedef union { }; } audio_config_t; -// implementation in the audio_avr/arm_* drivers -void audio_initialize_hardware(void); -void audio_start_hardware(void); -void audio_stop_hardware(void); +// ____ __ ___ +// / __ \__ __/ /_ / (_)____ +// / /_/ / / / / __ \/ / / ___/ +// / ____/ /_/ / /_/ / / / /__ +// /_/ \__,_/_.___/_/_/\___/ +// public interface +/** + * @brief one-time initialization called by quantum/quantum.c + * @details usually done lazy, when some notes are to be played + * + * @post audio system (and hardware) initialized and ready to play notes + */ void audio_init(void); void audio_startup(void); -) + +/** + * @brief en-/disable audio output, save this choice to the eeprom + */ void audio_toggle(void); +/** + * @brief ensable audio output, save this choice to the eeprom + */ void audio_on(void); +/** + * @brief dissable audio output, save this choice to the eeprom + */ void audio_off(void); +/** + * @brief query the if audio output is enabled + */ bool is_audio_on(void); +/** + * @bried start playback of a tone/frequency + * @details the 'freq' is appended to an internal 'frequencies' array as a new + * "voice" which is played by the hardware until a call to 'stop_note' + * with the same frequency. should the frequency already be active, its + * entry is pushed to the end of said internal array - so no duplicate + * entries are kept. + * 'hardware_start' is called upon the first note. + * @param[in] freq tone/frequenct to be played + * @param[in] vol volume NOTE: currently unused (not possible with PWM, DAC could use it though) + */ void play_note(float freq, int vol); +/** + * @brief stop a given tone/frequency + * @details removes the given frequency from the 'frequencies' array, stopping + * its playback, and the hardware in case this was the last/only frequency + * beeing played. + * @param[in] freq tone/frequenct to be stopped + */ void stop_note(float freq); +/** + * @brief play a melody + * @details starts playback of a melody passed in from a SONG definition - an + * array of {frequency, duration} float-tuples + * @param[in] np note-pointer to the SONG array + * @param[in] n_count number of MUSICAL_NOTES of the SONG + * @param[in] n_repeat false for onetime, true for looped playback + */ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat); +/** + * @brief stops all playback + * @details stops playback of both a meldoy as well as single voices, resetting + * the internal state + */ void stop_all_notes(void); - +/** + * @brief query if one/multiple voices are playing + */ bool is_playing_note(void); +/** + * @brief query if a melody/SONG is playing + */ bool is_playing_notes(void); -uint8_t audio_get_number_of_active_voices(void); -float audio_get_frequency(uint8_t voice_index); - -float audio_get_single_voice_frequency(uint8_t voice); - -void pwm_audio_timer_task(float *freq, float *freq_alt); - -bool audio_advance_note(uint32_t step, float end); +// These macros are used to allow play_notes to play an array of indeterminate +// length. This works around the limitation of C's sizeof operation on pointers. +// The global float array for the song must be used here. +#define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) +/** + * @brief convenience macro, to play a melody/SONG once + */ +#define PLAY_SONG(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), false) +/** + * @brief convenience macro, to play a melody/SONG in a loop, until stopped by 'stop_all_notes' + */ +#define PLAY_LOOP(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), true) // Vibrato rate functions @@ -84,29 +144,25 @@ bool audio_advance_note(uint32_t step, float end); // Enable vibrato strength/amplitude - slows down ISR too much (TODO: from/for/on avr only?) // #define VIBRATO_STRENGTH_ENABLE -#ifdef VIBRATO_ENABLE - +#ifdef AUDIO_ENABLE_VIBRATO void set_vibrato_rate(float rate); void increase_vibrato_rate(float change); void decrease_vibrato_rate(float change); - -# ifdef VIBRATO_STRENGTH_ENABLE - +# ifdef AUDIO_ENABLE_VIBRATO_STRENGTH void set_vibrato_strength(float strength); void increase_vibrato_strength(float change); void decrease_vibrato_strength(float change); - # endif - #endif // Polyphony functions - +#ifdef AUDIO_ENABLE_POLYPHONY void set_polyphony_rate(float rate); void enable_polyphony(void); void disable_polyphony(void); void increase_polyphony_rate(float change); void decrease_polyphony_rate(float change); +#endif // Timbre function @@ -118,18 +174,69 @@ void set_tempo(uint8_t tempo); void increase_tempo(uint8_t tempo_change); void decrease_tempo(uint8_t tempo_change); -#define SCALE \ - (int8_t[]) { 0 + (12 * 0), 2 + (12 * 0), 4 + (12 * 0), 5 + (12 * 0), 7 + (12 * 0), 9 + (12 * 0), 11 + (12 * 0), 0 + (12 * 1), 2 + (12 * 1), 4 + (12 * 1), 5 + (12 * 1), 7 + (12 * 1), 9 + (12 * 1), 11 + (12 * 1), 0 + (12 * 2), 2 + (12 * 2), 4 + (12 * 2), 5 + (12 * 2), 7 + (12 * 2), 9 + (12 * 2), 11 + (12 * 2), 0 + (12 * 3), 2 + (12 * 3), 4 + (12 * 3), 5 + (12 * 3), 7 + (12 * 3), 9 + (12 * 3), 11 + (12 * 3), 0 + (12 * 4), 2 + (12 * 4), 4 + (12 * 4), 5 + (12 * 4), 7 + (12 * 4), 9 + (12 * 4), 11 + (12 * 4), } -// These macros are used to allow play_notes to play an array of indeterminate -// length. This works around the limitation of C's sizeof operation on pointers. -// The global float array for the song must be used here. -#define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) -#define PLAY_SONG(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), false) -#define PLAY_LOOP(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), true) +// __ __ __ +// / / / /___ __________/ / ______ __________ +// / /_/ / __ `/ ___/ __ / | /| / / __ `/ ___/ _ / +// / __ / /_/ / / / /_/ /| |/ |/ / /_/ / / / __/ +// /_/ /_/\__,_/_/ \__,_/ |__/|__/\__,_/_/ \___/ +// hardware interface + +// implementation in the audio_avr/arm_* drivers +void audio_initialize_hardware(void); +void audio_start_hardware(void); +void audio_stop_hardware(void); + +/** + * @brief get the number of currently actibe voices + * @return number, 0=none active + */ +uint8_t audio_get_number_of_active_voices(void); +/** + * @brief access to the raw internal state of the current voices + * @details each active voice was started as a tone/frequency, the internal + * audio state keeps track of. + * this function allows access to that array + * @note: new voices are queued to the end, so the array is populated from 0 to + * number_of_active_voices-1, with 0 beeing the "oldest" + * @return frequency in Hz + */ +float audio_get_frequency(uint8_t index); +/** + * @brief calculate and return the frequency for the requested voice + * @details + * @param[in] voice number ranging from 1 to number_of_active_voices, with 1 beeing the most recent voice, with each increment yielding the next older voice + * @return frequency in Hz + */ +float audio_get_voice(uint8_t voice); + +/** + * @brief update audio internal state: currently playing note, active + * voices/frequencies, ... + * @details This function is intended to be called by the audio-hardware + * specific implementation on a regular basis while a SONG is + * playing, to 'advance' the the position/time + * @param[in] step arbitrary step value, audio.c keeps track of for the + * audio-driver + * @param[in] end scaling factor multiplied to the note_length. has to match + * step so that audio.c can determine when a note has finished playing + * @return true if the melody advanced to its next note, which the driver might + * need/choose to react to + */ +bool audio_advance_note(uint32_t step, float end); +// __ +// / / ___ ____ _____ ________ __ +// / / / _ \/ __ `/ __ `/ ___/ / / / +// / /___/ __/ /_/ / /_/ / /__/ /_/ / +// /_____/\___/\__, /\__,_/\___/\__, / +// /____/ /____/ +// legacy and backwarts compatibility stuff +#define PLAY_NOTE_ARRAY(note_array, note_repeat, deprecated_arg) \ + play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat)); \ + _Pragma("message \"'PLAY_NOTE_ARRAY' macro is deprecated\"") // LEGACY defines - TODO: remove and replace these in all keyboards using them #ifdef A4_AUDIO diff --git a/quantum/audio/audio_avr_pwm.c b/quantum/audio/audio_avr_pwm.c index 70f233788053..0592d4084161 100644 --- a/quantum/audio/audio_avr_pwm.c +++ b/quantum/audio/audio_avr_pwm.c @@ -261,7 +261,7 @@ ISR(AUDIO1_TIMERx_COMPy_vect) { if (playing_notes) channel_1_set_frequency( - audio_get_single_voice_frequency(1) + audio_get_voice(1) ); else channel_1_stop(); @@ -270,7 +270,7 @@ ISR(AUDIO1_TIMERx_COMPy_vect) { # ifdef AUDIO2_PIN_SET if (playing_notes) channel_2_set_frequency( - audio_get_single_voice_frequency(2) + audio_get_voice(2) ); else channel_2_stop(); @@ -285,7 +285,7 @@ ISR(AUDIO2_TIMERx_COMPy_vect) { if (playing_notes) channel_2_set_frequency( - audio_get_single_voice_frequency(1) + audio_get_voice(1) ); else channel_2_stop(); diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index b4091c139208..5a0422966671 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -206,7 +206,7 @@ void audio_start_hardware(void) { channel_1_start(); if (playing_note) { - freq = audio_get_single_voice_frequency(1); + freq = audio_get_voice(1); channel_1_set_frequency(freq); } if (playing_notes) { @@ -226,7 +226,7 @@ static void gpt_callback(GPTDriver *gptp) { float freq;// TODO: freq_alt if (audio_advance_note(1, 1)) { - freq = audio_get_single_voice_frequency(1); // freq_alt would be voice=2 + freq = audio_get_voice(1); // freq_alt would be voice=2 channel_1_set_frequency(freq); } } From f37394fbb3ad5f2ccced49abcbcb14b03d574525 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 27 Mar 2020 16:10:20 +0100 Subject: [PATCH 042/153] audio-avr-pwm: no fallback on unset AUDIO_PIN this seems to be the expected behaviour by some keyboards (looking at ckeys/handwire_101:default) which otherwise fail to build because the firmware-image ends up beeing too large for the atmega... so we fail silently instead to keep travis happy --- quantum/audio/audio_avr_pwm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/quantum/audio/audio_avr_pwm.c b/quantum/audio/audio_avr_pwm.c index 0592d4084161..e9b51ff3f10d 100644 --- a/quantum/audio/audio_avr_pwm.c +++ b/quantum/audio/audio_avr_pwm.c @@ -41,8 +41,7 @@ extern float note_timbre; // C6 seems to be the assumed default by many existing keyboard - but sill warn the user #if !defined(AUDIO1_PIN_SET) && !defined(AUDIO2_PIN_SET) -# pragma message "Audio feature enabled, but no pin selected - see docs/feature_audio under the AVR settings for available options. Falling back to C6" -# define AUDIO_PIN_C6 +# pragma message "Audio feature enabled, but no pin selected - see docs/feature_audio under the AVR settings for available options. Don't expect to hear anything... :-)" //TODO: make this an error - go through the breaking-change-process and change all keyboards to the new define #endif From f6cbbbf43570c0056794fce7a92f63f2fb1fae11 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 27 Mar 2020 19:09:33 +0100 Subject: [PATCH 043/153] audio-refactoring: untangling terminology: voice->tone the code actually was working on tones (combination of pitch/frequency, duration, timbre, intensity/volume) and not voices (characteristic sound of an instrument; think piano vs guitar, which can be played together, each having its own "track" = voice on a music sheet) --- .../planck/keymaps/synth_wavetable/keymap.c | 20 +-- quantum/audio/audio.c | 121 +++++++++--------- quantum/audio/audio.h | 64 +++++---- quantum/audio/audio_avr_pwm.c | 9 +- quantum/audio/audio_avr_pwm.h | 2 +- quantum/audio/audio_chibios_dac.c | 24 ++-- quantum/audio/audio_chibios_dac.h | 26 ++-- quantum/audio/audio_chibios_pwm.c | 6 +- quantum/audio/audio_chibios_pwm.h | 5 +- 9 files changed, 143 insertions(+), 134 deletions(-) diff --git a/keyboards/planck/keymaps/synth_wavetable/keymap.c b/keyboards/planck/keymaps/synth_wavetable/keymap.c index 6684f02c6595..2bd200cfefc2 100644 --- a/keyboards/planck/keymaps/synth_wavetable/keymap.c +++ b/keyboards/planck/keymaps/synth_wavetable/keymap.c @@ -272,13 +272,13 @@ uint8_t dac_morph = 0; uint16_t dac_value_generate(void) { uint16_t value = DAC_OFF_VALUE; - uint8_t working_voices = audio_get_number_of_active_voices(); - if (working_voices > AUDIO_VOICES_MAX) - working_voices = AUDIO_VOICES_MAX; + uint8_t active_tones = audio_get_number_of_active_tones(); + if (active_tones > AUDIO_MAX_SIMULTANEOUS_TONES) + active_tones = AUDIO_MAX_SIMULTANEOUS_TONES; - if (working_voices > 0) { + if (active_tones > 0) { uint16_t value_avg = 0; - for (uint8_t i = 0; i < working_voices; i++) { + for (uint8_t i = 0; i < active_tones; i++) { dac_if[i] = dac_if[i] + ((audio_get_frequency(i) * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE) * 2/3; // necessary to adjust for the gpt-timer frequency (three times the sample rate) and the dac-conversion beeing called twice per sample @@ -291,12 +291,12 @@ uint16_t dac_value_generate(void) { // #define DAC_MORPH_SPEED_COMPUTED (DAC_SAMPLE_RATE / DAC_WAVETABLE_CUSTOM_LENGTH * (1000 / DAC_MORPH_SPEED)) uint16_t dac_i = (uint16_t)dac_if[i]; - // value_avg += dac_buffer_custom[dac_morph_flipped][dac_i] / working_voices / 2 * ((dac_morph >= 63) ? 6400 - dac_morph_counter : dac_morph_counter) / 6400; - // value_avg += dac_buffer_custom[dac_morph_flipped + 1][dac_i] / working_voices / 2 * ((dac_morph >= 63) ? dac_morph_counter : 6400 - dac_morph_counter) / 6400; + // value_avg += dac_buffer_custom[dac_morph_flipped][dac_i] / active_tones / 2 * ((dac_morph >= 63) ? 6400 - dac_morph_counter : dac_morph_counter) / 6400; + // value_avg += dac_buffer_custom[dac_morph_flipped + 1][dac_i] / active_tones / 2 * ((dac_morph >= 63) ? dac_morph_counter : 6400 - dac_morph_counter) / 6400; - // value_avg += dac_wavetable_custom[dac_morph][dac_i] / working_voices / 2 * (DAC_MORPH_SPEED_COMPUTED - dac_morph_counter) / DAC_MORPH_SPEED_COMPUTED; - // value_avg += dac_wavetable_custom[dac_morph + 1][dac_i] / working_voices / 2 * dac_morph_counter / DAC_MORPH_SPEED_COMPUTED; - value_avg += dac_wavetable_custom[dac_morph][dac_i] / working_voices; + // value_avg += dac_wavetable_custom[dac_morph][dac_i] / active_tones / 2 * (DAC_MORPH_SPEED_COMPUTED - dac_morph_counter) / DAC_MORPH_SPEED_COMPUTED; + // value_avg += dac_wavetable_custom[dac_morph + 1][dac_i] / active_tones / 2 * dac_morph_counter / DAC_MORPH_SPEED_COMPUTED; + value_avg += dac_wavetable_custom[dac_morph][dac_i] / active_tones; } value = value_avg; diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 5f9667a52544..b2d65ce8ee99 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -21,23 +21,24 @@ /* audio system: * * audio.[ch] takes care of all overall state, tracking the actively playing - * notes/tones (as voices); the notes a SONG consists of; + * notes/tones; the notes a SONG consists of; * ... * * audio_[avr|chibios]_[dac|pwm] take care of the lower hardware dependent parts, * specific to each platform and the used subsystem/driver to drive * the output pins/channels with the calculated frequencies for each - * avtive voice + * avtive tone */ -#ifndef AUDIO_VOICES_MAX -# define AUDIO_VOICES_MAX 8 +#ifndef AUDIO_MAX_SIMULTANEOUS_TONES +# define AUDIO_MAX_SIMULTANEOUS_TONES 8 #endif -uint8_t voices = 0; // nuber of active/playing frequencies = voices -float frequencies[AUDIO_VOICES_MAX] = {0.0}; // frequencies of each active voice +uint8_t active_tones = 0; // nuber of active/playing tones/frequencies +float frequencies[AUDIO_MAX_SIMULTANEOUS_TONES] = {0.0}; // frequencies of each active tone +//TODO: array of musical_tone_t bool playing_notes = false; // playing a SONG? -bool playing_note = false; // or multiple polyphonic +bool playing_note = false; // or (possibly multiple simultanious) tones float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs uint16_t notes_count; // length of the notes_pointer array @@ -51,7 +52,8 @@ uint32_t note_position = 0; // where in time, during playback of the current_no //TODO/REFACTORING: check below variables if/where they are still used #ifdef AUDIO_ENABLE_POLYPHONY -int voice_place = 0; +int tone_place = 0; +float polyphony_rate = 0; #endif float note_frequency = 0; // Hz float note_timbre = TIMBRE_DEFAULT; @@ -67,7 +69,6 @@ float vibrato_rate = 0.125; uint16_t envelope_index = 0; bool glissando = true; -float polyphony_rate = 0; #ifndef STARTUP_SONG @@ -151,14 +152,14 @@ void stop_all_notes() { if (!audio_initialized) { audio_init(); } - voices = 0; + active_tones = 0; audio_stop_hardware(); playing_notes = false; playing_note = false; - for (uint8_t i = 0; i < AUDIO_VOICES_MAX; i++) { + for (uint8_t i = 0; i < AUDIO_MAX_SIMULTANEOUS_TONES; i++) { frequencies[i] = 0; } } @@ -169,11 +170,11 @@ void stop_note(float freq) { audio_init(); } bool found = false; - for (int i = AUDIO_VOICES_MAX-1; i >= 0; i--) { + for (int i = AUDIO_MAX_SIMULTANEOUS_TONES-1; i >= 0; i--) { found = (frequencies[i] == freq); if (found) { frequencies[i] = 0; - for (int j = i; (j < AUDIO_VOICES_MAX-1); j++) { + for (int j = i; (j < AUDIO_MAX_SIMULTANEOUS_TONES-1); j++) { frequencies[j] = frequencies[j + 1]; frequencies[j + 1] = 0; } @@ -183,14 +184,14 @@ void stop_note(float freq) { if (!found) return; - voices--; - if (voices < 0) voices = 0; + active_tones--; + if (active_tones < 0) active_tones = 0; #ifdef AUDIO_ENABLE_POLYPHONY - if (voice_place >= voices) { - voice_place = 0; + if (tone_place >= active_tones) { + tone_place = 0; } #endif - if (voices == 0) { + if (active_tones == 0) { audio_stop_hardware(); playing_note = false; @@ -198,6 +199,7 @@ void stop_note(float freq) { } } +//A musical tone is characterized by its duration, pitch, intensity (or loudness), and timbre (or quality) //TODO: rename to play_frequency; since a "note" is the combination of freq+duration (?) void play_note(float freq, int vol) { //NOTE: vol is unused if (!audio_config.enable) @@ -207,15 +209,15 @@ void play_note(float freq, int vol) { //NOTE: vol is unused audio_init(); } - // roundrobin: shifting out old voices, keeping only uniquie voices + // roundrobin: shifting out old tones, keeping only uniquie ones if (freq<=0) return; - // if the new frequency is already amongst the active voices, shift it to the end + // if the new frequency is already amongst the active tones, shift it to the end bool found = false; - for (int i = voices-1; i >= 0; i--) { + for (int i = active_tones-1; i >= 0; i--) { found = (frequencies[i] == freq); if (found) { - for (int j = i; (j < voices-1); j++) { + for (int j = i; (j < active_tones-1); j++) { frequencies[j] = frequencies[j + 1]; frequencies[j + 1] = freq; } @@ -225,25 +227,25 @@ void play_note(float freq, int vol) { //NOTE: vol is unused if (found) // since this frequency played already, the hardware was already started return; - // frequency/voice is actually new, so we queue it to the end - voices++; - if (voices > AUDIO_VOICES_MAX) { - voices = AUDIO_VOICES_MAX; - // shift out the oldest voice to make room - for (int i=0; i AUDIO_MAX_SIMULTANEOUS_TONES) { + active_tones = AUDIO_MAX_SIMULTANEOUS_TONES; + // shift out the oldest tone to make room + for (int i=0; i= voices) +float audio_get_frequency(uint8_t tone_index) { + if ((tone_index >= active_tones) return 0.0f; - return frequencies[index]; + return frequencies[active_tones-tone_index-1]; } -/* out of a possibly polyphonic setup, retrieve the frequency for a single voice - to calculate the pwm period and duty-cycle from, relative to the cpy-frequency - */ -float audio_get_voice(uint8_t voice) { +float audio_get_processed_frequency(uint8_t tone_index) { float frequency = 0.0; - if ((voice > voices) || (voice == 0)) return 0.0f; + if (tone_index >= active_tones) + return 0.0f; + uint8_t index = active_tones - tone_index - 1; + // new tones are appended at the end, so the most recent/current is MAX-1 - if (glissando) { - if (frequency != 0 && frequency < frequencies[voices - voice] - && frequency < frequencies[voices - voice] * pow(2, -440 / frequencies[voices - voice] / 12 / 2)) { + if (glissando) { // see voices.c + if (frequency != 0 && frequency < frequencies[index] + && frequency < frequencies[index] * pow(2, -440 / frequencies[index] / 12 / 2)) { frequency = frequency * pow(2, 440 / frequency / 12 / 2); - } else if (frequency != 0 && frequency > frequencies[voices - voice] - && frequency > frequencies[voices - voice] * pow(2, 440 / frequencies[voices - voice] / 12 / 2)) { + } else if (frequency != 0 && frequency > frequencies[index] + && frequency > frequencies[index] * pow(2, 440 / frequencies[index] / 12 / 2)) { frequency = frequency * pow(2, -440 / frequency / 12 / 2); } else { - frequency = frequencies[voices - voice]; + frequency = frequencies[index]; } } else { - frequency = frequencies[voices - voice]; //TODO: why not frequencies[voice]? - // -> new voices are appended at the end, so the most recent/current is MAX-1 + frequency = frequencies[index]; } #ifdef AUDIO_ENABLE_VIBRATO @@ -335,42 +336,42 @@ float audio_get_voice(uint8_t voice) { /* REMOVEME the following code block is a leftover of the audio-refactoring, which deduplicated code among the different implementations at the time - boiled down to this function, which was to be called by an avr ISR to do single/dual channel pwm - there are lots of avr hardware specifica in there, but also some features still that could/should? be refactored into the "new" audio system - like "software polyphonic" audio, which cycles through/time multiplexes the currently active voices, avoiding the hardware limit of one or two pwm outputs/speakers; which by themselve can only render one frequency at a time (unlike the arm-dac implementation, which can do wave-synthesis to combine multiple frequencies) + there are lots of avr hardware specifica in there, but also some features still that could/should? be refactored into the "new" audio system - like "software polyphonic" audio, which cycles through/time multiplexes the currently active tones, avoiding the hardware limit of one or two pwm outputs/speakers; which by themselve can only render one frequency at a time (unlike the arm-dac implementation, which can do wave-synthesis to combine multiple frequencies) most of the logic has been refactored and moved into the different parts of the current implementation though void pwm_audio_timer_task(float *freq, float *freq_alt) { if (playing_note) { - if (voices > 0) { + if (active_tones > 0) { #ifdef AUDIO1_PIN_SET //TODO: untangle avr specific defines - // speaker for second/alternate voice is available - *freq_alt = audio_get_voice(2); + // speaker for second/alternate tone is available + *freq_alt = audio_get_processed_frequency(2); #else *freq_alt = 0.0f; #endif if (polyphony_rate > 0) { - if (voices > 1) { - voice_place %= voices; ///2020-03-26: hm, is the voice_place (plus the polythony_rate?) intended to be used to cycle through active voices, if the number of available hardware channels is insufficient? (like with avr/arm pwm?) + if (active_tones > 1) { + tone_place %= active_tones; ///2020-03-26: hm, is the tone_place (plus the polythony_rate?) intended to be used to cycle through active tones, if the number of available hardware channels is insufficient? (like with avr/arm pwm?) - // if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { - // voice_place = (voice_place + 1) % voices; + // if (place++ > (frequencies[tone_place] / polyphony_rate / CPU_PRESCALER)) { + // tone_place = (tone_place + 1) % active_tones; // place = 0.0; // } } #ifdef AUDIO_ENABLE_VIBRATO if (vibrato_strength > 0) { - *freq = vibrato(frequencies[voice_place]); + *freq = vibrato(frequencies[tone_place]); } else { - *freq = frequencies[voice_place]; + *freq = frequencies[tone_place]; } #else - *freq = frequencies[voice_place]; + *freq = frequencies[tone_place]; #endif } else { - *freq = audio_get_voice(1); + *freq = audio_get_processed_frequency(1); } } } diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 6f60f68ac884..23a492b6e4b4 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -81,16 +81,20 @@ bool is_audio_on(void); /** * @bried start playback of a tone/frequency - * @details the 'freq' is appended to an internal 'frequencies' array as a new - * "voice" which is played by the hardware until a call to 'stop_note' - * with the same frequency. should the frequency already be active, its - * entry is pushed to the end of said internal array - so no duplicate + * @details the 'freq' is appended to an internal array of active tones, as a + * new tone with indefinite duration, default timbre and the given + * intensity/volume; this tone is played by the hardware until a call + * to 'stop_note' + * should a tone with that frequency already be active, its entry + * is pushed to the end of said internal array - so no duplicate * entries are kept. * 'hardware_start' is called upon the first note. - * @param[in] freq tone/frequenct to be played - * @param[in] vol volume NOTE: currently unused (not possible with PWM, DAC could use it though) + * @param[in] frequency frequency of the tone be played + * @param[in] intensity volume NOTE: currently unused (not possible with PWM, DAC could use it though) */ -void play_note(float freq, int vol); +void play_note(float frequency, int intensity); /// grm... should be pitch+duration only... +//TODO: void play_frequency? +//void play_tone? /** * @brief stop a given tone/frequency * @details removes the given frequency from the 'frequencies' array, stopping @@ -110,18 +114,18 @@ void stop_note(float freq); void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat); /** * @brief stops all playback - * @details stops playback of both a meldoy as well as single voices, resetting + * @details stops playback of both a meldoy as well as single tones, resetting * the internal state */ -void stop_all_notes(void); +void stop_all_notes(void); //TODO: stop_all /** - * @brief query if one/multiple voices are playing + * @brief query if one/multiple tones are playing */ -bool is_playing_note(void); +bool is_playing_note(void); // is_playing_tones? /** * @brief query if a melody/SONG is playing */ -bool is_playing_notes(void); +bool is_playing_notes(void); // is playing_melody? or _song? // These macros are used to allow play_notes to play an array of indeterminate // length. This works around the limitation of C's sizeof operation on pointers. @@ -188,34 +192,38 @@ void audio_start_hardware(void); void audio_stop_hardware(void); /** - * @brief get the number of currently actibe voices + * @brief get the number of currently active tones * @return number, 0=none active */ -uint8_t audio_get_number_of_active_voices(void); +uint8_t audio_get_number_of_active_tones(void); /** - * @brief access to the raw internal state of the current voices - * @details each active voice was started as a tone/frequency, the internal - * audio state keeps track of. - * this function allows access to that array - * @note: new voices are queued to the end, so the array is populated from 0 to - * number_of_active_voices-1, with 0 beeing the "oldest" + * @brief access to the raw/unprocessed frequency for a specific tone + * @details each active tone has a frequency associated with it, which + * the internal state keeps track of, and is usually influenced + * by various effects + * @param[in] tone_index, ranging from 0 to number_of_active_tones-1, with the + * first beeing the most recent and each increment yielding the next + * older one * @return frequency in Hz */ -float audio_get_frequency(uint8_t index); +float audio_get_frequency(uint8_t tone_index); /** - * @brief calculate and return the frequency for the requested voice - * @details - * @param[in] voice number ranging from 1 to number_of_active_voices, with 1 beeing the most recent voice, with each increment yielding the next older voice + * @brief calculate and return the frequency for the requested tone + * @details effects like glissando, vibrato, ... are postprocessed onto the + * each active tones 'base'-frequency; this function returns the + * postprocessed result. + * @param[in] tone_index, ranging from 0 to number_of_active_tones-1, with the + * first beeing the most recent and each increment yielding the next + * older one * @return frequency in Hz */ -float audio_get_voice(uint8_t voice); +float audio_get_processed_frequency(uint8_t tone_index); /** - * @brief update audio internal state: currently playing note, active - * voices/frequencies, ... + * @brief update audio internal state: currently playing and active tones,... * @details This function is intended to be called by the audio-hardware * specific implementation on a regular basis while a SONG is - * playing, to 'advance' the the position/time + * playing, to 'advance' the position/time/internal state * @param[in] step arbitrary step value, audio.c keeps track of for the * audio-driver * @param[in] end scaling factor multiplied to the note_length. has to match diff --git a/quantum/audio/audio_avr_pwm.c b/quantum/audio/audio_avr_pwm.c index e9b51ff3f10d..7a233bd5d13c 100644 --- a/quantum/audio/audio_avr_pwm.c +++ b/quantum/audio/audio_avr_pwm.c @@ -244,7 +244,7 @@ void audio_start_hardware(void) { #endif #ifdef AUDIO2_PIN_SET # ifdef AUDIO1_PIN_SET - if (audio_get_number_of_active_voices() > 1) { + if (audio_get_number_of_active_tones() > 1) { channel_2_start(); } # else @@ -260,16 +260,15 @@ ISR(AUDIO1_TIMERx_COMPy_vect) { if (playing_notes) channel_1_set_frequency( - audio_get_voice(1) + audio_get_processed_frequency(0) ); else channel_1_stop(); -// do polyphonic, if a second speaker is available # ifdef AUDIO2_PIN_SET if (playing_notes) channel_2_set_frequency( - audio_get_voice(2) + audio_get_processed_frequency(1) ); else channel_2_stop(); @@ -284,7 +283,7 @@ ISR(AUDIO2_TIMERx_COMPy_vect) { if (playing_notes) channel_2_set_frequency( - audio_get_voice(1) + audio_get_processed_frequency(0) ); else channel_2_stop(); diff --git a/quantum/audio/audio_avr_pwm.h b/quantum/audio/audio_avr_pwm.h index c3edd42160d1..b4705d523bbc 100644 --- a/quantum/audio/audio_avr_pwm.h +++ b/quantum/audio/audio_avr_pwm.h @@ -15,4 +15,4 @@ */ #pragma once -#define AUDIO_VOICES_MAX 2 +#define AUDIO_MAX_SIMULTANEOUS_TONES 2 diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index 8b2c8182ca16..4f7d39b17dfb 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -54,7 +54,7 @@ static const dacsample_t dac_buffer_staircase[DAC_BUFFER_SIZE] = { static dacsample_t dac_buffer_empty[DAC_BUFFER_SIZE] = {DAC_OFF_VALUE}; -/* keep track of the sample position for for each voice/frequency */ +/* keep track of the sample position for for each frequency */ static float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; /** @@ -63,15 +63,15 @@ static float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; */ __attribute__((weak)) uint16_t dac_value_generate(void) { uint16_t value = DAC_OFF_VALUE; - uint8_t working_voices = audio_get_number_of_active_voices(); - if (working_voices > AUDIO_VOICES_MAX) working_voices = AUDIO_VOICES_MAX; + uint8_t active_tones = audio_get_number_of_active_tones(); + if (active_tones > AUDIO_MAX_SIMULTANEOUS_TONES) active_tones = AUDIO_MAX_SIMULTANEOUS_TONES; - /* doing additive wave synthesis over all currently playing voices = adding up - * sine-wave-samples for each frequency, scaled by the number of active voices + /* doing additive wave synthesis over all currently playing tones = adding up + * sine-wave-samples for each frequency, scaled by the number of active tones */ - if (working_voices > 0) { + if (active_tones > 0) { uint16_t value_avg = 0; - for (uint8_t i = 0; i < working_voices; i++) { + for (uint8_t i = 0; i < active_tones; i++) { dac_if[i] = dac_if[i] + ((audio_get_frequency(i) //TODO: replace by glissando+vibrator+.. variant * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE) @@ -85,15 +85,15 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { // Wavetable generation/lookup uint16_t dac_i = (uint16_t)dac_if[i]; // SINE - value_avg += dac_buffer_sine[dac_i] / working_voices;// / 3; + value_avg += dac_buffer_sine[dac_i] / active_tones;// / 3; // TRIANGLE -// value_avg += dac_buffer_triangle[dac_i] / working_voices / 3; +// value_avg += dac_buffer_triangle[dac_i] / active_tones / 3; // SQUARE -// value_avg += dac_buffer_square[dac_i] / working_voices / 3; +// value_avg += dac_buffer_square[dac_i] / active_tones / 3; //NOTE: combination of these three waveforms is more exemplary - and doesn't sound particularly good :-P // STAIRS - //value_avg = dac_buffer_staircase[dac_i] / working_voices; + //value_avg = dac_buffer_staircase[dac_i] / active_tones; } value = value_avg; } @@ -117,7 +117,7 @@ static void dac_end(DACDriver *dacp){ sample_p[s] = dac_value_generate(); } - // update audio internal state (note position, current_note, voices, ...) + // update audio internal state (note position, current_note, ...) audio_advance_note( DAC_BUFFER_SIZE/2, DAC_SAMPLE_RATE/ (64*2.0f/3) diff --git a/quantum/audio/audio_chibios_dac.h b/quantum/audio/audio_chibios_dac.h index 1caa09b4828f..62d0cefe156a 100644 --- a/quantum/audio/audio_chibios_dac.h +++ b/quantum/audio/audio_chibios_dac.h @@ -32,9 +32,9 @@ #endif /** - * These presets allow you to quickly switch between quality/voice settings for - * the DAC. The sample rate and number of voices roughly has an inverse - * relationship - slightly higher sample rates may be possible. + * These presets allow you to quickly switch between quality settings for + * the DAC. The sample rate and maximum number of simultaneous tones roughly + * has an inverse relationship - slightly higher sample rates may be possible. * * NOTE: a high samplerate results in a higher cpu-load, which might lead to * (audible) discontinuities and/or starve other processes of cpu-time @@ -42,22 +42,22 @@ */ #ifdef DAC_QUALITY_VERY_LOW # define DAC_SAMPLE_RATE 11025U -# define AUDIO_VOICES_MAX 8 +# define AUDIO_MAX_SIMULTANEOUS_TONES 8 #endif #ifdef DAC_QUALITY_LOW # define DAC_SAMPLE_RATE 22050U -# define AUDIO_VOICES_MAX 4 +# define AUDIO_MAX_SIMULTANEOUS_TONES 4 #endif #ifdef DAC_QUALITY_HIGH # define DAC_SAMPLE_RATE 44100U -# define AUDIO_VOICES_MAX 2 +# define AUDIO_MAX_SIMULTANEOUS_TONES 2 #endif #ifdef DAC_QUALITY_VERY_HIGH # define DAC_SAMPLE_RATE 88200U -# define AUDIO_VOICES_MAX 1 +# define AUDIO_MAX_SIMULTANEOUS_TONES 1 #endif #ifdef DAC_QUALITY_SANE_MINIMUM @@ -70,14 +70,14 @@ * which works out (but the 'scope shows some sampling artifacts with lower harmonics :-P) */ # define DAC_SAMPLE_RATE 16384U -# define AUDIO_VOICES_MAX 8 +# define AUDIO_MAX_SIMULTANEOUS_TONES 8 #endif /** * Effective bitrate of the DAC. 44.1khz is the standard for most audio - any * lower will sacrifice perceptible audio quality. Any higher will limit the - * number of simultaneous voices. In most situations, a tenth (1/10) of the + * number of simultaneous tones. In most situations, a tenth (1/10) of the * sample rate is where notes become unbearable. */ #ifndef DAC_SAMPLE_RATE @@ -85,12 +85,12 @@ #endif /** - * The number of voices (in polyphony) that are supported. If too high a value - * is used here, the keyboard will freeze and glitch-out when that many voices + * The number of tones that can be played simultaneously. If too high a value + * is used here, the keyboard will freeze and glitch-out when that many tones * are being played. */ -#ifndef AUDIO_VOICES_MAX -# define AUDIO_VOICES_MAX 2 +#ifndef AUDIO_MAX_SIMULTANEOUS_TONES +# define AUDIO_MAX_SIMULTANEOUS_TONES 2 #endif /** diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index 5a0422966671..8c9f2f89cc8c 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -66,7 +66,7 @@ so adding to config.h: #define TO_CHIBIOS_PWMD_EVAL(t) TO_CHIBIOS_PWMD_PASTE(t) #define PWMD TO_CHIBIOS_PWMD_EVAL(AUDIO_PWM_PINALTERNATE_TIMER) -extern int voices; +extern int active_tones; extern bool playing_note; extern bool playing_notes; @@ -206,7 +206,7 @@ void audio_start_hardware(void) { channel_1_start(); if (playing_note) { - freq = audio_get_voice(1); + freq = audio_get_processed_frequency(0); channel_1_set_frequency(freq); } if (playing_notes) { @@ -226,7 +226,7 @@ static void gpt_callback(GPTDriver *gptp) { float freq;// TODO: freq_alt if (audio_advance_note(1, 1)) { - freq = audio_get_voice(1); // freq_alt would be voice=2 + freq = audio_get_processed_frequency(0); // freq_alt would be index=1 channel_1_set_frequency(freq); } } diff --git a/quantum/audio/audio_chibios_pwm.h b/quantum/audio/audio_chibios_pwm.h index 9c2d0140807a..773c767c440b 100644 --- a/quantum/audio/audio_chibios_pwm.h +++ b/quantum/audio/audio_chibios_pwm.h @@ -15,8 +15,9 @@ */ #pragma once -// with one pwm channel only one voice is possible (TODO: unless we start cycling through all frequencies[]) -#define AUDIO_VOICES_MAX 1 +// with one pwm channel, only one tone can be played at a time +// TODO: unless we start doing time-multiplexing... +#define AUDIO_MAX_SIMULTANEOUS_TONES 1 #if !defined(AUDIO_PWM_PINALTERNATE_TIMER) From 7ec6cb26f4b35fe1c0bdbd5ce5b1caf35ca36dc7 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 27 Mar 2020 20:22:39 +0100 Subject: [PATCH 044/153] audio-pwm: allow freq=0 aka a pause/rest in a SONG continue processing, but do not enable pwm units, since freq=0 wouldn't produce any sound anyway (and lead to division by zero on that occasion) --- quantum/audio/audio.c | 8 +++++--- quantum/audio/audio_avr_pwm.c | 6 ++++++ quantum/audio/audio_chibios_pwm.c | 3 +++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index b2d65ce8ee99..41a868fe81a5 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -210,8 +210,6 @@ void play_note(float freq, int vol) { //NOTE: vol is unused } // roundrobin: shifting out old tones, keeping only uniquie ones - if (freq<=0) - return; // if the new frequency is already amongst the active tones, shift it to the end bool found = false; for (int i = active_tones-1; i >= 0; i--) { @@ -284,7 +282,7 @@ bool is_playing_notes(void) { return playing_notes; } uint8_t audio_get_number_of_active_tones(void) { return active_tones; } float audio_get_frequency(uint8_t tone_index) { - if ((tone_index >= active_tones) + if (tone_index >= active_tones) return 0.0f; return frequencies[active_tones-tone_index-1]; } @@ -295,9 +293,13 @@ float audio_get_processed_frequency(uint8_t tone_index) { if (tone_index >= active_tones) return 0.0f; + uint8_t index = active_tones - tone_index - 1; // new tones are appended at the end, so the most recent/current is MAX-1 + if (frequencies[index] <= 0.0f) + return 0.0f; + if (glissando) { // see voices.c if (frequency != 0 && frequency < frequencies[index] && frequency < frequencies[index] * pow(2, -440 / frequencies[index] / 12 / 2)) { diff --git a/quantum/audio/audio_avr_pwm.c b/quantum/audio/audio_avr_pwm.c index 7a233bd5d13c..6e0bf8e91496 100644 --- a/quantum/audio/audio_avr_pwm.c +++ b/quantum/audio/audio_avr_pwm.c @@ -133,6 +133,9 @@ void channel_1_set_frequency(float freq) { channel_1_frequency = freq; + if (freq == 0.0f) // a pause has freq=0, no need to start the PWM (also avoids division by zero) + return; + // set pwm period AUDIO1_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); // and duty cycle @@ -164,6 +167,9 @@ void channel_2_set_frequency(float freq) { channel_2_frequency = freq; + if (freq == 0.0f) // a pause has freq=0, no need to start the PWM (also avoids division by zero) + return; + AUDIO2_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); AUDIO2_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); } diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index 8c9f2f89cc8c..af54194c8a2f 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -124,6 +124,9 @@ void channel_1_set_frequency(float freq) { channel_1_frequency = freq; + if (freq <= 0.0) //a pause/rest has freq=0 + return; + pwmcnt_t period = (pwmCFG.frequency / freq); pwmChangePeriod(&PWMD, period); pwmEnableChannel( From d33db7c1c485123500dd089881edc2362e1bf1a5 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 28 Mar 2020 04:56:36 +0100 Subject: [PATCH 045/153] audio-refactoring: audio_advance_note -> audio_advance_state since it does not only affect 'one note', but the internally kept state as a whole --- quantum/audio/audio.c | 2 +- quantum/audio/audio.h | 10 +++++----- quantum/audio/audio_avr_pwm.c | 4 ++-- quantum/audio/audio_chibios_dac.c | 2 +- quantum/audio/audio_chibios_pwm.c | 5 ++--- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 41a868fe81a5..12e5a099a0ee 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -449,7 +449,7 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { */ -bool audio_advance_note(uint32_t step, float end) { +bool audio_advance_state(uint32_t step, float end) { bool goto_next_note = false; //'playing_note' is stopped manually, so no need to keep track of it here diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 23a492b6e4b4..d726d26c2274 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -55,9 +55,9 @@ typedef union { /** * @brief one-time initialization called by quantum/quantum.c - * @details usually done lazy, when some notes are to be played + * @details usually done lazy, when some tones are to be played * - * @post audio system (and hardware) initialized and ready to play notes + * @post audio system (and hardware) initialized and ready to play tones */ void audio_init(void); void audio_startup(void); @@ -227,11 +227,11 @@ float audio_get_processed_frequency(uint8_t tone_index); * @param[in] step arbitrary step value, audio.c keeps track of for the * audio-driver * @param[in] end scaling factor multiplied to the note_length. has to match - * step so that audio.c can determine when a note has finished playing - * @return true if the melody advanced to its next note, which the driver might + * step so that audio.c can determine when a tone has finished playing + * @return true if the melody advanced to its next tone, which the driver might * need/choose to react to */ -bool audio_advance_note(uint32_t step, float end); +bool audio_advance_state(uint32_t step, float end); // __ diff --git a/quantum/audio/audio_avr_pwm.c b/quantum/audio/audio_avr_pwm.c index 6e0bf8e91496..d03b02508a60 100644 --- a/quantum/audio/audio_avr_pwm.c +++ b/quantum/audio/audio_avr_pwm.c @@ -262,7 +262,7 @@ void audio_start_hardware(void) { #ifdef AUDIO1_PIN_SET ISR(AUDIO1_TIMERx_COMPy_vect) { - audio_advance_note(1,channel_1_frequency/CPU_PRESCALER/8); + audio_advance_state(1,channel_1_frequency/CPU_PRESCALER/8); if (playing_notes) channel_1_set_frequency( @@ -285,7 +285,7 @@ ISR(AUDIO1_TIMERx_COMPy_vect) { #if !defined(AUDIO1_PIN_SET) && defined(AUDIO2_PIN_SET) ISR(AUDIO2_TIMERx_COMPy_vect) { - audio_advance_note(1,channel_2_frequency/CPU_PRESCALER/8); + audio_advance_state(1,channel_2_frequency/CPU_PRESCALER/8); if (playing_notes) channel_2_set_frequency( diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index 4f7d39b17dfb..2d2dcd78488f 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -118,7 +118,7 @@ static void dac_end(DACDriver *dacp){ } // update audio internal state (note position, current_note, ...) - audio_advance_note( + audio_advance_state( DAC_BUFFER_SIZE/2, DAC_SAMPLE_RATE/ (64*2.0f/3) /* End of the note: 64 is the number of 'units' of a whole note, 3 comes diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index af54194c8a2f..7573ad030494 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -66,7 +66,6 @@ so adding to config.h: #define TO_CHIBIOS_PWMD_EVAL(t) TO_CHIBIOS_PWMD_PASTE(t) #define PWMD TO_CHIBIOS_PWMD_EVAL(AUDIO_PWM_PINALTERNATE_TIMER) -extern int active_tones; extern bool playing_note; extern bool playing_notes; @@ -177,7 +176,7 @@ GPTConfig gptCFG = { therefore: if the timer ticks away at .frequency = (60*64)Hz, and the .intervall counts from 64 downwards - all we need to do is increment the note_position on each callback, and have the note_lengt = duration*tempo compare - against that; hence: audio_advance_note(step=1, end=1) + against that; hence: audio_advance_state(step=1, end=1) */ .frequency = 60 * 64, .callback = gpt_callback, @@ -228,7 +227,7 @@ void audio_stop_hardware(void) { static void gpt_callback(GPTDriver *gptp) { float freq;// TODO: freq_alt - if (audio_advance_note(1, 1)) { + if (audio_advance_state(1, 1)) { freq = audio_get_processed_frequency(0); // freq_alt would be index=1 channel_1_set_frequency(freq); } From 34d3b220b5104d3a355ee62d8847b4a696660baf Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 28 Mar 2020 04:58:31 +0100 Subject: [PATCH 046/153] audio-refactoring: untangling terminology: polyphony the feature om the "inherited" avr code has little to do with polyphony (see wikipedia), but is more a time-multiplexing feature, to work around hardware limitations - like only having one pwm channel, that could on its own only reproduce one voice/instrument at a time --- quantum/audio/audio.c | 39 ++++++++++++++++++++++----------------- quantum/audio/audio.h | 19 ++++++++++++------- quantum/audio/voices.c | 14 ++------------ 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 12e5a099a0ee..39d237f9bcb4 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -51,15 +51,15 @@ uint32_t note_position = 0; // where in time, during playback of the current_no //TODO/REFACTORING: check below variables if/where they are still used -#ifdef AUDIO_ENABLE_POLYPHONY -int tone_place = 0; -float polyphony_rate = 0; -#endif float note_frequency = 0; // Hz float note_timbre = TIMBRE_DEFAULT; bool note_resting = false; //?? current note is a pause? or is this supposed to indicate a 'tie'? - +#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING +//TODO: if active, AUDIO_MAX_SIMULTANEOUS_TONES should be set to >>1 for the feature to make sense +int tone_place = 0; +float tone_multiplexing_rate = 0; +#endif #ifdef AUDIO_ENABLE_VIBRATO float vibrato_counter = 0; @@ -67,8 +67,9 @@ float vibrato_strength = .5; float vibrato_rate = 0.125; #endif +// used by voices.c uint16_t envelope_index = 0; -bool glissando = true; +bool glissando = false; #ifndef STARTUP_SONG @@ -186,7 +187,7 @@ void stop_note(float freq) { active_tones--; if (active_tones < 0) active_tones = 0; -#ifdef AUDIO_ENABLE_POLYPHONY +#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING if (tone_place >= active_tones) { tone_place = 0; } @@ -300,6 +301,7 @@ float audio_get_processed_frequency(uint8_t tone_index) { if (frequencies[index] <= 0.0f) return 0.0f; + //TODO make it work and test, currently probably non-functional because it needs some state to keep track of previous tones, the current tone position ...? if (glissando) { // see voices.c if (frequency != 0 && frequency < frequencies[index] && frequency < frequencies[index] * pow(2, -440 / frequencies[index] / 12 / 2)) { @@ -338,7 +340,10 @@ float audio_get_processed_frequency(uint8_t tone_index) { /* REMOVEME the following code block is a leftover of the audio-refactoring, which deduplicated code among the different implementations at the time - boiled down to this function, which was to be called by an avr ISR to do single/dual channel pwm - there are lots of avr hardware specifica in there, but also some features still that could/should? be refactored into the "new" audio system - like "software polyphonic" audio, which cycles through/time multiplexes the currently active tones, avoiding the hardware limit of one or two pwm outputs/speakers; which by themselve can only render one frequency at a time (unlike the arm-dac implementation, which can do wave-synthesis to combine multiple frequencies) + there are lots of avr hardware specifica in there, but also some features still that could/should? be refactored into the "new" audio system - like + - "software polyphonic" audio, which cycles through/time multiplexes the currently active tones, avoiding the hardware limit of one or two pwm outputs/speakers; which by themselve can only render one frequency at a time (unlike the arm-dac implementation, which can do wave-synthesis to combine multiple frequencies) + (according to wikipedia: polyphonic is actually something different: concurrent melodies/voices that play with/against each other + - "note_resting": which does a short gab between consecutive tones of the same frequency; to not slurr them together, like making to quarter-notes into one half-note most of the logic has been refactored and moved into the different parts of the current implementation though @@ -353,11 +358,11 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { *freq_alt = 0.0f; #endif - if (polyphony_rate > 0) { + if (tone_multiplexing_rate > 0) { if (active_tones > 1) { tone_place %= active_tones; ///2020-03-26: hm, is the tone_place (plus the polythony_rate?) intended to be used to cycle through active tones, if the number of available hardware channels is insufficient? (like with avr/arm pwm?) - // if (place++ > (frequencies[tone_place] / polyphony_rate / CPU_PRESCALER)) { + // if (place++ > (frequencies[tone_place] / tone_multiplexing_rate / CPU_PRESCALER)) { // tone_place = (tone_place + 1) % active_tones; // place = 0.0; // } @@ -521,13 +526,13 @@ void decrease_vibrato_strength(float change) { vibrato_strength /= change; } # endif /* AUDIO_ENABLE_VIBRATO_STRENGTH */ #endif /* AUDIO_ENABLE_VIBRATO */ -// Polyphony functions -#ifdef AUDIO_ENABLE_POLYPHONY -void set_polyphony_rate(float rate) { polyphony_rate = rate; } -void enable_polyphony(void) { polyphony_rate = 5; } -void disable_polyphony(void) { polyphony_rate = 0; } -void increase_polyphony_rate(float change) { polyphony_rate *= change; } -void decrease_polyphony_rate(float change) { polyphony_rate /= change; } +// Tone-multiplexing functions +#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING +void set_tone_multiplexing_rate(float rate) { tone_multiplexing_rate = rate; } +void enable_tone_multiplexing(void) { tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT; } +void disable_tone_multiplexing(void) { tone_multiplexing_rate = 0; } +void increase_tone_multiplexing_rate(float change) { tone_multiplexing_rate *= change; } +void decrease_tone_multiplexing_rate(float change) { tone_multiplexing_rate /= change; } #endif // Timbre function diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index d726d26c2274..8a2fd752c7fb 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -159,13 +159,18 @@ void decrease_vibrato_strength(float change); # endif #endif -// Polyphony functions -#ifdef AUDIO_ENABLE_POLYPHONY -void set_polyphony_rate(float rate); -void enable_polyphony(void); -void disable_polyphony(void); -void increase_polyphony_rate(float change); -void decrease_polyphony_rate(float change); +// Tone-Multiplexing functions +// this feature only makes sense for hardware setups which can't do proper +// audio-wave synthesis = have no DAC and need to use PWM for tone generation +#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING +# ifndef AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT +# define AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT 0 +# endif +void set_tone_multiplexing_rate(float rate); +void enable_tone_multiplexing(void); +void disable_tone_multiplexing(void); +void increase_tone_multiplexing_rate(float change); +void decrease_tone_multiplexing_rate(float change); #endif // Timbre function diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 1592618be43e..65194769e621 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -20,7 +20,6 @@ // these are imported from audio.c extern uint16_t envelope_index; extern float note_timbre; -extern float polyphony_rate; extern bool glissando; voice_type voice = default_voice; @@ -39,14 +38,12 @@ float voice_envelope(float frequency) { case default_voice: glissando = false; note_timbre = TIMBRE_50; - polyphony_rate = 0; break; #ifdef AUDIO_VOICES case something: glissando = false; - polyphony_rate = 0; switch (compensated_index) { case 0 ... 9: note_timbre = TIMBRE_12; @@ -68,7 +65,6 @@ float voice_envelope(float frequency) { case drums: glissando = false; - polyphony_rate = 0; // switch (compensated_index) { // case 0 ... 10: // note_timbre = 0.5; @@ -146,7 +142,6 @@ float voice_envelope(float frequency) { break; case butts_fader: glissando = true; - polyphony_rate = 0; switch (compensated_index) { case 0 ... 9: frequency = frequency / 4; @@ -169,7 +164,6 @@ float voice_envelope(float frequency) { break; // case octave_crunch: - // polyphony_rate = 0; // switch (compensated_index) { // case 0 ... 9: // case 20 ... 24: @@ -187,14 +181,13 @@ float voice_envelope(float frequency) { // default: // note_timbre = TIMBRE_12; - // break; + // break; // } // break; case duty_osc: // This slows the loop down a substantial amount, so higher notes may freeze glissando = true; - polyphony_rate = 0; switch (compensated_index) { default: # define OCS_SPEED 10 @@ -209,14 +202,12 @@ float voice_envelope(float frequency) { case duty_octave_down: glissando = true; - polyphony_rate = 0; note_timbre = (envelope_index % 2) * .125 + .375 * 2; if ((envelope_index % 4) == 0) note_timbre = 0.5; if ((envelope_index % 8) == 0) note_timbre = 0; break; case delayed_vibrato: glissando = true; - polyphony_rate = 0; note_timbre = TIMBRE_50; # define VOICE_VIBRATO_DELAY 150 # define VOICE_VIBRATO_SPEED 50 @@ -229,7 +220,6 @@ float voice_envelope(float frequency) { } break; // case delayed_vibrato_octave: - // polyphony_rate = 0; // if ((envelope_index % 2) == 1) { // note_timbre = 0.55; // } else { @@ -270,7 +260,7 @@ float voice_envelope(float frequency) { // note_timbre = 0.25; // break; -#endif +#endif // AUDIO_VOICES default: break; From ada0775ef84334a7ef8028cca04d95c4da3c1a0c Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 28 Mar 2020 05:02:18 +0100 Subject: [PATCH 047/153] audio-chibios-dac: add zero-crossing feature have tones only change/stop when the waveform approaches zero - to avoid audible clicks note that this also requires the samples to start at zero, since the internally kept index into the samples is reset to zero too --- quantum/audio/audio.h | 1 + quantum/audio/audio_chibios_dac.c | 78 +++++++++++++++++++++++-------- 2 files changed, 60 insertions(+), 19 deletions(-) diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 8a2fd752c7fb..2ff89cdd4c6c 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -198,6 +198,7 @@ void audio_stop_hardware(void); /** * @brief get the number of currently active tones + * @note guaranteed to be below AUDIO_MAX_SIMULTANEOUS_TONES * @return number, 0=none active */ uint8_t audio_get_number_of_active_tones(void); diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index 2d2dcd78488f..a204d6ab80be 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -26,21 +26,21 @@ it ia also possible to have a custom sample-LUT by implementing/overriding 'dac_value_generate' */ + +/* one full sine wave over [0,2*pi], but shifted up one amplitude and left pi/4; for the samples to start at 0 + */ static const dacsample_t dac_buffer_sine[DAC_BUFFER_SIZE] = { // 256 values, max 4095 - 0x800, 0x832, 0x864, 0x896, 0x8c8, 0x8fa, 0x92c, 0x95e, 0x98f, 0x9c0, 0x9f1, 0xa22, 0xa52, 0xa82, 0xab1, 0xae0, 0xb0f, 0xb3d, 0xb6b, 0xb98, 0xbc5, 0xbf1, 0xc1c, 0xc47, 0xc71, 0xc9a, 0xcc3, 0xceb, 0xd12, 0xd39, 0xd5f, 0xd83, 0xda7, 0xdca, 0xded, 0xe0e, 0xe2e, 0xe4e, 0xe6c, 0xe8a, 0xea6, 0xec1, 0xedc, 0xef5, 0xf0d, 0xf24, 0xf3a, 0xf4f, 0xf63, 0xf76, 0xf87, 0xf98, 0xfa7, 0xfb5, 0xfc2, 0xfcd, 0xfd8, 0xfe1, 0xfe9, 0xff0, 0xff5, 0xff9, 0xffd, 0xffe, 0xfff, 0xffe, 0xffd, 0xff9, 0xff5, 0xff0, 0xfe9, 0xfe1, 0xfd8, 0xfcd, 0xfc2, 0xfb5, 0xfa7, 0xf98, 0xf87, 0xf76, 0xf63, 0xf4f, 0xf3a, 0xf24, 0xf0d, 0xef5, 0xedc, 0xec1, 0xea6, 0xe8a, 0xe6c, 0xe4e, 0xe2e, 0xe0e, 0xded, 0xdca, 0xda7, 0xd83, 0xd5f, 0xd39, 0xd12, 0xceb, 0xcc3, 0xc9a, 0xc71, 0xc47, 0xc1c, 0xbf1, 0xbc5, 0xb98, 0xb6b, 0xb3d, 0xb0f, 0xae0, 0xab1, 0xa82, 0xa52, 0xa22, 0x9f1, 0x9c0, 0x98f, 0x95e, 0x92c, 0x8fa, 0x8c8, 0x896, 0x864, 0x832, - 0x800, 0x7cd, 0x79b, 0x769, 0x737, 0x705, 0x6d3, 0x6a1, 0x670, 0x63f, 0x60e, 0x5dd, 0x5ad, 0x57d, 0x54e, 0x51f, 0x4f0, 0x4c2, 0x494, 0x467, 0x43a, 0x40e, 0x3e3, 0x3b8, 0x38e, 0x365, 0x33c, 0x314, 0x2ed, 0x2c6, 0x2a0, 0x27c, 0x258, 0x235, 0x212, 0x1f1, 0x1d1, 0x1b1, 0x193, 0x175, 0x159, 0x13e, 0x123, 0x10a, 0xf2, 0xdb, 0xc5, 0xb0, 0x9c, 0x89, 0x78, 0x67, 0x58, 0x4a, 0x3d, 0x32, 0x27, 0x1e, 0x16, 0xf, 0xa, 0x6, 0x2, 0x1, 0x0, 0x1, 0x2, 0x6, 0xa, 0xf, 0x16, 0x1e, 0x27, 0x32, 0x3d, 0x4a, 0x58, 0x67, 0x78, 0x89, 0x9c, 0xb0, 0xc5, 0xdb, 0xf2, 0x10a, 0x123, 0x13e, 0x159, 0x175, 0x193, 0x1b1, 0x1d1, 0x1f1, 0x212, 0x235, 0x258, 0x27c, 0x2a0, 0x2c6, 0x2ed, 0x314, 0x33c, 0x365, 0x38e, 0x3b8, 0x3e3, 0x40e, 0x43a, 0x467, 0x494, 0x4c2, 0x4f0, 0x51f, 0x54e, 0x57d, 0x5ad, 0x5dd, 0x60e, 0x63f, 0x670, 0x6a1, 0x6d3, 0x705, 0x737, 0x769, 0x79b, 0x7cd}; + 0x0, 0x1, 0x2, 0x6, 0xa, 0xf, 0x16, 0x1e, 0x27, 0x32, 0x3d, 0x4a, 0x58, 0x67, 0x78, 0x89, 0x9c, 0xb0, 0xc5, 0xdb, 0xf2, 0x10a, 0x123, 0x13e, 0x159, 0x175, 0x193, 0x1b1, 0x1d1, 0x1f1, 0x212, 0x235, 0x258, 0x27c, 0x2a0, 0x2c6, 0x2ed, 0x314, 0x33c, 0x365, 0x38e, 0x3b8, 0x3e3, 0x40e, 0x43a, 0x467, 0x494, 0x4c2, 0x4f0, 0x51f, 0x54e, 0x57d, 0x5ad, 0x5dd, 0x60e, 0x63f, 0x670, 0x6a1, 0x6d3, 0x705, 0x737, 0x769, 0x79b, 0x7cd, 0x800, 0x832, 0x864, 0x896, 0x8c8, 0x8fa, 0x92c, 0x95e, 0x98f, 0x9c0, 0x9f1, 0xa22, 0xa52, 0xa82, 0xab1, 0xae0, 0xb0f, 0xb3d, 0xb6b, 0xb98, 0xbc5, 0xbf1, 0xc1c, 0xc47, 0xc71, 0xc9a, 0xcc3, 0xceb, 0xd12, 0xd39, 0xd5f, 0xd83, 0xda7, 0xdca, 0xded, 0xe0e, 0xe2e, 0xe4e, 0xe6c, 0xe8a, 0xea6, 0xec1, 0xedc, 0xef5, 0xf0d, 0xf24, 0xf3a, 0xf4f, 0xf63, 0xf76, 0xf87, 0xf98, 0xfa7, 0xfb5, 0xfc2, 0xfcd, 0xfd8, 0xfe1, 0xfe9, 0xff0, 0xff5, 0xff9, 0xffd, 0xffe, 0xfff, 0xffe, 0xffd, 0xff9, 0xff5, 0xff0, 0xfe9, 0xfe1, 0xfd8, 0xfcd, 0xfc2, 0xfb5, 0xfa7, 0xf98, 0xf87, 0xf76, 0xf63, 0xf4f, 0xf3a, 0xf24, 0xf0d, 0xef5, 0xedc, 0xec1, 0xea6, 0xe8a, 0xe6c, 0xe4e, 0xe2e, 0xe0e, 0xded, 0xdca, 0xda7, 0xd83, 0xd5f, 0xd39, 0xd12, 0xceb, 0xcc3, 0xc9a, 0xc71, 0xc47, 0xc1c, 0xbf1, 0xbc5, 0xb98, 0xb6b, 0xb3d, 0xb0f, 0xae0, 0xab1, 0xa82, 0xa52, 0xa22, 0x9f1, 0x9c0, 0x98f, 0x95e, 0x92c, 0x8fa, 0x8c8, 0x896, 0x864, 0x832, 0x800, 0x7cd, 0x79b, 0x769, 0x737, 0x705, 0x6d3, 0x6a1, 0x670, 0x63f, 0x60e, 0x5dd, 0x5ad, 0x57d, 0x54e, 0x51f, 0x4f0, 0x4c2, 0x494, 0x467, 0x43a, 0x40e, 0x3e3, 0x3b8, 0x38e, 0x365, 0x33c, 0x314, 0x2ed, 0x2c6, 0x2a0, 0x27c, 0x258, 0x235, 0x212, 0x1f1, 0x1d1, 0x1b1, 0x193, 0x175, 0x159, 0x13e, 0x123, 0x10a, 0xf2, 0xdb, 0xc5, 0xb0, 0x9c, 0x89, 0x78, 0x67, 0x58, 0x4a, 0x3d, 0x32, 0x27, 0x1e, 0x16, 0xf, 0xa, 0x6, 0x2, 0x1}; /* static const dacsample_t dac_buffer_triangle[DAC_BUFFER_SIZE] = { // 256 values, max 4095 - 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x100, 0x120, 0x140, 0x160, 0x180, 0x1a0, 0x1c0, 0x1e0, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0x400, 0x420, 0x440, 0x460, 0x480, 0x4a0, 0x4c0, 0x4e0, 0x500, 0x520, 0x540, 0x560, 0x580, 0x5a0, 0x5c0, 0x5e0, 0x600, 0x620, 0x640, 0x660, 0x680, 0x6a0, 0x6c0, 0x6e0, 0x700, 0x720, 0x740, 0x760, 0x780, 0x7a0, 0x7c0, 0x7e0, 0x800, 0x81f, 0x83f, 0x85f, 0x87f, 0x89f, 0x8bf, 0x8df, 0x8ff, 0x91f, 0x93f, 0x95f, 0x97f, 0x99f, 0x9bf, 0x9df, 0x9ff, 0xa1f, 0xa3f, 0xa5f, 0xa7f, 0xa9f, 0xabf, 0xadf, 0xaff, 0xb1f, 0xb3f, 0xb5f, 0xb7f, 0xb9f, 0xbbf, 0xbdf, 0xbff, 0xc1f, 0xc3f, 0xc5f, 0xc7f, 0xc9f, 0xcbf, 0xcdf, 0xcff, 0xd1f, 0xd3f, 0xd5f, 0xd7f, 0xd9f, 0xdbf, 0xddf, 0xdff, 0xe1f, 0xe3f, 0xe5f, 0xe7f, 0xe9f, 0xebf, 0xedf, 0xeff, 0xf1f, 0xf3f, 0xf5f, 0xf7f, 0xf9f, 0xfbf, 0xfdf, 0xfff, - 0xfdf, 0xfbf, 0xf9f, 0xf7f, 0xf5f, 0xf3f, 0xf1f, 0xeff, 0xedf, 0xebf, 0xe9f, 0xe7f, 0xe5f, 0xe3f, 0xe1f, 0xdff, 0xddf, 0xdbf, 0xd9f, 0xd7f, 0xd5f, 0xd3f, 0xd1f, 0xcff, 0xcdf, 0xcbf, 0xc9f, 0xc7f, 0xc5f, 0xc3f, 0xc1f, 0xbff, 0xbdf, 0xbbf, 0xb9f, 0xb7f, 0xb5f, 0xb3f, 0xb1f, 0xaff, 0xadf, 0xabf, 0xa9f, 0xa7f, 0xa5f, 0xa3f, 0xa1f, 0x9ff, 0x9df, 0x9bf, 0x99f, 0x97f, 0x95f, 0x93f, 0x91f, 0x8ff, 0x8df, 0x8bf, 0x89f, 0x87f, 0x85f, 0x83f, 0x81f, 0x800, 0x7e0, 0x7c0, 0x7a0, 0x780, 0x760, 0x740, 0x720, 0x700, 0x6e0, 0x6c0, 0x6a0, 0x680, 0x660, 0x640, 0x620, 0x600, 0x5e0, 0x5c0, 0x5a0, 0x580, 0x560, 0x540, 0x520, 0x500, 0x4e0, 0x4c0, 0x4a0, 0x480, 0x460, 0x440, 0x420, 0x400, 0x3e0, 0x3c0, 0x3a0, 0x380, 0x360, 0x340, 0x320, 0x300, 0x2e0, 0x2c0, 0x2a0, 0x280, 0x260, 0x240, 0x220, 0x200, 0x1e0, 0x1c0, 0x1a0, 0x180, 0x160, 0x140, 0x120, 0x100, 0xe0, 0xc0, 0xa0, 0x80, 0x60, 0x40, 0x20, 0x0}; + 0x0, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x100, 0x120, 0x140, 0x160, 0x180, 0x1a0, 0x1c0, 0x1e0, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0x400, 0x420, 0x440, 0x460, 0x480, 0x4a0, 0x4c0, 0x4e0, 0x500, 0x520, 0x540, 0x560, 0x580, 0x5a0, 0x5c0, 0x5e0, 0x600, 0x620, 0x640, 0x660, 0x680, 0x6a0, 0x6c0, 0x6e0, 0x700, 0x720, 0x740, 0x760, 0x780, 0x7a0, 0x7c0, 0x7e0, 0x800, 0x81f, 0x83f, 0x85f, 0x87f, 0x89f, 0x8bf, 0x8df, 0x8ff, 0x91f, 0x93f, 0x95f, 0x97f, 0x99f, 0x9bf, 0x9df, 0x9ff, 0xa1f, 0xa3f, 0xa5f, 0xa7f, 0xa9f, 0xabf, 0xadf, 0xaff, 0xb1f, 0xb3f, 0xb5f, 0xb7f, 0xb9f, 0xbbf, 0xbdf, 0xbff, 0xc1f, 0xc3f, 0xc5f, 0xc7f, 0xc9f, 0xcbf, 0xcdf, 0xcff, 0xd1f, 0xd3f, 0xd5f, 0xd7f, 0xd9f, 0xdbf, 0xddf, 0xdff, 0xe1f, 0xe3f, 0xe5f, 0xe7f, 0xe9f, 0xebf, 0xedf, 0xeff, 0xf1f, 0xf3f, 0xf5f, 0xf7f, 0xf9f, 0xfbf, 0xfdf, 0xfff, 0xfdf, 0xfbf, 0xf9f, 0xf7f, 0xf5f, 0xf3f, 0xf1f, 0xeff, 0xedf, 0xebf, 0xe9f, 0xe7f, 0xe5f, 0xe3f, 0xe1f, 0xdff, 0xddf, 0xdbf, 0xd9f, 0xd7f, 0xd5f, 0xd3f, 0xd1f, 0xcff, 0xcdf, 0xcbf, 0xc9f, 0xc7f, 0xc5f, 0xc3f, 0xc1f, 0xbff, 0xbdf, 0xbbf, 0xb9f, 0xb7f, 0xb5f, 0xb3f, 0xb1f, 0xaff, 0xadf, 0xabf, 0xa9f, 0xa7f, 0xa5f, 0xa3f, 0xa1f, 0x9ff, 0x9df, 0x9bf, 0x99f, 0x97f, 0x95f, 0x93f, 0x91f, 0x8ff, 0x8df, 0x8bf, 0x89f, 0x87f, 0x85f, 0x83f, 0x81f, 0x800, 0x7e0, 0x7c0, 0x7a0, 0x780, 0x760, 0x740, 0x720, 0x700, 0x6e0, 0x6c0, 0x6a0, 0x680, 0x660, 0x640, 0x620, 0x600, 0x5e0, 0x5c0, 0x5a0, 0x580, 0x560, 0x540, 0x520, 0x500, 0x4e0, 0x4c0, 0x4a0, 0x480, 0x460, 0x440, 0x420, 0x400, 0x3e0, 0x3c0, 0x3a0, 0x380, 0x360, 0x340, 0x320, 0x300, 0x2e0, 0x2c0, 0x2a0, 0x280, 0x260, 0x240, 0x220, 0x200, 0x1e0, 0x1c0, 0x1a0, 0x180, 0x160, 0x140, 0x120, 0x100, 0xe0, 0xc0, 0xa0, 0x80, 0x60, 0x40, 0x20}; static const dacsample_t dac_buffer_square[DAC_BUFFER_SIZE] = { - // First half is max, second half is 0 - [0 ... DAC_BUFFER_SIZE / 2 - 1] = DAC_SAMPLE_MAX, - [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = 0, + [0 ... DAC_BUFFER_SIZE / 2 - 1] = 0, // first and + [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = DAC_SAMPLE_MAX, // second half }; // four steps: 0, 1/3, 2/3 and 1 @@ -55,27 +55,48 @@ static const dacsample_t dac_buffer_staircase[DAC_BUFFER_SIZE] = { static dacsample_t dac_buffer_empty[DAC_BUFFER_SIZE] = {DAC_OFF_VALUE}; /* keep track of the sample position for for each frequency */ -static float dac_if[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; +static float dac_if[AUDIO_MAX_SIMULTANEOUS_TONES] = {0.0}; + +/* state-"freezer", so we can continue playing tones until they cross-zero, then switch to the new ones*/ +static bool state_recently_changed = false; +//TODO have audio.c keep track of a previous state snapshot instead? +static float dac_previous_frequencies[AUDIO_MAX_SIMULTANEOUS_TONES] = {0.0}; +static uint8_t dac_previous_active_tones = 0; /** * Generation of the waveform being passed to the callback. Declared weak so users * can override it with their own waveforms/noises. */ __attribute__((weak)) uint16_t dac_value_generate(void) { - uint16_t value = DAC_OFF_VALUE; - uint8_t active_tones = audio_get_number_of_active_tones(); - if (active_tones > AUDIO_MAX_SIMULTANEOUS_TONES) active_tones = AUDIO_MAX_SIMULTANEOUS_TONES; + uint16_t value = DAC_OFF_VALUE; + uint8_t active_tones = 0; + + if (state_recently_changed) { + active_tones = dac_previous_active_tones; + } else { + active_tones = audio_get_number_of_active_tones(); + dac_previous_active_tones = active_tones; + } /* doing additive wave synthesis over all currently playing tones = adding up * sine-wave-samples for each frequency, scaled by the number of active tones */ if (active_tones > 0) { uint16_t value_avg = 0; + float frequency = 0.0f; + for (uint8_t i = 0; i < active_tones; i++) { + if (state_recently_changed) { // work from freezer, until zero crossing + frequency = dac_previous_frequencies[i]; + } else { // feed the freezer + frequency = audio_get_frequency(i); //TODO: replace by glissando+vibrato+.. variant + dac_previous_frequencies[i] = frequency; + } + dac_if[i] = dac_if[i] + - ((audio_get_frequency(i) //TODO: replace by glissando+vibrator+.. variant - * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE) - * 2/3; /*Note: necessary to get the correct frequencies on the + ((frequency + * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE) + * 2/3; /*Note: necessary to get the correct frequencies on the DAC output (as measured with an oscilloscope), since the gpt timer runs with 3*DAC_SAMPLE_RATE; and the DAC callback is called twice per conversion.*/ @@ -96,6 +117,18 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { //value_avg = dac_buffer_staircase[dac_i] / active_tones; } value = value_avg; + + // zero crossing/proximity => unfreeze + if ((value < 0xf) //arbitrary value near zero + && state_recently_changed) { + state_recently_changed=false; + /* the waveform sum approaches zero, each sample index can still point + * to a non-zero value; so all have to be reset + * Note: this to work without clocks, the samples have to start at zero + */ + for (uint8_t i = 0; i < AUDIO_MAX_SIMULTANEOUS_TONES; i++) + dac_if[i] = 0.0f; + } } return value; } @@ -118,7 +151,7 @@ static void dac_end(DACDriver *dacp){ } // update audio internal state (note position, current_note, ...) - audio_advance_state( + state_recently_changed = audio_advance_state( DAC_BUFFER_SIZE/2, DAC_SAMPLE_RATE/ (64*2.0f/3) /* End of the note: 64 is the number of 'units' of a whole note, 3 comes @@ -186,7 +219,18 @@ void audio_initialize_hardware() { #if defined(AUDIO_PIN_A5) DACD2.params->dac->CR &= ~DAC_CR_BOFF2; #endif +} +void audio_stop_hardware(void) { +/*TODO + should_stop = true + continue dac until zero-crossing, then stop timer + gptStopTimer + gptStop +*/ +} + +void audio_start_hardware(void) { gptStart(&GPTD6, &gpt6cfg1); gptStartContinuous(&GPTD6, 2U); @@ -196,7 +240,3 @@ void audio_initialize_hardware() { gptStart(&GPTD8, &gpt8cfg1); gptStartContinuous(&GPTD8, 2U); } - -void audio_stop_hardware(void) {} - -void audio_start_hardware(void) {} From d69cfcad1babd692a781b3b3f5ce84d67403e7a5 Mon Sep 17 00:00:00 2001 From: Johannes Date: Tue, 31 Mar 2020 17:08:32 +0200 Subject: [PATCH 048/153] audio-refactoring: feature: time-multiplexing of tones on a single output channel this feature was in the original avr-pwm implementation misnomed as "polyphony" with polyphony_rate and so on; did the same thing though: time-multiplexing multiple active notes so that a single output channel could reproduce more than one note at a time (which is not the same as a polyphony - see wikipedia :-) ) --- quantum/audio/audio.c | 46 +++++++++++++++++++++++-------- quantum/audio/audio.h | 1 + quantum/audio/audio_chibios_pwm.c | 10 +++++-- quantum/audio/audio_chibios_pwm.h | 7 +++-- 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 39d237f9bcb4..5708b2791283 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -49,18 +49,17 @@ uint16_t current_note = 0; // index into the array at notes_pointer uint16_t next_note = 0; uint32_t note_position = 0; // where in time, during playback of the current_note +#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING +float tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT; +float tone_multiplexing_counter = 0.0f; // incremented each state update, and compared to _rate +uint8_t tone_multiplexing_index_shift = 0; // offset used on active-tone array access +#endif + //TODO/REFACTORING: check below variables if/where they are still used float note_frequency = 0; // Hz -float note_timbre = TIMBRE_DEFAULT; bool note_resting = false; //?? current note is a pause? or is this supposed to indicate a 'tie'? -#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING -//TODO: if active, AUDIO_MAX_SIMULTANEOUS_TONES should be set to >>1 for the feature to make sense -int tone_place = 0; -float tone_multiplexing_rate = 0; -#endif - #ifdef AUDIO_ENABLE_VIBRATO float vibrato_counter = 0; float vibrato_strength = .5; @@ -68,6 +67,7 @@ float vibrato_rate = 0.125; #endif // used by voices.c +float note_timbre = TIMBRE_DEFAULT; uint16_t envelope_index = 0; bool glissando = false; @@ -188,8 +188,8 @@ void stop_note(float freq) { active_tones--; if (active_tones < 0) active_tones = 0; #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING - if (tone_place >= active_tones) { - tone_place = 0; + if (tone_multiplexing_index_shift >= active_tones) { + tone_multiplexing_index_shift = 0; } #endif if (active_tones == 0) { @@ -210,7 +210,7 @@ void play_note(float freq, int vol) { //NOTE: vol is unused audio_init(); } - // roundrobin: shifting out old tones, keeping only uniquie ones + // roundrobin: shifting out old tones, keeping only unique ones // if the new frequency is already amongst the active tones, shift it to the end bool found = false; for (int i = active_tones-1; i >= 0; i--) { @@ -236,7 +236,7 @@ void play_note(float freq, int vol) { //NOTE: vol is unused } } playing_note = true; - envelope_index = 0; // TODO: does what? + envelope_index = 0; // see voices.c // TODO: does what? frequencies[active_tones-1] = freq; if (active_tones==1) // sufficient to start when switching from 0 to 1 @@ -295,9 +295,15 @@ float audio_get_processed_frequency(uint8_t tone_index) { if (tone_index >= active_tones) return 0.0f; - uint8_t index = active_tones - tone_index - 1; + int8_t index = active_tones - tone_index - 1; // new tones are appended at the end, so the most recent/current is MAX-1 +#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING + index = index - tone_multiplexing_index_shift; + if (index < 0) // wrap around + index += active_tones; +#endif + if (frequencies[index] <= 0.0f) return 0.0f; @@ -457,6 +463,22 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { bool audio_advance_state(uint32_t step, float end) { bool goto_next_note = false; + if (playing_note) { +#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING +// tone_multiplexing_counter++; // TODO: use step and end from advance_State instead; so that frequencies are switched in a time-constant manner during playback of different tones (pitch+duration!) + tone_multiplexing_counter += step/end; + if (tone_multiplexing_counter == tone_multiplexing_rate) { +//palToggleLine(C10); + tone_multiplexing_counter = 0.0f; + tone_multiplexing_index_shift++; + if (tone_multiplexing_index_shift >= active_tones) + tone_multiplexing_index_shift = 0; + goto_next_note = true; + } +#endif + } + + //'playing_note' is stopped manually, so no need to keep track of it here if (playing_notes) { diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 2ff89cdd4c6c..e2075d47ffea 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -165,6 +165,7 @@ void decrease_vibrato_strength(float change); #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING # ifndef AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT # define AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT 0 +// 0=off, good starting value is 4; the lower the value the higher the cpu-load # endif void set_tone_multiplexing_rate(float rate); void enable_tone_multiplexing(void); diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index 7573ad030494..eea2f013a0b3 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -203,17 +203,21 @@ void audio_initialize_hardware(void) { } void audio_start_hardware(void) { - float freq;// TODO: freq_alt channel_1_stop(); channel_1_start(); +#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING + if (playing_note || playing_notes) { + gptStartContinuous(&GPTD6, 64); + } +#else if (playing_note) { - freq = audio_get_processed_frequency(0); - channel_1_set_frequency(freq); + channel_1_set_frequency(audio_get_processed_frequency(0)); } if (playing_notes) { gptStartContinuous(&GPTD6, 64); } +#endif } void audio_stop_hardware(void) { diff --git a/quantum/audio/audio_chibios_pwm.h b/quantum/audio/audio_chibios_pwm.h index 773c767c440b..93268030250a 100644 --- a/quantum/audio/audio_chibios_pwm.h +++ b/quantum/audio/audio_chibios_pwm.h @@ -17,8 +17,11 @@ // with one pwm channel, only one tone can be played at a time // TODO: unless we start doing time-multiplexing... -#define AUDIO_MAX_SIMULTANEOUS_TONES 1 - +#if defined (AUDIO_ENABLE_TONE_MULTIPLEXING) +# define AUDIO_MAX_SIMULTANEOUS_TONES 8 +#else +# define AUDIO_MAX_SIMULTANEOUS_TONES 1 +#endif #if !defined(AUDIO_PWM_PINALTERNATE_TIMER) //NOTE: Timer2 seems to be used otherwise in QMK, otherwise we could default to A5 (= TIM2_CH1, with PWMD2 and alternate-function(1)) From e5837cfca5a8d36a3ff400b317a635f0223dac13 Mon Sep 17 00:00:00 2001 From: Johannes Date: Tue, 31 Mar 2020 12:37:13 +0200 Subject: [PATCH 049/153] audio-avr-pwm: get music-mode working (again) on AVRs with both pwm channels, or either one of the two :-) play_notes worked already - but music_mode uses play_note --- common_features.mk | 2 +- quantum/audio/audio.c | 8 ++- quantum/audio/audio.h | 10 ++- quantum/audio/audio_avr_pwm.c | 112 ++++++++++++++++++++++------------ 4 files changed, 87 insertions(+), 45 deletions(-) diff --git a/common_features.mk b/common_features.mk index 2ffae5d81a52..044e524f480a 100644 --- a/common_features.mk +++ b/common_features.mk @@ -64,7 +64,7 @@ ifeq ($(strip $(AUDIO_ENABLE)), yes) OPT_DEFS += -DAUDIO_PIN=$(AUDIO_PIN) -DAUDIO_PIN_$(AUDIO_PIN) endif ifdef AUDIO_PIN_ALT - OPT_DEFS += -DAUDIO_PIN_ALT=$(AUDIO_PIN) -DAUDIO_PIN_ALT_$(AUDIO_PIN) + OPT_DEFS += -DAUDIO_PIN_ALT=$(AUDIO_PIN_ALT) -DAUDIO_PIN_ALT_$(AUDIO_PIN_ALT) endif OPT_DEFS += -DAUDIO_ENABLE MUSIC_ENABLE = yes diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 5708b2791283..e0e052ffc9a1 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -34,11 +34,13 @@ # define AUDIO_MAX_SIMULTANEOUS_TONES 8 #endif uint8_t active_tones = 0; // nuber of active/playing tones/frequencies +uint8_t active_tones_prev = 0; // for the state update to keep track of changes float frequencies[AUDIO_MAX_SIMULTANEOUS_TONES] = {0.0}; // frequencies of each active tone //TODO: array of musical_tone_t bool playing_notes = false; // playing a SONG? bool playing_note = false; // or (possibly multiple simultanious) tones +bool state_changed = false; // global flag, which is set if anything changes with the active_tones float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs uint16_t notes_count; // length of the notes_pointer array @@ -185,6 +187,7 @@ void stop_note(float freq) { if (!found) return; + state_changed = true; active_tones--; if (active_tones < 0) active_tones = 0; #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING @@ -235,6 +238,7 @@ void play_note(float freq, int vol) { //NOTE: vol is unused frequencies[i] = frequencies[i+1]; } } + state_changed = true; playing_note = true; envelope_index = 0; // see voices.c // TODO: does what? frequencies[active_tones-1] = freq; @@ -461,7 +465,8 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { bool audio_advance_state(uint32_t step, float end) { - bool goto_next_note = false; + bool goto_next_note = state_changed; + state_changed = false; if (playing_note) { #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING @@ -478,7 +483,6 @@ bool audio_advance_state(uint32_t step, float end) { #endif } - //'playing_note' is stopped manually, so no need to keep track of it here if (playing_notes) { diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index e2075d47ffea..74e620a946ce 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -211,7 +211,7 @@ uint8_t audio_get_number_of_active_tones(void); * @param[in] tone_index, ranging from 0 to number_of_active_tones-1, with the * first beeing the most recent and each increment yielding the next * older one - * @return frequency in Hz + * @return a positive frequency, in Hz; or zero if the tone is a pause */ float audio_get_frequency(uint8_t tone_index); /** @@ -222,7 +222,7 @@ float audio_get_frequency(uint8_t tone_index); * @param[in] tone_index, ranging from 0 to number_of_active_tones-1, with the * first beeing the most recent and each increment yielding the next * older one - * @return frequency in Hz + * @return a positive frequency, in Hz; or zero if the tone is a pause */ float audio_get_processed_frequency(uint8_t tone_index); @@ -231,6 +231,12 @@ float audio_get_processed_frequency(uint8_t tone_index); * @details This function is intended to be called by the audio-hardware * specific implementation on a regular basis while a SONG is * playing, to 'advance' the position/time/internal state + * + * @note: 'step' and 'end' can be used if the function is to be called from a + * timer/ISR with irregular period - say a pwm-isr - then one could use + * 'step=1' with 'end' set to the current pwm-frequency; and still have + * a somewhat regular state progression + * * @param[in] step arbitrary step value, audio.c keeps track of for the * audio-driver * @param[in] end scaling factor multiplied to the note_length. has to match diff --git a/quantum/audio/audio_avr_pwm.c b/quantum/audio/audio_avr_pwm.c index d03b02508a60..b412c59499a3 100644 --- a/quantum/audio/audio_avr_pwm.c +++ b/quantum/audio/audio_avr_pwm.c @@ -24,6 +24,7 @@ // TODO: move into audio-common state +extern bool playing_note; extern bool playing_notes; extern float note_timbre; @@ -39,12 +40,6 @@ extern float note_timbre; in a pinch with only one of the PB pins available as speaker output, they can be used as the primary channel too - by only setting the AUDIO_PIN_ALT_Bx define, and *none* of the AUDIO_PIN_Cx defines */ -// C6 seems to be the assumed default by many existing keyboard - but sill warn the user -#if !defined(AUDIO1_PIN_SET) && !defined(AUDIO2_PIN_SET) -# pragma message "Audio feature enabled, but no pin selected - see docs/feature_audio under the AVR settings for available options. Don't expect to hear anything... :-)" -//TODO: make this an error - go through the breaking-change-process and change all keyboards to the new define -#endif - #if defined(AUDIO_PIN_C4) || defined(AUDIO_PIN_C5) || defined(AUDIO_PIN_C6) # define AUDIO1_PIN_SET # define AUDIO1_TIMSKx TIMSK3 @@ -122,19 +117,32 @@ extern float note_timbre; # endif #endif +// C6 seems to be the assumed default by many existing keyboard - but sill warn the user +#if !defined(AUDIO1_PIN_SET) && !defined(AUDIO2_PIN_SET) +# pragma message "Audio feature enabled, but no pin selected - see docs/feature_audio under the AVR settings for available options. Don't expect to hear anything... :-)" +//TODO: make this an error - go through the breaking-change-process and change all keyboards to the new define +#endif // ----------------------------------------------------------------------------- #ifdef AUDIO1_PIN_SET static float channel_1_frequency = 0.0f; void channel_1_set_frequency(float freq) { - if (freq < 0.0f) freq = 0.0f; + //TODO: handle consecutive notes with the same frequency, there should be an audible gap inbetween them if (freq == channel_1_frequency) return; - channel_1_frequency = freq; - - if (freq == 0.0f) // a pause has freq=0, no need to start the PWM (also avoids division by zero) + if (freq == 0.0f) // a pause/rest is a valid "note" with freq=0 + { + // disable the output, but keep the pwm-ISR going (with the previous + // frequency) so the audio-state keeps getting updated + // Note: setting the duty-cycle 0 is not possible on non-inverting PWM mode - see the AVR datasheet + AUDIO1_TCCRxA &= ~(_BV(AUDIO1_COMxy1) | _BV(AUDIO1_COMxy0)); return; + } else { + AUDIO1_TCCRxA |= _BV(AUDIO1_COMxy1);// enable output, PWM mode + } + + channel_1_frequency = freq; // set pwm period AUDIO1_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); @@ -161,14 +169,18 @@ void channel_1_stop(void) { #ifdef AUDIO2_PIN_SET static float channel_2_frequency = 0.0f; void channel_2_set_frequency(float freq) { - if (freq < 0.0f) freq = 0.0f; if (freq == channel_2_frequency) return; - channel_2_frequency = freq; - - if (freq == 0.0f) // a pause has freq=0, no need to start the PWM (also avoids division by zero) + if (freq == 0.0f) + { + AUDIO2_TCCRxA &= ~(_BV(AUDIO2_COMxy1) | _BV(AUDIO2_COMxy0)); return; + } else { + AUDIO2_TCCRxA |= _BV(AUDIO2_COMxy1); + } + + channel_2_frequency = freq; AUDIO2_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); AUDIO2_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); @@ -220,15 +232,11 @@ void audio_initialize_hardware() { // initialize timer-counter AUDIO1_TCCRxA = (0 << AUDIO1_COMxy1) | (0 << AUDIO1_COMxy0) | (1 << AUDIO1_WGMx1) | (0 << AUDIO1_WGMx0); AUDIO1_TCCRxB = (1 << AUDIO1_WGMx3) | (1 << AUDIO1_WGMx2) | (0 << AUDIO1_CSx2) | (1 << AUDIO1_CSx1) | (0 << AUDIO1_CSx0); - - // channel_1_set_frequency(440); // original code set this frequency here... why? #endif #ifdef AUDIO2_PIN_SET AUDIO2_TCCRxA = (0 << AUDIO2_COMxy1) | (0 << AUDIO2_COMxy0) | (1 << AUDIO2_WGMx1) | (0 << AUDIO2_WGMx0); AUDIO2_TCCRxB = (1 << AUDIO2_WGMx3) | (1 << AUDIO2_WGMx2) | (0 << AUDIO2_CSx2) | (1 << AUDIO2_CSx1) | (0 << AUDIO2_CSx0); - - // channel_2_set_frequency(440); // original code set this frequency here... why? #endif } @@ -247,51 +255,75 @@ void audio_stop_hardware() { void audio_start_hardware(void) { #ifdef AUDIO1_PIN_SET channel_1_start(); + if (playing_note) + channel_1_set_frequency( + audio_get_processed_frequency(0) + ); #endif -#ifdef AUDIO2_PIN_SET -# ifdef AUDIO1_PIN_SET - if (audio_get_number_of_active_tones() > 1) { - channel_2_start(); - } -# else + +#if !defined(AUDIO1_PIN_SET) && defined(AUDIO2_PIN_SET) channel_2_start(); -# endif + if (playing_note) { + channel_2_set_frequency( + audio_get_processed_frequency(0) + ); + } #endif } +static volatile uint32_t isr_counter=0; #ifdef AUDIO1_PIN_SET ISR(AUDIO1_TIMERx_COMPy_vect) { + isr_counter++; + if (isr_counter < channel_1_frequency/(CPU_PRESCALER*8)) + return; + + isr_counter=0; + bool state_changed = audio_advance_state(1,1); - audio_advance_state(1,channel_1_frequency/CPU_PRESCALER/8); + if (!playing_note && !playing_notes) { + channel_1_stop(); +# ifdef AUDIO2_PIN_SET + channel_2_stop(); +# endif + return; + } - if (playing_notes) + if (state_changed){ channel_1_set_frequency( audio_get_processed_frequency(0) ); - else - channel_1_stop(); - # ifdef AUDIO2_PIN_SET - if (playing_notes) - channel_2_set_frequency( - audio_get_processed_frequency(1) - ); - else - channel_2_stop(); + if (audio_get_number_of_active_tones() > 1) { + channel_2_set_frequency( + audio_get_processed_frequency(1) + ); + } else { + channel_2_stop(); + } # endif + } } #endif #if !defined(AUDIO1_PIN_SET) && defined(AUDIO2_PIN_SET) ISR(AUDIO2_TIMERx_COMPy_vect) { + isr_counter++; + if (isr_counter < channel_2_frequency/(CPU_PRESCALER*8)) + return; - audio_advance_state(1,channel_2_frequency/CPU_PRESCALER/8); + isr_counter=0; + bool state_changed = audio_advance_state(1,1); - if (playing_notes) + if (!playing_note && !playing_notes) { + channel_2_stop(); + return; + } + + if (state_changed){ channel_2_set_frequency( audio_get_processed_frequency(0) ); - else - channel_2_stop(); + } } #endif From 7f1695aa5bbe37634091a3d56bb840615905fa20 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 1 Apr 2020 19:54:30 +0200 Subject: [PATCH 050/153] audio-refactoring: split define MAX_SIMULTANEOUS_TONES -> TONE_STACKSIZE since the two cases are independant from one another, the hardware might impose limitations on the number of simultaneously reproducable tones, but the audio state should be able to track an unrelated number of notes recently started by play_note --- quantum/audio/audio.c | 27 ++++++++++++++------------- quantum/audio/audio.h | 4 +++- quantum/audio/audio_avr_pwm.h | 2 -- quantum/audio/audio_chibios_dac.c | 4 ++-- quantum/audio/audio_chibios_pwm.c | 9 --------- quantum/audio/audio_chibios_pwm.h | 7 ------- 6 files changed, 19 insertions(+), 34 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index e0e052ffc9a1..3a6a4124a521 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -30,13 +30,12 @@ * avtive tone */ -#ifndef AUDIO_MAX_SIMULTANEOUS_TONES -# define AUDIO_MAX_SIMULTANEOUS_TONES 8 +#ifndef AUDIO_TONE_STACKSIZE +# define AUDIO_TONE_STACKSIZE 8 #endif -uint8_t active_tones = 0; // nuber of active/playing tones/frequencies -uint8_t active_tones_prev = 0; // for the state update to keep track of changes -float frequencies[AUDIO_MAX_SIMULTANEOUS_TONES] = {0.0}; // frequencies of each active tone -//TODO: array of musical_tone_t +uint8_t active_tones = 0; // nuber of tones pushed onto the stack by play_note - might be more than the harware is able to reproduce at any single time +float frequencies[AUDIO_TONE_STACKSIZE] = {0.0}; // frequencies of each active tone +//TODO: array of musical_tone_t? bool playing_notes = false; // playing a SONG? bool playing_note = false; // or (possibly multiple simultanious) tones @@ -52,6 +51,9 @@ uint16_t next_note = 0; uint32_t note_position = 0; // where in time, during playback of the current_note #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING +# ifndef AUDIO_MAX_SIMULTANEOUS_TONES +# define AUDIO_MAX_SIMULTANEOUS_TONES 3 +# endif float tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT; float tone_multiplexing_counter = 0.0f; // incremented each state update, and compared to _rate uint8_t tone_multiplexing_index_shift = 0; // offset used on active-tone array access @@ -162,7 +164,7 @@ void stop_all_notes() { playing_notes = false; playing_note = false; - for (uint8_t i = 0; i < AUDIO_MAX_SIMULTANEOUS_TONES; i++) { + for (uint8_t i = 0; i < AUDIO_TONE_STACKSIZE; i++) { frequencies[i] = 0; } } @@ -173,11 +175,11 @@ void stop_note(float freq) { audio_init(); } bool found = false; - for (int i = AUDIO_MAX_SIMULTANEOUS_TONES-1; i >= 0; i--) { + for (int i = AUDIO_TONE_STACKSIZE-1; i >= 0; i--) { found = (frequencies[i] == freq); if (found) { frequencies[i] = 0; - for (int j = i; (j < AUDIO_MAX_SIMULTANEOUS_TONES-1); j++) { + for (int j = i; (j < AUDIO_TONE_STACKSIZE-1); j++) { frequencies[j] = frequencies[j + 1]; frequencies[j + 1] = 0; } @@ -231,8 +233,8 @@ void play_note(float freq, int vol) { //NOTE: vol is unused // frequency/tone is actually new, so we queue it to the end active_tones++; - if (active_tones > AUDIO_MAX_SIMULTANEOUS_TONES) { - active_tones = AUDIO_MAX_SIMULTANEOUS_TONES; + if (active_tones > AUDIO_TONE_STACKSIZE) { + active_tones = AUDIO_TONE_STACKSIZE; // shift out the oldest tone to make room for (int i=0; i= active_tones) + if (tone_multiplexing_index_shift >= MIN(AUDIO_MAX_SIMULTANEOUS_TONES, active_tones)) tone_multiplexing_index_shift = 0; goto_next_note = true; } diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 74e620a946ce..1006b87b8d12 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -46,6 +46,9 @@ typedef union { }; } audio_config_t; + +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + // ____ __ ___ // / __ \__ __/ /_ / (_)____ // / /_/ / / / / __ \/ / / ___/ @@ -199,7 +202,6 @@ void audio_stop_hardware(void); /** * @brief get the number of currently active tones - * @note guaranteed to be below AUDIO_MAX_SIMULTANEOUS_TONES * @return number, 0=none active */ uint8_t audio_get_number_of_active_tones(void); diff --git a/quantum/audio/audio_avr_pwm.h b/quantum/audio/audio_avr_pwm.h index b4705d523bbc..a3335cc56b40 100644 --- a/quantum/audio/audio_avr_pwm.h +++ b/quantum/audio/audio_avr_pwm.h @@ -14,5 +14,3 @@ * along with this program. If not, see . */ #pragma once - -#define AUDIO_MAX_SIMULTANEOUS_TONES 2 diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index a204d6ab80be..64fa020c47e4 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -74,7 +74,7 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { if (state_recently_changed) { active_tones = dac_previous_active_tones; } else { - active_tones = audio_get_number_of_active_tones(); + active_tones = MIN(AUDIO_MAX_SIMULTANEOUS_TONES, audio_get_number_of_active_tones()); dac_previous_active_tones = active_tones; } @@ -124,7 +124,7 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { state_recently_changed=false; /* the waveform sum approaches zero, each sample index can still point * to a non-zero value; so all have to be reset - * Note: this to work without clocks, the samples have to start at zero + * Note: for this to work without clicks, the samples have to start at zero */ for (uint8_t i = 0; i < AUDIO_MAX_SIMULTANEOUS_TONES; i++) dac_if[i] = 0.0f; diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/audio_chibios_pwm.c index eea2f013a0b3..5ea95d1e3c39 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/audio_chibios_pwm.c @@ -206,18 +206,9 @@ void audio_start_hardware(void) { channel_1_stop(); channel_1_start(); -#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING if (playing_note || playing_notes) { gptStartContinuous(&GPTD6, 64); } -#else - if (playing_note) { - channel_1_set_frequency(audio_get_processed_frequency(0)); - } - if (playing_notes) { - gptStartContinuous(&GPTD6, 64); - } -#endif } void audio_stop_hardware(void) { diff --git a/quantum/audio/audio_chibios_pwm.h b/quantum/audio/audio_chibios_pwm.h index 93268030250a..35059fd676e0 100644 --- a/quantum/audio/audio_chibios_pwm.h +++ b/quantum/audio/audio_chibios_pwm.h @@ -15,13 +15,6 @@ */ #pragma once -// with one pwm channel, only one tone can be played at a time -// TODO: unless we start doing time-multiplexing... -#if defined (AUDIO_ENABLE_TONE_MULTIPLEXING) -# define AUDIO_MAX_SIMULTANEOUS_TONES 8 -#else -# define AUDIO_MAX_SIMULTANEOUS_TONES 1 -#endif #if !defined(AUDIO_PWM_PINALTERNATE_TIMER) //NOTE: Timer2 seems to be used otherwise in QMK, otherwise we could default to A5 (= TIM2_CH1, with PWMD2 and alternate-function(1)) From 4cab662cd9eaa48f8145f238aedf900aa1172ac1 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 1 Apr 2020 20:16:15 +0200 Subject: [PATCH 051/153] audio-arm-dac: per define selectable sample-luts plus generation script in ./util --- quantum/audio/audio_chibios_dac.c | 38 ++++++++++++++++++----- util/audio_generate_dac_lut.py | 51 +++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 util/audio_generate_dac_lut.py diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/audio_chibios_dac.c index 64fa020c47e4..f414ef9d80f9 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/audio_chibios_dac.c @@ -26,23 +26,29 @@ it ia also possible to have a custom sample-LUT by implementing/overriding 'dac_value_generate' */ +#if !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID) +# define AUDIO_DAC_SAMPLE_WAVEFORM_SINE +#endif +#ifdef AUDIO_DAC_SAMPLE_WAVEFORM_SINE /* one full sine wave over [0,2*pi], but shifted up one amplitude and left pi/4; for the samples to start at 0 */ static const dacsample_t dac_buffer_sine[DAC_BUFFER_SIZE] = { // 256 values, max 4095 0x0, 0x1, 0x2, 0x6, 0xa, 0xf, 0x16, 0x1e, 0x27, 0x32, 0x3d, 0x4a, 0x58, 0x67, 0x78, 0x89, 0x9c, 0xb0, 0xc5, 0xdb, 0xf2, 0x10a, 0x123, 0x13e, 0x159, 0x175, 0x193, 0x1b1, 0x1d1, 0x1f1, 0x212, 0x235, 0x258, 0x27c, 0x2a0, 0x2c6, 0x2ed, 0x314, 0x33c, 0x365, 0x38e, 0x3b8, 0x3e3, 0x40e, 0x43a, 0x467, 0x494, 0x4c2, 0x4f0, 0x51f, 0x54e, 0x57d, 0x5ad, 0x5dd, 0x60e, 0x63f, 0x670, 0x6a1, 0x6d3, 0x705, 0x737, 0x769, 0x79b, 0x7cd, 0x800, 0x832, 0x864, 0x896, 0x8c8, 0x8fa, 0x92c, 0x95e, 0x98f, 0x9c0, 0x9f1, 0xa22, 0xa52, 0xa82, 0xab1, 0xae0, 0xb0f, 0xb3d, 0xb6b, 0xb98, 0xbc5, 0xbf1, 0xc1c, 0xc47, 0xc71, 0xc9a, 0xcc3, 0xceb, 0xd12, 0xd39, 0xd5f, 0xd83, 0xda7, 0xdca, 0xded, 0xe0e, 0xe2e, 0xe4e, 0xe6c, 0xe8a, 0xea6, 0xec1, 0xedc, 0xef5, 0xf0d, 0xf24, 0xf3a, 0xf4f, 0xf63, 0xf76, 0xf87, 0xf98, 0xfa7, 0xfb5, 0xfc2, 0xfcd, 0xfd8, 0xfe1, 0xfe9, 0xff0, 0xff5, 0xff9, 0xffd, 0xffe, 0xfff, 0xffe, 0xffd, 0xff9, 0xff5, 0xff0, 0xfe9, 0xfe1, 0xfd8, 0xfcd, 0xfc2, 0xfb5, 0xfa7, 0xf98, 0xf87, 0xf76, 0xf63, 0xf4f, 0xf3a, 0xf24, 0xf0d, 0xef5, 0xedc, 0xec1, 0xea6, 0xe8a, 0xe6c, 0xe4e, 0xe2e, 0xe0e, 0xded, 0xdca, 0xda7, 0xd83, 0xd5f, 0xd39, 0xd12, 0xceb, 0xcc3, 0xc9a, 0xc71, 0xc47, 0xc1c, 0xbf1, 0xbc5, 0xb98, 0xb6b, 0xb3d, 0xb0f, 0xae0, 0xab1, 0xa82, 0xa52, 0xa22, 0x9f1, 0x9c0, 0x98f, 0x95e, 0x92c, 0x8fa, 0x8c8, 0x896, 0x864, 0x832, 0x800, 0x7cd, 0x79b, 0x769, 0x737, 0x705, 0x6d3, 0x6a1, 0x670, 0x63f, 0x60e, 0x5dd, 0x5ad, 0x57d, 0x54e, 0x51f, 0x4f0, 0x4c2, 0x494, 0x467, 0x43a, 0x40e, 0x3e3, 0x3b8, 0x38e, 0x365, 0x33c, 0x314, 0x2ed, 0x2c6, 0x2a0, 0x27c, 0x258, 0x235, 0x212, 0x1f1, 0x1d1, 0x1b1, 0x193, 0x175, 0x159, 0x13e, 0x123, 0x10a, 0xf2, 0xdb, 0xc5, 0xb0, 0x9c, 0x89, 0x78, 0x67, 0x58, 0x4a, 0x3d, 0x32, 0x27, 0x1e, 0x16, 0xf, 0xa, 0x6, 0x2, 0x1}; - -/* +#endif // AUDIO_DAC_SAMPLE_WAVEFORM_SINE +#ifdef AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE static const dacsample_t dac_buffer_triangle[DAC_BUFFER_SIZE] = { // 256 values, max 4095 0x0, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x100, 0x120, 0x140, 0x160, 0x180, 0x1a0, 0x1c0, 0x1e0, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0x400, 0x420, 0x440, 0x460, 0x480, 0x4a0, 0x4c0, 0x4e0, 0x500, 0x520, 0x540, 0x560, 0x580, 0x5a0, 0x5c0, 0x5e0, 0x600, 0x620, 0x640, 0x660, 0x680, 0x6a0, 0x6c0, 0x6e0, 0x700, 0x720, 0x740, 0x760, 0x780, 0x7a0, 0x7c0, 0x7e0, 0x800, 0x81f, 0x83f, 0x85f, 0x87f, 0x89f, 0x8bf, 0x8df, 0x8ff, 0x91f, 0x93f, 0x95f, 0x97f, 0x99f, 0x9bf, 0x9df, 0x9ff, 0xa1f, 0xa3f, 0xa5f, 0xa7f, 0xa9f, 0xabf, 0xadf, 0xaff, 0xb1f, 0xb3f, 0xb5f, 0xb7f, 0xb9f, 0xbbf, 0xbdf, 0xbff, 0xc1f, 0xc3f, 0xc5f, 0xc7f, 0xc9f, 0xcbf, 0xcdf, 0xcff, 0xd1f, 0xd3f, 0xd5f, 0xd7f, 0xd9f, 0xdbf, 0xddf, 0xdff, 0xe1f, 0xe3f, 0xe5f, 0xe7f, 0xe9f, 0xebf, 0xedf, 0xeff, 0xf1f, 0xf3f, 0xf5f, 0xf7f, 0xf9f, 0xfbf, 0xfdf, 0xfff, 0xfdf, 0xfbf, 0xf9f, 0xf7f, 0xf5f, 0xf3f, 0xf1f, 0xeff, 0xedf, 0xebf, 0xe9f, 0xe7f, 0xe5f, 0xe3f, 0xe1f, 0xdff, 0xddf, 0xdbf, 0xd9f, 0xd7f, 0xd5f, 0xd3f, 0xd1f, 0xcff, 0xcdf, 0xcbf, 0xc9f, 0xc7f, 0xc5f, 0xc3f, 0xc1f, 0xbff, 0xbdf, 0xbbf, 0xb9f, 0xb7f, 0xb5f, 0xb3f, 0xb1f, 0xaff, 0xadf, 0xabf, 0xa9f, 0xa7f, 0xa5f, 0xa3f, 0xa1f, 0x9ff, 0x9df, 0x9bf, 0x99f, 0x97f, 0x95f, 0x93f, 0x91f, 0x8ff, 0x8df, 0x8bf, 0x89f, 0x87f, 0x85f, 0x83f, 0x81f, 0x800, 0x7e0, 0x7c0, 0x7a0, 0x780, 0x760, 0x740, 0x720, 0x700, 0x6e0, 0x6c0, 0x6a0, 0x680, 0x660, 0x640, 0x620, 0x600, 0x5e0, 0x5c0, 0x5a0, 0x580, 0x560, 0x540, 0x520, 0x500, 0x4e0, 0x4c0, 0x4a0, 0x480, 0x460, 0x440, 0x420, 0x400, 0x3e0, 0x3c0, 0x3a0, 0x380, 0x360, 0x340, 0x320, 0x300, 0x2e0, 0x2c0, 0x2a0, 0x280, 0x260, 0x240, 0x220, 0x200, 0x1e0, 0x1c0, 0x1a0, 0x180, 0x160, 0x140, 0x120, 0x100, 0xe0, 0xc0, 0xa0, 0x80, 0x60, 0x40, 0x20}; - +#endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE +#ifdef AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE static const dacsample_t dac_buffer_square[DAC_BUFFER_SIZE] = { [0 ... DAC_BUFFER_SIZE / 2 - 1] = 0, // first and [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = DAC_SAMPLE_MAX, // second half }; - +#endif // AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE +/* // four steps: 0, 1/3, 2/3 and 1 static const dacsample_t dac_buffer_staircase[DAC_BUFFER_SIZE] = { [0 ... DAC_BUFFER_SIZE/3 -1 ] = 0, @@ -51,6 +57,10 @@ static const dacsample_t dac_buffer_staircase[DAC_BUFFER_SIZE] = { [3 * DAC_BUFFER_SIZE / 4 ... DAC_BUFFER_SIZE -1 ] = DAC_SAMPLE_MAX, } */ +#ifdef AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID +static const dacsample_t dac_buffer_trapezoid[DAC_BUFFER_SIZE] = {0x0, 0x1f, 0x7f, 0xdf, 0x13f, 0x19f, 0x1ff, 0x25f, 0x2bf, 0x31f, 0x37f, 0x3df, 0x43f, 0x49f, 0x4ff, 0x55f, 0x5bf, 0x61f, 0x67f, 0x6df, 0x73f, 0x79f, 0x7ff, 0x85f, 0x8bf, 0x91f, 0x97f, 0x9df, 0xa3f, 0xa9f, 0xaff, 0xb5f, 0xbbf, 0xc1f, 0xc7f, 0xcdf, 0xd3f, 0xd9f, 0xdff, 0xe5f, 0xebf, 0xf1f, 0xf7f, 0xfdf, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfdf, 0xf7f, 0xf1f, 0xebf, 0xe5f, 0xdff, 0xd9f, 0xd3f, 0xcdf, 0xc7f, 0xc1f, 0xbbf, 0xb5f, 0xaff, 0xa9f, 0xa3f, 0x9df, 0x97f, 0x91f, 0x8bf, 0x85f, 0x7ff, 0x79f, 0x73f, 0x6df, 0x67f, 0x61f, 0x5bf, 0x55f, 0x4ff, 0x49f, 0x43f, 0x3df, 0x37f, 0x31f, 0x2bf, 0x25f, 0x1ff, 0x19f, 0x13f, 0xdf, 0x7f, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; +#endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID + static dacsample_t dac_buffer_empty[DAC_BUFFER_SIZE] = {DAC_OFF_VALUE}; @@ -105,15 +115,27 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { // Wavetable generation/lookup uint16_t dac_i = (uint16_t)dac_if[i]; + +#if defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) + value_avg += dac_buffer_sine[dac_i] / active_tones; +#elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE) + value_avg += dac_buffer_triangle[dac_i] / active_tones; +#elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID) + value_avg += dac_buffer_trapezoid[dac_i] / active_tones; +#elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE) + value_avg += dac_buffer_square[dac_i] / active_tones; +#endif + /* // SINE - value_avg += dac_buffer_sine[dac_i] / active_tones;// / 3; + value_avg += dac_buffer_sine[dac_i] / active_tones / 3; // TRIANGLE -// value_avg += dac_buffer_triangle[dac_i] / active_tones / 3; + value_avg += dac_buffer_triangle[dac_i] / active_tones / 3; // SQUARE -// value_avg += dac_buffer_square[dac_i] / active_tones / 3; + value_avg += dac_buffer_square[dac_i] / active_tones / 3; //NOTE: combination of these three waveforms is more exemplary - and doesn't sound particularly good :-P + */ - // STAIRS + // STAIRS (mostly usefull as test-pattern) //value_avg = dac_buffer_staircase[dac_i] / active_tones; } value = value_avg; diff --git a/util/audio_generate_dac_lut.py b/util/audio_generate_dac_lut.py new file mode 100644 index 000000000000..0be1b4eb0f74 --- /dev/null +++ b/util/audio_generate_dac_lut.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 + +DAC_BUFFER_SIZE=256 +DAC_SAMPLE_MAX=4095 + +def plot(values): + for v in values: + print('0'* int(v * 80/DAC_SAMPLE_MAX)) + +def to_lut(values): + for v in values: + print(hex(int(v)), end=", ") + + +from math import sin, tau, pi + +samples=[] + +def sampleSine(): + for s in range(DAC_BUFFER_SIZE): + samples.append((sin((s/DAC_BUFFER_SIZE)*tau - pi/2) + 1 )/2* DAC_SAMPLE_MAX) + +def sampleTriangle(): + for s in range(DAC_BUFFER_SIZE): + if s < DAC_BUFFER_SIZE/2: + samples.append(s/(DAC_BUFFER_SIZE/2) * DAC_SAMPLE_MAX) + else: + samples.append(DAC_SAMPLE_MAX - (s-DAC_BUFFER_SIZE/2)/(DAC_BUFFER_SIZE/2) * DAC_SAMPLE_MAX) + +#compromise between square and triangle wave, +def sampleTrapezoidal(): + for i in range(DAC_BUFFER_SIZE): + a=3 #slope/inclination + if (i < DAC_BUFFER_SIZE/2): + s = a * (i * DAC_SAMPLE_MAX/(DAC_BUFFER_SIZE/2)) + (1-a)*DAC_SAMPLE_MAX/2 + else: + i = i - DAC_BUFFER_SIZE/2 + s = DAC_SAMPLE_MAX - a * (i * DAC_SAMPLE_MAX/(DAC_BUFFER_SIZE/2)) - (1-a)*DAC_SAMPLE_MAX/2 + + if s < 0: + s=0 + if s> DAC_SAMPLE_MAX: + s=DAC_SAMPLE_MAX + samples.append(s) + + +#sampleSine() +sampleTrapezoidal() +#print(samples) +plot(samples) +to_lut(samples) From 88f28305b06710a971f6bee839ec39b1dc008a84 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 2 Apr 2020 15:39:24 +0200 Subject: [PATCH 052/153] audio-refactoring: heh, avr has a MIN... --- quantum/audio/audio.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 1006b87b8d12..853c7788b626 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -46,8 +46,10 @@ typedef union { }; } audio_config_t; - -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +//AVR/LUFA has a MIN, arm/chibios does not +#ifndef MIN +# define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif // ____ __ ___ // / __ \__ __/ /_ / (_)____ From 1330844191d8a83397bd41fd6c60a86db682ab2c Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 2 Apr 2020 15:40:38 +0200 Subject: [PATCH 053/153] audio-refactoring: add basic dac audio-driver based on the current/master implementation whereas current=d96380e65496912e0f68e6531565f4b45efd1623 which is the state of things before this whole audio-refactoring branch boiled down to interface with the refactored audio system = removing all redundant state-managing and frequency calculation --- quantum/audio/audio_chibios_dac_basic.c | 208 ++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 quantum/audio/audio_chibios_dac_basic.c diff --git a/quantum/audio/audio_chibios_dac_basic.c b/quantum/audio/audio_chibios_dac_basic.c new file mode 100644 index 000000000000..0d8388bb8b3b --- /dev/null +++ b/quantum/audio/audio_chibios_dac_basic.c @@ -0,0 +1,208 @@ +/* Copyright 2016-2020 Jack Humbert + * + * 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 2 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 . + */ + +#include "audio.h" +#include "ch.h" +#include "hal.h" + +/* + Audio Driver: DAC + + which utilizes both channels of the DAC unit many STM32 are equipped with to output a modulated square-wave, from precomputed samples stored in a buffer, which is passed to the hardware through DMA + + +TODOS: +- channel_X_stop should respect dac conversion buffer-complete; currently the output might end up 'high' = halfway through a sample conversion +*/ + + +// squarewave +static const dacsample_t dac_buffer_1[DAC_BUFFER_SIZE] = { + // First half is max, second half is 0 + [0 ... DAC_BUFFER_SIZE / 2 - 1] = DAC_SAMPLE_MAX, + [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = 0, +}; + +// squarewave +static const dacsample_t dac_buffer_2[DAC_BUFFER_SIZE] = { + // opposite of dac_buffer above + [0 ... DAC_BUFFER_SIZE / 2 - 1] = 0, + [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = DAC_SAMPLE_MAX, +}; + + + +GPTConfig gpt6cfg1 = {.frequency = 440U * DAC_BUFFER_SIZE, + .callback = NULL, + .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ + .dier = 0U}; + +GPTConfig gpt7cfg1 = {.frequency = 440U * DAC_BUFFER_SIZE, + .callback = NULL, + .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ + .dier = 0U}; + +static void gpt_cb8(GPTDriver *gptp); +GPTConfig gpt8cfg1 = {.frequency = 10, + .callback = gpt_cb8, + .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ + .dier = 0U}; + +/* +// DAC streaming callback. +//size_t nz = 0; +static void end_cb1(DACDriver *dacp) { + (void)dacp; +// nz++; +// if ((nz % 1000) == 0) { +// palTogglePad(GPIOD, GPIOD_LED3); +// } +} + +// DAC error callback. +static void error_cb1(DACDriver *dacp, dacerror_t err) { + (void)dacp; + (void)err; + + chSysHalt("DAC failure"); +} +*/ + +static const DACConfig dac_conf_ch1 = {.init = DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; +static const DACConfig dac_conf_ch2 = {.init = DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; + +/** + * @note The DAC_TRG(0) here selects the Timer 6 TRGO event, which is triggered + * on the rising edge after 3 APB1 clock cycles, causing our gpt6cfg1.frequency + * to be a third of what we expect. + * + * Here are all the values for DAC_TRG (TSEL in the ref manual) + * TIM15_TRGO 0b011 + * TIM2_TRGO 0b100 + * TIM3_TRGO 0b001 + * TIM6_TRGO 0b000 + * TIM7_TRGO 0b010 + * EXTI9 0b110 + * SWTRIG 0b111 + */ +static const DACConversionGroup dac_conv_grp_ch1 = {.num_channels = 1U, /* .end_cb = end_cb1, .error_cb = error_cb1, */ .trigger = DAC_TRG(0b000)}; +static const DACConversionGroup dac_conv_grp_ch2 = {.num_channels = 1U, /* .end_cb = end_cb1, .error_cb = error_cb1, */ .trigger = DAC_TRG(0b010)}; + + + +void channel_1_start(void) { + gptStart(&GPTD6, &gpt6cfg1); + gptStartContinuous(&GPTD6, 2U); +} + +void channel_1_stop(void) { + gptStopTimer(&GPTD6); +} + +static float channel_1_frequency = 0.0f; +void channel_1_set_frequency(float freq) { + channel_1_frequency = freq; + + channel_1_stop(); + if (freq <= 0.0) //a pause/rest has freq=0 + return; + + gpt6cfg1.frequency = 2 * freq * DAC_BUFFER_SIZE; + channel_1_start(); +} +float channel_1_get_frequency(void) { return channel_1_frequency; } + + +void channel_2_start(void) { + gptStart(&GPTD7, &gpt7cfg1); + gptStartContinuous(&GPTD7, 2U); +} + +void channel_2_stop(void) { + gptStopTimer(&GPTD7); +} + +static float channel_2_frequency = 0.0f; +void channel_2_set_frequency(float freq) { + channel_2_frequency = freq; + + channel_2_stop(); + if (freq <= 0.0) //a pause/rest has freq=0 + return; + + gpt7cfg1.frequency = 2 * freq * DAC_BUFFER_SIZE; + channel_2_start(); +} +float channel_2_get_frequency(void) { return channel_2_frequency; } + + +static void gpt_cb8(GPTDriver *gptp) { + // state_recently_changed = + if(audio_advance_state(1,gpt8cfg1.frequency)) { + channel_1_set_frequency(audio_get_processed_frequency(0)); + if (audio_get_number_of_active_tones() > 1) { + channel_2_set_frequency(audio_get_processed_frequency(1)); + } else { + channel_2_stop(); + } + } +} + +void audio_initialize_hardware() { +//#if defined(AUDIO_PIN_A4) + palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); + dacStart(&DACD1, &dac_conf_ch1); + dacStartConversion(&DACD1, &dac_conv_grp_ch1, (dacsample_t *)dac_buffer_1, DAC_BUFFER_SIZE); +//#endif +//#if defined(AUDIO_PIN_A5) + palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); + dacStart(&DACD2, &dac_conf_ch2); + dacStartConversion(&DACD2, &dac_conv_grp_ch2, (dacsample_t *)dac_buffer_2, DAC_BUFFER_SIZE); +//#endif + + /* enable the output buffer, to directly drive external loads with no additional circuitry + * + * see: AN4566 Application note: Extending the DAC performance of STM32 microcontrollers + * Note: Buffer-Off bit -> has to be set 0 to enable the output buffer + * Note: enabling the output buffer imparts an additional dc-offset of a couple mV + * + * this is done here, reaching directly into the stm32 registers since chibios has not implemented BOFF handling yet + * (see: chibios/os/hal/ports/STM32/todo.txt '- BOFF handling in DACv1.' + */ +//#if defined(AUDIO_PIN_A4) + DACD1.params->dac->CR &= ~DAC_CR_BOFF1; +//#endif +//#if defined(AUDIO_PIN_A5) + DACD2.params->dac->CR &= ~DAC_CR_BOFF2; +//#endif + + // initialize both timers used to trigger the DAC conversions + gptStart(&GPTD6, &gpt6cfg1); + gptStart(&GPTD7, &gpt7cfg1); + + // start state-updater + gptStart(&GPTD8, &gpt8cfg1); +} + +void audio_stop_hardware(void) { + gptStopTimer(&GPTD6); + gptStopTimer(&GPTD7); + gptStopTimer(&GPTD8); +} + +void audio_start_hardware(void) { + gptStartContinuous(&GPTD8, 2U); +} From 1286d480f340ea4c62ddc9ae89a57ae2a0e9645a Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 2 Apr 2020 15:40:50 +0200 Subject: [PATCH 054/153] audio-refactoring: rename audio-drivers to driver_$PLATFORM_$DRIVER --- common_features.mk | 19 ++++++------------- quantum/audio/audio.c | 16 ++++++++-------- quantum/audio/audio.h | 16 ++++++++-------- .../{audio_avr_pwm.h => driver_avr_pwm.h} | 0 ...io_avr_pwm.c => driver_avr_pwm_hardware.c} | 7 +++---- ...dio_chibios_dac.h => driver_chibios_dac.h} | 0 ...os_dac.c => driver_chibios_dac_additive.c} | 11 ++++++----- ...dac_basic.c => driver_chibios_dac_basic.c} | 6 +++--- ...dio_chibios_pwm.h => driver_chibios_pwm.h} | 0 ...os_pwm.c => driver_chibios_pwm_hardware.c} | 6 +++--- 10 files changed, 37 insertions(+), 44 deletions(-) rename quantum/audio/{audio_avr_pwm.h => driver_avr_pwm.h} (100%) rename quantum/audio/{audio_avr_pwm.c => driver_avr_pwm_hardware.c} (99%) rename quantum/audio/{audio_chibios_dac.h => driver_chibios_dac.h} (100%) rename quantum/audio/{audio_chibios_dac.c => driver_chibios_dac_additive.c} (97%) rename quantum/audio/{audio_chibios_dac_basic.c => driver_chibios_dac_basic.c} (98%) rename quantum/audio/{audio_chibios_pwm.h => driver_chibios_pwm.h} (100%) rename quantum/audio/{audio_chibios_pwm.c => driver_chibios_pwm_hardware.c} (98%) diff --git a/common_features.mk b/common_features.mk index 044e524f480a..9463cc2f61ad 100644 --- a/common_features.mk +++ b/common_features.mk @@ -45,20 +45,13 @@ endif AUDIO_ENABLE ?= no ifeq ($(strip $(AUDIO_ENABLE)), yes) ifeq ($(PLATFORM),CHIBIOS) - AUDIO_DRIVER ?= dac - ## stm32f2 and above have a usable DAC unit, f1 do not - ifeq ($(strip $(AUDIO_DRIVER)), dac) - OPT_DEFS += -DAUDIO_DRIVER_DAC - else ifeq ($(strip $(AUDIO_DRIVER)), pwm-pin-alternate) - OPT_DEFS += -DAUDIO_DRIVER_PWM_PIN_ALTERNATE - # reset config switch, to end up with the correct filename below - AUDIO_DRIVER := pwm - else # fallback=pwm - OPT_DEFS += -DAUDIO_DRIVER_PWM - endif + AUDIO_DRIVER ?= dac_basic + ## stm32f2 and above have a usable DAC unit, f1 do not, and need to use pwm instead + OPT_DEFS += -DAUDIO_DRIVER_DAC else # fallback for all other platforms is pwm - AUDIO_DRIVER ?= pwm + AUDIO_DRIVER ?= pwm_hardware + OPT_DEFS += -DAUDIO_DRIVER_PWM endif ifdef AUDIO_PIN OPT_DEFS += -DAUDIO_PIN=$(AUDIO_PIN) -DAUDIO_PIN_$(AUDIO_PIN) @@ -71,7 +64,7 @@ ifeq ($(strip $(AUDIO_ENABLE)), yes) SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c SRC += $(QUANTUM_DIR)/process_keycode/process_clicky.c SRC += $(QUANTUM_DIR)/audio/audio.c ## common audio code, hardware agnostic - SRC += $(QUANTUM_DIR)/audio/audio_$(PLATFORM_KEY)_$(AUDIO_DRIVER).c + SRC += $(QUANTUM_DIR)/audio/driver_$(PLATFORM_KEY)_$(AUDIO_DRIVER).c SRC += $(QUANTUM_DIR)/audio/voices.c SRC += $(QUANTUM_DIR)/audio/luts.c endif diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 3a6a4124a521..2e98f512b563 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -24,7 +24,7 @@ * notes/tones; the notes a SONG consists of; * ... * - * audio_[avr|chibios]_[dac|pwm] take care of the lower hardware dependent parts, + * driver_[avr|chibios]_[dac|pwm] take care of the lower hardware dependent parts, * specific to each platform and the used subsystem/driver to drive * the output pins/channels with the calculated frequencies for each * avtive tone @@ -38,7 +38,7 @@ float frequencies[AUDIO_TONE_STACKSIZE] = {0.0}; // frequencies of each activ //TODO: array of musical_tone_t? bool playing_notes = false; // playing a SONG? -bool playing_note = false; // or (possibly multiple simultanious) tones +bool playing_note = false; // or (possibly multiple simultaneous) tones bool state_changed = false; // global flag, which is set if anything changes with the active_tones float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs @@ -113,7 +113,7 @@ void audio_init() { #endif // ARM EEPROM if (!audio_initialized) { - audio_initialize_hardware(); + audio_driver_initialize(); audio_initialized = true; } stop_all_notes(); @@ -159,7 +159,7 @@ void stop_all_notes() { } active_tones = 0; - audio_stop_hardware(); + audio_driver_stop(); playing_notes = false; playing_note = false; @@ -198,7 +198,7 @@ void stop_note(float freq) { } #endif if (active_tones == 0) { - audio_stop_hardware(); + audio_driver_stop(); playing_note = false; } @@ -246,11 +246,11 @@ void play_note(float freq, int vol) { //NOTE: vol is unused frequencies[active_tones-1] = freq; if (active_tones==1) // sufficient to start when switching from 0 to 1 - audio_start_hardware(); + audio_driver_start(); } /* the two ways to feed the audio system: - play_note to add (or start) playing notes simultaniously with multiple tones + play_note to add (or start) playing notes simultaneously with multiple tones play_nots to playback a melody, which is just an array of notes (of different frequencies and durations) */ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) { @@ -277,7 +277,7 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) { note_length = ((*notes_pointer)[current_note][1]) * (60.0f / note_tempo); note_position = 0; // position in the currently playing note = "elapsed time" (with no specific unit, depends on how fast/slow the respective audio-driver/hardware ticks) - audio_start_hardware(); + audio_driver_start(); } } diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 853c7788b626..2fce569cf475 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -26,14 +26,14 @@ #if defined(__AVR__) # include -# include "audio_avr_pwm.h" +# include "driver_avr_pwm.h" #endif -#if defined(AUDIO_DRIVER_PWM) || defined(AUDIO_DRIVER_PWM_PIN_ALTERNATE) -# include "audio_chibios_pwm.h" +#if defined(AUDIO_DRIVER_PWM) +# include "driver_chibios_pwm.h" #endif #if defined(AUDIO_DRIVER_DAC) -# include "audio_chibios_dac.h" +# include "driver_chibios_dac.h" #endif @@ -197,10 +197,10 @@ void decrease_tempo(uint8_t tempo_change); // /_/ /_/\__,_/_/ \__,_/ |__/|__/\__,_/_/ \___/ // hardware interface -// implementation in the audio_avr/arm_* drivers -void audio_initialize_hardware(void); -void audio_start_hardware(void); -void audio_stop_hardware(void); +// implementation in the driver_avr/arm_* respective parts +void audio_driver_initialize(void); +void audio_driver_start(void); +void audio_driver_stop(void); /** * @brief get the number of currently active tones diff --git a/quantum/audio/audio_avr_pwm.h b/quantum/audio/driver_avr_pwm.h similarity index 100% rename from quantum/audio/audio_avr_pwm.h rename to quantum/audio/driver_avr_pwm.h diff --git a/quantum/audio/audio_avr_pwm.c b/quantum/audio/driver_avr_pwm_hardware.c similarity index 99% rename from quantum/audio/audio_avr_pwm.c rename to quantum/audio/driver_avr_pwm_hardware.c index b412c59499a3..89e099ddb22e 100644 --- a/quantum/audio/audio_avr_pwm.c +++ b/quantum/audio/driver_avr_pwm_hardware.c @@ -199,7 +199,7 @@ void channel_2_stop(void) { } #endif -void audio_initialize_hardware() { +void audio_driver_initialize() { #ifdef AUDIO1_PIN_SET channel_1_stop(); setPinOutput(AUDIO1_PIN); @@ -241,8 +241,7 @@ void audio_initialize_hardware() { } - -void audio_stop_hardware() { +void audio_driver_stop() { #ifdef AUDIO1_PIN_SET channel_1_stop(); #endif @@ -252,7 +251,7 @@ void audio_stop_hardware() { #endif } -void audio_start_hardware(void) { +void audio_driver_start(void) { #ifdef AUDIO1_PIN_SET channel_1_start(); if (playing_note) diff --git a/quantum/audio/audio_chibios_dac.h b/quantum/audio/driver_chibios_dac.h similarity index 100% rename from quantum/audio/audio_chibios_dac.h rename to quantum/audio/driver_chibios_dac.h diff --git a/quantum/audio/audio_chibios_dac.c b/quantum/audio/driver_chibios_dac_additive.c similarity index 97% rename from quantum/audio/audio_chibios_dac.c rename to quantum/audio/driver_chibios_dac_additive.c index f414ef9d80f9..85026e24bcb3 100644 --- a/quantum/audio/audio_chibios_dac.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -21,9 +21,11 @@ /* Audio Driver: DAC - which utilizes the dac unit many STM32 are equipped with to output a modulated sinewave from samples stored in the dac_buffer_sine array and are passed to the hardware through DMA + which utilizes the dac unit many STM32 are equipped with, to output a modulated waveform from samples stored in the dac_buffer_* array who are passed to the hardware through DMA it ia also possible to have a custom sample-LUT by implementing/overriding 'dac_value_generate' + + this driver allows for multiple simultaneous tones to be played through one single channel by doing additive wave-synthesis */ #if !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID) @@ -213,8 +215,7 @@ static const DACConfig dac_conf = {.init = DAC_SAMPLE_MAX, .datamode = DAC_DHRM_ */ static const DACConversionGroup dac_conv_cfg = {.num_channels = 1U, .end_cb = dac_end, .error_cb = dac_error, .trigger = DAC_TRG(0b000)}; - -void audio_initialize_hardware() { +void audio_driver_initialize() { #if defined(AUDIO_PIN_A4) palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); dacStart(&DACD1, &dac_conf); @@ -243,7 +244,7 @@ void audio_initialize_hardware() { #endif } -void audio_stop_hardware(void) { +void audio_driver_stop(void) { /*TODO should_stop = true continue dac until zero-crossing, then stop timer @@ -252,7 +253,7 @@ void audio_stop_hardware(void) { */ } -void audio_start_hardware(void) { +void audio_driver_start(void) { gptStart(&GPTD6, &gpt6cfg1); gptStartContinuous(&GPTD6, 2U); diff --git a/quantum/audio/audio_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c similarity index 98% rename from quantum/audio/audio_chibios_dac_basic.c rename to quantum/audio/driver_chibios_dac_basic.c index 0d8388bb8b3b..ba354d9c0e24 100644 --- a/quantum/audio/audio_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -161,7 +161,7 @@ static void gpt_cb8(GPTDriver *gptp) { } } -void audio_initialize_hardware() { +void audio_driver_initialize() { //#if defined(AUDIO_PIN_A4) palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); dacStart(&DACD1, &dac_conf_ch1); @@ -197,12 +197,12 @@ void audio_initialize_hardware() { gptStart(&GPTD8, &gpt8cfg1); } -void audio_stop_hardware(void) { +void audio_driver_stop(void) { gptStopTimer(&GPTD6); gptStopTimer(&GPTD7); gptStopTimer(&GPTD8); } -void audio_start_hardware(void) { +void audio_driver_start(void) { gptStartContinuous(&GPTD8, 2U); } diff --git a/quantum/audio/audio_chibios_pwm.h b/quantum/audio/driver_chibios_pwm.h similarity index 100% rename from quantum/audio/audio_chibios_pwm.h rename to quantum/audio/driver_chibios_pwm.h diff --git a/quantum/audio/audio_chibios_pwm.c b/quantum/audio/driver_chibios_pwm_hardware.c similarity index 98% rename from quantum/audio/audio_chibios_pwm.c rename to quantum/audio/driver_chibios_pwm_hardware.c index 5ea95d1e3c39..8832d0c226c1 100644 --- a/quantum/audio/audio_chibios_pwm.c +++ b/quantum/audio/driver_chibios_pwm_hardware.c @@ -182,7 +182,7 @@ GPTConfig gptCFG = { .callback = gpt_callback, }; -void audio_initialize_hardware(void) { +void audio_driver_initialize(void) { pwmStart(&PWMD, &pwmCFG); #if defined(AUDIO_DRIVER_PWM_PIN_ALTERNATE) @@ -202,7 +202,7 @@ void audio_initialize_hardware(void) { gptStart(&GPTD6, &gptCFG); } -void audio_start_hardware(void) { +void audio_driver_start(void) { channel_1_stop(); channel_1_start(); @@ -211,7 +211,7 @@ void audio_start_hardware(void) { } } -void audio_stop_hardware(void) { +void audio_driver_stop(void) { channel_1_stop(); gptStopTimer(&GPTD6); } From 66f5d086a02a4bc3516adbfd1745d219e7127e24 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 2 Apr 2020 15:40:59 +0200 Subject: [PATCH 055/153] audio-arm-pwm: split the software/hardware implementations into separate files which saves us partially from a 'define hell', with the tradeoff that now two somewhat similar chibios_pwm implementations have to be maintained --- common_features.mk | 10 +- quantum/audio/driver_chibios_pwm.h | 8 +- quantum/audio/driver_chibios_pwm_hardware.c | 79 ++-------- quantum/audio/driver_chibios_pwm_software.c | 159 ++++++++++++++++++++ 4 files changed, 188 insertions(+), 68 deletions(-) create mode 100644 quantum/audio/driver_chibios_pwm_software.c diff --git a/common_features.mk b/common_features.mk index 9463cc2f61ad..d6feb6ad7472 100644 --- a/common_features.mk +++ b/common_features.mk @@ -46,8 +46,16 @@ AUDIO_ENABLE ?= no ifeq ($(strip $(AUDIO_ENABLE)), yes) ifeq ($(PLATFORM),CHIBIOS) AUDIO_DRIVER ?= dac_basic + ifeq ($(strip $(AUDIO_DRIVER)), dac_basic) + OPT_DEFS += -DAUDIO_DRIVER_DAC + else ifeq ($(strip $(AUDIO_DRIVER)), dac_additive) + OPT_DEFS += -DAUDIO_DRIVER_DAC ## stm32f2 and above have a usable DAC unit, f1 do not, and need to use pwm instead - OPT_DEFS += -DAUDIO_DRIVER_DAC + else ifeq ($(strip $(AUDIO_DRIVER)), pwm_software) + OPT_DEFS += -DAUDIO_DRIVER_PWM + else ifeq ($(strip $(AUDIO_DRIVER)), pwm_hardware) + OPT_DEFS += -DAUDIO_DRIVER_PWM + endif else # fallback for all other platforms is pwm AUDIO_DRIVER ?= pwm_hardware diff --git a/quantum/audio/driver_chibios_pwm.h b/quantum/audio/driver_chibios_pwm.h index 35059fd676e0..e1e5b8a86fee 100644 --- a/quantum/audio/driver_chibios_pwm.h +++ b/quantum/audio/driver_chibios_pwm.h @@ -16,15 +16,15 @@ #pragma once -#if !defined(AUDIO_PWM_PINALTERNATE_TIMER) +#if !defined(AUDIO_PWM_TIMER) //NOTE: Timer2 seems to be used otherwise in QMK, otherwise we could default to A5 (= TIM2_CH1, with PWMD2 and alternate-function(1)) -# define AUDIO_PWM_PINALTERNATE_TIMER 1 +# define AUDIO_PWM_TIMER 1 #endif -#if !defined(AUDIO_PWM_PINALTERNATE_TIMERCHANNEL) +#if !defined(AUDIO_PWM_TIMERCHANNEL) //NOTE: sticking to the STM datasheet numbering: TIMxCH1 to TIMxCH4 // default: STM32F303CC PA8+TIM1_CH1 -> 1 -# define AUDIO_PWM_PINALTERNATE_TIMERCHANNEL 1 +# define AUDIO_PWM_TIMERCHANNEL 1 #endif #if !defined(AUDIO_PWM_PINALTERNATE_FUNCTION) diff --git a/quantum/audio/driver_chibios_pwm_hardware.c b/quantum/audio/driver_chibios_pwm_hardware.c index 8832d0c226c1..0d8946b4d57b 100644 --- a/quantum/audio/driver_chibios_pwm_hardware.c +++ b/quantum/audio/driver_chibios_pwm_hardware.c @@ -19,8 +19,8 @@ Audio Driver: PWM the duty-cycle is always kept at 50%, and the pwm-period is adjusted to match the frequency of a note to be played back. -this driver uses the chibios-PWM system to produce a squarewave on a given output pin. -Either in software through a pwm callback and set/clear; or through the pwm hardware which directly toggles the pin via its alternate function. see your MCUs datasheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function. +this driver uses the chibios-PWM system to produce a squarewave on specific output pins that are connected to the PWM hardware. +The hardware directly toggles the pin via its alternate function. see your MCUs datasheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function. */ @@ -45,8 +45,8 @@ TIM1_CH4 = PA11 so adding to config.h: #define AUDIO_PIN A8 -#define AUDIO_PWM_PINALTERNATE_TIMER 1 -#define AUDIO_PWM_PINALTERNATE_TIMERCHANNEL 1 +#define AUDIO_PWM_TIMER 1 +#define AUDIO_PWM_TIMERCHANNEL 1 */ #include "audio.h" @@ -54,63 +54,45 @@ so adding to config.h: #include "hal.h" -#if defined (AUDIO_DRIVER_PWM) -# if !defined(AUDIO_PIN) -# error "Audio feature enabled, but no pin selected - see docs/feature_audio under the ARM PWM settings" -# endif +#if !defined(AUDIO_PIN) +# error "Audio feature enabled, but no pin selected - see docs/feature_audio under the ARM PWM settings" #endif // some preprocessor trickery to get the corresponding chibios-PWMDriver #define TO_CHIBIOS_PWMD_PASTE(t) (PWMD##t) #define TO_CHIBIOS_PWMD_EVAL(t) TO_CHIBIOS_PWMD_PASTE(t) -#define PWMD TO_CHIBIOS_PWMD_EVAL(AUDIO_PWM_PINALTERNATE_TIMER) +#define PWMD TO_CHIBIOS_PWMD_EVAL(AUDIO_PWM_TIMER) extern bool playing_note; extern bool playing_notes; -#if defined(AUDIO_DRIVER_PWM) -static void pwm_audio_period_callback(PWMDriver *pwmp); -static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp); -#endif // AUDIO_DRIVER_PWM static PWMConfig pwmCFG = {.frequency = 100000, /* PWM clock frequency */ //CHIBIOS-BUG? can't set the initial period to <2, or the pwm (hard or software) takes ~130ms with .frequency=500000 for a pwmChangePeriod to take effect; with no ouput=silence in the meantime .period = 2, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ -#if defined(AUDIO_DRIVER_PWM_PIN_ALTERNATE) .callback = NULL, // no callback, the hardware directly toggles the pin -#else // AUDIO_DRIVER_PWM - .callback = pwm_audio_period_callback, -#endif .channels = { -#if AUDIO_DRIVER_PWM_PIN_ALTERNATE -# if AUDIO_PWM_PINALTERNATE_TIMERCHANNEL == 4 +#if AUDIO_PWM_TIMERCHANNEL == 4 {PWM_OUTPUT_DISABLED, NULL}, /* channel 0 -> TIMx_CH1 */ {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIMx_CH2 */ {PWM_OUTPUT_DISABLED, NULL}, /* channel 2 -> TIMx_CH3 */ {PWM_OUTPUT_ACTIVE_HIGH, NULL} /* channel 3 -> TIMx_CH4 */ -# elif AUDIO_PWM_PINALTERNATE_TIMERCHANNEL == 3 +#elif AUDIO_PWM_TIMERCHANNEL == 3 {PWM_OUTPUT_DISABLED, NULL}, {PWM_OUTPUT_DISABLED, NULL}, {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH3 */ {PWM_OUTPUT_DISABLED, NULL} -# elif AUDIO_PWM_PINALTERNATE_TIMERCHANNEL == 2 +#elif AUDIO_PWM_TIMERCHANNEL == 2 {PWM_OUTPUT_DISABLED, NULL}, {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH2 */ {PWM_OUTPUT_DISABLED, NULL}, {PWM_OUTPUT_DISABLED, NULL} -# else /*fallback to CH1 */ +#else /*fallback to CH1 */ {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH1 */ {PWM_OUTPUT_DISABLED, NULL}, {PWM_OUTPUT_DISABLED, NULL}, {PWM_OUTPUT_DISABLED, NULL} -# endif // AUDIO_DRIVER_PWM_PIN_ALTERNATE_CHANNEL -#else // AUDIO_DRIVER_PWM - // software-PWM just needs another callback on any channel - {PWM_OUTPUT_ACTIVE_HIGH, pwm_audio_channel_interrupt_callback}, /* channel 0 -> TIMx_CH1 */ - {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIMx_CH2 */ - {PWM_OUTPUT_DISABLED, NULL}, /* channel 2 -> TIMx_CH3 */ - {PWM_OUTPUT_DISABLED, NULL} /* channel 3 -> TIMx_CH4 */ #endif }, }; @@ -130,7 +112,7 @@ void channel_1_set_frequency(float freq) { pwmChangePeriod(&PWMD, period); pwmEnableChannel( &PWMD, - AUDIO_PWM_PINALTERNATE_TIMERCHANNEL -1, + AUDIO_PWM_TIMERCHANNEL -1, PWM_PERCENTAGE_TO_WIDTH(&PWMD, 5000) /*TODO: adjust by timbre */ ); } @@ -140,34 +122,12 @@ float channel_1_get_frequency(void) { return channel_1_frequency; } void channel_1_start(void) { pwmStop(&PWMD); pwmStart(&PWMD, &pwmCFG); - -#if defined(AUDIO_DRIVER_PWM) - pwmEnablePeriodicNotification(&PWMD); - pwmEnableChannelNotification(&PWMD, AUDIO_PWM_PINALTERNATE_TIMERCHANNEL-1); -#endif } void channel_1_stop(void) { pwmStop(&PWMD); - -#if defined(AUDIO_DRIVER_PWM) - palClearLine(AUDIO_PIN); // leave the line low, after last note was played -#endif } -#if defined(AUDIO_DRIVER_PWM) -// generate a PWM signal on any pin, not neccessarily the one connected to the timer -static void pwm_audio_period_callback(PWMDriver *pwmp) { - (void)pwmp; - palClearLine(AUDIO_PIN); -} -static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { - (void)pwmp; - if (channel_1_frequency > 0) - palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer -} -#endif // AUDIO_DRIVER_PWM - static void gpt_callback(GPTDriver *gptp); GPTConfig gptCFG = { /* a whole note is one beat, which is - per definition in musical_notes.h - set to 64 @@ -185,19 +145,12 @@ GPTConfig gptCFG = { void audio_driver_initialize(void) { pwmStart(&PWMD, &pwmCFG); -#if defined(AUDIO_DRIVER_PWM_PIN_ALTERNATE) -# if defined(USE_GPIOV1) // STM32F103C8 + // connect the AUDIO_PIN to the PWM hardware +#if defined(USE_GPIOV1) // STM32F103C8 palSetLineMode(AUDIO_PIN, PAL_MODE_STM32_ALTERNATE_PUSHPULL); -# else // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command) +#else // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command) palSetLineMode(AUDIO_PIN, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(AUDIO_PWM_PINALTERNATE_FUNCTION)); -# endif -#else // AUDIO_DRIVER_PWM - palSetLineMode(AUDIO_PIN, PAL_MODE_OUTPUT_PUSHPULL); - palClearLine(AUDIO_PIN); - - pwmEnablePeriodicNotification(&PWMD); // enable pwm callbacks - pwmEnableChannelNotification(&PWMD, AUDIO_PWM_PINALTERNATE_TIMERCHANNEL-1); -#endif // AUDIO_DRIVER_PWM +#endif gptStart(&GPTD6, &gptCFG); } diff --git a/quantum/audio/driver_chibios_pwm_software.c b/quantum/audio/driver_chibios_pwm_software.c new file mode 100644 index 000000000000..368db31f4754 --- /dev/null +++ b/quantum/audio/driver_chibios_pwm_software.c @@ -0,0 +1,159 @@ +/* Copyright 2020 Jack Humbert + * + * 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 2 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 . + */ + +/* +Audio Driver: PWM + +the duty-cycle is always kept at 50%, and the pwm-period is adjusted to match the frequency of a note to be played back. + +this driver uses the chibios-PWM system to produce a squarewave on any given output pin in software +- a pwm callback is used to set/clear the configured pin. + + */ +#include "audio.h" +#include "ch.h" +#include "hal.h" + + +#if !defined(AUDIO_PIN) +# error "Audio feature enabled, but no pin selected - see docs/feature_audio under the ARM PWM settings" +#endif + + +// some preprocessor trickery to get the corresponding chibios-PWMDriver +#define TO_CHIBIOS_PWMD_PASTE(t) (PWMD##t) +#define TO_CHIBIOS_PWMD_EVAL(t) TO_CHIBIOS_PWMD_PASTE(t) +#define PWMD TO_CHIBIOS_PWMD_EVAL(AUDIO_PWM_TIMER) + +extern bool playing_note; +extern bool playing_notes; + + +static void pwm_audio_period_callback(PWMDriver *pwmp); +static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp); + + +static PWMConfig pwmCFG = {.frequency = 100000, /* PWM clock frequency */ + //CHIBIOS-BUG? can't set the initial period to <2, or the pwm (hard or software) takes ~130ms with .frequency=500000 for a pwmChangePeriod to take effect; with no ouput=silence in the meantime + .period = 2, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ + .callback = pwm_audio_period_callback, + .channels = { + // software-PWM just needs another callback on any channel + {PWM_OUTPUT_ACTIVE_HIGH, pwm_audio_channel_interrupt_callback}, /* channel 0 -> TIMx_CH1 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIMx_CH2 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 2 -> TIMx_CH3 */ + {PWM_OUTPUT_DISABLED, NULL} /* channel 3 -> TIMx_CH4 */ + }, + }; + + +static float channel_1_frequency = 0.0f; +void channel_1_set_frequency(float freq) { +// if (freq == channel_1_frequency) return; + //TODO: interrupt same-frequency notes? + + channel_1_frequency = freq; + + if (freq <= 0.0) //a pause/rest has freq=0 + return; + + pwmcnt_t period = (pwmCFG.frequency / freq); + pwmChangePeriod(&PWMD, period); + pwmEnableChannel( + &PWMD, + AUDIO_PWM_TIMERCHANNEL -1, + PWM_PERCENTAGE_TO_WIDTH(&PWMD, 5000) /*TODO: adjust by timbre */ + ); +} + +float channel_1_get_frequency(void) { return channel_1_frequency; } + +void channel_1_start(void) { + pwmStop(&PWMD); + pwmStart(&PWMD, &pwmCFG); + + pwmEnablePeriodicNotification(&PWMD); + pwmEnableChannelNotification(&PWMD, AUDIO_PWM_TIMERCHANNEL-1); +} + +void channel_1_stop(void) { + pwmStop(&PWMD); + + palClearLine(AUDIO_PIN); // leave the line low, after last note was played +} + +// generate a PWM signal on any pin, not neccessarily the one connected to the timer +static void pwm_audio_period_callback(PWMDriver *pwmp) { + (void)pwmp; + palClearLine(AUDIO_PIN); +} +static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { + (void)pwmp; + if (channel_1_frequency > 0) + palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer +} + +static void gpt_callback(GPTDriver *gptp); +GPTConfig gptCFG = { + /* a whole note is one beat, which is - per definition in musical_notes.h - set to 64 + the longest note is BREAVE_DOT=128+64=192, the shortest SIXTEENTH=4 + the tempo (which might vary!) is in bpm (beats per minute) + therefore: if the timer ticks away at .frequency = (60*64)Hz, + and the .intervall counts from 64 downwards - all we need to do is increment the + note_position on each callback, and have the note_lengt = duration*tempo compare + against that; hence: audio_advance_state(step=1, end=1) + */ + .frequency = 60 * 64, + .callback = gpt_callback, +}; + +void audio_driver_initialize(void) { + pwmStart(&PWMD, &pwmCFG); + + palSetLineMode(AUDIO_PIN, PAL_MODE_OUTPUT_PUSHPULL); + palClearLine(AUDIO_PIN); + + pwmEnablePeriodicNotification(&PWMD); // enable pwm callbacks + pwmEnableChannelNotification(&PWMD, AUDIO_PWM_TIMERCHANNEL-1); + + gptStart(&GPTD6, &gptCFG); +} + +void audio_driver_start(void) { + channel_1_stop(); + channel_1_start(); + + if (playing_note || playing_notes) { + gptStartContinuous(&GPTD6, 64); + } +} + +void audio_driver_stop(void) { + channel_1_stop(); + gptStopTimer(&GPTD6); +} + +/* a regular timer task, that checks the note to be currently played + * and updates the pwm to output that frequency + */ +static void gpt_callback(GPTDriver *gptp) { + float freq;// TODO: freq_alt + + if (audio_advance_state(1, 1)) { + freq = audio_get_processed_frequency(0); // freq_alt would be index=1 + channel_1_set_frequency(freq); + } +} From a42d605a3db465627859d33937497ba78e3c0f10 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 2 Apr 2020 15:41:10 +0200 Subject: [PATCH 056/153] audio-refactoring: update documentation --- docs/feature_audio.md | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 3d1867a4e517..bf9640f046d2 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -1,6 +1,6 @@ # Audio -Your keyboard can make sounds! If you've got a Planck, Preonic, or basically any keyboard that allows access to certain PWM-capable pins, you can hook up a simple speaker and make it beep. You can use those beeps to indicate layer transitions, modifiers, special keys, or just to play some funky 8bit tunes. +Your keyboard can make sounds! If you've got a spare pin you can hook up a simple speaker and make it beep. You can use those beeps to indicate layer transitions, modifiers, special keys, or just to play some funky 8bit tunes. To activate this feature, add `AUDIO_ENABLE = yes` to your `rules.mk`. @@ -19,24 +19,34 @@ and *optionally*, a secondary voice, using Timer 1, on ONE of these pins: ## ARM based boards -Most STM32 MCUs have DAC peripherals, with a notable exception of the STM32F1xx series. Generally, the DAC peripheral drives pins A4 or A5. To enable DAC-based audio output on STM32 devices, add `AUDIO_DRIVER = dac` to `rules.mk` and set either:` +Most STM32 MCUs have DAC peripherals, with a notable exception of the STM32F1xx series. Generally, the DAC peripheral drives pins A4 or A5. To enable DAC-based audio output on STM32 devices, add `AUDIO_DRIVER = dac_basic` to `rules.mk` and set either:` `AUDIO_PIN = A4` OR `AUDIO_PIN = A5` +Another option, besides dac_basic (which produces sound through a squarewave), is to use the DAC to do additive wave synthesis. +Eith a number of predefined waveforms or by providing your own implementation to generate samples on the fly. +To use this feature set `AUDIO_DRIVER = dac_additive` in your `rules.mk`. +The used waveform defaults to a sine, but can be selected by adding one of the following defines to `config.h`: +`#define AUDIO_DAC_SAMPLE_WAVEFORM_SINE` +`#define AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE` +`#define AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID` +`#define AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE` +Should you rather choose to generate and use your own sample-table to the DAC unit, implement `uint16_t dac_value_generate(void)` in your keyboard - for an example see keyboards/planck/keymaps/synth_sample or keyboards/planck/keymaps/synth_wavetable + STM32F1xx have to fall back to using PWM (on the up side: with any pin you choose), Either: set in `rules.mk`: -`AUDIO_SYSTEM = pwm` and +`AUDIO_SYSTEM = pwm_software` and `AUDIO_PIN = C13` (can be any pin) -to have the selected pin output a pwm signal, generated from a timer callback (e.g. toggled in software) +to have the selected pin output a pwm signal, generated from a timer callback which toggles the pin in software. OR -`AUDIO_SYSTEM = pwm-pin-alternate` in `rules.mk` and in `config.h`: +`AUDIO_SYSTEM = pwm_hardware` in `rules.mk` and in `config.h`: `#define AUDIO_PIN A8` -`#define AUDIO_PWM_PINALTERNATE_TIMER 1` -`#define AUDIO_PWM_PINALTERNATE_TIMERCHANNEL 1` +`#define AUDIO_PWM_TIMER 1` +`#define AUDIO_PWM_TIMERCHANNEL 1` (as well as `#define AUDIO_PWM_PINALTERNATE_FUNCTION 42` if you are on STM32F2 or larger) which will use Timer 1 to directly drive pin PA8 through the PWM hardware (TIM1_CH1 = PA8). Should you want to use the pwm-hardware on another pin and timer - be ready to dig into the STM32 datasheet to pick the right TIMx_CHy and pin-alternate function. From e098b7fb7a6b55afbb137a1acd5315168b71e291 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 2 Apr 2020 17:07:45 +0200 Subject: [PATCH 057/153] audio-arm-dac: apply AUDIO_PIN defines to driver_chibios_dac_basic --- docs/feature_audio.md | 9 ++- quantum/audio/driver_chibios_dac_basic.c | 94 +++++++++++++----------- 2 files changed, 60 insertions(+), 43 deletions(-) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index bf9640f046d2..ab8d4db6a713 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -24,15 +24,20 @@ Most STM32 MCUs have DAC peripherals, with a notable exception of the STM32F1xx OR `AUDIO_PIN = A5` +the other DAC channel can optionally be used with a secondary speaker, just set: +`AUDIO_PIN_ALT = A4` or `AUDIO_PIN_ALT = A5` + +Do note though that the dac_basic driver is only capable of reproducing one tone per speaker/channel at a time, for more tones simultaneously, try the dac_additive driver. + Another option, besides dac_basic (which produces sound through a squarewave), is to use the DAC to do additive wave synthesis. -Eith a number of predefined waveforms or by providing your own implementation to generate samples on the fly. +With a number of predefined waveforms or by providing your own implementation to generate samples on the fly. To use this feature set `AUDIO_DRIVER = dac_additive` in your `rules.mk`. The used waveform defaults to a sine, but can be selected by adding one of the following defines to `config.h`: `#define AUDIO_DAC_SAMPLE_WAVEFORM_SINE` `#define AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE` `#define AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID` `#define AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE` -Should you rather choose to generate and use your own sample-table to the DAC unit, implement `uint16_t dac_value_generate(void)` in your keyboard - for an example see keyboards/planck/keymaps/synth_sample or keyboards/planck/keymaps/synth_wavetable +Should you rather choose to generate and use your own sample-table with the DAC unit, implement `uint16_t dac_value_generate(void)` with your keyboard - for an example implementation see keyboards/planck/keymaps/synth_sample or keyboards/planck/keymaps/synth_wavetable STM32F1xx have to fall back to using PWM (on the up side: with any pin you choose), diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index ba354d9c0e24..ea2fe8384e60 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -29,31 +29,36 @@ */ +#if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) // squarewave static const dacsample_t dac_buffer_1[DAC_BUFFER_SIZE] = { // First half is max, second half is 0 [0 ... DAC_BUFFER_SIZE / 2 - 1] = DAC_SAMPLE_MAX, [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = 0, }; - +#endif +#if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) // squarewave static const dacsample_t dac_buffer_2[DAC_BUFFER_SIZE] = { // opposite of dac_buffer above [0 ... DAC_BUFFER_SIZE / 2 - 1] = 0, [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = DAC_SAMPLE_MAX, }; +#endif - +#if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) GPTConfig gpt6cfg1 = {.frequency = 440U * DAC_BUFFER_SIZE, .callback = NULL, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U}; - +#endif +#if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) GPTConfig gpt7cfg1 = {.frequency = 440U * DAC_BUFFER_SIZE, .callback = NULL, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U}; +#endif static void gpt_cb8(GPTDriver *gptp); GPTConfig gpt8cfg1 = {.frequency = 10, @@ -61,28 +66,12 @@ GPTConfig gpt8cfg1 = {.frequency = 10, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U}; -/* -// DAC streaming callback. -//size_t nz = 0; -static void end_cb1(DACDriver *dacp) { - (void)dacp; -// nz++; -// if ((nz % 1000) == 0) { -// palTogglePad(GPIOD, GPIOD_LED3); -// } -} - -// DAC error callback. -static void error_cb1(DACDriver *dacp, dacerror_t err) { - (void)dacp; - (void)err; - - chSysHalt("DAC failure"); -} -*/ - +#if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) static const DACConfig dac_conf_ch1 = {.init = DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; +#endif +#if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) static const DACConfig dac_conf_ch2 = {.init = DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; +#endif /** * @note The DAC_TRG(0) here selects the Timer 6 TRGO event, which is triggered @@ -98,11 +87,15 @@ static const DACConfig dac_conf_ch2 = {.init = DAC_SAMPLE_MAX, .datamode = DAC_D * EXTI9 0b110 * SWTRIG 0b111 */ -static const DACConversionGroup dac_conv_grp_ch1 = {.num_channels = 1U, /* .end_cb = end_cb1, .error_cb = error_cb1, */ .trigger = DAC_TRG(0b000)}; -static const DACConversionGroup dac_conv_grp_ch2 = {.num_channels = 1U, /* .end_cb = end_cb1, .error_cb = error_cb1, */ .trigger = DAC_TRG(0b010)}; - +#if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) +static const DACConversionGroup dac_conv_grp_ch1 = {.num_channels = 1U, .trigger = DAC_TRG(0b000)}; +#endif +#if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) +static const DACConversionGroup dac_conv_grp_ch2 = {.num_channels = 1U, .trigger = DAC_TRG(0b010)}; +#endif +#if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) void channel_1_start(void) { gptStart(&GPTD6, &gpt6cfg1); gptStartContinuous(&GPTD6, 2U); @@ -124,8 +117,9 @@ void channel_1_set_frequency(float freq) { channel_1_start(); } float channel_1_get_frequency(void) { return channel_1_frequency; } +#endif // AUDIO_PIN(_ALT)_A4 - +#if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) void channel_2_start(void) { gptStart(&GPTD7, &gpt7cfg1); gptStartContinuous(&GPTD7, 2U); @@ -147,31 +141,47 @@ void channel_2_set_frequency(float freq) { channel_2_start(); } float channel_2_get_frequency(void) { return channel_2_frequency; } - +#endif // AUDIO_PIN(_ALT)_A5 static void gpt_cb8(GPTDriver *gptp) { - // state_recently_changed = if(audio_advance_state(1,gpt8cfg1.frequency)) { + +#if defined(AUDIO_PIN_A4) channel_1_set_frequency(audio_get_processed_frequency(0)); +# if defined(AUDIO_PIN_ALT_A5) if (audio_get_number_of_active_tones() > 1) { channel_2_set_frequency(audio_get_processed_frequency(1)); } else { channel_2_stop(); - } + } +# endif +#endif + +#if defined(AUDIO_PIN_A5) + channel_2_set_frequency(audio_get_processed_frequency(0)); +# if defined(AUDIO_PIN_ALT_A4) + if (audio_get_number_of_active_tones() > 1) { + channel_1_set_frequency(audio_get_processed_frequency(1)); + } else { + channel_1_stop(); + } +# endif +#endif + } } void audio_driver_initialize() { -//#if defined(AUDIO_PIN_A4) +#if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); dacStart(&DACD1, &dac_conf_ch1); dacStartConversion(&DACD1, &dac_conv_grp_ch1, (dacsample_t *)dac_buffer_1, DAC_BUFFER_SIZE); -//#endif -//#if defined(AUDIO_PIN_A5) +#endif +#if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); dacStart(&DACD2, &dac_conf_ch2); dacStartConversion(&DACD2, &dac_conv_grp_ch2, (dacsample_t *)dac_buffer_2, DAC_BUFFER_SIZE); -//#endif +#endif /* enable the output buffer, to directly drive external loads with no additional circuitry * @@ -182,24 +192,26 @@ void audio_driver_initialize() { * this is done here, reaching directly into the stm32 registers since chibios has not implemented BOFF handling yet * (see: chibios/os/hal/ports/STM32/todo.txt '- BOFF handling in DACv1.' */ -//#if defined(AUDIO_PIN_A4) +#if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) DACD1.params->dac->CR &= ~DAC_CR_BOFF1; -//#endif -//#if defined(AUDIO_PIN_A5) + gptStart(&GPTD6, &gpt6cfg1); // initialize the timer used to trigger the DAC conversions +#endif +#if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) DACD2.params->dac->CR &= ~DAC_CR_BOFF2; -//#endif - - // initialize both timers used to trigger the DAC conversions - gptStart(&GPTD6, &gpt6cfg1); gptStart(&GPTD7, &gpt7cfg1); +#endif // start state-updater gptStart(&GPTD8, &gpt8cfg1); } void audio_driver_stop(void) { +#if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) gptStopTimer(&GPTD6); +#endif +#if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) gptStopTimer(&GPTD7); +#endif gptStopTimer(&GPTD8); } From 65ed46b8c70b813d0ca4581ed1c5418f6a462994 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 2 Apr 2020 20:12:18 +0200 Subject: [PATCH 058/153] audio-arm-dac: dac_additive: stop the hardware when the last sample completed the audio system calls for a driver_stop, which is delayed until the current sample conversion finishes --- quantum/audio/driver_chibios_dac_additive.c | 27 ++++++++++++--------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index 85026e24bcb3..09a4a6ed723c 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -74,6 +74,7 @@ static bool state_recently_changed = false; //TODO have audio.c keep track of a previous state snapshot instead? static float dac_previous_frequencies[AUDIO_MAX_SIMULTANEOUS_TONES] = {0.0}; static uint8_t dac_previous_active_tones = 0; +static bool should_stop = false; /** * Generation of the waveform being passed to the callback. Declared weak so users @@ -165,6 +166,12 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { static void dac_end(DACDriver *dacp){ dacsample_t *sample_p = (dacp)->samples; + // the audio system triggered a stop, now that the sample-conversion is done stop the dac-triggering timer and go into idle + if (should_stop) { + gptStopTimer(&GPTD6); + return; + } + // work on the other half of the buffer if (dacIsBufferComplete(dacp)) { sample_p += DAC_BUFFER_SIZE/2; // 'half_index' @@ -227,6 +234,12 @@ void audio_driver_initialize() { dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, DAC_BUFFER_SIZE); #endif + /* + * Start the note timer + */ + gptStart(&GPTD8, &gpt8cfg1); + gptStartContinuous(&GPTD8, 2U); + /* enable the output buffer, to directly drive external loads with no additional circuitry * * see: AN4566 Application note: Extending the DAC performance of STM32 microcontrollers @@ -245,21 +258,13 @@ void audio_driver_initialize() { } void audio_driver_stop(void) { -/*TODO - should_stop = true - continue dac until zero-crossing, then stop timer - gptStopTimer - gptStop -*/ + should_stop = true; } void audio_driver_start(void) { gptStart(&GPTD6, &gpt6cfg1); gptStartContinuous(&GPTD6, 2U); - /* - * Start the note timer - */ - gptStart(&GPTD8, &gpt8cfg1); - gptStartContinuous(&GPTD8, 2U); + + should_stop = false; } From 4eb7d770123645707feb6a238117ac7241a4a370 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 3 Apr 2020 02:41:47 +0200 Subject: [PATCH 059/153] audio-refactoring: make function-namespace consistent - all (public) audio functions start with audio_ - also refactoring play*_notes/tones to play*_melody, to visually distance it a bit from play*_tone/_note --- quantum/audio/audio.c | 123 +++++++++++--------- quantum/audio/audio.h | 84 +++++++------ quantum/audio/driver_avr_pwm_hardware.c | 6 +- quantum/audio/driver_chibios_pwm_hardware.c | 4 +- quantum/audio/driver_chibios_pwm_software.c | 4 +- 5 files changed, 122 insertions(+), 99 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 2e98f512b563..b6924dce74b7 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -28,17 +28,30 @@ * specific to each platform and the used subsystem/driver to drive * the output pins/channels with the calculated frequencies for each * avtive tone + * + * + * A Note on terminology: + * tone and frequency are used somewhat interchangeably, in a strict wikipedia-sense: + * "(Musical) tone, a sound characterized by its duration, pitch (=frequency), + * intensity (=volume), and timbre" + * - intensity/volume is currently not handled at all, although the 'dac_additive' driver could do so + * - timbre is handled globally (TODO: only by the avr driver at the moment) + * + * a (musical) note is the combination of a pitch and a duration + * musical_notes are used to create SONG arrays; during playback their + * frequencies are handled as single successive tones, while the durations are + * kept track of in 'audio_advance_state' */ #ifndef AUDIO_TONE_STACKSIZE # define AUDIO_TONE_STACKSIZE 8 #endif -uint8_t active_tones = 0; // nuber of tones pushed onto the stack by play_note - might be more than the harware is able to reproduce at any single time +uint8_t active_tones = 0; // number of tones pushed onto the stack by audio_play_tone - might be more than the harware is able to reproduce at any single time float frequencies[AUDIO_TONE_STACKSIZE] = {0.0}; // frequencies of each active tone //TODO: array of musical_tone_t? -bool playing_notes = false; // playing a SONG? -bool playing_note = false; // or (possibly multiple simultaneous) tones +bool playing_melody = false; // playing a SONG? +bool playing_note = false; // or (possibly multiple simultaneous) tones TODO: should this be playing_tone instead, since we don't handle any duration (yet) bool state_changed = false; // global flag, which is set if anything changes with the active_tones float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs @@ -146,14 +159,14 @@ void audio_on(void) { void audio_off(void) { PLAY_SONG(audio_off_song); wait_ms(100); - stop_all_notes(); + audio_stop_all(); audio_config.enable = 0; eeconfig_update_audio(audio_config.raw); } -bool is_audio_on(void) { return (audio_config.enable != 0); } +bool audio_is_on(void) { return (audio_config.enable != 0); } -void stop_all_notes() { +void audio_stop_all() { if (!audio_initialized) { audio_init(); } @@ -161,7 +174,7 @@ void stop_all_notes() { audio_driver_stop(); - playing_notes = false; + playing_melody = false; playing_note = false; for (uint8_t i = 0; i < AUDIO_TONE_STACKSIZE; i++) { @@ -169,14 +182,14 @@ void stop_all_notes() { } } -void stop_note(float freq) { +void audio_stop_tone(float frequency) { if (playing_note) { if (!audio_initialized) { audio_init(); } bool found = false; for (int i = AUDIO_TONE_STACKSIZE-1; i >= 0; i--) { - found = (frequencies[i] == freq); + found = (frequencies[i] == frequency); if (found) { frequencies[i] = 0; for (int j = i; (j < AUDIO_TONE_STACKSIZE-1); j++) { @@ -205,9 +218,7 @@ void stop_note(float freq) { } } -//A musical tone is characterized by its duration, pitch, intensity (or loudness), and timbre (or quality) -//TODO: rename to play_frequency; since a "note" is the combination of freq+duration (?) -void play_note(float freq, int vol) { //NOTE: vol is unused +void audio_play_tone(float frequency) { if (!audio_config.enable) return; @@ -216,14 +227,14 @@ void play_note(float freq, int vol) { //NOTE: vol is unused } // roundrobin: shifting out old tones, keeping only unique ones - // if the new frequency is already amongst the active tones, shift it to the end + // if the new frequency is already amongst the active tones, shift it to the top of the stack bool found = false; for (int i = active_tones-1; i >= 0; i--) { - found = (frequencies[i] == freq); + found = (frequencies[i] == frequency); if (found) { for (int j = i; (j < active_tones-1); j++) { frequencies[j] = frequencies[j + 1]; - frequencies[j + 1] = freq; + frequencies[j + 1] = frequency; } break; } @@ -231,7 +242,7 @@ void play_note(float freq, int vol) { //NOTE: vol is unused if (found) // since this frequency played already, the hardware was already started return; - // frequency/tone is actually new, so we queue it to the end + // frequency/tone is actually new, so we put it on the top of the stack active_tones++; if (active_tones > AUDIO_TONE_STACKSIZE) { active_tones = AUDIO_TONE_STACKSIZE; @@ -243,17 +254,17 @@ void play_note(float freq, int vol) { //NOTE: vol is unused state_changed = true; playing_note = true; envelope_index = 0; // see voices.c // TODO: does what? - frequencies[active_tones-1] = freq; + frequencies[active_tones-1] = frequency; if (active_tones==1) // sufficient to start when switching from 0 to 1 audio_driver_start(); } - -/* the two ways to feed the audio system: - play_note to add (or start) playing notes simultaneously with multiple tones - play_nots to playback a melody, which is just an array of notes (of different frequencies and durations) -*/ -void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) { +/* + * the two ways to feed the audio system: + * - audio_play_tone to add (or start) playing notes simultaneously with multiple tones + * - audio_play_melody which gets passed a SONG = array of musical-notes (combinations of frequencies and durations) + */ +void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) { if (!audio_config.enable) return; @@ -263,9 +274,9 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) { if (audio_config.enable) { // Cancel note if a note is playing - if (playing_note) stop_all_notes(); + if (playing_note) audio_stop_all(); - playing_notes = true; + playing_melody = true; notes_pointer = np; notes_count = n_count; @@ -281,13 +292,13 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) { } } -bool is_playing_note(void) { return playing_note; } - -bool is_playing_notes(void) { return playing_notes; } +bool audio_is_playing_note(void) { return playing_note; } +bool audio_is_playing_melody(void) { return playing_melody; } uint8_t audio_get_number_of_active_tones(void) { return active_tones; } + float audio_get_frequency(uint8_t tone_index) { if (tone_index >= active_tones) return 0.0f; @@ -302,7 +313,7 @@ float audio_get_processed_frequency(uint8_t tone_index) { return 0.0f; int8_t index = active_tones - tone_index - 1; - // new tones are appended at the end, so the most recent/current is MAX-1 + // new tones are stacked on top (= appended at the end), so the most recent/current is MAX-1 #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING index = index - tone_multiplexing_index_shift; @@ -395,7 +406,7 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { } } - if (playing_notes) { + if (playing_melody) { if (note_frequency > 0) { #ifdef AUDIO_ENABLE_VIBRATO if (vibrato_strength > 0) { @@ -426,7 +437,7 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { if (notes_repeat) { current_note = 0; } else { - playing_notes = false; + playing_melody = false; return; } } @@ -458,7 +469,7 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { } if (!audio_config.enable) { - playing_notes = false; + playing_melody = false; playing_note = false; } } @@ -486,26 +497,26 @@ bool audio_advance_state(uint32_t step, float end) { //'playing_note' is stopped manually, so no need to keep track of it here - if (playing_notes) { + if (playing_melody) { note_position += step; goto_next_note = note_position >= (note_length * end); if (goto_next_note) { - stop_note((*notes_pointer)[current_note][0]); + audio_stop_tone((*notes_pointer)[current_note][0]); current_note++; if (current_note >= notes_count) { if (notes_repeat) { current_note = 0; } else { - playing_notes = false; + playing_melody = false; return goto_next_note; } } - play_note( - (*notes_pointer)[current_note][0], // frequency only; the duration is handled by calling this function regularly and advancing the note_position - 0xff);// volume TODO: second parameter is unused... refactor! + audio_play_tone( + (*notes_pointer)[current_note][0] // frequency only; the duration is handled by calling this function regularly and advancing the note_position + ); envelope_index = 0; @@ -517,9 +528,9 @@ bool audio_advance_state(uint32_t step, float end) { } } - if (!playing_note && !playing_notes ) - stop_all_notes(); - //TODO: trigger a stop of the hardware or just a stop_note on the last frequency? + if (!playing_note && !playing_melody ) + audio_stop_all(); + //TODO: trigger a stop of the hardware or just a audio_stop_tone on the last frequency? return goto_next_note; } @@ -543,32 +554,32 @@ float vibrato(float average_freq) { return vibrated_freq; } -void set_vibrato_rate(float rate) { vibrato_rate = rate; } -void increase_vibrato_rate(float change) { vibrato_rate *= change; } -void decrease_vibrato_rate(float change) { vibrato_rate /= change; } +void audio_set_vibrato_rate(float rate) { vibrato_rate = rate; } +void audio_increase_vibrato_rate(float change) { vibrato_rate *= change; } +void audio_decrease_vibrato_rate(float change) { vibrato_rate /= change; } # ifdef AUDIO_ENABLE_VIBRATO_STRENGTH -void set_vibrato_strength(float strength) { vibrato_strength = strength; } -void increase_vibrato_strength(float change) { vibrato_strength *= change; } -void decrease_vibrato_strength(float change) { vibrato_strength /= change; } +void audio_set_vibrato_strength(float strength) { vibrato_strength = strength; } +void audio_increase_vibrato_strength(float change) { vibrato_strength *= change; } +void audio_decrease_vibrato_strength(float change) { vibrato_strength /= change; } # endif /* AUDIO_ENABLE_VIBRATO_STRENGTH */ #endif /* AUDIO_ENABLE_VIBRATO */ // Tone-multiplexing functions #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING -void set_tone_multiplexing_rate(float rate) { tone_multiplexing_rate = rate; } -void enable_tone_multiplexing(void) { tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT; } -void disable_tone_multiplexing(void) { tone_multiplexing_rate = 0; } -void increase_tone_multiplexing_rate(float change) { tone_multiplexing_rate *= change; } -void decrease_tone_multiplexing_rate(float change) { tone_multiplexing_rate /= change; } +void audio_set_tone_multiplexing_rate(float rate) { tone_multiplexing_rate = rate; } +void audio_enable_tone_multiplexing(void) { tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT; } +void audio_disable_tone_multiplexing(void) { tone_multiplexing_rate = 0; } +void audio_increase_tone_multiplexing_rate(float change) { tone_multiplexing_rate *= change; } +void audio_decrease_tone_multiplexing_rate(float change) { tone_multiplexing_rate /= change; } #endif // Timbre function -void set_timbre(float timbre) { note_timbre = timbre; } +void audio_set_timbre(float timbre) { note_timbre = timbre; } // Tempo functions -void set_tempo(uint8_t tempo) { +void audio_set_tempo(uint8_t tempo) { if (tempo < 10) note_tempo = 10; // else if (tempo > 250) @@ -577,14 +588,14 @@ void set_tempo(uint8_t tempo) { note_tempo = tempo; } -void increase_tempo(uint8_t tempo_change) { +void audio_increase_tempo(uint8_t tempo_change) { if (tempo_change > 255-note_tempo) note_tempo = 255; else note_tempo += tempo_change; } -void decrease_tempo(uint8_t tempo_change) { +void audio_decrease_tempo(uint8_t tempo_change) { if (tempo_change >= note_tempo-10) note_tempo = 10; else diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 2fce569cf475..658decc20d27 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -82,24 +82,21 @@ void audio_off(void); /** * @brief query the if audio output is enabled */ -bool is_audio_on(void); +bool audio_is_on(void); /** - * @bried start playback of a tone/frequency - * @details the 'freq' is appended to an internal array of active tones, as a - * new tone with indefinite duration, default timbre and the given - * intensity/volume; this tone is played by the hardware until a call - * to 'stop_note' + * @bried start playback of a tone with the given frequency + * @details the 'frequency' is appended to an internal stack of active tones, + * as a new tone with indefinite duration. this tone is played by + * the hardware until a call to 'audio_stop_tone'. * should a tone with that frequency already be active, its entry - * is pushed to the end of said internal array - so no duplicate + * is put on the top of said internal stack - so no duplicate * entries are kept. * 'hardware_start' is called upon the first note. * @param[in] frequency frequency of the tone be played - * @param[in] intensity volume NOTE: currently unused (not possible with PWM, DAC could use it though) */ -void play_note(float frequency, int intensity); /// grm... should be pitch+duration only... -//TODO: void play_frequency? -//void play_tone? +void audio_play_tone(float frequency); +//TODO: add audio_play_note(float pitch, float duration, float intensity, float timbre); /** * @brief stop a given tone/frequency * @details removes the given frequency from the 'frequencies' array, stopping @@ -107,7 +104,7 @@ void play_note(float frequency, int intensity); /// grm... should be pitch+durat * beeing played. * @param[in] freq tone/frequenct to be stopped */ -void stop_note(float freq); +void audio_stop_tone(float frequency); /** * @brief play a melody * @details starts playback of a melody passed in from a SONG definition - an @@ -116,34 +113,35 @@ void stop_note(float freq); * @param[in] n_count number of MUSICAL_NOTES of the SONG * @param[in] n_repeat false for onetime, true for looped playback */ -void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat); +void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat); /** * @brief stops all playback * @details stops playback of both a meldoy as well as single tones, resetting * the internal state */ -void stop_all_notes(void); //TODO: stop_all +void audio_stop_all(void); /** * @brief query if one/multiple tones are playing */ -bool is_playing_note(void); // is_playing_tones? +bool audio_is_playing_note(void); // TODO: is_playing_tone? /** * @brief query if a melody/SONG is playing */ -bool is_playing_notes(void); // is playing_melody? or _song? +bool audio_is_playing_melody(void); -// These macros are used to allow play_notes to play an array of indeterminate +// These macros are used to allow audio_play_melody to play an array of indeterminate // length. This works around the limitation of C's sizeof operation on pointers. // The global float array for the song must be used here. #define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) /** * @brief convenience macro, to play a melody/SONG once */ -#define PLAY_SONG(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), false) +#define PLAY_SONG(note_array) audio_play_melody(¬e_array, NOTE_ARRAY_SIZE((note_array)), false) +//TODO: a 'song' is a melody plus singing/vocals -> PLAY_MELODY /** - * @brief convenience macro, to play a melody/SONG in a loop, until stopped by 'stop_all_notes' + * @brief convenience macro, to play a melody/SONG in a loop, until stopped by 'audio_stop_all' */ -#define PLAY_LOOP(note_array) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), true) +#define PLAY_LOOP(note_array) audio_play_melody(¬e_array, NOTE_ARRAY_SIZE((note_array)), true) // Vibrato rate functions @@ -154,13 +152,13 @@ bool is_playing_notes(void); // is playing_melody? or _song? // #define VIBRATO_STRENGTH_ENABLE #ifdef AUDIO_ENABLE_VIBRATO -void set_vibrato_rate(float rate); -void increase_vibrato_rate(float change); -void decrease_vibrato_rate(float change); +void audio_set_vibrato_rate(float rate); +void audio_increase_vibrato_rate(float change); +void audio_decrease_vibrato_rate(float change); # ifdef AUDIO_ENABLE_VIBRATO_STRENGTH -void set_vibrato_strength(float strength); -void increase_vibrato_strength(float change); -void decrease_vibrato_strength(float change); +void audio_set_vibrato_strength(float strength); +void audio_increase_vibrato_strength(float change); +void audio_decrease_vibrato_strength(float change); # endif #endif @@ -172,22 +170,22 @@ void decrease_vibrato_strength(float change); # define AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT 0 // 0=off, good starting value is 4; the lower the value the higher the cpu-load # endif -void set_tone_multiplexing_rate(float rate); -void enable_tone_multiplexing(void); -void disable_tone_multiplexing(void); -void increase_tone_multiplexing_rate(float change); -void decrease_tone_multiplexing_rate(float change); +void audio_set_tone_multiplexing_rate(float rate); +void audio_enable_tone_multiplexing(void); +void audio_disable_tone_multiplexing(void); +void audio_increase_tone_multiplexing_rate(float change); +void audio_decrease_tone_multiplexing_rate(float change); #endif // Timbre function -void set_timbre(float timbre); +void audio_set_timbre(float timbre); // Tempo functions -void set_tempo(uint8_t tempo); -void increase_tempo(uint8_t tempo_change); -void decrease_tempo(uint8_t tempo_change); +void audio_set_tempo(uint8_t tempo); +void audio_increase_tempo(uint8_t tempo_change); +void audio_decrease_tempo(uint8_t tempo_change); // __ __ __ @@ -260,7 +258,7 @@ bool audio_advance_state(uint32_t step, float end); // legacy and backwarts compatibility stuff #define PLAY_NOTE_ARRAY(note_array, note_repeat, deprecated_arg) \ - play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat)); \ + audio_play_melody(¬e_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat)); \ _Pragma("message \"'PLAY_NOTE_ARRAY' macro is deprecated\"") // LEGACY defines - TODO: remove and replace these in all keyboards using them @@ -296,3 +294,17 @@ bool audio_advance_state(uint32_t step, float end); # define AUDIO_PIN_C6 # define AUDIO_PIN C6 #endif + + +#define is_audio_on() audio_is_on() +#define is_playing_notes() audio_is_playing_melody() +#define is_playing_note() audio_is_playing_note() +#define stop_all_notes() audio_stop_all() +#define stop_note(f) audio_stop_tone(f) +#define play_note(f, v) audio_play_tone(f) + +#define set_timbre(t) audio_set_timbre(t) +#define set_tempo(t) audio_set_tempo(t) +#define increase_tempo(t) audio_increase_tempo(t) +#define decrease_tempo(t) audio_decrease_tempo(t) +// vibrato functions are not used in any keyboards diff --git a/quantum/audio/driver_avr_pwm_hardware.c b/quantum/audio/driver_avr_pwm_hardware.c index 89e099ddb22e..c83139a80397 100644 --- a/quantum/audio/driver_avr_pwm_hardware.c +++ b/quantum/audio/driver_avr_pwm_hardware.c @@ -25,7 +25,7 @@ // TODO: move into audio-common state extern bool playing_note; -extern bool playing_notes; +extern bool playing_melody; extern float note_timbre; #define CPU_PRESCALER 8 @@ -280,7 +280,7 @@ ISR(AUDIO1_TIMERx_COMPy_vect) { isr_counter=0; bool state_changed = audio_advance_state(1,1); - if (!playing_note && !playing_notes) { + if (!playing_note && !playing_melody) { channel_1_stop(); # ifdef AUDIO2_PIN_SET channel_2_stop(); @@ -314,7 +314,7 @@ ISR(AUDIO2_TIMERx_COMPy_vect) { isr_counter=0; bool state_changed = audio_advance_state(1,1); - if (!playing_note && !playing_notes) { + if (!playing_note && !playing_melody) { channel_2_stop(); return; } diff --git a/quantum/audio/driver_chibios_pwm_hardware.c b/quantum/audio/driver_chibios_pwm_hardware.c index 0d8946b4d57b..67142330c170 100644 --- a/quantum/audio/driver_chibios_pwm_hardware.c +++ b/quantum/audio/driver_chibios_pwm_hardware.c @@ -65,7 +65,7 @@ so adding to config.h: #define PWMD TO_CHIBIOS_PWMD_EVAL(AUDIO_PWM_TIMER) extern bool playing_note; -extern bool playing_notes; +extern bool playing_melody; static PWMConfig pwmCFG = {.frequency = 100000, /* PWM clock frequency */ @@ -159,7 +159,7 @@ void audio_driver_start(void) { channel_1_stop(); channel_1_start(); - if (playing_note || playing_notes) { + if (playing_note || playing_melody) { gptStartContinuous(&GPTD6, 64); } } diff --git a/quantum/audio/driver_chibios_pwm_software.c b/quantum/audio/driver_chibios_pwm_software.c index 368db31f4754..1dd22c37307a 100644 --- a/quantum/audio/driver_chibios_pwm_software.c +++ b/quantum/audio/driver_chibios_pwm_software.c @@ -39,7 +39,7 @@ this driver uses the chibios-PWM system to produce a squarewave on any given out #define PWMD TO_CHIBIOS_PWMD_EVAL(AUDIO_PWM_TIMER) extern bool playing_note; -extern bool playing_notes; +extern bool playing_melody; static void pwm_audio_period_callback(PWMDriver *pwmp); @@ -136,7 +136,7 @@ void audio_driver_start(void) { channel_1_stop(); channel_1_start(); - if (playing_note || playing_notes) { + if (playing_note || playing_melody) { gptStartContinuous(&GPTD6, 64); } } From b3d481bb4e0a2564d84af87fc49c9cbbf891e973 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 3 Apr 2020 16:20:32 +0200 Subject: [PATCH 060/153] audio-refactoring: consistent define namespace: DAC_ -> AUDIO_DAC_ --- docs/feature_audio.md | 4 +- .../planck/keymaps/synth_sample/keymap.c | 4 +- .../planck/keymaps/synth_sample/rules.mk | 3 ++ .../planck/keymaps/synth_sample/sample.h | 2 +- .../planck/keymaps/synth_wavetable/keymap.c | 24 ++++----- .../planck/keymaps/synth_wavetable/rules.mk | 2 +- .../keymaps/synth_wavetable/wavetable.h | 2 +- quantum/audio/driver_chibios_dac.h | 44 ++++++++-------- quantum/audio/driver_chibios_dac_additive.c | 50 +++++++++---------- quantum/audio/driver_chibios_dac_basic.c | 28 +++++------ util/audio_generate_dac_lut.py | 32 ++++++------ 11 files changed, 99 insertions(+), 96 deletions(-) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index ab8d4db6a713..83e1b4eb37a1 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -114,10 +114,10 @@ The available keycodes for audio are: ## ARM Audio Volume -For ARM devices, you can adjust the DAC sample values. If your board is too loud for you or your coworkers, you can set the max using `DAC_SAMPLE_MAX` in your `config.h`: +For ARM devices, you can adjust the DAC sample values. If your board is too loud for you or your coworkers, you can set the max using `AUDIO_DAC_SAMPLE_MAX` in your `config.h`: ```c -#define DAC_SAMPLE_MAX 65535U +#define AUDIO_DAC_SAMPLE_MAX 65535U ``` ## Music Mode diff --git a/keyboards/planck/keymaps/synth_sample/keymap.c b/keyboards/planck/keymaps/synth_sample/keymap.c index 36e88390aa91..3015b174b7c9 100644 --- a/keyboards/planck/keymaps/synth_sample/keymap.c +++ b/keyboards/planck/keymaps/synth_sample/keymap.c @@ -290,9 +290,9 @@ uint32_t dac_sample_custom_counter = 0; uint16_t dac_value_generate(void) { if (is_playing_note()) { uint16_t sample = dac_sample_custom[dac_sample_custom_counter]; - dac_sample_custom_counter = (dac_sample_custom_counter + 1) % DAC_SAMPLE_CUSTOM_LENGTH; + dac_sample_custom_counter = (dac_sample_custom_counter + 1) % AUDIO_DAC_SAMPLE_CUSTOM_LENGTH; return sample; } else { - return DAC_OFF_VALUE; + return AUDIO_DAC_OFF_VALUE; } } diff --git a/keyboards/planck/keymaps/synth_sample/rules.mk b/keyboards/planck/keymaps/synth_sample/rules.mk index e69de29bb2d1..56fb6bed2bf2 100644 --- a/keyboards/planck/keymaps/synth_sample/rules.mk +++ b/keyboards/planck/keymaps/synth_sample/rules.mk @@ -0,0 +1,3 @@ +AUDIO_ENABLE = yes +AUDIO_DRIVER = dac_additive +AUDIO_PIN = A5 diff --git a/keyboards/planck/keymaps/synth_sample/sample.h b/keyboards/planck/keymaps/synth_sample/sample.h index 5ba1be1b9738..fa63dd5d067c 100644 --- a/keyboards/planck/keymaps/synth_sample/sample.h +++ b/keyboards/planck/keymaps/synth_sample/sample.h @@ -1,4 +1,4 @@ -#define DAC_SAMPLE_CUSTOM_LENGTH 30208 +#define AUDIO_DAC_SAMPLE_CUSTOM_LENGTH 30208 static const dacsample_t dac_sample_custom[30208] = { 2041, 2039, 2039, 2037, 2035, 2037, 2037, 2037, diff --git a/keyboards/planck/keymaps/synth_wavetable/keymap.c b/keyboards/planck/keymaps/synth_wavetable/keymap.c index 2bd200cfefc2..2b3bce790f42 100644 --- a/keyboards/planck/keymaps/synth_wavetable/keymap.c +++ b/keyboards/planck/keymaps/synth_wavetable/keymap.c @@ -271,7 +271,7 @@ uint8_t dac_morph = 0; uint16_t dac_value_generate(void) { - uint16_t value = DAC_OFF_VALUE; + uint16_t value = AUDIO_DAC_OFF_VALUE; uint8_t active_tones = audio_get_number_of_active_tones(); if (active_tones > AUDIO_MAX_SIMULTANEOUS_TONES) active_tones = AUDIO_MAX_SIMULTANEOUS_TONES; @@ -280,32 +280,32 @@ uint16_t dac_value_generate(void) { uint16_t value_avg = 0; for (uint8_t i = 0; i < active_tones; i++) { dac_if[i] = dac_if[i] - + ((audio_get_frequency(i) * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE) + + ((audio_get_frequency(i) * AUDIO_DAC_BUFFER_SIZE) / AUDIO_DAC_SAMPLE_RATE) * 2/3; // necessary to adjust for the gpt-timer frequency (three times the sample rate) and the dac-conversion beeing called twice per sample // Needed because % doesn't work with floats - while (dac_if[i] >= (DAC_BUFFER_SIZE)) - dac_if[i] = dac_if[i] - DAC_BUFFER_SIZE; + while (dac_if[i] >= (AUDIO_DAC_BUFFER_SIZE)) + dac_if[i] = dac_if[i] - AUDIO_DAC_BUFFER_SIZE; - // #define DAC_MORPH_SPEED 372 - // #define DAC_MORPH_SPEED_COMPUTED (DAC_SAMPLE_RATE / DAC_WAVETABLE_CUSTOM_LENGTH * (1000 / DAC_MORPH_SPEED)) + // #define AUDIO_DAC_MORPH_SPEED 372 + // #define AUDIO_DAC_MORPH_SPEED_COMPUTED (AUDIO_DAC_SAMPLE_RATE / AUDIO_DAC_WAVETABLE_CUSTOM_LENGTH * (1000 / AUDIO_DAC_MORPH_SPEED)) uint16_t dac_i = (uint16_t)dac_if[i]; // value_avg += dac_buffer_custom[dac_morph_flipped][dac_i] / active_tones / 2 * ((dac_morph >= 63) ? 6400 - dac_morph_counter : dac_morph_counter) / 6400; // value_avg += dac_buffer_custom[dac_morph_flipped + 1][dac_i] / active_tones / 2 * ((dac_morph >= 63) ? dac_morph_counter : 6400 - dac_morph_counter) / 6400; - // value_avg += dac_wavetable_custom[dac_morph][dac_i] / active_tones / 2 * (DAC_MORPH_SPEED_COMPUTED - dac_morph_counter) / DAC_MORPH_SPEED_COMPUTED; - // value_avg += dac_wavetable_custom[dac_morph + 1][dac_i] / active_tones / 2 * dac_morph_counter / DAC_MORPH_SPEED_COMPUTED; + // value_avg += dac_wavetable_custom[dac_morph][dac_i] / active_tones / 2 * (AUDIO_DAC_MORPH_SPEED_COMPUTED - dac_morph_counter) / AUDIO_DAC_MORPH_SPEED_COMPUTED; + // value_avg += dac_wavetable_custom[dac_morph + 1][dac_i] / active_tones / 2 * dac_morph_counter / AUDIO_DAC_MORPH_SPEED_COMPUTED; value_avg += dac_wavetable_custom[dac_morph][dac_i] / active_tones; } value = value_avg; // dac_morph_counter++; - // if (dac_morph_counter >= DAC_MORPH_SPEED_COMPUTED) { + // if (dac_morph_counter >= AUDIO_DAC_MORPH_SPEED_COMPUTED) { // dac_morph_counter = 0; // dac_morph = (dac_morph + 1) % 125; // dac_morph_flipped = ((dac_morph >= 63) ? (125 - dac_morph) : dac_morph); - // dac_morph = (dac_morph + 1) % (DAC_WAVETABLE_CUSTOM_LENGTH - 1); + // dac_morph = (dac_morph + 1) % (AUDIO_DAC_WAVETABLE_CUSTOM_LENGTH - 1); // } } return value; @@ -313,10 +313,10 @@ uint16_t dac_value_generate(void) { void encoder_update(bool clockwise) { if (clockwise) { - dac_morph = (dac_morph + 1) % DAC_WAVETABLE_CUSTOM_LENGTH; + dac_morph = (dac_morph + 1) % AUDIO_DAC_WAVETABLE_CUSTOM_LENGTH; } else { if (dac_morph == 0) - dac_morph = (DAC_WAVETABLE_CUSTOM_LENGTH - 1); + dac_morph = (AUDIO_DAC_WAVETABLE_CUSTOM_LENGTH - 1); else dac_morph--; } diff --git a/keyboards/planck/keymaps/synth_wavetable/rules.mk b/keyboards/planck/keymaps/synth_wavetable/rules.mk index 39a472b63152..56fb6bed2bf2 100644 --- a/keyboards/planck/keymaps/synth_wavetable/rules.mk +++ b/keyboards/planck/keymaps/synth_wavetable/rules.mk @@ -1,3 +1,3 @@ AUDIO_ENABLE = yes -AUDIO_DRIVER = dac +AUDIO_DRIVER = dac_additive AUDIO_PIN = A5 diff --git a/keyboards/planck/keymaps/synth_wavetable/wavetable.h b/keyboards/planck/keymaps/synth_wavetable/wavetable.h index 08e9b01bce9c..0de8ee46cc82 100644 --- a/keyboards/planck/keymaps/synth_wavetable/wavetable.h +++ b/keyboards/planck/keymaps/synth_wavetable/wavetable.h @@ -1,4 +1,4 @@ -#define DAC_WAVETABLE_CUSTOM_LENGTH 64 +#define AUDIO_DAC_WAVETABLE_CUSTOM_LENGTH 64 static const dacsample_t dac_wavetable_custom[64][256] = { { diff --git a/quantum/audio/driver_chibios_dac.h b/quantum/audio/driver_chibios_dac.h index 62d0cefe156a..b33a000ca342 100644 --- a/quantum/audio/driver_chibios_dac.h +++ b/quantum/audio/driver_chibios_dac.h @@ -18,17 +18,17 @@ /** * Size of the dac_buffer arrays. All must be the same size. */ -#define DAC_BUFFER_SIZE 256U +#define AUDIO_DAC_BUFFER_SIZE 256U /** * Highest value allowed by our 12bit DAC. */ -#ifndef DAC_SAMPLE_MAX -# define DAC_SAMPLE_MAX 4095U +#ifndef AUDIO_DAC_SAMPLE_MAX +# define AUDIO_DAC_SAMPLE_MAX 4095U #endif -#if !defined(DAC_QUALITY_VERY_LOW) && !defined(DAC_QUALITY_LOW) && !defined(DAC_QUALITY_HIGH) && !defined(DAC_QUALITY_VERY_HIGH) -# define DAC_QUALITY_SANE_MINIMUM +#if !defined(AUDIO_DAC_QUALITY_VERY_LOW) && !defined(AUDIO_DAC_QUALITY_LOW) && !defined(AUDIO_DAC_QUALITY_HIGH) && !defined(AUDIO_DAC_QUALITY_VERY_HIGH) +# define AUDIO_DAC_QUALITY_SANE_MINIMUM #endif /** @@ -40,36 +40,36 @@ * (audible) discontinuities and/or starve other processes of cpu-time * (like RGB-led backlighting, ...) */ -#ifdef DAC_QUALITY_VERY_LOW -# define DAC_SAMPLE_RATE 11025U +#ifdef AUDIO_DAC_QUALITY_VERY_LOW +# define AUDIO_DAC_SAMPLE_RATE 11025U # define AUDIO_MAX_SIMULTANEOUS_TONES 8 #endif -#ifdef DAC_QUALITY_LOW -# define DAC_SAMPLE_RATE 22050U +#ifdef AUDIO_DAC_QUALITY_LOW +# define AUDIO_DAC_SAMPLE_RATE 22050U # define AUDIO_MAX_SIMULTANEOUS_TONES 4 #endif -#ifdef DAC_QUALITY_HIGH -# define DAC_SAMPLE_RATE 44100U +#ifdef AUDIO_DAC_QUALITY_HIGH +# define AUDIO_DAC_SAMPLE_RATE 44100U # define AUDIO_MAX_SIMULTANEOUS_TONES 2 #endif -#ifdef DAC_QUALITY_VERY_HIGH -# define DAC_SAMPLE_RATE 88200U +#ifdef AUDIO_DAC_QUALITY_VERY_HIGH +# define AUDIO_DAC_SAMPLE_RATE 88200U # define AUDIO_MAX_SIMULTANEOUS_TONES 1 #endif -#ifdef DAC_QUALITY_SANE_MINIMUM +#ifdef AUDIO_DAC_QUALITY_SANE_MINIMUM /* a sane-minimum config: with a tradeoff between cpu-load and tone-range * * the (currently) highest defined note is NOTE_B8 with 7902Hz; if we now * aim for an even even multiple of the buffersize, we end up with: - * ( roundUptoPow2(highest note / DAC_BUFFER_SIZE) * nyquist-rate * DAC_BUFFER_SIZE) - * 7902/256 = 30.867 * 2 * 256 ~= 16384 + * ( roundUptoPow2(highest note / AUDIO_DAC_BUFFER_SIZE) * nyquist-rate * AUDIO_DAC_BUFFER_SIZE) + * 7902/256 = 30.867 * 2 * 256 ~= 16384 * which works out (but the 'scope shows some sampling artifacts with lower harmonics :-P) */ -# define DAC_SAMPLE_RATE 16384U +# define AUDIO_DAC_SAMPLE_RATE 16384U # define AUDIO_MAX_SIMULTANEOUS_TONES 8 #endif @@ -80,8 +80,8 @@ * number of simultaneous tones. In most situations, a tenth (1/10) of the * sample rate is where notes become unbearable. */ -#ifndef DAC_SAMPLE_RATE -# define DAC_SAMPLE_RATE 44100U +#ifndef AUDIO_DAC_SAMPLE_RATE +# define AUDIO_DAC_SAMPLE_RATE 44100U #endif /** @@ -95,10 +95,10 @@ /** * The default value of the DAC when not playing anything. Certain hardware - * setups may require a high (DAC_SAMPLE_MAX) or low (0) value here. + * setups may require a high (AUDIO_DAC_SAMPLE_MAX) or low (0) value here. */ -#ifndef DAC_OFF_VALUE -# define DAC_OFF_VALUE DAC_SAMPLE_MAX / 2 +#ifndef AUDIO_DAC_OFF_VALUE +# define AUDIO_DAC_OFF_VALUE AUDIO_DAC_SAMPLE_MAX / 2 #endif /** diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index 09a4a6ed723c..dbeccc4262ce 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -35,36 +35,36 @@ #ifdef AUDIO_DAC_SAMPLE_WAVEFORM_SINE /* one full sine wave over [0,2*pi], but shifted up one amplitude and left pi/4; for the samples to start at 0 */ -static const dacsample_t dac_buffer_sine[DAC_BUFFER_SIZE] = { +static const dacsample_t dac_buffer_sine[AUDIO_DAC_BUFFER_SIZE] = { // 256 values, max 4095 0x0, 0x1, 0x2, 0x6, 0xa, 0xf, 0x16, 0x1e, 0x27, 0x32, 0x3d, 0x4a, 0x58, 0x67, 0x78, 0x89, 0x9c, 0xb0, 0xc5, 0xdb, 0xf2, 0x10a, 0x123, 0x13e, 0x159, 0x175, 0x193, 0x1b1, 0x1d1, 0x1f1, 0x212, 0x235, 0x258, 0x27c, 0x2a0, 0x2c6, 0x2ed, 0x314, 0x33c, 0x365, 0x38e, 0x3b8, 0x3e3, 0x40e, 0x43a, 0x467, 0x494, 0x4c2, 0x4f0, 0x51f, 0x54e, 0x57d, 0x5ad, 0x5dd, 0x60e, 0x63f, 0x670, 0x6a1, 0x6d3, 0x705, 0x737, 0x769, 0x79b, 0x7cd, 0x800, 0x832, 0x864, 0x896, 0x8c8, 0x8fa, 0x92c, 0x95e, 0x98f, 0x9c0, 0x9f1, 0xa22, 0xa52, 0xa82, 0xab1, 0xae0, 0xb0f, 0xb3d, 0xb6b, 0xb98, 0xbc5, 0xbf1, 0xc1c, 0xc47, 0xc71, 0xc9a, 0xcc3, 0xceb, 0xd12, 0xd39, 0xd5f, 0xd83, 0xda7, 0xdca, 0xded, 0xe0e, 0xe2e, 0xe4e, 0xe6c, 0xe8a, 0xea6, 0xec1, 0xedc, 0xef5, 0xf0d, 0xf24, 0xf3a, 0xf4f, 0xf63, 0xf76, 0xf87, 0xf98, 0xfa7, 0xfb5, 0xfc2, 0xfcd, 0xfd8, 0xfe1, 0xfe9, 0xff0, 0xff5, 0xff9, 0xffd, 0xffe, 0xfff, 0xffe, 0xffd, 0xff9, 0xff5, 0xff0, 0xfe9, 0xfe1, 0xfd8, 0xfcd, 0xfc2, 0xfb5, 0xfa7, 0xf98, 0xf87, 0xf76, 0xf63, 0xf4f, 0xf3a, 0xf24, 0xf0d, 0xef5, 0xedc, 0xec1, 0xea6, 0xe8a, 0xe6c, 0xe4e, 0xe2e, 0xe0e, 0xded, 0xdca, 0xda7, 0xd83, 0xd5f, 0xd39, 0xd12, 0xceb, 0xcc3, 0xc9a, 0xc71, 0xc47, 0xc1c, 0xbf1, 0xbc5, 0xb98, 0xb6b, 0xb3d, 0xb0f, 0xae0, 0xab1, 0xa82, 0xa52, 0xa22, 0x9f1, 0x9c0, 0x98f, 0x95e, 0x92c, 0x8fa, 0x8c8, 0x896, 0x864, 0x832, 0x800, 0x7cd, 0x79b, 0x769, 0x737, 0x705, 0x6d3, 0x6a1, 0x670, 0x63f, 0x60e, 0x5dd, 0x5ad, 0x57d, 0x54e, 0x51f, 0x4f0, 0x4c2, 0x494, 0x467, 0x43a, 0x40e, 0x3e3, 0x3b8, 0x38e, 0x365, 0x33c, 0x314, 0x2ed, 0x2c6, 0x2a0, 0x27c, 0x258, 0x235, 0x212, 0x1f1, 0x1d1, 0x1b1, 0x193, 0x175, 0x159, 0x13e, 0x123, 0x10a, 0xf2, 0xdb, 0xc5, 0xb0, 0x9c, 0x89, 0x78, 0x67, 0x58, 0x4a, 0x3d, 0x32, 0x27, 0x1e, 0x16, 0xf, 0xa, 0x6, 0x2, 0x1}; #endif // AUDIO_DAC_SAMPLE_WAVEFORM_SINE #ifdef AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE -static const dacsample_t dac_buffer_triangle[DAC_BUFFER_SIZE] = { +static const dacsample_t dac_buffer_triangle[AUDIO_DAC_BUFFER_SIZE] = { // 256 values, max 4095 0x0, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x100, 0x120, 0x140, 0x160, 0x180, 0x1a0, 0x1c0, 0x1e0, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0x400, 0x420, 0x440, 0x460, 0x480, 0x4a0, 0x4c0, 0x4e0, 0x500, 0x520, 0x540, 0x560, 0x580, 0x5a0, 0x5c0, 0x5e0, 0x600, 0x620, 0x640, 0x660, 0x680, 0x6a0, 0x6c0, 0x6e0, 0x700, 0x720, 0x740, 0x760, 0x780, 0x7a0, 0x7c0, 0x7e0, 0x800, 0x81f, 0x83f, 0x85f, 0x87f, 0x89f, 0x8bf, 0x8df, 0x8ff, 0x91f, 0x93f, 0x95f, 0x97f, 0x99f, 0x9bf, 0x9df, 0x9ff, 0xa1f, 0xa3f, 0xa5f, 0xa7f, 0xa9f, 0xabf, 0xadf, 0xaff, 0xb1f, 0xb3f, 0xb5f, 0xb7f, 0xb9f, 0xbbf, 0xbdf, 0xbff, 0xc1f, 0xc3f, 0xc5f, 0xc7f, 0xc9f, 0xcbf, 0xcdf, 0xcff, 0xd1f, 0xd3f, 0xd5f, 0xd7f, 0xd9f, 0xdbf, 0xddf, 0xdff, 0xe1f, 0xe3f, 0xe5f, 0xe7f, 0xe9f, 0xebf, 0xedf, 0xeff, 0xf1f, 0xf3f, 0xf5f, 0xf7f, 0xf9f, 0xfbf, 0xfdf, 0xfff, 0xfdf, 0xfbf, 0xf9f, 0xf7f, 0xf5f, 0xf3f, 0xf1f, 0xeff, 0xedf, 0xebf, 0xe9f, 0xe7f, 0xe5f, 0xe3f, 0xe1f, 0xdff, 0xddf, 0xdbf, 0xd9f, 0xd7f, 0xd5f, 0xd3f, 0xd1f, 0xcff, 0xcdf, 0xcbf, 0xc9f, 0xc7f, 0xc5f, 0xc3f, 0xc1f, 0xbff, 0xbdf, 0xbbf, 0xb9f, 0xb7f, 0xb5f, 0xb3f, 0xb1f, 0xaff, 0xadf, 0xabf, 0xa9f, 0xa7f, 0xa5f, 0xa3f, 0xa1f, 0x9ff, 0x9df, 0x9bf, 0x99f, 0x97f, 0x95f, 0x93f, 0x91f, 0x8ff, 0x8df, 0x8bf, 0x89f, 0x87f, 0x85f, 0x83f, 0x81f, 0x800, 0x7e0, 0x7c0, 0x7a0, 0x780, 0x760, 0x740, 0x720, 0x700, 0x6e0, 0x6c0, 0x6a0, 0x680, 0x660, 0x640, 0x620, 0x600, 0x5e0, 0x5c0, 0x5a0, 0x580, 0x560, 0x540, 0x520, 0x500, 0x4e0, 0x4c0, 0x4a0, 0x480, 0x460, 0x440, 0x420, 0x400, 0x3e0, 0x3c0, 0x3a0, 0x380, 0x360, 0x340, 0x320, 0x300, 0x2e0, 0x2c0, 0x2a0, 0x280, 0x260, 0x240, 0x220, 0x200, 0x1e0, 0x1c0, 0x1a0, 0x180, 0x160, 0x140, 0x120, 0x100, 0xe0, 0xc0, 0xa0, 0x80, 0x60, 0x40, 0x20}; #endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE #ifdef AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE -static const dacsample_t dac_buffer_square[DAC_BUFFER_SIZE] = { - [0 ... DAC_BUFFER_SIZE / 2 - 1] = 0, // first and - [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = DAC_SAMPLE_MAX, // second half +static const dacsample_t dac_buffer_square[AUDIO_DAC_BUFFER_SIZE] = { + [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1] = 0, // first and + [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = AUDIO_DAC_SAMPLE_MAX, // second half }; #endif // AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE /* // four steps: 0, 1/3, 2/3 and 1 -static const dacsample_t dac_buffer_staircase[DAC_BUFFER_SIZE] = { - [0 ... DAC_BUFFER_SIZE/3 -1 ] = 0, - [DAC_BUFFER_SIZE / 4 ... DAC_BUFFER_SIZE / 2 -1 ] = DAC_SAMPLE_MAX / 3, - [DAC_BUFFER_SIZE / 2 ... 3 * DAC_BUFFER_SIZE / 4 -1 ] = 2 * DAC_SAMPLE_MAX / 3, - [3 * DAC_BUFFER_SIZE / 4 ... DAC_BUFFER_SIZE -1 ] = DAC_SAMPLE_MAX, +static const dacsample_t dac_buffer_staircase[AUDIO_DAC_BUFFER_SIZE] = { + [0 ... AUDIO_DAC_BUFFER_SIZE/3 -1 ] = 0, + [AUDIO_DAC_BUFFER_SIZE / 4 ... AUDIO_DAC_BUFFER_SIZE / 2 -1 ] = AUDIO_DAC_SAMPLE_MAX / 3, + [AUDIO_DAC_BUFFER_SIZE / 2 ... 3 * AUDIO_DAC_BUFFER_SIZE / 4 -1 ] = 2 * AUDIO_DAC_SAMPLE_MAX / 3, + [3 * AUDIO_DAC_BUFFER_SIZE / 4 ... AUDIO_DAC_BUFFER_SIZE -1 ] = AUDIO_DAC_SAMPLE_MAX, } */ #ifdef AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID -static const dacsample_t dac_buffer_trapezoid[DAC_BUFFER_SIZE] = {0x0, 0x1f, 0x7f, 0xdf, 0x13f, 0x19f, 0x1ff, 0x25f, 0x2bf, 0x31f, 0x37f, 0x3df, 0x43f, 0x49f, 0x4ff, 0x55f, 0x5bf, 0x61f, 0x67f, 0x6df, 0x73f, 0x79f, 0x7ff, 0x85f, 0x8bf, 0x91f, 0x97f, 0x9df, 0xa3f, 0xa9f, 0xaff, 0xb5f, 0xbbf, 0xc1f, 0xc7f, 0xcdf, 0xd3f, 0xd9f, 0xdff, 0xe5f, 0xebf, 0xf1f, 0xf7f, 0xfdf, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfdf, 0xf7f, 0xf1f, 0xebf, 0xe5f, 0xdff, 0xd9f, 0xd3f, 0xcdf, 0xc7f, 0xc1f, 0xbbf, 0xb5f, 0xaff, 0xa9f, 0xa3f, 0x9df, 0x97f, 0x91f, 0x8bf, 0x85f, 0x7ff, 0x79f, 0x73f, 0x6df, 0x67f, 0x61f, 0x5bf, 0x55f, 0x4ff, 0x49f, 0x43f, 0x3df, 0x37f, 0x31f, 0x2bf, 0x25f, 0x1ff, 0x19f, 0x13f, 0xdf, 0x7f, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; +static const dacsample_t dac_buffer_trapezoid[AUDIO_DAC_BUFFER_SIZE] = {0x0, 0x1f, 0x7f, 0xdf, 0x13f, 0x19f, 0x1ff, 0x25f, 0x2bf, 0x31f, 0x37f, 0x3df, 0x43f, 0x49f, 0x4ff, 0x55f, 0x5bf, 0x61f, 0x67f, 0x6df, 0x73f, 0x79f, 0x7ff, 0x85f, 0x8bf, 0x91f, 0x97f, 0x9df, 0xa3f, 0xa9f, 0xaff, 0xb5f, 0xbbf, 0xc1f, 0xc7f, 0xcdf, 0xd3f, 0xd9f, 0xdff, 0xe5f, 0xebf, 0xf1f, 0xf7f, 0xfdf, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfdf, 0xf7f, 0xf1f, 0xebf, 0xe5f, 0xdff, 0xd9f, 0xd3f, 0xcdf, 0xc7f, 0xc1f, 0xbbf, 0xb5f, 0xaff, 0xa9f, 0xa3f, 0x9df, 0x97f, 0x91f, 0x8bf, 0x85f, 0x7ff, 0x79f, 0x73f, 0x6df, 0x67f, 0x61f, 0x5bf, 0x55f, 0x4ff, 0x49f, 0x43f, 0x3df, 0x37f, 0x31f, 0x2bf, 0x25f, 0x1ff, 0x19f, 0x13f, 0xdf, 0x7f, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; #endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID -static dacsample_t dac_buffer_empty[DAC_BUFFER_SIZE] = {DAC_OFF_VALUE}; +static dacsample_t dac_buffer_empty[AUDIO_DAC_BUFFER_SIZE] = {AUDIO_DAC_OFF_VALUE}; /* keep track of the sample position for for each frequency */ static float dac_if[AUDIO_MAX_SIMULTANEOUS_TONES] = {0.0}; @@ -81,7 +81,7 @@ static bool should_stop = false; * can override it with their own waveforms/noises. */ __attribute__((weak)) uint16_t dac_value_generate(void) { - uint16_t value = DAC_OFF_VALUE; + uint16_t value = AUDIO_DAC_OFF_VALUE; uint8_t active_tones = 0; if (state_recently_changed) { @@ -108,13 +108,13 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { dac_if[i] = dac_if[i] + ((frequency - * DAC_BUFFER_SIZE) / DAC_SAMPLE_RATE) + * AUDIO_DAC_BUFFER_SIZE) / AUDIO_DAC_SAMPLE_RATE) * 2/3; /*Note: necessary to get the correct frequencies on the DAC output (as measured with an oscilloscope), since - the gpt timer runs with 3*DAC_SAMPLE_RATE; and the DAC + the gpt timer runs with 3*AUDIO_DAC_SAMPLE_RATE; and the DAC callback is called twice per conversion.*/ - dac_if[i] = fmod(dac_if[i], DAC_BUFFER_SIZE); + dac_if[i] = fmod(dac_if[i], AUDIO_DAC_BUFFER_SIZE); // Wavetable generation/lookup uint16_t dac_i = (uint16_t)dac_if[i]; @@ -174,19 +174,19 @@ static void dac_end(DACDriver *dacp){ // work on the other half of the buffer if (dacIsBufferComplete(dacp)) { - sample_p += DAC_BUFFER_SIZE/2; // 'half_index' + sample_p += AUDIO_DAC_BUFFER_SIZE/2; // 'half_index' } - for (uint8_t s = 0; s < DAC_BUFFER_SIZE/2; s++) { + for (uint8_t s = 0; s < AUDIO_DAC_BUFFER_SIZE/2; s++) { sample_p[s] = dac_value_generate(); } // update audio internal state (note position, current_note, ...) state_recently_changed = audio_advance_state( - DAC_BUFFER_SIZE/2, - DAC_SAMPLE_RATE/ (64*2.0f/3) + AUDIO_DAC_BUFFER_SIZE/2, + AUDIO_DAC_SAMPLE_RATE/ (64*2.0f/3) /* End of the note: 64 is the number of 'units' of a whole note, 3 comes - from the gpttimer: DAC_SAMPLE_RATE * 3; 2 from the callback beeing + from the gpttimer: AUDIO_DAC_SAMPLE_RATE * 3; 2 from the callback beeing called twice per sample conversion. with a TEMPO set to 60 a whole note lasts exactly one second */ ); @@ -199,12 +199,12 @@ static void dac_error(DACDriver *dacp, dacerror_t err) { chSysHalt("DAC failure. halp"); } -static const GPTConfig gpt6cfg1 = {.frequency = DAC_SAMPLE_RATE * 3, +static const GPTConfig gpt6cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE * 3, .callback = NULL, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U}; -static const DACConfig dac_conf = {.init = DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; +static const DACConfig dac_conf = {.init = AUDIO_DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; /** * @note The DAC_TRG(0) here selects the Timer 6 TRGO event, which is triggered @@ -226,12 +226,12 @@ void audio_driver_initialize() { #if defined(AUDIO_PIN_A4) palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); dacStart(&DACD1, &dac_conf); - dacStartConversion(&DACD1, &dac_conv_cfg, dac_buffer_empty, DAC_BUFFER_SIZE); + dacStartConversion(&DACD1, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); #endif #if defined(AUDIO_PIN_A5) palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); dacStart(&DACD2, &dac_conf); - dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, DAC_BUFFER_SIZE); + dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); #endif /* diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index ea2fe8384e60..1f7da8b6ec62 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -31,30 +31,30 @@ #if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) // squarewave -static const dacsample_t dac_buffer_1[DAC_BUFFER_SIZE] = { +static const dacsample_t dac_buffer_1[AUDIO_DAC_BUFFER_SIZE] = { // First half is max, second half is 0 - [0 ... DAC_BUFFER_SIZE / 2 - 1] = DAC_SAMPLE_MAX, - [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = 0, + [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1] = AUDIO_DAC_SAMPLE_MAX, + [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = 0, }; #endif #if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) // squarewave -static const dacsample_t dac_buffer_2[DAC_BUFFER_SIZE] = { +static const dacsample_t dac_buffer_2[AUDIO_DAC_BUFFER_SIZE] = { // opposite of dac_buffer above - [0 ... DAC_BUFFER_SIZE / 2 - 1] = 0, - [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = DAC_SAMPLE_MAX, + [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1] = 0, + [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = AUDIO_DAC_SAMPLE_MAX, }; #endif #if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) -GPTConfig gpt6cfg1 = {.frequency = 440U * DAC_BUFFER_SIZE, +GPTConfig gpt6cfg1 = {.frequency = 440U * AUDIO_DAC_BUFFER_SIZE, .callback = NULL, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U}; #endif #if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) -GPTConfig gpt7cfg1 = {.frequency = 440U * DAC_BUFFER_SIZE, +GPTConfig gpt7cfg1 = {.frequency = 440U * AUDIO_DAC_BUFFER_SIZE, .callback = NULL, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U}; @@ -67,10 +67,10 @@ GPTConfig gpt8cfg1 = {.frequency = 10, .dier = 0U}; #if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) -static const DACConfig dac_conf_ch1 = {.init = DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; +static const DACConfig dac_conf_ch1 = {.init = AUDIO_DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; #endif #if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) -static const DACConfig dac_conf_ch2 = {.init = DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; +static const DACConfig dac_conf_ch2 = {.init = AUDIO_DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; #endif /** @@ -113,7 +113,7 @@ void channel_1_set_frequency(float freq) { if (freq <= 0.0) //a pause/rest has freq=0 return; - gpt6cfg1.frequency = 2 * freq * DAC_BUFFER_SIZE; + gpt6cfg1.frequency = 2 * freq * AUDIO_DAC_BUFFER_SIZE; channel_1_start(); } float channel_1_get_frequency(void) { return channel_1_frequency; } @@ -137,7 +137,7 @@ void channel_2_set_frequency(float freq) { if (freq <= 0.0) //a pause/rest has freq=0 return; - gpt7cfg1.frequency = 2 * freq * DAC_BUFFER_SIZE; + gpt7cfg1.frequency = 2 * freq * AUDIO_DAC_BUFFER_SIZE; channel_2_start(); } float channel_2_get_frequency(void) { return channel_2_frequency; } @@ -175,12 +175,12 @@ void audio_driver_initialize() { #if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); dacStart(&DACD1, &dac_conf_ch1); - dacStartConversion(&DACD1, &dac_conv_grp_ch1, (dacsample_t *)dac_buffer_1, DAC_BUFFER_SIZE); + dacStartConversion(&DACD1, &dac_conv_grp_ch1, (dacsample_t *)dac_buffer_1, AUDIO_DAC_BUFFER_SIZE); #endif #if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); dacStart(&DACD2, &dac_conf_ch2); - dacStartConversion(&DACD2, &dac_conv_grp_ch2, (dacsample_t *)dac_buffer_2, DAC_BUFFER_SIZE); + dacStartConversion(&DACD2, &dac_conv_grp_ch2, (dacsample_t *)dac_buffer_2, AUDIO_DAC_BUFFER_SIZE); #endif /* enable the output buffer, to directly drive external loads with no additional circuitry diff --git a/util/audio_generate_dac_lut.py b/util/audio_generate_dac_lut.py index 0be1b4eb0f74..e8c7be851625 100644 --- a/util/audio_generate_dac_lut.py +++ b/util/audio_generate_dac_lut.py @@ -1,11 +1,11 @@ #!/usr/bin/env python3 -DAC_BUFFER_SIZE=256 -DAC_SAMPLE_MAX=4095 +AUDIO_DAC_BUFFER_SIZE=256 +AUDIO_DAC_SAMPLE_MAX=4095 def plot(values): for v in values: - print('0'* int(v * 80/DAC_SAMPLE_MAX)) + print('0'* int(v * 80/AUDIO_DAC_SAMPLE_MAX)) def to_lut(values): for v in values: @@ -17,30 +17,30 @@ def to_lut(values): samples=[] def sampleSine(): - for s in range(DAC_BUFFER_SIZE): - samples.append((sin((s/DAC_BUFFER_SIZE)*tau - pi/2) + 1 )/2* DAC_SAMPLE_MAX) + for s in range(AUDIO_DAC_BUFFER_SIZE): + samples.append((sin((s/AUDIO_DAC_BUFFER_SIZE)*tau - pi/2) + 1 )/2* AUDIO_DAC_SAMPLE_MAX) def sampleTriangle(): - for s in range(DAC_BUFFER_SIZE): - if s < DAC_BUFFER_SIZE/2: - samples.append(s/(DAC_BUFFER_SIZE/2) * DAC_SAMPLE_MAX) + for s in range(AUDIO_DAC_BUFFER_SIZE): + if s < AUDIO_DAC_BUFFER_SIZE/2: + samples.append(s/(AUDIO_DAC_BUFFER_SIZE/2) * AUDIO_DAC_SAMPLE_MAX) else: - samples.append(DAC_SAMPLE_MAX - (s-DAC_BUFFER_SIZE/2)/(DAC_BUFFER_SIZE/2) * DAC_SAMPLE_MAX) + samples.append(AUDIO_DAC_SAMPLE_MAX - (s-AUDIO_DAC_BUFFER_SIZE/2)/(AUDIO_DAC_BUFFER_SIZE/2) * AUDIO_DAC_SAMPLE_MAX) #compromise between square and triangle wave, def sampleTrapezoidal(): - for i in range(DAC_BUFFER_SIZE): + for i in range(AUDIO_DAC_BUFFER_SIZE): a=3 #slope/inclination - if (i < DAC_BUFFER_SIZE/2): - s = a * (i * DAC_SAMPLE_MAX/(DAC_BUFFER_SIZE/2)) + (1-a)*DAC_SAMPLE_MAX/2 + if (i < AUDIO_DAC_BUFFER_SIZE/2): + s = a * (i * AUDIO_DAC_SAMPLE_MAX/(AUDIO_DAC_BUFFER_SIZE/2)) + (1-a)*AUDIO_DAC_SAMPLE_MAX/2 else: - i = i - DAC_BUFFER_SIZE/2 - s = DAC_SAMPLE_MAX - a * (i * DAC_SAMPLE_MAX/(DAC_BUFFER_SIZE/2)) - (1-a)*DAC_SAMPLE_MAX/2 + i = i - AUDIO_DAC_BUFFER_SIZE/2 + s = AUDIO_DAC_SAMPLE_MAX - a * (i * AUDIO_DAC_SAMPLE_MAX/(AUDIO_DAC_BUFFER_SIZE/2)) - (1-a)*AUDIO_DAC_SAMPLE_MAX/2 if s < 0: s=0 - if s> DAC_SAMPLE_MAX: - s=DAC_SAMPLE_MAX + if s> AUDIO_DAC_SAMPLE_MAX: + s=AUDIO_DAC_SAMPLE_MAX samples.append(s) From 404b5e37ee3be2beecc22c1080e0ea116aefa904 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 3 Apr 2020 16:20:41 +0200 Subject: [PATCH 061/153] audio-arm-dac: update (inline) documentation regarding MAX for sample values --- docs/feature_audio.md | 6 +++++- quantum/audio/audio.h | 5 ++--- quantum/audio/driver_chibios_dac.h | 7 ++++++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 83e1b4eb37a1..d514c888d311 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -117,8 +117,12 @@ The available keycodes for audio are: For ARM devices, you can adjust the DAC sample values. If your board is too loud for you or your coworkers, you can set the max using `AUDIO_DAC_SAMPLE_MAX` in your `config.h`: ```c -#define AUDIO_DAC_SAMPLE_MAX 65535U +#define AUDIO_DAC_SAMPLE_MAX 4095U ``` +the DAC usually runs in 12Bit mode, hence a volume of 100% = 4095U + +Note: this only adjusts the volume aka 'works' if you stick to WAVEFORM_SQUARE, since its samples are generated on the fly - any other waveform uses a hardcoded/precomputed sample-buffer. + ## Music Mode diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 658decc20d27..8355327d832c 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -146,10 +146,9 @@ bool audio_is_playing_melody(void); // Vibrato rate functions -// #define VIBRATO_ENABLE - +// #define AUDIO_ENABLE_VIBRATO // Enable vibrato strength/amplitude - slows down ISR too much (TODO: from/for/on avr only?) -// #define VIBRATO_STRENGTH_ENABLE +// #define AUDIO_ENABLE_VIBRATO_STRENGTH #ifdef AUDIO_ENABLE_VIBRATO void audio_set_vibrato_rate(float rate); diff --git a/quantum/audio/driver_chibios_dac.h b/quantum/audio/driver_chibios_dac.h index b33a000ca342..e0c178614dba 100644 --- a/quantum/audio/driver_chibios_dac.h +++ b/quantum/audio/driver_chibios_dac.h @@ -21,7 +21,12 @@ #define AUDIO_DAC_BUFFER_SIZE 256U /** - * Highest value allowed by our 12bit DAC. + * Highest value allowed sample value. + + * since the DAC is limited to 12 bit, the absolute max is 0xfff = 4095U; + * lower values adjust the peak-voltage aka volume down. + * adjusting this value has only an effect on a sample-buffer whose values are + * are NOT pregenerated - see squarewave */ #ifndef AUDIO_DAC_SAMPLE_MAX # define AUDIO_DAC_SAMPLE_MAX 4095U From 94efb30a401f2e7dd335131561ac297f5adfae6b Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 3 Apr 2020 16:53:24 +0200 Subject: [PATCH 062/153] audio-chibios-dac: remove zero-crossing feature didn't quite work as intended anyway, and stopping the hardware on close-to-zero seems to be enought anyway --- quantum/audio/driver_chibios_dac_additive.c | 74 ++++++++------------- 1 file changed, 28 insertions(+), 46 deletions(-) diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index dbeccc4262ce..f3234d0709e2 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -69,12 +69,7 @@ static dacsample_t dac_buffer_empty[AUDIO_DAC_BUFFER_SIZE] = {AUDIO_DAC_OFF_VALU /* keep track of the sample position for for each frequency */ static float dac_if[AUDIO_MAX_SIMULTANEOUS_TONES] = {0.0}; -/* state-"freezer", so we can continue playing tones until they cross-zero, then switch to the new ones*/ -static bool state_recently_changed = false; -//TODO have audio.c keep track of a previous state snapshot instead? -static float dac_previous_frequencies[AUDIO_MAX_SIMULTANEOUS_TONES] = {0.0}; -static uint8_t dac_previous_active_tones = 0; -static bool should_stop = false; +static uint8_t hardware_should_stop = 0; /** * Generation of the waveform being passed to the callback. Declared weak so users @@ -84,13 +79,12 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { uint16_t value = AUDIO_DAC_OFF_VALUE; uint8_t active_tones = 0; - if (state_recently_changed) { - active_tones = dac_previous_active_tones; - } else { - active_tones = MIN(AUDIO_MAX_SIMULTANEOUS_TONES, audio_get_number_of_active_tones()); - dac_previous_active_tones = active_tones; + if (hardware_should_stop > 0) { + return 0.0f; } + active_tones = MIN(AUDIO_MAX_SIMULTANEOUS_TONES-1, audio_get_number_of_active_tones()); + /* doing additive wave synthesis over all currently playing tones = adding up * sine-wave-samples for each frequency, scaled by the number of active tones */ @@ -99,12 +93,7 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { float frequency = 0.0f; for (uint8_t i = 0; i < active_tones; i++) { - if (state_recently_changed) { // work from freezer, until zero crossing - frequency = dac_previous_frequencies[i]; - } else { // feed the freezer - frequency = audio_get_frequency(i); //TODO: replace by glissando+vibrato+.. variant - dac_previous_frequencies[i] = frequency; - } + frequency = audio_get_processed_frequency(i); dac_if[i] = dac_if[i] + ((frequency @@ -142,18 +131,6 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { //value_avg = dac_buffer_staircase[dac_i] / active_tones; } value = value_avg; - - // zero crossing/proximity => unfreeze - if ((value < 0xf) //arbitrary value near zero - && state_recently_changed) { - state_recently_changed=false; - /* the waveform sum approaches zero, each sample index can still point - * to a non-zero value; so all have to be reset - * Note: for this to work without clicks, the samples have to start at zero - */ - for (uint8_t i = 0; i < AUDIO_MAX_SIMULTANEOUS_TONES; i++) - dac_if[i] = 0.0f; - } } return value; } @@ -166,23 +143,29 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { static void dac_end(DACDriver *dacp){ dacsample_t *sample_p = (dacp)->samples; - // the audio system triggered a stop, now that the sample-conversion is done stop the dac-triggering timer and go into idle - if (should_stop) { - gptStopTimer(&GPTD6); - return; - } - // work on the other half of the buffer if (dacIsBufferComplete(dacp)) { sample_p += AUDIO_DAC_BUFFER_SIZE/2; // 'half_index' } - for (uint8_t s = 0; s < AUDIO_DAC_BUFFER_SIZE/2; s++) { + uint8_t s = 0; + for (s = 0; s < AUDIO_DAC_BUFFER_SIZE/2; s++) { sample_p[s] = dac_value_generate(); } + // looking at the last sample of the second buffer-half + if ((sample_p[s] < 0x5) //arbitrary value near zero + && !dacIsBufferComplete(dacp)) { + + // the audio system triggered a stop, now that the sample-conversion is done stop the dac-triggering timer and go into idle + if (hardware_should_stop > 0) { + hardware_should_stop=2; + gptStopTimer(&GPTD6); + } + } + // update audio internal state (note position, current_note, ...) - state_recently_changed = audio_advance_state( + audio_advance_state( AUDIO_DAC_BUFFER_SIZE/2, AUDIO_DAC_SAMPLE_RATE/ (64*2.0f/3) /* End of the note: 64 is the number of 'units' of a whole note, 3 comes @@ -224,12 +207,11 @@ static const DACConversionGroup dac_conv_cfg = {.num_channels = 1U, .end_cb = da void audio_driver_initialize() { #if defined(AUDIO_PIN_A4) - palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); + palSetLineMode(A4, PAL_MODE_INPUT_ANALOG); dacStart(&DACD1, &dac_conf); dacStartConversion(&DACD1, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); -#endif -#if defined(AUDIO_PIN_A5) - palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); +#elif defined(AUDIO_PIN_A5) + palSetLineMode(A5, PAL_MODE_INPUT_ANALOG); dacStart(&DACD2, &dac_conf); dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); #endif @@ -251,20 +233,20 @@ void audio_driver_initialize() { */ #if defined(AUDIO_PIN_A4) DACD1.params->dac->CR &= ~DAC_CR_BOFF1; -#endif -#if defined(AUDIO_PIN_A5) +#elif defined(AUDIO_PIN_A5) DACD2.params->dac->CR &= ~DAC_CR_BOFF2; #endif } void audio_driver_stop(void) { - should_stop = true; + hardware_should_stop=1; } void audio_driver_start(void) { gptStart(&GPTD6, &gpt6cfg1); gptStartContinuous(&GPTD6, 2U); - - should_stop = false; + for (uint8_t i = 0; i < AUDIO_MAX_SIMULTANEOUS_TONES; i++) + dac_if[i] = 0.0f; + hardware_should_stop = 0; } From 15b76b01c89ff664931f260947a870263b680378 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 4 Apr 2020 07:40:48 +0200 Subject: [PATCH 063/153] audio-arm-dac: dac_basic: respect the configured sample-rate --- quantum/audio/driver_chibios_dac.h | 3 ++- quantum/audio/driver_chibios_dac_basic.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/quantum/audio/driver_chibios_dac.h b/quantum/audio/driver_chibios_dac.h index e0c178614dba..1b579c6b6262 100644 --- a/quantum/audio/driver_chibios_dac.h +++ b/quantum/audio/driver_chibios_dac.h @@ -32,7 +32,8 @@ # define AUDIO_DAC_SAMPLE_MAX 4095U #endif -#if !defined(AUDIO_DAC_QUALITY_VERY_LOW) && !defined(AUDIO_DAC_QUALITY_LOW) && !defined(AUDIO_DAC_QUALITY_HIGH) && !defined(AUDIO_DAC_QUALITY_VERY_HIGH) +#if !defined(AUDIO_DAC_SAMPLE_RATE) && !defined(AUDIO_MAX_SIMULTANEOUS_TONES) && \ + !defined(AUDIO_DAC_QUALITY_VERY_LOW) && !defined(AUDIO_DAC_QUALITY_LOW) && !defined(AUDIO_DAC_QUALITY_HIGH) && !defined(AUDIO_DAC_QUALITY_VERY_HIGH) # define AUDIO_DAC_QUALITY_SANE_MINIMUM #endif diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index 1f7da8b6ec62..8c77ef227a0f 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -48,13 +48,13 @@ static const dacsample_t dac_buffer_2[AUDIO_DAC_BUFFER_SIZE] = { #if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) -GPTConfig gpt6cfg1 = {.frequency = 440U * AUDIO_DAC_BUFFER_SIZE, +GPTConfig gpt6cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE, .callback = NULL, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U}; #endif #if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) -GPTConfig gpt7cfg1 = {.frequency = 440U * AUDIO_DAC_BUFFER_SIZE, +GPTConfig gpt7cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE, .callback = NULL, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U}; From 7e1c67036145777895b4a708eb305d438edda39a Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Apr 2020 16:00:11 +0200 Subject: [PATCH 064/153] audio-arm-pwm: have 'note_timbre' influence the pwm-duty cycle like it already does in the avr implementation --- quantum/audio/audio.c | 10 +++++++++- quantum/audio/audio.h | 7 +++++++ quantum/audio/driver_chibios_pwm_hardware.c | 4 +++- quantum/audio/driver_chibios_pwm_software.c | 5 ++++- quantum/audio/voices.c | 2 +- 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index b6924dce74b7..ce007b28d40c 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -575,7 +575,15 @@ void audio_decrease_tone_multiplexing_rate(float change) { tone_multiplexing_rat // Timbre function -void audio_set_timbre(float timbre) { note_timbre = timbre; } +void audio_set_timbre(float timbre) { + if ((timbre > 0.0f) && (timbre < 1.0f)) { + note_timbre = timbre; + } +} +float audio_get_timbre(void) { + return note_timbre; +} + // Tempo functions diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 8355327d832c..9c1740624071 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -178,7 +178,14 @@ void audio_decrease_tone_multiplexing_rate(float change); // Timbre function +/** + * @brief set the global timbre for tones to be played + * @note: only applies to pwm implementations - where it adjusts the duty-cycle + * @note: using any instrument from voices.[ch] other than 'default' may override the set value + * @param[in]: timbre: valid range is (0.0,1.0) + */ void audio_set_timbre(float timbre); +float audio_get_timbre(void); // Tempo functions diff --git a/quantum/audio/driver_chibios_pwm_hardware.c b/quantum/audio/driver_chibios_pwm_hardware.c index 67142330c170..0811a388c1c3 100644 --- a/quantum/audio/driver_chibios_pwm_hardware.c +++ b/quantum/audio/driver_chibios_pwm_hardware.c @@ -66,6 +66,7 @@ so adding to config.h: extern bool playing_note; extern bool playing_melody; +extern float note_timbre; static PWMConfig pwmCFG = {.frequency = 100000, /* PWM clock frequency */ @@ -113,7 +114,8 @@ void channel_1_set_frequency(float freq) { pwmEnableChannel( &PWMD, AUDIO_PWM_TIMERCHANNEL -1, - PWM_PERCENTAGE_TO_WIDTH(&PWMD, 5000) /*TODO: adjust by timbre */ + // adjust the duty-cycle so that the output is for 'note_timbre' duration HIGH + PWM_PERCENTAGE_TO_WIDTH(&PWMD, (1.0f-note_timbre) * 10000) ); } diff --git a/quantum/audio/driver_chibios_pwm_software.c b/quantum/audio/driver_chibios_pwm_software.c index 1dd22c37307a..48541711dc10 100644 --- a/quantum/audio/driver_chibios_pwm_software.c +++ b/quantum/audio/driver_chibios_pwm_software.c @@ -40,6 +40,7 @@ this driver uses the chibios-PWM system to produce a squarewave on any given out extern bool playing_note; extern bool playing_melody; +extern float note_timbre; static void pwm_audio_period_callback(PWMDriver *pwmp); @@ -72,10 +73,12 @@ void channel_1_set_frequency(float freq) { pwmcnt_t period = (pwmCFG.frequency / freq); pwmChangePeriod(&PWMD, period); + pwmEnableChannel( &PWMD, AUDIO_PWM_TIMERCHANNEL -1, - PWM_PERCENTAGE_TO_WIDTH(&PWMD, 5000) /*TODO: adjust by timbre */ + // adjust the duty-cycle so that the output is for 'note_timbre' duration HIGH + PWM_PERCENTAGE_TO_WIDTH(&PWMD, (1.0f-note_timbre) * 10000) ); } diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 65194769e621..bce8f9a2e9c4 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -37,7 +37,7 @@ float voice_envelope(float frequency) { switch (voice) { case default_voice: glissando = false; - note_timbre = TIMBRE_50; + //note_timbre = TIMBRE_50; //Note: leave the user the possibility to adjust the timbre with 'audio_set_timbre' break; #ifdef AUDIO_VOICES From 0c14fc8f65515fc316f4376f75aba194a245b1c2 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Apr 2020 16:00:35 +0200 Subject: [PATCH 065/153] audio-refactoring: get VIBRATO working (again) with all drivers (verified with chibios_[dac|pwm]) --- quantum/audio/audio.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index ce007b28d40c..9908536ed38a 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -79,8 +79,10 @@ bool note_resting = false; //?? current note is a pause? or is this supposed #ifdef AUDIO_ENABLE_VIBRATO float vibrato_counter = 0; -float vibrato_strength = .5; +float vibrato_strength = 0.5; float vibrato_rate = 0.125; +// forward declataion +float vibrato(float average_freq); #endif // used by voices.c @@ -492,6 +494,10 @@ bool audio_advance_state(uint32_t step, float end) { tone_multiplexing_index_shift = 0; goto_next_note = true; } +#endif +#ifdef AUDIO_ENABLE_VIBRATO + // force update on each cycle, since vibrato shifts the frequency slightly + goto_next_note = true; #endif } From 4690dc15f8fe9926be1d03acbd25ca8a90274638 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Apr 2020 16:00:55 +0200 Subject: [PATCH 066/153] audio-arm-dac: zero-crossing feature (Mk II) wait for the generated waveform to approach 'zero' before either turning off the output+timer or switching to the current set of active_tones --- quantum/audio/audio.c | 2 +- quantum/audio/driver_chibios_dac_additive.c | 146 +++++++++++++------- 2 files changed, 98 insertions(+), 50 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 9908536ed38a..c636fcc99646 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -516,7 +516,7 @@ bool audio_advance_state(uint32_t step, float end) { current_note = 0; } else { playing_melody = false; - return goto_next_note; + return true; } } diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index f3234d0709e2..40ae0238e036 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -69,7 +69,22 @@ static dacsample_t dac_buffer_empty[AUDIO_DAC_BUFFER_SIZE] = {AUDIO_DAC_OFF_VALU /* keep track of the sample position for for each frequency */ static float dac_if[AUDIO_MAX_SIMULTANEOUS_TONES] = {0.0}; -static uint8_t hardware_should_stop = 0; +static float active_tones_snapshot[AUDIO_MAX_SIMULTANEOUS_TONES] = {0,0}; +static uint8_t active_tones_snapshot_length = 0; + +typedef enum { + OUTPUT_RUN_NORMALY, + // path 1: wait for zero, then change/update active tones + OUTPUT_TONES_CHANGED, + OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE, + // path 2: hardware should stop, wait for zero then turn output off = stop the timer + OUTPUT_SHOULD_STOP, + OUTPUT_REACHED_ZERO_BEFORE_OFF, + OUTPUT_OFF, + number_of_output_states +} output_states_t; +output_states_t state = OUTPUT_OFF; + /** * Generation of the waveform being passed to the callback. Declared weak so users @@ -77,25 +92,27 @@ static uint8_t hardware_should_stop = 0; */ __attribute__((weak)) uint16_t dac_value_generate(void) { uint16_t value = AUDIO_DAC_OFF_VALUE; - uint8_t active_tones = 0; - if (hardware_should_stop > 0) { - return 0.0f; + if (OUTPUT_OFF == state) + return AUDIO_DAC_OFF_VALUE; + + if ((0 == active_tones_snapshot_length) && (OUTPUT_REACHED_ZERO_BEFORE_OFF == state)) { + state = OUTPUT_OFF; + return AUDIO_DAC_OFF_VALUE; } - active_tones = MIN(AUDIO_MAX_SIMULTANEOUS_TONES-1, audio_get_number_of_active_tones()); /* doing additive wave synthesis over all currently playing tones = adding up * sine-wave-samples for each frequency, scaled by the number of active tones */ - if (active_tones > 0) { - uint16_t value_avg = 0; - float frequency = 0.0f; + uint16_t value_avg = 0; + float frequency = 0.0f; - for (uint8_t i = 0; i < active_tones; i++) { - frequency = audio_get_processed_frequency(i); + for (uint8_t i = 0; i < active_tones_snapshot_length; i++) { - dac_if[i] = dac_if[i] + + frequency = active_tones_snapshot[i]; + + dac_if[i] = dac_if[i] + ((frequency * AUDIO_DAC_BUFFER_SIZE) / AUDIO_DAC_SAMPLE_RATE) * 2/3; /*Note: necessary to get the correct frequencies on the @@ -103,34 +120,66 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { the gpt timer runs with 3*AUDIO_DAC_SAMPLE_RATE; and the DAC callback is called twice per conversion.*/ - dac_if[i] = fmod(dac_if[i], AUDIO_DAC_BUFFER_SIZE); + dac_if[i] = fmod(dac_if[i], AUDIO_DAC_BUFFER_SIZE); - // Wavetable generation/lookup - uint16_t dac_i = (uint16_t)dac_if[i]; + // Wavetable generation/lookup + uint16_t dac_i = (uint16_t)dac_if[i]; #if defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) - value_avg += dac_buffer_sine[dac_i] / active_tones; + value_avg += dac_buffer_sine[dac_i] / active_tones_snapshot_length; #elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE) - value_avg += dac_buffer_triangle[dac_i] / active_tones; + value_avg += dac_buffer_triangle[dac_i] / active_tones_snapshot_length; #elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID) - value_avg += dac_buffer_trapezoid[dac_i] / active_tones; + value_avg += dac_buffer_trapezoid[dac_i] / active_tones_snapshot_length; #elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE) - value_avg += dac_buffer_square[dac_i] / active_tones; + value_avg += dac_buffer_square[dac_i] / active_tones_snapshot_length; #endif - /* - // SINE - value_avg += dac_buffer_sine[dac_i] / active_tones / 3; - // TRIANGLE - value_avg += dac_buffer_triangle[dac_i] / active_tones / 3; - // SQUARE - value_avg += dac_buffer_square[dac_i] / active_tones / 3; - //NOTE: combination of these three waveforms is more exemplary - and doesn't sound particularly good :-P - */ - - // STAIRS (mostly usefull as test-pattern) - //value_avg = dac_buffer_staircase[dac_i] / active_tones; + /* + // SINE + value_avg += dac_buffer_sine[dac_i] / active_tones_snapshot_length / 3; + // TRIANGLE + value_avg += dac_buffer_triangle[dac_i] / active_tones_snapshot_length / 3; + // SQUARE + value_avg += dac_buffer_square[dac_i] / active_tones_snapshot_length / 3; + //NOTE: combination of these three waveforms is more exemplary - and doesn't sound particularly good :-P + */ + + // STAIRS (mostly usefull as test-pattern) + //value_avg = dac_buffer_staircase[dac_i] / active_tones_snapshot_length; + } + value = value_avg; + + + /* zero crossing (or approach) + * + * TODO: what about different values, other than AUDIO_DAC_OFF_VALUE=0, AUDIO_DAC_SAMPLE_MAX or AUDIO_DAC_SAMPLE_MAX/2 ? + */ + if ((OUTPUT_SHOULD_STOP == state) + && (value < AUDIO_DAC_SAMPLE_MAX/100)) { //TODO: works only if DAC_OFF_VALUE = 0! + state = OUTPUT_REACHED_ZERO_BEFORE_OFF; + } + else if ((OUTPUT_TONES_CHANGED == state) + && (value < AUDIO_DAC_SAMPLE_MAX/100)) { //TODO: works only if DAC_OFF_VALUE = 0! + state = OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE; + } + + if (( OUTPUT_REACHED_ZERO_BEFORE_OFF == state) + || (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state)){ + uint8_t active_tones = MIN(AUDIO_MAX_SIMULTANEOUS_TONES, audio_get_number_of_active_tones()); + + active_tones_snapshot_length = 0; + // update the snapshot - once, and only on occasion that something changed; + // -> saves cpu cycles (?) + for (uint8_t i = 0; i < active_tones; i++) { + float freq = audio_get_processed_frequency(i); + if (freq > 0) { // disregard 'rest' notes, with valid frequency 0.0f; which would only lower the resulting waveform volume during the additive synthesis step + active_tones_snapshot[active_tones_snapshot_length++] = freq; + } + } + + if (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state) { + state = OUTPUT_RUN_NORMALY; } - value = value_avg; } return value; } @@ -148,31 +197,27 @@ static void dac_end(DACDriver *dacp){ sample_p += AUDIO_DAC_BUFFER_SIZE/2; // 'half_index' } - uint8_t s = 0; - for (s = 0; s < AUDIO_DAC_BUFFER_SIZE/2; s++) { + for (uint8_t s = 0; s < AUDIO_DAC_BUFFER_SIZE/2; s++) { sample_p[s] = dac_value_generate(); } - // looking at the last sample of the second buffer-half - if ((sample_p[s] < 0x5) //arbitrary value near zero - && !dacIsBufferComplete(dacp)) { - - // the audio system triggered a stop, now that the sample-conversion is done stop the dac-triggering timer and go into idle - if (hardware_should_stop > 0) { - hardware_should_stop=2; - gptStopTimer(&GPTD6); - } - } - // update audio internal state (note position, current_note, ...) - audio_advance_state( + if(audio_advance_state( AUDIO_DAC_BUFFER_SIZE/2, AUDIO_DAC_SAMPLE_RATE/ (64*2.0f/3) /* End of the note: 64 is the number of 'units' of a whole note, 3 comes from the gpttimer: AUDIO_DAC_SAMPLE_RATE * 3; 2 from the callback beeing called twice per sample conversion. with a TEMPO set to 60 a whole note lasts exactly one second */ - ); + ) + ){ + if (OUTPUT_SHOULD_STOP != state) + state = OUTPUT_TONES_CHANGED; + } + + if (OUTPUT_OFF == state) { + gptStopTimer(&GPTD6); + } } static void dac_error(DACDriver *dacp, dacerror_t err) { @@ -239,14 +284,17 @@ void audio_driver_initialize() { } void audio_driver_stop(void) { - hardware_should_stop=1; + state = OUTPUT_SHOULD_STOP; } void audio_driver_start(void) { gptStart(&GPTD6, &gpt6cfg1); gptStartContinuous(&GPTD6, 2U); - for (uint8_t i = 0; i < AUDIO_MAX_SIMULTANEOUS_TONES; i++) + for (uint8_t i = 0; i < AUDIO_MAX_SIMULTANEOUS_TONES; i++) { dac_if[i] = 0.0f; - hardware_should_stop = 0; + active_tones_snapshot[i] = 0.0f; + } + active_tones_snapshot_length = 0; + state = OUTPUT_RUN_NORMALY; } From 8f43ec43d135a5748bd8053962800999e092cbd5 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Apr 2020 16:19:27 +0200 Subject: [PATCH 067/153] audio-refactoring: re-add note-resting -> introduce short_rest inbetween - introduce a short pause/rest between two notes of the same frequency, to separate them audibly - also updating the refactoring comments --- quantum/audio/audio.c | 73 ++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 18 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index c636fcc99646..5c45e9c88f47 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -23,11 +23,16 @@ * audio.[ch] takes care of all overall state, tracking the actively playing * notes/tones; the notes a SONG consists of; * ... + * = everything audio-related that is platform agnostic * * driver_[avr|chibios]_[dac|pwm] take care of the lower hardware dependent parts, * specific to each platform and the used subsystem/driver to drive * the output pins/channels with the calculated frequencies for each * avtive tone + * as part of this, the driver has to trigger regular state updates by + * calling 'audio_advance_state' through some sort of timer - be it a + * dedicated one or piggybacking on for example the timer used to + * generate a pwm signal/clock. * * * A Note on terminology: @@ -62,6 +67,7 @@ uint8_t note_tempo = TEMPO_DEFAULT; // beats-per-minute uint16_t current_note = 0; // index into the array at notes_pointer uint16_t next_note = 0; uint32_t note_position = 0; // where in time, during playback of the current_note +bool note_resting = false; // if a short pause was introduced between too notes with the same frequency while playing a melody #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING # ifndef AUDIO_MAX_SIMULTANEOUS_TONES @@ -73,10 +79,6 @@ uint8_t tone_multiplexing_index_shift = 0; // offset used on active-tone array #endif -//TODO/REFACTORING: check below variables if/where they are still used -float note_frequency = 0; // Hz -bool note_resting = false; //?? current note is a pause? or is this supposed to indicate a 'tie'? - #ifdef AUDIO_ENABLE_VIBRATO float vibrato_counter = 0; float vibrato_strength = 0.5; @@ -279,6 +281,7 @@ void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) { if (playing_note) audio_stop_all(); playing_melody = true; + note_resting = false; notes_pointer = np; notes_count = n_count; @@ -286,7 +289,7 @@ void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) { current_note = 0; // note in the melody-array/list at note_pointer - note_frequency = (*notes_pointer)[current_note][0]; + audio_play_tone((*notes_pointer)[current_note][0]); // start first note manually, all remaining are triggered during audio_advance_state note_length = ((*notes_pointer)[current_note][1]) * (60.0f / note_tempo); note_position = 0; // position in the currently playing note = "elapsed time" (with no specific unit, depends on how fast/slow the respective audio-driver/hardware ticks) @@ -366,12 +369,20 @@ float audio_get_processed_frequency(uint8_t tone_index) { the following code block is a leftover of the audio-refactoring, which deduplicated code among the different implementations at the time - boiled down to this function, which was to be called by an avr ISR to do single/dual channel pwm there are lots of avr hardware specifica in there, but also some features still that could/should? be refactored into the "new" audio system - like - - "software polyphonic" audio, which cycles through/time multiplexes the currently active tones, avoiding the hardware limit of one or two pwm outputs/speakers; which by themselve can only render one frequency at a time (unlike the arm-dac implementation, which can do wave-synthesis to combine multiple frequencies) + + [X] "software polyphonic" audio, which cycles through/time multiplexes the currently active tones, avoiding the hardware limit of one or two pwm outputs/speakers; which by themselve can only render one frequency at a time (unlike the arm-dac implementation, which can do wave-synthesis to combine multiple frequencies) (according to wikipedia: polyphonic is actually something different: concurrent melodies/voices that play with/against each other - - "note_resting": which does a short gab between consecutive tones of the same frequency; to not slurr them together, like making to quarter-notes into one half-note + -> refactored as AUDIO_ENABLE_TONE_MULTIPLEXING + + [X] "note_resting": which does a short gab between consecutive tones of the same frequency; to not slurr them together, like making to quarter-notes into one half-note + -> shortRest added on-the-fly during audio_advance_state most of the logic has been refactored and moved into the different parts of the current implementation though + + + + void pwm_audio_timer_task(float *freq, float *freq_alt) { if (playing_note) { if (active_tones > 0) { @@ -409,7 +420,7 @@ void pwm_audio_timer_task(float *freq, float *freq_alt) { } if (playing_melody) { - if (note_frequency > 0) { + if (note_frequency > 0) { // 'note_frequency' used to be set to the current not in the melody #ifdef AUDIO_ENABLE_VIBRATO if (vibrato_strength > 0) { *freq = vibrato(note_frequency); @@ -508,33 +519,59 @@ bool audio_advance_state(uint32_t step, float end) { goto_next_note = note_position >= (note_length * end); if (goto_next_note) { - audio_stop_tone((*notes_pointer)[current_note][0]); + uint16_t previous_note = current_note; current_note++; + envelope_index = 0; if (current_note >= notes_count) { if (notes_repeat) { current_note = 0; } else { playing_melody = false; + audio_stop_tone((*notes_pointer)[previous_note][0]); return true; } } - audio_play_tone( - (*notes_pointer)[current_note][0] // frequency only; the duration is handled by calling this function regularly and advancing the note_position - ); + if (!note_resting + && (*notes_pointer)[previous_note][0] == (*notes_pointer)[current_note][0] + ) { + note_resting = true; - envelope_index = 0; + // special handling for successive notes of the same frequency: + // insert a short pause to separate them audibly + current_note = previous_note; + float shortRest[2] = {0.0f, 2 /*duration of a THIRTYTWOTH_NOTE*/}; + audio_play_tone(shortRest[0]); + audio_stop_tone((*notes_pointer)[previous_note][0]); + note_position = note_position - (note_length * end); + note_length = shortRest[1] * (60.0f / note_tempo); - // Skip forward in the next note's length if we've over shot the last, so - // the overall length of the song is the same - note_position = note_position - (note_length * end); + } else { + note_resting = false; + + // need only to pass the frequency - the duration is handled by + // calling this function regularly and advancing the note_position + audio_play_tone( + (*notes_pointer)[current_note][0] + ); + // start the next note prior to stopping the previous one, to + // allow the hardware to do a clean transition; and avoid a brief + // state where active_tones==0 -> driver_stop + if ((*notes_pointer)[previous_note][0] != (*notes_pointer)[current_note][0]) { + audio_stop_tone((*notes_pointer)[previous_note][0]); + } + + // Skip forward in the next note's length if we've over shot the last, so + // the overall length of the song is the same + note_position = note_position - (note_length * end); - note_length = ((*notes_pointer)[current_note][1]) * (60.0f / note_tempo); + note_length = ((*notes_pointer)[current_note][1]) * (60.0f / note_tempo); + } } } - if (!playing_note && !playing_melody ) + if (!playing_note && !playing_melody) audio_stop_all(); //TODO: trigger a stop of the hardware or just a audio_stop_tone on the last frequency? From 27a9500e3301593feded37f314aea8f0cc9e2ba5 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Apr 2020 16:20:37 +0200 Subject: [PATCH 068/153] audio-refactoring: cleanup refactoring remnants remove the former avr-isr code block - since all its features are now refactored into the different parts of the current system also updates the TODOS --- quantum/audio/audio.c | 134 +--------------------------------- quantum/audio/audio.h | 10 +++ quantum/audio/musical_notes.h | 3 + 3 files changed, 14 insertions(+), 133 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 5c45e9c88f47..ae6350c27baa 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -356,138 +356,9 @@ float audio_get_processed_frequency(uint8_t tone_index) { frequency = voice_envelope(frequency); - /*TODO: why the cutoff? - if (frequency < 30.517578125) { - frequency = 30.52; - } - */ - return frequency; } -/* REMOVEME - the following code block is a leftover of the audio-refactoring, which deduplicated code among the different implementations at the time - boiled down to this function, which was to be called by an avr ISR to do single/dual channel pwm - - there are lots of avr hardware specifica in there, but also some features still that could/should? be refactored into the "new" audio system - like - - [X] "software polyphonic" audio, which cycles through/time multiplexes the currently active tones, avoiding the hardware limit of one or two pwm outputs/speakers; which by themselve can only render one frequency at a time (unlike the arm-dac implementation, which can do wave-synthesis to combine multiple frequencies) - (according to wikipedia: polyphonic is actually something different: concurrent melodies/voices that play with/against each other - -> refactored as AUDIO_ENABLE_TONE_MULTIPLEXING - - [X] "note_resting": which does a short gab between consecutive tones of the same frequency; to not slurr them together, like making to quarter-notes into one half-note - -> shortRest added on-the-fly during audio_advance_state - - most of the logic has been refactored and moved into the different parts of the current implementation though - - - - - -void pwm_audio_timer_task(float *freq, float *freq_alt) { - if (playing_note) { - if (active_tones > 0) { -#ifdef AUDIO1_PIN_SET - //TODO: untangle avr specific defines - // speaker for second/alternate tone is available - *freq_alt = audio_get_processed_frequency(2); -#else - *freq_alt = 0.0f; -#endif - - if (tone_multiplexing_rate > 0) { - if (active_tones > 1) { - tone_place %= active_tones; ///2020-03-26: hm, is the tone_place (plus the polythony_rate?) intended to be used to cycle through active tones, if the number of available hardware channels is insufficient? (like with avr/arm pwm?) - - // if (place++ > (frequencies[tone_place] / tone_multiplexing_rate / CPU_PRESCALER)) { - // tone_place = (tone_place + 1) % active_tones; - // place = 0.0; - // } - } - -#ifdef AUDIO_ENABLE_VIBRATO - if (vibrato_strength > 0) { - *freq = vibrato(frequencies[tone_place]); - } else { - *freq = frequencies[tone_place]; - } -#else - *freq = frequencies[tone_place]; -#endif - } else { - *freq = audio_get_processed_frequency(1); - } - } - } - - if (playing_melody) { - if (note_frequency > 0) { // 'note_frequency' used to be set to the current not in the melody -#ifdef AUDIO_ENABLE_VIBRATO - if (vibrato_strength > 0) { - *freq = vibrato(note_frequency); - } else { - *freq = note_frequency; - } -#else - *freq = note_frequency; -#endif - - if (envelope_index < 65535) { - envelope_index++; - } - *freq = voice_envelope(*freq); - } - - note_position++; - bool end_of_note = false; - if (!note_resting) - end_of_note = (note_position >= (note_length * 8 - 1)); - else - end_of_note = (note_position >= (note_length * 8)); -// hm... maybe the whole point of the note_resting related parts is to have a slight gap/pause between two consecutive musical_notes with the same frequency. so they can bei distinguished? - if (end_of_note) { - current_note++; - if (current_note >= notes_count) { - if (notes_repeat) { - current_note = 0; - } else { - playing_melody = false; - return; - } - } - - if (!note_resting) { - note_resting = true; - if (current_note == 0) { - current_note = notes_count-1; - next_note = 0; - } else { - next_note = current_note; - current_note--; - } - - if ((*notes_pointer)[current_note][0] == (*notes_pointer)[next_note][0]) { - note_frequency = 0; //why? this disables the output frequency and makes the next note a 'rest' - } else { - note_frequency = (*notes_pointer)[current_note][0]; - } - note_length = 1; - } else { - note_resting = false; - envelope_index = 0; - note_frequency = (*notes_pointer)[current_note][0]; - note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); - } - - note_position = 0; - } - - if (!audio_config.enable) { - playing_melody = false; - playing_note = false; - } - } -} -*/ bool audio_advance_state(uint32_t step, float end) { bool goto_next_note = state_changed; @@ -495,10 +366,8 @@ bool audio_advance_state(uint32_t step, float end) { if (playing_note) { #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING -// tone_multiplexing_counter++; // TODO: use step and end from advance_State instead; so that frequencies are switched in a time-constant manner during playback of different tones (pitch+duration!) tone_multiplexing_counter += step/end; if (tone_multiplexing_counter == tone_multiplexing_rate) { -//palToggleLine(C10); tone_multiplexing_counter = 0.0f; tone_multiplexing_index_shift++; if (tone_multiplexing_index_shift >= MIN(AUDIO_MAX_SIMULTANEOUS_TONES, active_tones)) @@ -512,7 +381,6 @@ bool audio_advance_state(uint32_t step, float end) { #endif } - //'playing_note' is stopped manually, so no need to keep track of it here if (playing_melody) { note_position += step; @@ -573,7 +441,6 @@ bool audio_advance_state(uint32_t step, float end) { if (!playing_note && !playing_melody) audio_stop_all(); - //TODO: trigger a stop of the hardware or just a audio_stop_tone on the last frequency? return goto_next_note; } @@ -587,6 +454,7 @@ float mod(float a, int b) { return r < 0 ? r + b : r; } +// TODO: unify with vibrato function/call in voices.c float vibrato(float average_freq) { # ifdef AUDIO_ENABLE_VIBRATO_STRENGTH float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 9c1740624071..d305f8525c21 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -97,6 +97,9 @@ bool audio_is_on(void); */ void audio_play_tone(float frequency); //TODO: add audio_play_note(float pitch, float duration, float intensity, float timbre); +// audio_play_note_with_instrument ifdef AUDIO_ENABLE_VOICES +// audio_play_pulses(frequency, count, delay/initialpause) - for fauxclicky, have pwm output exactly $count pulses + /** * @brief stop a given tone/frequency * @details removes the given frequency from the 'frequencies' array, stopping @@ -105,6 +108,7 @@ void audio_play_tone(float frequency); * @param[in] freq tone/frequenct to be stopped */ void audio_stop_tone(float frequency); + /** * @brief play a melody * @details starts playback of a melody passed in from a SONG definition - an @@ -114,16 +118,19 @@ void audio_stop_tone(float frequency); * @param[in] n_repeat false for onetime, true for looped playback */ void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat); + /** * @brief stops all playback * @details stops playback of both a meldoy as well as single tones, resetting * the internal state */ void audio_stop_all(void); + /** * @brief query if one/multiple tones are playing */ bool audio_is_playing_note(void); // TODO: is_playing_tone? + /** * @brief query if a melody/SONG is playing */ @@ -133,6 +140,7 @@ bool audio_is_playing_melody(void); // length. This works around the limitation of C's sizeof operation on pointers. // The global float array for the song must be used here. #define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) + /** * @brief convenience macro, to play a melody/SONG once */ @@ -211,6 +219,7 @@ void audio_driver_stop(void); * @return number, 0=none active */ uint8_t audio_get_number_of_active_tones(void); + /** * @brief access to the raw/unprocessed frequency for a specific tone * @details each active tone has a frequency associated with it, which @@ -222,6 +231,7 @@ uint8_t audio_get_number_of_active_tones(void); * @return a positive frequency, in Hz; or zero if the tone is a pause */ float audio_get_frequency(uint8_t tone_index); + /** * @brief calculate and return the frequency for the requested tone * @details effects like glissando, vibrato, ... are postprocessed onto the diff --git a/quantum/audio/musical_notes.h b/quantum/audio/musical_notes.h index 14e9e20c950a..9d4bc0bc0556 100644 --- a/quantum/audio/musical_notes.h +++ b/quantum/audio/musical_notes.h @@ -26,12 +26,14 @@ // Note Types #define MUSICAL_NOTE(note, duration) \ { (NOTE##note), duration } + #define BREVE_NOTE(note) MUSICAL_NOTE(note, 128) #define WHOLE_NOTE(note) MUSICAL_NOTE(note, 64) #define HALF_NOTE(note) MUSICAL_NOTE(note, 32) #define QUARTER_NOTE(note) MUSICAL_NOTE(note, 16) #define EIGHTH_NOTE(note) MUSICAL_NOTE(note, 8) #define SIXTEENTH_NOTE(note) MUSICAL_NOTE(note, 4) +#define THIRTYTWOTH_NOTE(note) MUSICAL_NOTE(note, 2) //TODO: still usable? #define BREVE_DOT_NOTE(note) MUSICAL_NOTE(note, 128 + 64) #define WHOLE_DOT_NOTE(note) MUSICAL_NOTE(note, 64 + 32) @@ -50,6 +52,7 @@ #define Q__NOTE(n) QUARTER_NOTE(n) #define E__NOTE(n) EIGHTH_NOTE(n) #define S__NOTE(n) SIXTEENTH_NOTE(n) +#define T__NOTE(n) THIRTYTWOTH_NOTE(n) #define BD_NOTE(n) BREVE_DOT_NOTE(n) #define WD_NOTE(n) WHOLE_DOT_NOTE(n) #define HD_NOTE(n) HALF_DOT_NOTE(n) From ca5acf213e70c1ba6e31fa322caa55ddee6d2642 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Apr 2020 16:20:51 +0200 Subject: [PATCH 069/153] audio-refactoring: reserve negative numbers as unitialized frequencies to allow the valid tone/frequency f=0Hz == rest/pause --- quantum/audio/audio.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index ae6350c27baa..611f0cca4f04 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -52,7 +52,7 @@ # define AUDIO_TONE_STACKSIZE 8 #endif uint8_t active_tones = 0; // number of tones pushed onto the stack by audio_play_tone - might be more than the harware is able to reproduce at any single time -float frequencies[AUDIO_TONE_STACKSIZE] = {0.0}; // frequencies of each active tone +float frequencies[AUDIO_TONE_STACKSIZE] = {-1.0}; // frequencies of each active tone //TODO: array of musical_tone_t? bool playing_melody = false; // playing a SONG? @@ -182,11 +182,15 @@ void audio_stop_all() { playing_note = false; for (uint8_t i = 0; i < AUDIO_TONE_STACKSIZE; i++) { - frequencies[i] = 0; + frequencies[i] = -1.0f; } } void audio_stop_tone(float frequency) { + if (frequency < 0.0f) { + frequency = -1 * frequency; + } + if (playing_note) { if (!audio_initialized) { audio_init(); @@ -195,10 +199,10 @@ void audio_stop_tone(float frequency) { for (int i = AUDIO_TONE_STACKSIZE-1; i >= 0; i--) { found = (frequencies[i] == frequency); if (found) { - frequencies[i] = 0; + frequencies[i] = -1.0f; for (int j = i; (j < AUDIO_TONE_STACKSIZE-1); j++) { frequencies[j] = frequencies[j + 1]; - frequencies[j + 1] = 0; + frequencies[j + 1] = -1.0f; } break; } @@ -230,6 +234,10 @@ void audio_play_tone(float frequency) { audio_init(); } + if (frequency < 0.0f) { + frequency = -1 * frequency; + } + // roundrobin: shifting out old tones, keeping only unique ones // if the new frequency is already amongst the active tones, shift it to the top of the stack bool found = false; From 61e6711e95031fc498e1be66206b80d1fc915a4a Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Apr 2020 16:20:57 +0200 Subject: [PATCH 070/153] audio-refactoring: FIX: first note of melody was missing the first note was missing because 'goto_next_note'=false overrode a state_change=true of the initial play_tone and some code-indentations/cleanup of related parts --- quantum/audio/audio.c | 49 +++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 611f0cca4f04..6bdf063d1127 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -55,19 +55,18 @@ uint8_t active_tones = 0; // number of tones pushed onto the stack by a float frequencies[AUDIO_TONE_STACKSIZE] = {-1.0}; // frequencies of each active tone //TODO: array of musical_tone_t? -bool playing_melody = false; // playing a SONG? +bool playing_melody = false; // playing a SONG? bool playing_note = false; // or (possibly multiple simultaneous) tones TODO: should this be playing_tone instead, since we don't handle any duration (yet) bool state_changed = false; // global flag, which is set if anything changes with the active_tones float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs uint16_t notes_count; // length of the notes_pointer array bool notes_repeat; // PLAY_SONG or PLAY_LOOP? -float note_length = 0; // in 64 parts to a beat -uint8_t note_tempo = TEMPO_DEFAULT; // beats-per-minute -uint16_t current_note = 0; // index into the array at notes_pointer -uint16_t next_note = 0; -uint32_t note_position = 0; // where in time, during playback of the current_note -bool note_resting = false; // if a short pause was introduced between too notes with the same frequency while playing a melody +float note_length = 0; // in 64 parts to a beat +uint8_t note_tempo = TEMPO_DEFAULT; // beats-per-minute +uint16_t current_note = 0; // index into the array at notes_pointer +uint32_t note_position = 0; // position in the currently playing note = "elapsed time" (with no specific unit, depends on how fast/slow the respective audio-driver/hardware ticks) +bool note_resting = false; // if a short pause was introduced between two notes with the same frequency while playing a melody #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING # ifndef AUDIO_MAX_SIMULTANEOUS_TONES @@ -284,25 +283,24 @@ void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) { audio_init(); } - if (audio_config.enable) { - // Cancel note if a note is playing - if (playing_note) audio_stop_all(); + // Cancel note if a note is playing + if (playing_note) audio_stop_all(); - playing_melody = true; - note_resting = false; + playing_melody = true; + note_resting = false; - notes_pointer = np; - notes_count = n_count; - notes_repeat = n_repeat; + notes_pointer = np; + notes_count = n_count; + notes_repeat = n_repeat; - current_note = 0; // note in the melody-array/list at note_pointer + current_note = 0; // note in the melody-array/list at note_pointer - audio_play_tone((*notes_pointer)[current_note][0]); // start first note manually, all remaining are triggered during audio_advance_state - note_length = ((*notes_pointer)[current_note][1]) * (60.0f / note_tempo); - note_position = 0; // position in the currently playing note = "elapsed time" (with no specific unit, depends on how fast/slow the respective audio-driver/hardware ticks) + note_length = ((*notes_pointer)[current_note][1]) * (60.0f / note_tempo); + note_position = 0; - audio_driver_start(); - } + // start first note manually, which also starts the audio_driver + // all following/remaining notes are played by 'audio_advance_state' + audio_play_tone((*notes_pointer)[current_note][0]); } bool audio_is_playing_note(void) { return playing_note; } @@ -369,8 +367,7 @@ float audio_get_processed_frequency(uint8_t tone_index) { bool audio_advance_state(uint32_t step, float end) { - bool goto_next_note = state_changed; - state_changed = false; + bool goto_next_note = false; if (playing_note) { #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING @@ -450,6 +447,12 @@ bool audio_advance_state(uint32_t step, float end) { if (!playing_note && !playing_melody) audio_stop_all(); + // state-changes have a higher priority, always triggering the hardware to update + if (state_changed) { + state_changed = false; + return true; + } + return goto_next_note; } From 1a1d986caba4c4a90ada38b12c10aaf623e1575e Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Apr 2020 16:21:01 +0200 Subject: [PATCH 071/153] audio-arm-dac: fix hardware init-click due to wron .init= value --- quantum/audio/driver_chibios_dac_additive.c | 2 +- quantum/audio/driver_chibios_dac_basic.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index 40ae0238e036..cc192d498b24 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -232,7 +232,7 @@ static const GPTConfig gpt6cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE * 3, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U}; -static const DACConfig dac_conf = {.init = AUDIO_DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; +static const DACConfig dac_conf = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_DHRM_12BIT_RIGHT}; /** * @note The DAC_TRG(0) here selects the Timer 6 TRGO event, which is triggered diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index 8c77ef227a0f..8db9231ca57e 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -67,10 +67,10 @@ GPTConfig gpt8cfg1 = {.frequency = 10, .dier = 0U}; #if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) -static const DACConfig dac_conf_ch1 = {.init = AUDIO_DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; +static const DACConfig dac_conf_ch1 = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_DHRM_12BIT_RIGHT}; #endif #if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) -static const DACConfig dac_conf_ch2 = {.init = AUDIO_DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; +static const DACConfig dac_conf_ch2 = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_DHRM_12BIT_RIGHT}; #endif /** From 38de9dbc2230681a0ee8b346aab0d33a379b5197 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Apr 2020 16:21:14 +0200 Subject: [PATCH 072/153] audio-refactoring: new conveniance function: audio_play_click which can be used to further refactor/remove fauxclicky (avr only) and/or the 'clicky' features --- quantum/audio/audio.c | 24 ++++++++++++++++++++++++ quantum/audio/audio.h | 13 +++++++++++++ 2 files changed, 37 insertions(+) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 6bdf063d1127..bc7cada11c61 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -303,6 +303,30 @@ void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) { audio_play_tone((*notes_pointer)[current_note][0]); } + +float click[2][2]; +void audio_play_click(float delay, float frequency, float duration) { + float duration_tone = (64/60) * note_tempo * duration; + float duration_delay = (64/60) * note_tempo * delay; + + if (delay <= 0.0f) { + click[0][0] = frequency; + click[0][1] = duration_tone; + click[1][0] = 0.0f; + click[1][1] = 0.0f; + audio_play_melody(&click, 1, false); + } else { + // first note is a rest/pause + click[0][0] = 0.0f; + click[0][1] = duration_delay; + // second note is the actual click + click[1][0] = frequency; + click[1][1] = duration_tone; + audio_play_melody(&click, 2, false); + } +} + + bool audio_is_playing_note(void) { return playing_note; } bool audio_is_playing_melody(void) { return playing_melody; } diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index d305f8525c21..3f24f5033b83 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -119,6 +119,19 @@ void audio_stop_tone(float frequency); */ void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat); +/** + * @brief play a short tone of a specific frequency to emulate a 'click' + * + * @details constructs a two-note melody (one pause plus a note) and plays it through + * audio_play_melody. very short durations might not quite work due to + * hardware limitations (DAC: added pulses from zero-crossing feature;...) + * + * @param[in] delay in seconds, lenght for the pause before the pulses, can be zero + * @param[in] frequency + * @param[in] duration in seconds, length of the 'click' + */ +void audio_play_click(float delay, float frequency, float duration); + /** * @brief stops all playback * @details stops playback of both a meldoy as well as single tones, resetting From 35d71a7d8f494fdbcb0ad62c90ce2c47e0939a6b Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Apr 2020 16:21:19 +0200 Subject: [PATCH 073/153] audio-refactoring: clang-format on quantum/audio/* --- quantum/audio/audio.c | 161 +++++++++----------- quantum/audio/audio.h | 20 +-- quantum/audio/driver_avr_pwm_hardware.c | 70 ++++----- quantum/audio/driver_chibios_dac.h | 6 +- quantum/audio/driver_chibios_dac_additive.c | 96 +++++------- quantum/audio/driver_chibios_dac_basic.c | 67 ++++---- quantum/audio/driver_chibios_pwm.h | 5 +- quantum/audio/driver_chibios_pwm_hardware.c | 83 +++++----- quantum/audio/driver_chibios_pwm_software.c | 64 ++++---- quantum/audio/musical_notes.h | 2 +- quantum/audio/voices.c | 22 +-- 11 files changed, 256 insertions(+), 340 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index bc7cada11c61..23fe17f4367a 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -51,33 +51,32 @@ #ifndef AUDIO_TONE_STACKSIZE # define AUDIO_TONE_STACKSIZE 8 #endif -uint8_t active_tones = 0; // number of tones pushed onto the stack by audio_play_tone - might be more than the harware is able to reproduce at any single time -float frequencies[AUDIO_TONE_STACKSIZE] = {-1.0}; // frequencies of each active tone -//TODO: array of musical_tone_t? - -bool playing_melody = false; // playing a SONG? -bool playing_note = false; // or (possibly multiple simultaneous) tones TODO: should this be playing_tone instead, since we don't handle any duration (yet) -bool state_changed = false; // global flag, which is set if anything changes with the active_tones - -float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs -uint16_t notes_count; // length of the notes_pointer array -bool notes_repeat; // PLAY_SONG or PLAY_LOOP? -float note_length = 0; // in 64 parts to a beat -uint8_t note_tempo = TEMPO_DEFAULT; // beats-per-minute -uint16_t current_note = 0; // index into the array at notes_pointer -uint32_t note_position = 0; // position in the currently playing note = "elapsed time" (with no specific unit, depends on how fast/slow the respective audio-driver/hardware ticks) -bool note_resting = false; // if a short pause was introduced between two notes with the same frequency while playing a melody +uint8_t active_tones = 0; // number of tones pushed onto the stack by audio_play_tone - might be more than the harware is able to reproduce at any single time +float frequencies[AUDIO_TONE_STACKSIZE] = {-1.0}; // frequencies of each active tone +// TODO: array of musical_tone_t? + +bool playing_melody = false; // playing a SONG? +bool playing_note = false; // or (possibly multiple simultaneous) tones TODO: should this be playing_tone instead, since we don't handle any duration (yet) +bool state_changed = false; // global flag, which is set if anything changes with the active_tones + +float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs +uint16_t notes_count; // length of the notes_pointer array +bool notes_repeat; // PLAY_SONG or PLAY_LOOP? +float note_length = 0; // in 64 parts to a beat +uint8_t note_tempo = TEMPO_DEFAULT; // beats-per-minute +uint16_t current_note = 0; // index into the array at notes_pointer +uint32_t note_position = 0; // position in the currently playing note = "elapsed time" (with no specific unit, depends on how fast/slow the respective audio-driver/hardware ticks) +bool note_resting = false; // if a short pause was introduced between two notes with the same frequency while playing a melody #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING # ifndef AUDIO_MAX_SIMULTANEOUS_TONES # define AUDIO_MAX_SIMULTANEOUS_TONES 3 # endif -float tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT; -float tone_multiplexing_counter = 0.0f; // incremented each state update, and compared to _rate -uint8_t tone_multiplexing_index_shift = 0; // offset used on active-tone array access +float tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT; +float tone_multiplexing_counter = 0.0f; // incremented each state update, and compared to _rate +uint8_t tone_multiplexing_index_shift = 0; // offset used on active-tone array access #endif - #ifdef AUDIO_ENABLE_VIBRATO float vibrato_counter = 0; float vibrato_strength = 0.5; @@ -91,7 +90,6 @@ float note_timbre = TIMBRE_DEFAULT; uint16_t envelope_index = 0; bool glissando = false; - #ifndef STARTUP_SONG # define STARTUP_SONG SONG(STARTUP_SOUND) #endif @@ -105,8 +103,7 @@ float startup_song[][2] = STARTUP_SONG; float audio_on_song[][2] = AUDIO_ON_SONG; float audio_off_song[][2] = AUDIO_OFF_SONG; - -static bool audio_initialized = false; +static bool audio_initialized = false; audio_config_t audio_config; void audio_init() { @@ -178,7 +175,7 @@ void audio_stop_all() { audio_driver_stop(); playing_melody = false; - playing_note = false; + playing_note = false; for (uint8_t i = 0; i < AUDIO_TONE_STACKSIZE; i++) { frequencies[i] = -1.0f; @@ -195,19 +192,20 @@ void audio_stop_tone(float frequency) { audio_init(); } bool found = false; - for (int i = AUDIO_TONE_STACKSIZE-1; i >= 0; i--) { + for (int i = AUDIO_TONE_STACKSIZE - 1; i >= 0; i--) { found = (frequencies[i] == frequency); if (found) { frequencies[i] = -1.0f; - for (int j = i; (j < AUDIO_TONE_STACKSIZE-1); j++) { + for (int j = i; (j < AUDIO_TONE_STACKSIZE - 1); j++) { frequencies[j] = frequencies[j + 1]; frequencies[j + 1] = -1.0f; } break; } } - if (!found) + if (!found) { return; + } state_changed = true; active_tones--; @@ -220,14 +218,15 @@ void audio_stop_tone(float frequency) { if (active_tones == 0) { audio_driver_stop(); - playing_note = false; + playing_note = false; } } } void audio_play_tone(float frequency) { - if (!audio_config.enable) + if (!audio_config.enable) { return; + } if (!audio_initialized) { audio_init(); @@ -240,34 +239,35 @@ void audio_play_tone(float frequency) { // roundrobin: shifting out old tones, keeping only unique ones // if the new frequency is already amongst the active tones, shift it to the top of the stack bool found = false; - for (int i = active_tones-1; i >= 0; i--) { + for (int i = active_tones - 1; i >= 0; i--) { found = (frequencies[i] == frequency); if (found) { - for (int j = i; (j < active_tones-1); j++) { + for (int j = i; (j < active_tones - 1); j++) { frequencies[j] = frequencies[j + 1]; frequencies[j + 1] = frequency; } break; } } - if (found) // since this frequency played already, the hardware was already started + if (found) { // since this frequency played already, the hardware was already started return; + } // frequency/tone is actually new, so we put it on the top of the stack active_tones++; if (active_tones > AUDIO_TONE_STACKSIZE) { active_tones = AUDIO_TONE_STACKSIZE; // shift out the oldest tone to make room - for (int i=0; i= active_tones) + if (tone_index >= active_tones) { return 0.0f; - return frequencies[active_tones-tone_index-1]; + } + return frequencies[active_tones - tone_index - 1]; } - float audio_get_processed_frequency(uint8_t tone_index) { float frequency = 0.0; - if (tone_index >= active_tones) + if (tone_index >= active_tones) { return 0.0f; + } int8_t index = active_tones - tone_index - 1; // new tones are stacked on top (= appended at the end), so the most recent/current is MAX-1 #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING index = index - tone_multiplexing_index_shift; - if (index < 0) // wrap around + if (index < 0) // wrap around index += active_tones; #endif - if (frequencies[index] <= 0.0f) + if (frequencies[index] <= 0.0f) { return 0.0f; + } - //TODO make it work and test, currently probably non-functional because it needs some state to keep track of previous tones, the current tone position ...? - if (glissando) { // see voices.c - if (frequency != 0 && frequency < frequencies[index] - && frequency < frequencies[index] * pow(2, -440 / frequencies[index] / 12 / 2)) { + // TODO make it work and test, currently probably non-functional because it needs some state to keep track of previous tones, the current tone position ...? + if (glissando) { // see voices.c + if (frequency != 0 && frequency < frequencies[index] && frequency < frequencies[index] * pow(2, -440 / frequencies[index] / 12 / 2)) { frequency = frequency * pow(2, 440 / frequency / 12 / 2); - } else if (frequency != 0 && frequency > frequencies[index] - && frequency > frequencies[index] * pow(2, 440 / frequencies[index] / 12 / 2)) { + } else if (frequency != 0 && frequency > frequencies[index] && frequency > frequencies[index] * pow(2, 440 / frequencies[index] / 12 / 2)) { frequency = frequency * pow(2, -440 / frequency / 12 / 2); } else { frequency = frequencies[index]; @@ -389,18 +387,18 @@ float audio_get_processed_frequency(uint8_t tone_index) { return frequency; } - bool audio_advance_state(uint32_t step, float end) { bool goto_next_note = false; if (playing_note) { #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING - tone_multiplexing_counter += step/end; + tone_multiplexing_counter += step / end; if (tone_multiplexing_counter == tone_multiplexing_rate) { tone_multiplexing_counter = 0.0f; tone_multiplexing_index_shift++; - if (tone_multiplexing_index_shift >= MIN(AUDIO_MAX_SIMULTANEOUS_TONES, active_tones)) + if (tone_multiplexing_index_shift >= MIN(AUDIO_MAX_SIMULTANEOUS_TONES, active_tones)) { tone_multiplexing_index_shift = 0; + } goto_next_note = true; } #endif @@ -410,7 +408,6 @@ bool audio_advance_state(uint32_t step, float end) { #endif } - if (playing_melody) { note_position += step; @@ -430,28 +427,24 @@ bool audio_advance_state(uint32_t step, float end) { } } - if (!note_resting - && (*notes_pointer)[previous_note][0] == (*notes_pointer)[current_note][0] - ) { + if (!note_resting && (*notes_pointer)[previous_note][0] == (*notes_pointer)[current_note][0]) { note_resting = true; // special handling for successive notes of the same frequency: // insert a short pause to separate them audibly - current_note = previous_note; + current_note = previous_note; float shortRest[2] = {0.0f, 2 /*duration of a THIRTYTWOTH_NOTE*/}; audio_play_tone(shortRest[0]); audio_stop_tone((*notes_pointer)[previous_note][0]); note_position = note_position - (note_length * end); - note_length = shortRest[1] * (60.0f / note_tempo); + note_length = shortRest[1] * (60.0f / note_tempo); } else { note_resting = false; // need only to pass the frequency - the duration is handled by // calling this function regularly and advancing the note_position - audio_play_tone( - (*notes_pointer)[current_note][0] - ); + audio_play_tone((*notes_pointer)[current_note][0]); // start the next note prior to stopping the previous one, to // allow the hardware to do a clean transition; and avoid a brief // state where active_tones==0 -> driver_stop @@ -468,8 +461,9 @@ bool audio_advance_state(uint32_t step, float end) { } } - if (!playing_note && !playing_melody) + if (!playing_note && !playing_melody) { audio_stop_all(); + } // state-changes have a higher priority, always triggering the hardware to update if (state_changed) { @@ -480,7 +474,6 @@ bool audio_advance_state(uint32_t step, float end) { return goto_next_note; } - // Vibrato functions #ifdef AUDIO_ENABLE_VIBRATO @@ -508,7 +501,7 @@ void audio_set_vibrato_strength(float strength) { vibrato_strength = strength; } void audio_increase_vibrato_strength(float change) { vibrato_strength *= change; } void audio_decrease_vibrato_strength(float change) { vibrato_strength /= change; } # endif /* AUDIO_ENABLE_VIBRATO_STRENGTH */ -#endif /* AUDIO_ENABLE_VIBRATO */ +#endif /* AUDIO_ENABLE_VIBRATO */ // Tone-multiplexing functions #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING @@ -526,31 +519,27 @@ void audio_set_timbre(float timbre) { note_timbre = timbre; } } -float audio_get_timbre(void) { - return note_timbre; -} - +float audio_get_timbre(void) { return note_timbre; } // Tempo functions void audio_set_tempo(uint8_t tempo) { - if (tempo < 10) - note_tempo = 10; -// else if (tempo > 250) -// note_tempo = 250; + if (tempo < 10) note_tempo = 10; + // else if (tempo > 250) + // note_tempo = 250; else note_tempo = tempo; } void audio_increase_tempo(uint8_t tempo_change) { - if (tempo_change > 255-note_tempo) + if (tempo_change > 255 - note_tempo) note_tempo = 255; else note_tempo += tempo_change; } void audio_decrease_tempo(uint8_t tempo_change) { - if (tempo_change >= note_tempo-10) + if (tempo_change >= note_tempo - 10) note_tempo = 10; else note_tempo -= tempo_change; diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 3f24f5033b83..b954124044c4 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -13,7 +13,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #pragma once #include @@ -36,7 +35,6 @@ # include "driver_chibios_dac.h" #endif - typedef union { uint8_t raw; struct { @@ -46,9 +44,9 @@ typedef union { }; } audio_config_t; -//AVR/LUFA has a MIN, arm/chibios does not +// AVR/LUFA has a MIN, arm/chibios does not #ifndef MIN -# define MIN(a,b) (((a) < (b)) ? (a) : (b)) +# define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif // ____ __ ___ @@ -96,7 +94,7 @@ bool audio_is_on(void); * @param[in] frequency frequency of the tone be played */ void audio_play_tone(float frequency); -//TODO: add audio_play_note(float pitch, float duration, float intensity, float timbre); +// TODO: add audio_play_note(float pitch, float duration, float intensity, float timbre); // audio_play_note_with_instrument ifdef AUDIO_ENABLE_VOICES // audio_play_pulses(frequency, count, delay/initialpause) - for fauxclicky, have pwm output exactly $count pulses @@ -142,7 +140,7 @@ void audio_stop_all(void); /** * @brief query if one/multiple tones are playing */ -bool audio_is_playing_note(void); // TODO: is_playing_tone? +bool audio_is_playing_note(void); // TODO: is_playing_tone? /** * @brief query if a melody/SONG is playing @@ -158,13 +156,12 @@ bool audio_is_playing_melody(void); * @brief convenience macro, to play a melody/SONG once */ #define PLAY_SONG(note_array) audio_play_melody(¬e_array, NOTE_ARRAY_SIZE((note_array)), false) -//TODO: a 'song' is a melody plus singing/vocals -> PLAY_MELODY +// TODO: a 'song' is a melody plus singing/vocals -> PLAY_MELODY /** * @brief convenience macro, to play a melody/SONG in a loop, until stopped by 'audio_stop_all' */ #define PLAY_LOOP(note_array) audio_play_melody(¬e_array, NOTE_ARRAY_SIZE((note_array)), true) - // Vibrato rate functions // #define AUDIO_ENABLE_VIBRATO @@ -205,7 +202,7 @@ void audio_decrease_tone_multiplexing_rate(float change); * @note: using any instrument from voices.[ch] other than 'default' may override the set value * @param[in]: timbre: valid range is (0.0,1.0) */ -void audio_set_timbre(float timbre); +void audio_set_timbre(float timbre); float audio_get_timbre(void); // Tempo functions @@ -214,7 +211,6 @@ void audio_set_tempo(uint8_t tempo); void audio_increase_tempo(uint8_t tempo_change); void audio_decrease_tempo(uint8_t tempo_change); - // __ __ __ // / / / /___ __________/ / ______ __________ // / /_/ / __ `/ ___/ __ / | /| / / __ `/ ___/ _ / @@ -277,7 +273,6 @@ float audio_get_processed_frequency(uint8_t tone_index); */ bool audio_advance_state(uint32_t step, float end); - // __ // / / ___ ____ _____ ________ __ // / / / _ \/ __ `/ __ `/ ___/ / / / @@ -286,7 +281,7 @@ bool audio_advance_state(uint32_t step, float end); // /____/ /____/ // legacy and backwarts compatibility stuff -#define PLAY_NOTE_ARRAY(note_array, note_repeat, deprecated_arg) \ +#define PLAY_NOTE_ARRAY(note_array, note_repeat, deprecated_arg) \ audio_play_melody(¬e_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat)); \ _Pragma("message \"'PLAY_NOTE_ARRAY' macro is deprecated\"") @@ -324,7 +319,6 @@ bool audio_advance_state(uint32_t step, float end); # define AUDIO_PIN C6 #endif - #define is_audio_on() audio_is_on() #define is_playing_notes() audio_is_playing_melody() #define is_playing_note() audio_is_playing_note() diff --git a/quantum/audio/driver_avr_pwm_hardware.c b/quantum/audio/driver_avr_pwm_hardware.c index c83139a80397..3c683e6199dc 100644 --- a/quantum/audio/driver_avr_pwm_hardware.c +++ b/quantum/audio/driver_avr_pwm_hardware.c @@ -22,11 +22,10 @@ #include "audio.h" - // TODO: move into audio-common state -extern bool playing_note; -extern bool playing_melody; -extern float note_timbre; +extern bool playing_note; +extern bool playing_melody; +extern float note_timbre; #define CPU_PRESCALER 8 @@ -78,7 +77,6 @@ extern float note_timbre; # endif #endif - #if defined(AUDIO_PIN_ALT_B5) || defined(AUDIO_PIN_ALT_B6) || defined(AUDIO_PIN_ALT_B7) # define AUDIO2_PIN_SET # define AUDIO2_TIMSKx TIMSK1 @@ -120,18 +118,17 @@ extern float note_timbre; // C6 seems to be the assumed default by many existing keyboard - but sill warn the user #if !defined(AUDIO1_PIN_SET) && !defined(AUDIO2_PIN_SET) # pragma message "Audio feature enabled, but no pin selected - see docs/feature_audio under the AVR settings for available options. Don't expect to hear anything... :-)" -//TODO: make this an error - go through the breaking-change-process and change all keyboards to the new define +// TODO: make this an error - go through the breaking-change-process and change all keyboards to the new define #endif // ----------------------------------------------------------------------------- #ifdef AUDIO1_PIN_SET static float channel_1_frequency = 0.0f; void channel_1_set_frequency(float freq) { - - //TODO: handle consecutive notes with the same frequency, there should be an audible gap inbetween them + // TODO: handle consecutive notes with the same frequency, there should be an audible gap inbetween them if (freq == channel_1_frequency) return; - if (freq == 0.0f) // a pause/rest is a valid "note" with freq=0 + if (freq == 0.0f) // a pause/rest is a valid "note" with freq=0 { // disable the output, but keep the pwm-ISR going (with the previous // frequency) so the audio-state keeps getting updated @@ -139,13 +136,13 @@ void channel_1_set_frequency(float freq) { AUDIO1_TCCRxA &= ~(_BV(AUDIO1_COMxy1) | _BV(AUDIO1_COMxy0)); return; } else { - AUDIO1_TCCRxA |= _BV(AUDIO1_COMxy1);// enable output, PWM mode + AUDIO1_TCCRxA |= _BV(AUDIO1_COMxy1); // enable output, PWM mode } channel_1_frequency = freq; // set pwm period - AUDIO1_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + AUDIO1_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); // and duty cycle AUDIO1_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); } @@ -165,15 +162,12 @@ void channel_1_stop(void) { } #endif - #ifdef AUDIO2_PIN_SET static float channel_2_frequency = 0.0f; void channel_2_set_frequency(float freq) { - if (freq == channel_2_frequency) return; - if (freq == 0.0f) - { + if (freq == 0.0f) { AUDIO2_TCCRxA &= ~(_BV(AUDIO2_COMxy1) | _BV(AUDIO2_COMxy0)); return; } else { @@ -182,7 +176,7 @@ void channel_2_set_frequency(float freq) { channel_2_frequency = freq; - AUDIO2_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); + AUDIO2_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); AUDIO2_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); } @@ -238,7 +232,6 @@ void audio_driver_initialize() { AUDIO2_TCCRxA = (0 << AUDIO2_COMxy1) | (0 << AUDIO2_COMxy0) | (1 << AUDIO2_WGMx1) | (0 << AUDIO2_WGMx0); AUDIO2_TCCRxB = (1 << AUDIO2_WGMx3) | (1 << AUDIO2_WGMx2) | (0 << AUDIO2_CSx2) | (1 << AUDIO2_CSx1) | (0 << AUDIO2_CSx0); #endif - } void audio_driver_stop() { @@ -254,31 +247,27 @@ void audio_driver_stop() { void audio_driver_start(void) { #ifdef AUDIO1_PIN_SET channel_1_start(); - if (playing_note) - channel_1_set_frequency( - audio_get_processed_frequency(0) - ); + if (playing_note) { + channel_1_set_frequency(audio_get_processed_frequency(0)); + } #endif #if !defined(AUDIO1_PIN_SET) && defined(AUDIO2_PIN_SET) channel_2_start(); if (playing_note) { - channel_2_set_frequency( - audio_get_processed_frequency(0) - ); + channel_2_set_frequency(audio_get_processed_frequency(0)); } #endif } -static volatile uint32_t isr_counter=0; +static volatile uint32_t isr_counter = 0; #ifdef AUDIO1_PIN_SET ISR(AUDIO1_TIMERx_COMPy_vect) { isr_counter++; - if (isr_counter < channel_1_frequency/(CPU_PRESCALER*8)) - return; + if (isr_counter < channel_1_frequency / (CPU_PRESCALER * 8)) return; - isr_counter=0; - bool state_changed = audio_advance_state(1,1); + isr_counter = 0; + bool state_changed = audio_advance_state(1, 1); if (!playing_note && !playing_melody) { channel_1_stop(); @@ -288,15 +277,11 @@ ISR(AUDIO1_TIMERx_COMPy_vect) { return; } - if (state_changed){ - channel_1_set_frequency( - audio_get_processed_frequency(0) - ); + if (state_changed) { + channel_1_set_frequency(audio_get_processed_frequency(0)); # ifdef AUDIO2_PIN_SET if (audio_get_number_of_active_tones() > 1) { - channel_2_set_frequency( - audio_get_processed_frequency(1) - ); + channel_2_set_frequency(audio_get_processed_frequency(1)); } else { channel_2_stop(); } @@ -308,21 +293,18 @@ ISR(AUDIO1_TIMERx_COMPy_vect) { #if !defined(AUDIO1_PIN_SET) && defined(AUDIO2_PIN_SET) ISR(AUDIO2_TIMERx_COMPy_vect) { isr_counter++; - if (isr_counter < channel_2_frequency/(CPU_PRESCALER*8)) - return; + if (isr_counter < channel_2_frequency / (CPU_PRESCALER * 8)) return; - isr_counter=0; - bool state_changed = audio_advance_state(1,1); + isr_counter = 0; + bool state_changed = audio_advance_state(1, 1); if (!playing_note && !playing_melody) { channel_2_stop(); return; } - if (state_changed){ - channel_2_set_frequency( - audio_get_processed_frequency(0) - ); + if (state_changed) { + channel_2_set_frequency(audio_get_processed_frequency(0)); } } #endif diff --git a/quantum/audio/driver_chibios_dac.h b/quantum/audio/driver_chibios_dac.h index 1b579c6b6262..d1d5313d22db 100644 --- a/quantum/audio/driver_chibios_dac.h +++ b/quantum/audio/driver_chibios_dac.h @@ -32,8 +32,7 @@ # define AUDIO_DAC_SAMPLE_MAX 4095U #endif -#if !defined(AUDIO_DAC_SAMPLE_RATE) && !defined(AUDIO_MAX_SIMULTANEOUS_TONES) && \ - !defined(AUDIO_DAC_QUALITY_VERY_LOW) && !defined(AUDIO_DAC_QUALITY_LOW) && !defined(AUDIO_DAC_QUALITY_HIGH) && !defined(AUDIO_DAC_QUALITY_VERY_HIGH) +#if !defined(AUDIO_DAC_SAMPLE_RATE) && !defined(AUDIO_MAX_SIMULTANEOUS_TONES) && !defined(AUDIO_DAC_QUALITY_VERY_LOW) && !defined(AUDIO_DAC_QUALITY_LOW) && !defined(AUDIO_DAC_QUALITY_HIGH) && !defined(AUDIO_DAC_QUALITY_VERY_HIGH) # define AUDIO_DAC_QUALITY_SANE_MINIMUM #endif @@ -79,7 +78,6 @@ # define AUDIO_MAX_SIMULTANEOUS_TONES 8 #endif - /** * Effective bitrate of the DAC. 44.1khz is the standard for most audio - any * lower will sacrifice perceptible audio quality. Any higher will limit the @@ -113,7 +111,7 @@ #if !defined(AUDIO_PIN_A4) && !defined(AUDIO_PIN_A5) # pragma message "Audio feature enabled, but no pin selected - see docs/feature_audio under the ARM DAC settings for available options. Falling back to A5" # define AUDIO_PIN_A5 -//TODO: go through a breaking change, and add AUDIO_PIN=A5 to all keyboards currently using AUDIO on STM32 based boards +// TODO: go through a breaking change, and add AUDIO_PIN=A5 to all keyboards currently using AUDIO on STM32 based boards #endif /** diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index cc192d498b24..832f38e1891c 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -37,19 +37,21 @@ */ static const dacsample_t dac_buffer_sine[AUDIO_DAC_BUFFER_SIZE] = { // 256 values, max 4095 - 0x0, 0x1, 0x2, 0x6, 0xa, 0xf, 0x16, 0x1e, 0x27, 0x32, 0x3d, 0x4a, 0x58, 0x67, 0x78, 0x89, 0x9c, 0xb0, 0xc5, 0xdb, 0xf2, 0x10a, 0x123, 0x13e, 0x159, 0x175, 0x193, 0x1b1, 0x1d1, 0x1f1, 0x212, 0x235, 0x258, 0x27c, 0x2a0, 0x2c6, 0x2ed, 0x314, 0x33c, 0x365, 0x38e, 0x3b8, 0x3e3, 0x40e, 0x43a, 0x467, 0x494, 0x4c2, 0x4f0, 0x51f, 0x54e, 0x57d, 0x5ad, 0x5dd, 0x60e, 0x63f, 0x670, 0x6a1, 0x6d3, 0x705, 0x737, 0x769, 0x79b, 0x7cd, 0x800, 0x832, 0x864, 0x896, 0x8c8, 0x8fa, 0x92c, 0x95e, 0x98f, 0x9c0, 0x9f1, 0xa22, 0xa52, 0xa82, 0xab1, 0xae0, 0xb0f, 0xb3d, 0xb6b, 0xb98, 0xbc5, 0xbf1, 0xc1c, 0xc47, 0xc71, 0xc9a, 0xcc3, 0xceb, 0xd12, 0xd39, 0xd5f, 0xd83, 0xda7, 0xdca, 0xded, 0xe0e, 0xe2e, 0xe4e, 0xe6c, 0xe8a, 0xea6, 0xec1, 0xedc, 0xef5, 0xf0d, 0xf24, 0xf3a, 0xf4f, 0xf63, 0xf76, 0xf87, 0xf98, 0xfa7, 0xfb5, 0xfc2, 0xfcd, 0xfd8, 0xfe1, 0xfe9, 0xff0, 0xff5, 0xff9, 0xffd, 0xffe, 0xfff, 0xffe, 0xffd, 0xff9, 0xff5, 0xff0, 0xfe9, 0xfe1, 0xfd8, 0xfcd, 0xfc2, 0xfb5, 0xfa7, 0xf98, 0xf87, 0xf76, 0xf63, 0xf4f, 0xf3a, 0xf24, 0xf0d, 0xef5, 0xedc, 0xec1, 0xea6, 0xe8a, 0xe6c, 0xe4e, 0xe2e, 0xe0e, 0xded, 0xdca, 0xda7, 0xd83, 0xd5f, 0xd39, 0xd12, 0xceb, 0xcc3, 0xc9a, 0xc71, 0xc47, 0xc1c, 0xbf1, 0xbc5, 0xb98, 0xb6b, 0xb3d, 0xb0f, 0xae0, 0xab1, 0xa82, 0xa52, 0xa22, 0x9f1, 0x9c0, 0x98f, 0x95e, 0x92c, 0x8fa, 0x8c8, 0x896, 0x864, 0x832, 0x800, 0x7cd, 0x79b, 0x769, 0x737, 0x705, 0x6d3, 0x6a1, 0x670, 0x63f, 0x60e, 0x5dd, 0x5ad, 0x57d, 0x54e, 0x51f, 0x4f0, 0x4c2, 0x494, 0x467, 0x43a, 0x40e, 0x3e3, 0x3b8, 0x38e, 0x365, 0x33c, 0x314, 0x2ed, 0x2c6, 0x2a0, 0x27c, 0x258, 0x235, 0x212, 0x1f1, 0x1d1, 0x1b1, 0x193, 0x175, 0x159, 0x13e, 0x123, 0x10a, 0xf2, 0xdb, 0xc5, 0xb0, 0x9c, 0x89, 0x78, 0x67, 0x58, 0x4a, 0x3d, 0x32, 0x27, 0x1e, 0x16, 0xf, 0xa, 0x6, 0x2, 0x1}; -#endif // AUDIO_DAC_SAMPLE_WAVEFORM_SINE + 0x0, 0x1, 0x2, 0x6, 0xa, 0xf, 0x16, 0x1e, 0x27, 0x32, 0x3d, 0x4a, 0x58, 0x67, 0x78, 0x89, 0x9c, 0xb0, 0xc5, 0xdb, 0xf2, 0x10a, 0x123, 0x13e, 0x159, 0x175, 0x193, 0x1b1, 0x1d1, 0x1f1, 0x212, 0x235, 0x258, 0x27c, 0x2a0, 0x2c6, 0x2ed, 0x314, 0x33c, 0x365, 0x38e, 0x3b8, 0x3e3, 0x40e, 0x43a, 0x467, 0x494, 0x4c2, 0x4f0, 0x51f, 0x54e, 0x57d, 0x5ad, 0x5dd, 0x60e, 0x63f, 0x670, 0x6a1, 0x6d3, 0x705, 0x737, 0x769, 0x79b, 0x7cd, 0x800, 0x832, 0x864, 0x896, 0x8c8, 0x8fa, 0x92c, 0x95e, 0x98f, 0x9c0, 0x9f1, 0xa22, 0xa52, 0xa82, 0xab1, 0xae0, 0xb0f, 0xb3d, 0xb6b, 0xb98, 0xbc5, 0xbf1, 0xc1c, 0xc47, 0xc71, 0xc9a, 0xcc3, 0xceb, 0xd12, 0xd39, 0xd5f, 0xd83, 0xda7, 0xdca, 0xded, 0xe0e, 0xe2e, 0xe4e, 0xe6c, 0xe8a, 0xea6, 0xec1, 0xedc, 0xef5, 0xf0d, 0xf24, 0xf3a, 0xf4f, 0xf63, 0xf76, 0xf87, 0xf98, 0xfa7, 0xfb5, 0xfc2, 0xfcd, 0xfd8, 0xfe1, 0xfe9, 0xff0, 0xff5, 0xff9, 0xffd, 0xffe, + 0xfff, 0xffe, 0xffd, 0xff9, 0xff5, 0xff0, 0xfe9, 0xfe1, 0xfd8, 0xfcd, 0xfc2, 0xfb5, 0xfa7, 0xf98, 0xf87, 0xf76, 0xf63, 0xf4f, 0xf3a, 0xf24, 0xf0d, 0xef5, 0xedc, 0xec1, 0xea6, 0xe8a, 0xe6c, 0xe4e, 0xe2e, 0xe0e, 0xded, 0xdca, 0xda7, 0xd83, 0xd5f, 0xd39, 0xd12, 0xceb, 0xcc3, 0xc9a, 0xc71, 0xc47, 0xc1c, 0xbf1, 0xbc5, 0xb98, 0xb6b, 0xb3d, 0xb0f, 0xae0, 0xab1, 0xa82, 0xa52, 0xa22, 0x9f1, 0x9c0, 0x98f, 0x95e, 0x92c, 0x8fa, 0x8c8, 0x896, 0x864, 0x832, 0x800, 0x7cd, 0x79b, 0x769, 0x737, 0x705, 0x6d3, 0x6a1, 0x670, 0x63f, 0x60e, 0x5dd, 0x5ad, 0x57d, 0x54e, 0x51f, 0x4f0, 0x4c2, 0x494, 0x467, 0x43a, 0x40e, 0x3e3, 0x3b8, 0x38e, 0x365, 0x33c, 0x314, 0x2ed, 0x2c6, 0x2a0, 0x27c, 0x258, 0x235, 0x212, 0x1f1, 0x1d1, 0x1b1, 0x193, 0x175, 0x159, 0x13e, 0x123, 0x10a, 0xf2, 0xdb, 0xc5, 0xb0, 0x9c, 0x89, 0x78, 0x67, 0x58, 0x4a, 0x3d, 0x32, 0x27, 0x1e, 0x16, 0xf, 0xa, 0x6, 0x2, 0x1}; +#endif // AUDIO_DAC_SAMPLE_WAVEFORM_SINE #ifdef AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE static const dacsample_t dac_buffer_triangle[AUDIO_DAC_BUFFER_SIZE] = { // 256 values, max 4095 - 0x0, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x100, 0x120, 0x140, 0x160, 0x180, 0x1a0, 0x1c0, 0x1e0, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0x400, 0x420, 0x440, 0x460, 0x480, 0x4a0, 0x4c0, 0x4e0, 0x500, 0x520, 0x540, 0x560, 0x580, 0x5a0, 0x5c0, 0x5e0, 0x600, 0x620, 0x640, 0x660, 0x680, 0x6a0, 0x6c0, 0x6e0, 0x700, 0x720, 0x740, 0x760, 0x780, 0x7a0, 0x7c0, 0x7e0, 0x800, 0x81f, 0x83f, 0x85f, 0x87f, 0x89f, 0x8bf, 0x8df, 0x8ff, 0x91f, 0x93f, 0x95f, 0x97f, 0x99f, 0x9bf, 0x9df, 0x9ff, 0xa1f, 0xa3f, 0xa5f, 0xa7f, 0xa9f, 0xabf, 0xadf, 0xaff, 0xb1f, 0xb3f, 0xb5f, 0xb7f, 0xb9f, 0xbbf, 0xbdf, 0xbff, 0xc1f, 0xc3f, 0xc5f, 0xc7f, 0xc9f, 0xcbf, 0xcdf, 0xcff, 0xd1f, 0xd3f, 0xd5f, 0xd7f, 0xd9f, 0xdbf, 0xddf, 0xdff, 0xe1f, 0xe3f, 0xe5f, 0xe7f, 0xe9f, 0xebf, 0xedf, 0xeff, 0xf1f, 0xf3f, 0xf5f, 0xf7f, 0xf9f, 0xfbf, 0xfdf, 0xfff, 0xfdf, 0xfbf, 0xf9f, 0xf7f, 0xf5f, 0xf3f, 0xf1f, 0xeff, 0xedf, 0xebf, 0xe9f, 0xe7f, 0xe5f, 0xe3f, 0xe1f, 0xdff, 0xddf, 0xdbf, 0xd9f, 0xd7f, 0xd5f, 0xd3f, 0xd1f, 0xcff, 0xcdf, 0xcbf, 0xc9f, 0xc7f, 0xc5f, 0xc3f, 0xc1f, 0xbff, 0xbdf, 0xbbf, 0xb9f, 0xb7f, 0xb5f, 0xb3f, 0xb1f, 0xaff, 0xadf, 0xabf, 0xa9f, 0xa7f, 0xa5f, 0xa3f, 0xa1f, 0x9ff, 0x9df, 0x9bf, 0x99f, 0x97f, 0x95f, 0x93f, 0x91f, 0x8ff, 0x8df, 0x8bf, 0x89f, 0x87f, 0x85f, 0x83f, 0x81f, 0x800, 0x7e0, 0x7c0, 0x7a0, 0x780, 0x760, 0x740, 0x720, 0x700, 0x6e0, 0x6c0, 0x6a0, 0x680, 0x660, 0x640, 0x620, 0x600, 0x5e0, 0x5c0, 0x5a0, 0x580, 0x560, 0x540, 0x520, 0x500, 0x4e0, 0x4c0, 0x4a0, 0x480, 0x460, 0x440, 0x420, 0x400, 0x3e0, 0x3c0, 0x3a0, 0x380, 0x360, 0x340, 0x320, 0x300, 0x2e0, 0x2c0, 0x2a0, 0x280, 0x260, 0x240, 0x220, 0x200, 0x1e0, 0x1c0, 0x1a0, 0x180, 0x160, 0x140, 0x120, 0x100, 0xe0, 0xc0, 0xa0, 0x80, 0x60, 0x40, 0x20}; -#endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE + 0x0, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x100, 0x120, 0x140, 0x160, 0x180, 0x1a0, 0x1c0, 0x1e0, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0x400, 0x420, 0x440, 0x460, 0x480, 0x4a0, 0x4c0, 0x4e0, 0x500, 0x520, 0x540, 0x560, 0x580, 0x5a0, 0x5c0, 0x5e0, 0x600, 0x620, 0x640, 0x660, 0x680, 0x6a0, 0x6c0, 0x6e0, 0x700, 0x720, 0x740, 0x760, 0x780, 0x7a0, 0x7c0, 0x7e0, 0x800, 0x81f, 0x83f, 0x85f, 0x87f, 0x89f, 0x8bf, 0x8df, 0x8ff, 0x91f, 0x93f, 0x95f, 0x97f, 0x99f, 0x9bf, 0x9df, 0x9ff, 0xa1f, 0xa3f, 0xa5f, 0xa7f, 0xa9f, 0xabf, 0xadf, 0xaff, 0xb1f, 0xb3f, 0xb5f, 0xb7f, 0xb9f, 0xbbf, 0xbdf, 0xbff, 0xc1f, 0xc3f, 0xc5f, 0xc7f, 0xc9f, 0xcbf, 0xcdf, 0xcff, 0xd1f, 0xd3f, 0xd5f, 0xd7f, 0xd9f, 0xdbf, 0xddf, 0xdff, 0xe1f, 0xe3f, 0xe5f, 0xe7f, 0xe9f, 0xebf, 0xedf, 0xeff, 0xf1f, 0xf3f, 0xf5f, 0xf7f, 0xf9f, 0xfbf, 0xfdf, + 0xfff, 0xfdf, 0xfbf, 0xf9f, 0xf7f, 0xf5f, 0xf3f, 0xf1f, 0xeff, 0xedf, 0xebf, 0xe9f, 0xe7f, 0xe5f, 0xe3f, 0xe1f, 0xdff, 0xddf, 0xdbf, 0xd9f, 0xd7f, 0xd5f, 0xd3f, 0xd1f, 0xcff, 0xcdf, 0xcbf, 0xc9f, 0xc7f, 0xc5f, 0xc3f, 0xc1f, 0xbff, 0xbdf, 0xbbf, 0xb9f, 0xb7f, 0xb5f, 0xb3f, 0xb1f, 0xaff, 0xadf, 0xabf, 0xa9f, 0xa7f, 0xa5f, 0xa3f, 0xa1f, 0x9ff, 0x9df, 0x9bf, 0x99f, 0x97f, 0x95f, 0x93f, 0x91f, 0x8ff, 0x8df, 0x8bf, 0x89f, 0x87f, 0x85f, 0x83f, 0x81f, 0x800, 0x7e0, 0x7c0, 0x7a0, 0x780, 0x760, 0x740, 0x720, 0x700, 0x6e0, 0x6c0, 0x6a0, 0x680, 0x660, 0x640, 0x620, 0x600, 0x5e0, 0x5c0, 0x5a0, 0x580, 0x560, 0x540, 0x520, 0x500, 0x4e0, 0x4c0, 0x4a0, 0x480, 0x460, 0x440, 0x420, 0x400, 0x3e0, 0x3c0, 0x3a0, 0x380, 0x360, 0x340, 0x320, 0x300, 0x2e0, 0x2c0, 0x2a0, 0x280, 0x260, 0x240, 0x220, 0x200, 0x1e0, 0x1c0, 0x1a0, 0x180, 0x160, 0x140, 0x120, 0x100, 0xe0, 0xc0, 0xa0, 0x80, 0x60, 0x40, 0x20}; +#endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE #ifdef AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE static const dacsample_t dac_buffer_square[AUDIO_DAC_BUFFER_SIZE] = { - [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1] = 0, // first and - [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = AUDIO_DAC_SAMPLE_MAX, // second half + [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1] = 0, // first and + [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = AUDIO_DAC_SAMPLE_MAX, // second half }; -#endif // AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE +#endif // AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE /* // four steps: 0, 1/3, 2/3 and 1 static const dacsample_t dac_buffer_staircase[AUDIO_DAC_BUFFER_SIZE] = { @@ -60,17 +62,17 @@ static const dacsample_t dac_buffer_staircase[AUDIO_DAC_BUFFER_SIZE] = { } */ #ifdef AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID -static const dacsample_t dac_buffer_trapezoid[AUDIO_DAC_BUFFER_SIZE] = {0x0, 0x1f, 0x7f, 0xdf, 0x13f, 0x19f, 0x1ff, 0x25f, 0x2bf, 0x31f, 0x37f, 0x3df, 0x43f, 0x49f, 0x4ff, 0x55f, 0x5bf, 0x61f, 0x67f, 0x6df, 0x73f, 0x79f, 0x7ff, 0x85f, 0x8bf, 0x91f, 0x97f, 0x9df, 0xa3f, 0xa9f, 0xaff, 0xb5f, 0xbbf, 0xc1f, 0xc7f, 0xcdf, 0xd3f, 0xd9f, 0xdff, 0xe5f, 0xebf, 0xf1f, 0xf7f, 0xfdf, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfdf, 0xf7f, 0xf1f, 0xebf, 0xe5f, 0xdff, 0xd9f, 0xd3f, 0xcdf, 0xc7f, 0xc1f, 0xbbf, 0xb5f, 0xaff, 0xa9f, 0xa3f, 0x9df, 0x97f, 0x91f, 0x8bf, 0x85f, 0x7ff, 0x79f, 0x73f, 0x6df, 0x67f, 0x61f, 0x5bf, 0x55f, 0x4ff, 0x49f, 0x43f, 0x3df, 0x37f, 0x31f, 0x2bf, 0x25f, 0x1ff, 0x19f, 0x13f, 0xdf, 0x7f, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; -#endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID - +static const dacsample_t dac_buffer_trapezoid[AUDIO_DAC_BUFFER_SIZE] = {0x0, 0x1f, 0x7f, 0xdf, 0x13f, 0x19f, 0x1ff, 0x25f, 0x2bf, 0x31f, 0x37f, 0x3df, 0x43f, 0x49f, 0x4ff, 0x55f, 0x5bf, 0x61f, 0x67f, 0x6df, 0x73f, 0x79f, 0x7ff, 0x85f, 0x8bf, 0x91f, 0x97f, 0x9df, 0xa3f, 0xa9f, 0xaff, 0xb5f, 0xbbf, 0xc1f, 0xc7f, 0xcdf, 0xd3f, 0xd9f, 0xdff, 0xe5f, 0xebf, 0xf1f, 0xf7f, 0xfdf, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, + 0xfff, 0xfdf, 0xf7f, 0xf1f, 0xebf, 0xe5f, 0xdff, 0xd9f, 0xd3f, 0xcdf, 0xc7f, 0xc1f, 0xbbf, 0xb5f, 0xaff, 0xa9f, 0xa3f, 0x9df, 0x97f, 0x91f, 0x8bf, 0x85f, 0x7ff, 0x79f, 0x73f, 0x6df, 0x67f, 0x61f, 0x5bf, 0x55f, 0x4ff, 0x49f, 0x43f, 0x3df, 0x37f, 0x31f, 0x2bf, 0x25f, 0x1ff, 0x19f, 0x13f, 0xdf, 0x7f, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; +#endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID static dacsample_t dac_buffer_empty[AUDIO_DAC_BUFFER_SIZE] = {AUDIO_DAC_OFF_VALUE}; /* keep track of the sample position for for each frequency */ static float dac_if[AUDIO_MAX_SIMULTANEOUS_TONES] = {0.0}; -static float active_tones_snapshot[AUDIO_MAX_SIMULTANEOUS_TONES] = {0,0}; -static uint8_t active_tones_snapshot_length = 0; +static float active_tones_snapshot[AUDIO_MAX_SIMULTANEOUS_TONES] = {0, 0}; +static uint8_t active_tones_snapshot_length = 0; typedef enum { OUTPUT_RUN_NORMALY, @@ -85,40 +87,34 @@ typedef enum { } output_states_t; output_states_t state = OUTPUT_OFF; - /** * Generation of the waveform being passed to the callback. Declared weak so users * can override it with their own waveforms/noises. */ __attribute__((weak)) uint16_t dac_value_generate(void) { - uint16_t value = AUDIO_DAC_OFF_VALUE; + uint16_t value = AUDIO_DAC_OFF_VALUE; - if (OUTPUT_OFF == state) - return AUDIO_DAC_OFF_VALUE; + if (OUTPUT_OFF == state) return AUDIO_DAC_OFF_VALUE; if ((0 == active_tones_snapshot_length) && (OUTPUT_REACHED_ZERO_BEFORE_OFF == state)) { state = OUTPUT_OFF; return AUDIO_DAC_OFF_VALUE; } - /* doing additive wave synthesis over all currently playing tones = adding up * sine-wave-samples for each frequency, scaled by the number of active tones */ uint16_t value_avg = 0; - float frequency = 0.0f; + float frequency = 0.0f; for (uint8_t i = 0; i < active_tones_snapshot_length; i++) { - frequency = active_tones_snapshot[i]; - dac_if[i] = dac_if[i] + - ((frequency - * AUDIO_DAC_BUFFER_SIZE) / AUDIO_DAC_SAMPLE_RATE) - * 2/3; /*Note: necessary to get the correct frequencies on the - DAC output (as measured with an oscilloscope), since - the gpt timer runs with 3*AUDIO_DAC_SAMPLE_RATE; and the DAC - callback is called twice per conversion.*/ + dac_if[i] = dac_if[i] + ((frequency * AUDIO_DAC_BUFFER_SIZE) / AUDIO_DAC_SAMPLE_RATE) * 2 / 3; + /*Note: the 2/3 are necessary to get the correct frequencies on the + * DAC output (as measured with an oscilloscope), since the gpt + * timer runs with 3*AUDIO_DAC_SAMPLE_RATE; and the DAC callback + * is called twice per conversion.*/ dac_if[i] = fmod(dac_if[i], AUDIO_DAC_BUFFER_SIZE); @@ -145,34 +141,29 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { */ // STAIRS (mostly usefull as test-pattern) - //value_avg = dac_buffer_staircase[dac_i] / active_tones_snapshot_length; + // value_avg = dac_buffer_staircase[dac_i] / active_tones_snapshot_length; } value = value_avg; - /* zero crossing (or approach) * * TODO: what about different values, other than AUDIO_DAC_OFF_VALUE=0, AUDIO_DAC_SAMPLE_MAX or AUDIO_DAC_SAMPLE_MAX/2 ? */ - if ((OUTPUT_SHOULD_STOP == state) - && (value < AUDIO_DAC_SAMPLE_MAX/100)) { //TODO: works only if DAC_OFF_VALUE = 0! + if ((OUTPUT_SHOULD_STOP == state) && (value < AUDIO_DAC_SAMPLE_MAX / 100)) { // TODO: works only if DAC_OFF_VALUE = 0! state = OUTPUT_REACHED_ZERO_BEFORE_OFF; - } - else if ((OUTPUT_TONES_CHANGED == state) - && (value < AUDIO_DAC_SAMPLE_MAX/100)) { //TODO: works only if DAC_OFF_VALUE = 0! + } else if ((OUTPUT_TONES_CHANGED == state) && (value < AUDIO_DAC_SAMPLE_MAX / 100)) { // TODO: works only if DAC_OFF_VALUE = 0! state = OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE; } - if (( OUTPUT_REACHED_ZERO_BEFORE_OFF == state) - || (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state)){ - uint8_t active_tones = MIN(AUDIO_MAX_SIMULTANEOUS_TONES, audio_get_number_of_active_tones()); + if ((OUTPUT_REACHED_ZERO_BEFORE_OFF == state) || (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state)) { + uint8_t active_tones = MIN(AUDIO_MAX_SIMULTANEOUS_TONES, audio_get_number_of_active_tones()); active_tones_snapshot_length = 0; // update the snapshot - once, and only on occasion that something changed; // -> saves cpu cycles (?) for (uint8_t i = 0; i < active_tones; i++) { - float freq = audio_get_processed_frequency(i); - if (freq > 0) { // disregard 'rest' notes, with valid frequency 0.0f; which would only lower the resulting waveform volume during the additive synthesis step + float freq = audio_get_processed_frequency(i); + if (freq > 0) { // disregard 'rest' notes, with valid frequency 0.0f; which would only lower the resulting waveform volume during the additive synthesis step active_tones_snapshot[active_tones_snapshot_length++] = freq; } } @@ -189,30 +180,27 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { * * Note: chibios calls this CB twice: during the 'half buffer event', and the 'full buffer event'. */ -static void dac_end(DACDriver *dacp){ +static void dac_end(DACDriver *dacp) { dacsample_t *sample_p = (dacp)->samples; // work on the other half of the buffer if (dacIsBufferComplete(dacp)) { - sample_p += AUDIO_DAC_BUFFER_SIZE/2; // 'half_index' + sample_p += AUDIO_DAC_BUFFER_SIZE / 2; // 'half_index' } - for (uint8_t s = 0; s < AUDIO_DAC_BUFFER_SIZE/2; s++) { + for (uint8_t s = 0; s < AUDIO_DAC_BUFFER_SIZE / 2; s++) { sample_p[s] = dac_value_generate(); } // update audio internal state (note position, current_note, ...) - if(audio_advance_state( - AUDIO_DAC_BUFFER_SIZE/2, - AUDIO_DAC_SAMPLE_RATE/ (64*2.0f/3) + if (audio_advance_state(AUDIO_DAC_BUFFER_SIZE / 2, AUDIO_DAC_SAMPLE_RATE / (64 * 2.0f / 3))) { /* End of the note: 64 is the number of 'units' of a whole note, 3 comes - from the gpttimer: AUDIO_DAC_SAMPLE_RATE * 3; 2 from the callback beeing - called twice per sample conversion. - with a TEMPO set to 60 a whole note lasts exactly one second */ - ) - ){ - if (OUTPUT_SHOULD_STOP != state) + * from the gpttimer: AUDIO_DAC_SAMPLE_RATE * 3; 2 from the callback beeing + * called twice per sample conversion. + */ + if (OUTPUT_SHOULD_STOP != state) { state = OUTPUT_TONES_CHANGED; + } } if (OUTPUT_OFF == state) { @@ -283,18 +271,16 @@ void audio_driver_initialize() { #endif } -void audio_driver_stop(void) { - state = OUTPUT_SHOULD_STOP; -} +void audio_driver_stop(void) { state = OUTPUT_SHOULD_STOP; } void audio_driver_start(void) { gptStart(&GPTD6, &gpt6cfg1); gptStartContinuous(&GPTD6, 2U); for (uint8_t i = 0; i < AUDIO_MAX_SIMULTANEOUS_TONES; i++) { - dac_if[i] = 0.0f; + dac_if[i] = 0.0f; active_tones_snapshot[i] = 0.0f; } active_tones_snapshot_length = 0; - state = OUTPUT_RUN_NORMALY; + state = OUTPUT_RUN_NORMALY; } diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index 8db9231ca57e..79ec246d0361 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -28,8 +28,7 @@ - channel_X_stop should respect dac conversion buffer-complete; currently the output might end up 'high' = halfway through a sample conversion */ - -#if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) +#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) // squarewave static const dacsample_t dac_buffer_1[AUDIO_DAC_BUFFER_SIZE] = { // First half is max, second half is 0 @@ -37,7 +36,7 @@ static const dacsample_t dac_buffer_1[AUDIO_DAC_BUFFER_SIZE] = { [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = 0, }; #endif -#if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) +#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) // squarewave static const dacsample_t dac_buffer_2[AUDIO_DAC_BUFFER_SIZE] = { // opposite of dac_buffer above @@ -46,14 +45,13 @@ static const dacsample_t dac_buffer_2[AUDIO_DAC_BUFFER_SIZE] = { }; #endif - -#if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) +#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) GPTConfig gpt6cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE, .callback = NULL, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U}; #endif -#if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) +#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) GPTConfig gpt7cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE, .callback = NULL, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ @@ -61,15 +59,15 @@ GPTConfig gpt7cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE, #endif static void gpt_cb8(GPTDriver *gptp); -GPTConfig gpt8cfg1 = {.frequency = 10, +GPTConfig gpt8cfg1 = {.frequency = 10, .callback = gpt_cb8, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U}; -#if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) +#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) static const DACConfig dac_conf_ch1 = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_DHRM_12BIT_RIGHT}; #endif -#if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) +#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) static const DACConfig dac_conf_ch2 = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_DHRM_12BIT_RIGHT}; #endif @@ -87,65 +85,59 @@ static const DACConfig dac_conf_ch2 = {.init = AUDIO_DAC_OFF_VALUE, .datamode = * EXTI9 0b110 * SWTRIG 0b111 */ -#if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) +#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) static const DACConversionGroup dac_conv_grp_ch1 = {.num_channels = 1U, .trigger = DAC_TRG(0b000)}; #endif -#if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) +#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) static const DACConversionGroup dac_conv_grp_ch2 = {.num_channels = 1U, .trigger = DAC_TRG(0b010)}; #endif - -#if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) +#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) void channel_1_start(void) { gptStart(&GPTD6, &gpt6cfg1); gptStartContinuous(&GPTD6, 2U); } -void channel_1_stop(void) { - gptStopTimer(&GPTD6); -} +void channel_1_stop(void) { gptStopTimer(&GPTD6); } static float channel_1_frequency = 0.0f; -void channel_1_set_frequency(float freq) { +void channel_1_set_frequency(float freq) { channel_1_frequency = freq; channel_1_stop(); - if (freq <= 0.0) //a pause/rest has freq=0 + if (freq <= 0.0) // a pause/rest has freq=0 return; gpt6cfg1.frequency = 2 * freq * AUDIO_DAC_BUFFER_SIZE; channel_1_start(); } float channel_1_get_frequency(void) { return channel_1_frequency; } -#endif // AUDIO_PIN(_ALT)_A4 +#endif // AUDIO_PIN(_ALT)_A4 -#if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) +#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) void channel_2_start(void) { gptStart(&GPTD7, &gpt7cfg1); gptStartContinuous(&GPTD7, 2U); } -void channel_2_stop(void) { - gptStopTimer(&GPTD7); -} +void channel_2_stop(void) { gptStopTimer(&GPTD7); } static float channel_2_frequency = 0.0f; -void channel_2_set_frequency(float freq) { +void channel_2_set_frequency(float freq) { channel_2_frequency = freq; channel_2_stop(); - if (freq <= 0.0) //a pause/rest has freq=0 + if (freq <= 0.0) // a pause/rest has freq=0 return; gpt7cfg1.frequency = 2 * freq * AUDIO_DAC_BUFFER_SIZE; channel_2_start(); } float channel_2_get_frequency(void) { return channel_2_frequency; } -#endif // AUDIO_PIN(_ALT)_A5 +#endif // AUDIO_PIN(_ALT)_A5 static void gpt_cb8(GPTDriver *gptp) { - if(audio_advance_state(1,gpt8cfg1.frequency)) { - + if (audio_advance_state(1, gpt8cfg1.frequency)) { #if defined(AUDIO_PIN_A4) channel_1_set_frequency(audio_get_processed_frequency(0)); # if defined(AUDIO_PIN_ALT_A5) @@ -167,17 +159,16 @@ static void gpt_cb8(GPTDriver *gptp) { } # endif #endif - } } void audio_driver_initialize() { -#if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) +#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); dacStart(&DACD1, &dac_conf_ch1); dacStartConversion(&DACD1, &dac_conv_grp_ch1, (dacsample_t *)dac_buffer_1, AUDIO_DAC_BUFFER_SIZE); #endif -#if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) +#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); dacStart(&DACD2, &dac_conf_ch2); dacStartConversion(&DACD2, &dac_conv_grp_ch2, (dacsample_t *)dac_buffer_2, AUDIO_DAC_BUFFER_SIZE); @@ -192,11 +183,11 @@ void audio_driver_initialize() { * this is done here, reaching directly into the stm32 registers since chibios has not implemented BOFF handling yet * (see: chibios/os/hal/ports/STM32/todo.txt '- BOFF handling in DACv1.' */ -#if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) +#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) DACD1.params->dac->CR &= ~DAC_CR_BOFF1; - gptStart(&GPTD6, &gpt6cfg1); // initialize the timer used to trigger the DAC conversions + gptStart(&GPTD6, &gpt6cfg1); // initialize the timer used to trigger the DAC conversions #endif -#if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) +#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) DACD2.params->dac->CR &= ~DAC_CR_BOFF2; gptStart(&GPTD7, &gpt7cfg1); #endif @@ -206,15 +197,13 @@ void audio_driver_initialize() { } void audio_driver_stop(void) { -#if defined(AUDIO_PIN_A4) || defined (AUDIO_PIN_ALT_A4) +#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) gptStopTimer(&GPTD6); #endif -#if defined(AUDIO_PIN_A5) || defined (AUDIO_PIN_ALT_A5) +#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) gptStopTimer(&GPTD7); #endif gptStopTimer(&GPTD8); } -void audio_driver_start(void) { - gptStartContinuous(&GPTD8, 2U); -} +void audio_driver_start(void) { gptStartContinuous(&GPTD8, 2U); } diff --git a/quantum/audio/driver_chibios_pwm.h b/quantum/audio/driver_chibios_pwm.h index e1e5b8a86fee..56fec0d20c47 100644 --- a/quantum/audio/driver_chibios_pwm.h +++ b/quantum/audio/driver_chibios_pwm.h @@ -15,14 +15,13 @@ */ #pragma once - #if !defined(AUDIO_PWM_TIMER) -//NOTE: Timer2 seems to be used otherwise in QMK, otherwise we could default to A5 (= TIM2_CH1, with PWMD2 and alternate-function(1)) +// NOTE: Timer2 seems to be used otherwise in QMK, otherwise we could default to A5 (= TIM2_CH1, with PWMD2 and alternate-function(1)) # define AUDIO_PWM_TIMER 1 #endif #if !defined(AUDIO_PWM_TIMERCHANNEL) -//NOTE: sticking to the STM datasheet numbering: TIMxCH1 to TIMxCH4 +// NOTE: sticking to the STM datasheet numbering: TIMxCH1 to TIMxCH4 // default: STM32F303CC PA8+TIM1_CH1 -> 1 # define AUDIO_PWM_TIMERCHANNEL 1 #endif diff --git a/quantum/audio/driver_chibios_pwm_hardware.c b/quantum/audio/driver_chibios_pwm_hardware.c index 0811a388c1c3..7f0036490d3d 100644 --- a/quantum/audio/driver_chibios_pwm_hardware.c +++ b/quantum/audio/driver_chibios_pwm_hardware.c @@ -24,7 +24,6 @@ The hardware directly toggles the pin via its alternate function. see your MCUs */ - /* STM32F103C8 Setup: halconf.h: #define HAL_USE_PWM TRUE @@ -53,70 +52,62 @@ so adding to config.h: #include "ch.h" #include "hal.h" - #if !defined(AUDIO_PIN) # error "Audio feature enabled, but no pin selected - see docs/feature_audio under the ARM PWM settings" #endif - // some preprocessor trickery to get the corresponding chibios-PWMDriver #define TO_CHIBIOS_PWMD_PASTE(t) (PWMD##t) #define TO_CHIBIOS_PWMD_EVAL(t) TO_CHIBIOS_PWMD_PASTE(t) #define PWMD TO_CHIBIOS_PWMD_EVAL(AUDIO_PWM_TIMER) -extern bool playing_note; -extern bool playing_melody; +extern bool playing_note; +extern bool playing_melody; extern float note_timbre; - -static PWMConfig pwmCFG = {.frequency = 100000, /* PWM clock frequency */ - //CHIBIOS-BUG? can't set the initial period to <2, or the pwm (hard or software) takes ~130ms with .frequency=500000 for a pwmChangePeriod to take effect; with no ouput=silence in the meantime - .period = 2, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ - .callback = NULL, // no callback, the hardware directly toggles the pin - .channels = { +static PWMConfig pwmCFG = { + .frequency = 100000, /* PWM clock frequency */ + // CHIBIOS-BUG? can't set the initial period to <2, or the pwm (hard or software) takes ~130ms with .frequency=500000 for a pwmChangePeriod to take effect; with no ouput=silence in the meantime + .period = 2, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ + .callback = NULL, /* no callback, the hardware directly toggles the pin */ + .channels = + { #if AUDIO_PWM_TIMERCHANNEL == 4 - {PWM_OUTPUT_DISABLED, NULL}, /* channel 0 -> TIMx_CH1 */ - {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIMx_CH2 */ - {PWM_OUTPUT_DISABLED, NULL}, /* channel 2 -> TIMx_CH3 */ - {PWM_OUTPUT_ACTIVE_HIGH, NULL} /* channel 3 -> TIMx_CH4 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 0 -> TIMx_CH1 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIMx_CH2 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 2 -> TIMx_CH3 */ + {PWM_OUTPUT_ACTIVE_HIGH, NULL} /* channel 3 -> TIMx_CH4 */ #elif AUDIO_PWM_TIMERCHANNEL == 3 - {PWM_OUTPUT_DISABLED, NULL}, - {PWM_OUTPUT_DISABLED, NULL}, - {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH3 */ - {PWM_OUTPUT_DISABLED, NULL} + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH3 */ + {PWM_OUTPUT_DISABLED, NULL} #elif AUDIO_PWM_TIMERCHANNEL == 2 - {PWM_OUTPUT_DISABLED, NULL}, - {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH2 */ - {PWM_OUTPUT_DISABLED, NULL}, - {PWM_OUTPUT_DISABLED, NULL} + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH2 */ + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_DISABLED, NULL} #else /*fallback to CH1 */ - {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH1 */ - {PWM_OUTPUT_DISABLED, NULL}, - {PWM_OUTPUT_DISABLED, NULL}, - {PWM_OUTPUT_DISABLED, NULL} + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH1 */ + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_DISABLED, NULL} #endif - }, - }; - + }, +}; static float channel_1_frequency = 0.0f; -void channel_1_set_frequency(float freq) { -// if (freq == channel_1_frequency) return; - //TODO: interrupt same-frequency notes? - +void channel_1_set_frequency(float freq) { channel_1_frequency = freq; - if (freq <= 0.0) //a pause/rest has freq=0 + if (freq <= 0.0) // a pause/rest has freq=0 return; pwmcnt_t period = (pwmCFG.frequency / freq); pwmChangePeriod(&PWMD, period); - pwmEnableChannel( - &PWMD, - AUDIO_PWM_TIMERCHANNEL -1, + pwmEnableChannel(&PWMD, AUDIO_PWM_TIMERCHANNEL - 1, // adjust the duty-cycle so that the output is for 'note_timbre' duration HIGH - PWM_PERCENTAGE_TO_WIDTH(&PWMD, (1.0f-note_timbre) * 10000) - ); + PWM_PERCENTAGE_TO_WIDTH(&PWMD, (1.0f - note_timbre) * 10000)); } float channel_1_get_frequency(void) { return channel_1_frequency; } @@ -126,9 +117,7 @@ void channel_1_start(void) { pwmStart(&PWMD, &pwmCFG); } -void channel_1_stop(void) { - pwmStop(&PWMD); -} +void channel_1_stop(void) { pwmStop(&PWMD); } static void gpt_callback(GPTDriver *gptp); GPTConfig gptCFG = { @@ -148,9 +137,9 @@ void audio_driver_initialize(void) { pwmStart(&PWMD, &pwmCFG); // connect the AUDIO_PIN to the PWM hardware -#if defined(USE_GPIOV1) // STM32F103C8 +#if defined(USE_GPIOV1) // STM32F103C8 palSetLineMode(AUDIO_PIN, PAL_MODE_STM32_ALTERNATE_PUSHPULL); -#else // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command) +#else // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command) palSetLineMode(AUDIO_PIN, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(AUDIO_PWM_PINALTERNATE_FUNCTION)); #endif @@ -175,10 +164,10 @@ void audio_driver_stop(void) { * and updates the pwm to output that frequency */ static void gpt_callback(GPTDriver *gptp) { - float freq;// TODO: freq_alt + float freq; // TODO: freq_alt if (audio_advance_state(1, 1)) { - freq = audio_get_processed_frequency(0); // freq_alt would be index=1 + freq = audio_get_processed_frequency(0); // freq_alt would be index=1 channel_1_set_frequency(freq); } } diff --git a/quantum/audio/driver_chibios_pwm_software.c b/quantum/audio/driver_chibios_pwm_software.c index 48541711dc10..9bc804c2da7a 100644 --- a/quantum/audio/driver_chibios_pwm_software.c +++ b/quantum/audio/driver_chibios_pwm_software.c @@ -27,59 +27,50 @@ this driver uses the chibios-PWM system to produce a squarewave on any given out #include "ch.h" #include "hal.h" - #if !defined(AUDIO_PIN) # error "Audio feature enabled, but no pin selected - see docs/feature_audio under the ARM PWM settings" #endif - // some preprocessor trickery to get the corresponding chibios-PWMDriver #define TO_CHIBIOS_PWMD_PASTE(t) (PWMD##t) #define TO_CHIBIOS_PWMD_EVAL(t) TO_CHIBIOS_PWMD_PASTE(t) #define PWMD TO_CHIBIOS_PWMD_EVAL(AUDIO_PWM_TIMER) -extern bool playing_note; -extern bool playing_melody; +extern bool playing_note; +extern bool playing_melody; extern float note_timbre; - static void pwm_audio_period_callback(PWMDriver *pwmp); static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp); - -static PWMConfig pwmCFG = {.frequency = 100000, /* PWM clock frequency */ - //CHIBIOS-BUG? can't set the initial period to <2, or the pwm (hard or software) takes ~130ms with .frequency=500000 for a pwmChangePeriod to take effect; with no ouput=silence in the meantime - .period = 2, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ - .callback = pwm_audio_period_callback, - .channels = { - // software-PWM just needs another callback on any channel - {PWM_OUTPUT_ACTIVE_HIGH, pwm_audio_channel_interrupt_callback}, /* channel 0 -> TIMx_CH1 */ - {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIMx_CH2 */ - {PWM_OUTPUT_DISABLED, NULL}, /* channel 2 -> TIMx_CH3 */ - {PWM_OUTPUT_DISABLED, NULL} /* channel 3 -> TIMx_CH4 */ - }, - }; - +static PWMConfig pwmCFG = { + .frequency = 100000, /* PWM clock frequency */ + // CHIBIOS-BUG? can't set the initial period to <2, or the pwm (hard or software) takes ~130ms with .frequency=500000 for a pwmChangePeriod to take effect; with no ouput=silence in the meantime + .period = 2, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ + .callback = pwm_audio_period_callback, + .channels = + { + // software-PWM just needs another callback on any channel + {PWM_OUTPUT_ACTIVE_HIGH, pwm_audio_channel_interrupt_callback}, /* channel 0 -> TIMx_CH1 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIMx_CH2 */ + {PWM_OUTPUT_DISABLED, NULL}, /* channel 2 -> TIMx_CH3 */ + {PWM_OUTPUT_DISABLED, NULL} /* channel 3 -> TIMx_CH4 */ + }, +}; static float channel_1_frequency = 0.0f; -void channel_1_set_frequency(float freq) { -// if (freq == channel_1_frequency) return; - //TODO: interrupt same-frequency notes? - +void channel_1_set_frequency(float freq) { channel_1_frequency = freq; - if (freq <= 0.0) //a pause/rest has freq=0 + if (freq <= 0.0) // a pause/rest has freq=0 return; pwmcnt_t period = (pwmCFG.frequency / freq); pwmChangePeriod(&PWMD, period); - pwmEnableChannel( - &PWMD, - AUDIO_PWM_TIMERCHANNEL -1, + pwmEnableChannel(&PWMD, AUDIO_PWM_TIMERCHANNEL - 1, // adjust the duty-cycle so that the output is for 'note_timbre' duration HIGH - PWM_PERCENTAGE_TO_WIDTH(&PWMD, (1.0f-note_timbre) * 10000) - ); + PWM_PERCENTAGE_TO_WIDTH(&PWMD, (1.0f - note_timbre) * 10000)); } float channel_1_get_frequency(void) { return channel_1_frequency; } @@ -89,13 +80,13 @@ void channel_1_start(void) { pwmStart(&PWMD, &pwmCFG); pwmEnablePeriodicNotification(&PWMD); - pwmEnableChannelNotification(&PWMD, AUDIO_PWM_TIMERCHANNEL-1); + pwmEnableChannelNotification(&PWMD, AUDIO_PWM_TIMERCHANNEL - 1); } void channel_1_stop(void) { pwmStop(&PWMD); - palClearLine(AUDIO_PIN); // leave the line low, after last note was played + palClearLine(AUDIO_PIN); // leave the line low, after last note was played } // generate a PWM signal on any pin, not neccessarily the one connected to the timer @@ -105,8 +96,7 @@ static void pwm_audio_period_callback(PWMDriver *pwmp) { } static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { (void)pwmp; - if (channel_1_frequency > 0) - palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer + if (channel_1_frequency > 0) palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer } static void gpt_callback(GPTDriver *gptp); @@ -129,8 +119,8 @@ void audio_driver_initialize(void) { palSetLineMode(AUDIO_PIN, PAL_MODE_OUTPUT_PUSHPULL); palClearLine(AUDIO_PIN); - pwmEnablePeriodicNotification(&PWMD); // enable pwm callbacks - pwmEnableChannelNotification(&PWMD, AUDIO_PWM_TIMERCHANNEL-1); + pwmEnablePeriodicNotification(&PWMD); // enable pwm callbacks + pwmEnableChannelNotification(&PWMD, AUDIO_PWM_TIMERCHANNEL - 1); gptStart(&GPTD6, &gptCFG); } @@ -153,10 +143,10 @@ void audio_driver_stop(void) { * and updates the pwm to output that frequency */ static void gpt_callback(GPTDriver *gptp) { - float freq;// TODO: freq_alt + float freq; // TODO: freq_alt if (audio_advance_state(1, 1)) { - freq = audio_get_processed_frequency(0); // freq_alt would be index=1 + freq = audio_get_processed_frequency(0); // freq_alt would be index=1 channel_1_set_frequency(freq); } } diff --git a/quantum/audio/musical_notes.h b/quantum/audio/musical_notes.h index 9d4bc0bc0556..d8d31427c25a 100644 --- a/quantum/audio/musical_notes.h +++ b/quantum/audio/musical_notes.h @@ -33,7 +33,7 @@ #define QUARTER_NOTE(note) MUSICAL_NOTE(note, 16) #define EIGHTH_NOTE(note) MUSICAL_NOTE(note, 8) #define SIXTEENTH_NOTE(note) MUSICAL_NOTE(note, 4) -#define THIRTYTWOTH_NOTE(note) MUSICAL_NOTE(note, 2) //TODO: still usable? +#define THIRTYTWOTH_NOTE(note) MUSICAL_NOTE(note, 2) #define BREVE_DOT_NOTE(note) MUSICAL_NOTE(note, 128 + 64) #define WHOLE_DOT_NOTE(note) MUSICAL_NOTE(note, 64 + 32) diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index bce8f9a2e9c4..83f46468e8fc 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -36,14 +36,14 @@ float voice_envelope(float frequency) { switch (voice) { case default_voice: - glissando = false; - //note_timbre = TIMBRE_50; //Note: leave the user the possibility to adjust the timbre with 'audio_set_timbre' + glissando = false; + // note_timbre = TIMBRE_50; //Note: leave the user the possibility to adjust the timbre with 'audio_set_timbre' break; #ifdef AUDIO_VOICES case something: - glissando = false; + glissando = false; switch (compensated_index) { case 0 ... 9: note_timbre = TIMBRE_12; @@ -64,7 +64,7 @@ float voice_envelope(float frequency) { break; case drums: - glissando = false; + glissando = false; // switch (compensated_index) { // case 0 ... 10: // note_timbre = 0.5; @@ -141,7 +141,7 @@ float voice_envelope(float frequency) { } break; case butts_fader: - glissando = true; + glissando = true; switch (compensated_index) { case 0 ... 9: frequency = frequency / 4; @@ -187,7 +187,7 @@ float voice_envelope(float frequency) { case duty_osc: // This slows the loop down a substantial amount, so higher notes may freeze - glissando = true; + glissando = true; switch (compensated_index) { default: # define OCS_SPEED 10 @@ -201,14 +201,14 @@ float voice_envelope(float frequency) { break; case duty_octave_down: - glissando = true; - note_timbre = (envelope_index % 2) * .125 + .375 * 2; + glissando = true; + note_timbre = (envelope_index % 2) * .125 + .375 * 2; if ((envelope_index % 4) == 0) note_timbre = 0.5; if ((envelope_index % 8) == 0) note_timbre = 0; break; case delayed_vibrato: - glissando = true; - note_timbre = TIMBRE_50; + glissando = true; + note_timbre = TIMBRE_50; # define VOICE_VIBRATO_DELAY 150 # define VOICE_VIBRATO_SPEED 50 switch (compensated_index) { @@ -260,7 +260,7 @@ float voice_envelope(float frequency) { // note_timbre = 0.25; // break; -#endif // AUDIO_VOICES +#endif // AUDIO_VOICES default: break; From f235ef6c8ffd84852c29063b50d228f289a3f9fa Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 8 Apr 2020 17:33:26 +0200 Subject: [PATCH 074/153] audio-avr-pwm: consecutive notes of the same frequency get a pause inserted inbetween by audio.c --- quantum/audio/driver_avr_pwm_hardware.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/quantum/audio/driver_avr_pwm_hardware.c b/quantum/audio/driver_avr_pwm_hardware.c index 3c683e6199dc..379875bb6006 100644 --- a/quantum/audio/driver_avr_pwm_hardware.c +++ b/quantum/audio/driver_avr_pwm_hardware.c @@ -125,9 +125,6 @@ extern float note_timbre; #ifdef AUDIO1_PIN_SET static float channel_1_frequency = 0.0f; void channel_1_set_frequency(float freq) { - // TODO: handle consecutive notes with the same frequency, there should be an audible gap inbetween them - if (freq == channel_1_frequency) return; - if (freq == 0.0f) // a pause/rest is a valid "note" with freq=0 { // disable the output, but keep the pwm-ISR going (with the previous @@ -165,8 +162,6 @@ void channel_1_stop(void) { #ifdef AUDIO2_PIN_SET static float channel_2_frequency = 0.0f; void channel_2_set_frequency(float freq) { - if (freq == channel_2_frequency) return; - if (freq == 0.0f) { AUDIO2_TCCRxA &= ~(_BV(AUDIO2_COMxy1) | _BV(AUDIO2_COMxy0)); return; From 6bb4e4081561875787cb411d5c388fe2bf9e53ad Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 10 Apr 2020 07:33:02 +0200 Subject: [PATCH 075/153] audio-refactoring: use milliseconds instead of seconds for 'click' parameters clicks are supposed to be short, seconds make little sense --- quantum/audio/audio.c | 6 +++--- quantum/audio/audio.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 23fe17f4367a..cbe8fe8131c8 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -305,9 +305,9 @@ void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) { } float click[2][2]; -void audio_play_click(float delay, float frequency, float duration) { - float duration_tone = (64 / 60) * note_tempo * duration; - float duration_delay = (64 / 60) * note_tempo * delay; +void audio_play_click(uint16_t delay, float frequency, uint16_t duration) { + float duration_tone = (64 / 60) * note_tempo * (duration / 1000.0f); + float duration_delay = (64 / 60) * note_tempo * (delay / 1000.0f); if (delay <= 0.0f) { click[0][0] = frequency; diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index b954124044c4..e009ec99e345 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -124,11 +124,11 @@ void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat); * audio_play_melody. very short durations might not quite work due to * hardware limitations (DAC: added pulses from zero-crossing feature;...) * - * @param[in] delay in seconds, lenght for the pause before the pulses, can be zero + * @param[in] delay in milliseconds, lenght for the pause before the pulses, can be zero * @param[in] frequency - * @param[in] duration in seconds, length of the 'click' + * @param[in] duration in milliseconds, length of the 'click' */ -void audio_play_click(float delay, float frequency, float duration); +void audio_play_click(uint16_t delay, float frequency, uint16_t duration); /** * @brief stops all playback From 2d4f90743f09f2c4a5694c7a2fb8c521641b9837 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 10 Apr 2020 15:33:43 +0200 Subject: [PATCH 076/153] audio-refactoring: use timer ticks instead of counters local counters were used in the original (avr)ISR to advance an index into the lookup tables (for vibrato), and something similar was used for the tone-multiplexing feature decoupling these from the (possibly irregular) calls to advance_state made sesne, since those counters/lookups need to be in relation to a wall-time anyway --- quantum/audio/audio.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index cbe8fe8131c8..b531062a847d 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -14,9 +14,9 @@ * along with this program. If not, see . */ #include "audio.h" -#include "wait.h" - #include "eeconfig.h" +#include "timer.h" +#include "wait.h" /* audio system: * @@ -73,12 +73,10 @@ bool note_resting = false; // if a short pause was introduced betw # define AUDIO_MAX_SIMULTANEOUS_TONES 3 # endif float tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT; -float tone_multiplexing_counter = 0.0f; // incremented each state update, and compared to _rate uint8_t tone_multiplexing_index_shift = 0; // offset used on active-tone array access #endif #ifdef AUDIO_ENABLE_VIBRATO -float vibrato_counter = 0; float vibrato_strength = 0.5; float vibrato_rate = 0.125; // forward declataion @@ -392,18 +390,12 @@ bool audio_advance_state(uint32_t step, float end) { if (playing_note) { #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING - tone_multiplexing_counter += step / end; - if (tone_multiplexing_counter == tone_multiplexing_rate) { - tone_multiplexing_counter = 0.0f; - tone_multiplexing_index_shift++; - if (tone_multiplexing_index_shift >= MIN(AUDIO_MAX_SIMULTANEOUS_TONES, active_tones)) { - tone_multiplexing_index_shift = 0; - } - goto_next_note = true; - } + tone_multiplexing_index_shift = + (int)(timer_read() / tone_multiplexing_rate) + % MIN(AUDIO_MAX_SIMULTANEOUS_TONES, active_tones); + goto_next_note = true; #endif #ifdef AUDIO_ENABLE_VIBRATO - // force update on each cycle, since vibrato shifts the frequency slightly goto_next_note = true; #endif } @@ -482,14 +474,16 @@ float mod(float a, int b) { return r < 0 ? r + b : r; } -// TODO: unify with vibrato function/call in voices.c +// TODO: unify with vibrato calculation in voices.c; which does basically the same float vibrato(float average_freq) { + float vibrato_counter = mod(timer_read() / (100 * vibrato_rate), VIBRATO_LUT_LENGTH); + # ifdef AUDIO_ENABLE_VIBRATO_STRENGTH float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); # else float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; # endif - vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0 / average_freq)), VIBRATO_LUT_LENGTH); + //vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0 / average_freq)), VIBRATO_LUT_LENGTH); return vibrated_freq; } From 264734aa86c70a05d4a2607f7027d43df33f6800 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 10 Apr 2020 16:15:51 +0200 Subject: [PATCH 077/153] audio-refactoring: voices.c: drop 'envelope_index' counter in favour of timer ticks --- quantum/audio/audio.c | 42 +++++++++++++++++++++++++----------------- quantum/audio/voices.c | 40 +++++++++++++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 22 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index b531062a847d..98553019cb97 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -40,12 +40,20 @@ * "(Musical) tone, a sound characterized by its duration, pitch (=frequency), * intensity (=volume), and timbre" * - intensity/volume is currently not handled at all, although the 'dac_additive' driver could do so - * - timbre is handled globally (TODO: only by the avr driver at the moment) + * - timbre is handled globally (TODO: only used with the pwm drivers at the moment) * - * a (musical) note is the combination of a pitch and a duration - * musical_notes are used to create SONG arrays; during playback their - * frequencies are handled as single successive tones, while the durations are + * in musical_note.h a 'note' is the combination of a pitch and a duration + * these are used to create SONG arrays; during playback their frequencies + * are handled as single successive tones, while the durations are * kept track of in 'audio_advance_state' + * + * 'voice' as it is used here, equates to a sort of instrument with its own + * charactersitic sound and effects + * the audio system as-is deals only with (possibly multiple) tones of one + * instrument/voice at a time (think: chords). since the number of tones that + * can be reproduced depends on the hardware/driver in use: pwm can only + * reproduce one tone per output/speaker; DACs can reproduce/mix multiple + * when doing additive synthese. */ #ifndef AUDIO_TONE_STACKSIZE @@ -83,10 +91,12 @@ float vibrato_rate = 0.125; float vibrato(float average_freq); #endif -// used by voices.c -float note_timbre = TIMBRE_DEFAULT; -uint16_t envelope_index = 0; -bool glissando = false; +// proviced and used by voices.c +extern float note_timbre; +extern bool glissando; +extern bool vibrato; +extern uint16_t voices_timer; + #ifndef STARTUP_SONG # define STARTUP_SONG SONG(STARTUP_SOUND) @@ -262,9 +272,10 @@ void audio_play_tone(float frequency) { } state_changed = true; playing_note = true; - envelope_index = 0; // see voices.c // TODO: does what? frequencies[active_tones - 1] = frequency; + voices_timer = timer_read(); // reset to zero, for the effects added by voices.c + if (active_tones == 1) // sufficient to start when switching from 0 to 1 audio_driver_start(); } @@ -376,10 +387,6 @@ float audio_get_processed_frequency(uint8_t tone_index) { } #endif - if (envelope_index < 65535) { - envelope_index++; - } - frequency = voice_envelope(frequency); return frequency; @@ -395,9 +402,10 @@ bool audio_advance_state(uint32_t step, float end) { % MIN(AUDIO_MAX_SIMULTANEOUS_TONES, active_tones); goto_next_note = true; #endif -#ifdef AUDIO_ENABLE_VIBRATO - goto_next_note = true; -#endif + if (vibrato || glissando) { + // force update on each cycle, since vibrato shifts the frequency slightly + goto_next_note = true; + } } if (playing_melody) { @@ -407,7 +415,7 @@ bool audio_advance_state(uint32_t step, float end) { if (goto_next_note) { uint16_t previous_note = current_note; current_note++; - envelope_index = 0; + voices_timer = timer_read(); // reset to zero, for the effects added by voices.c if (current_note >= notes_count) { if (notes_repeat) { diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 83f46468e8fc..263bd62166bd 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -17,10 +17,14 @@ #include "audio.h" #include -// these are imported from audio.c -extern uint16_t envelope_index; -extern float note_timbre; -extern bool glissando; +float note_timbre = TIMBRE_DEFAULT; +bool glissando = false; +#ifdef AUDIO_ENABLE_VIBRATO +bool vibrato = true; +#else +bool vibrato = false; +#endif +uint16_t voices_timer = 0; voice_type voice = default_voice; @@ -30,9 +34,35 @@ void voice_iterate() { voice = (voice + 1) % number_of_voices; } void voice_deiterate() { voice = (voice - 1 + number_of_voices) % number_of_voices; } + +#ifdef AUDIO_VOICES +float mod(float a, int b) { + float r = fmod(a, b); + return r < 0 ? r + b : r; +} + + +float voice_add_vibrato(float average_freq) { + float vibrato_counter = mod(timer_read() / (100 * vibrato_rate), VIBRATO_LUT_LENGTH); + +# ifdef AUDIO_ENABLE_VIBRATO_STRENGTH + float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); +# else + float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; +# endif + //vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0 / average_freq)), VIBRATO_LUT_LENGTH); + return vibrated_freq; +} +#endif + + float voice_envelope(float frequency) { // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz - __attribute__((unused)) uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency)); +// __attribute__((unused)) uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency)); +#ifdef AUDIO_VOICES + uint16_t envelope_index = timer_elapsed(voices_timer); //TODO: multiply in some factor? + uint16_t compensated_index = envelope_index / 100; // TODO: correct factor would be? +#endif switch (voice) { case default_voice: From 136f6a03731429db36d691cc9f2fd76b72b513b0 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 10 Apr 2020 17:07:13 +0200 Subject: [PATCH 078/153] audio-refactoring: move vibrato and timbre related parts from audio.c to voices.c also drops the now (globally) unused AUDIO_VIBRATO/AUDIO_ENABLE_VIBRATO defines --- docs/feature_audio.md | 11 ++++++--- quantum/audio/audio.c | 51 --------------------------------------- quantum/audio/audio.h | 27 --------------------- quantum/audio/voices.c | 55 ++++++++++++++++++++++++++++++------------ quantum/audio/voices.h | 22 +++++++++++++++-- 5 files changed, 68 insertions(+), 98 deletions(-) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index d514c888d311..0693e4d14788 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -5,14 +5,14 @@ Your keyboard can make sounds! If you've got a spare pin you can hook up a simpl To activate this feature, add `AUDIO_ENABLE = yes` to your `rules.mk`. ## AVR based boards -Up to two simultaneous audio voices are supported, one driven by timer 1 and another driven by timer 3. The following pins can be configured as audio outputs in `rules.mk`: +Up to two simultaneous tones can be rendered. with one speaker driven by timer 1 and another driven by timer 3. The following pins can be configured as audio outputs in `rules.mk`: -for the primary voice, with Timer 3, pick ONE these pins: +for the primary speaker, with Timer 3, pick ONE these pins: `AUDIO_PIN = C4` `AUDIO_PIN = C5` `AUDIO_PIN = C6` -and *optionally*, a secondary voice, using Timer 1, on ONE of these pins: +and *optionally*, a secondary speaker, using Timer 1, on ONE of these pins: `AUDIO_PIN_ALT = B5` `AUDIO_PIN_ALT = B6` `AUDIO_PIN_ALT = B7` @@ -123,6 +123,11 @@ the DAC usually runs in 12Bit mode, hence a volume of 100% = 4095U Note: this only adjusts the volume aka 'works' if you stick to WAVEFORM_SQUARE, since its samples are generated on the fly - any other waveform uses a hardcoded/precomputed sample-buffer. +## Voices +Aka "audio effects", different ones can be enabled by setting in `config.h` these defines: +`#define AUDIO_VOICES` to enable the feature, and `#define AUDIO_VOICE_DEFAULT something` to select a specific effect +for details see quantum/audio/voices.h and .c + ## Music Mode diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 98553019cb97..3cf6f0bac40f 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -84,13 +84,6 @@ float tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT; uint8_t tone_multiplexing_index_shift = 0; // offset used on active-tone array access #endif -#ifdef AUDIO_ENABLE_VIBRATO -float vibrato_strength = 0.5; -float vibrato_rate = 0.125; -// forward declataion -float vibrato(float average_freq); -#endif - // proviced and used by voices.c extern float note_timbre; extern bool glissando; @@ -381,12 +374,6 @@ float audio_get_processed_frequency(uint8_t tone_index) { frequency = frequencies[index]; } -#ifdef AUDIO_ENABLE_VIBRATO - if (vibrato_strength > 0) { - frequency = vibrato(frequency); - } -#endif - frequency = voice_envelope(frequency); return frequency; @@ -474,36 +461,6 @@ bool audio_advance_state(uint32_t step, float end) { return goto_next_note; } -// Vibrato functions -#ifdef AUDIO_ENABLE_VIBRATO - -float mod(float a, int b) { - float r = fmod(a, b); - return r < 0 ? r + b : r; -} - -// TODO: unify with vibrato calculation in voices.c; which does basically the same -float vibrato(float average_freq) { - float vibrato_counter = mod(timer_read() / (100 * vibrato_rate), VIBRATO_LUT_LENGTH); - -# ifdef AUDIO_ENABLE_VIBRATO_STRENGTH - float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); -# else - float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; -# endif - //vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0 / average_freq)), VIBRATO_LUT_LENGTH); - return vibrated_freq; -} - -void audio_set_vibrato_rate(float rate) { vibrato_rate = rate; } -void audio_increase_vibrato_rate(float change) { vibrato_rate *= change; } -void audio_decrease_vibrato_rate(float change) { vibrato_rate /= change; } -# ifdef AUDIO_ENABLE_VIBRATO_STRENGTH -void audio_set_vibrato_strength(float strength) { vibrato_strength = strength; } -void audio_increase_vibrato_strength(float change) { vibrato_strength *= change; } -void audio_decrease_vibrato_strength(float change) { vibrato_strength /= change; } -# endif /* AUDIO_ENABLE_VIBRATO_STRENGTH */ -#endif /* AUDIO_ENABLE_VIBRATO */ // Tone-multiplexing functions #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING @@ -514,14 +471,6 @@ void audio_increase_tone_multiplexing_rate(float change) { tone_multiplexing_rat void audio_decrease_tone_multiplexing_rate(float change) { tone_multiplexing_rate /= change; } #endif -// Timbre function - -void audio_set_timbre(float timbre) { - if ((timbre > 0.0f) && (timbre < 1.0f)) { - note_timbre = timbre; - } -} -float audio_get_timbre(void) { return note_timbre; } // Tempo functions diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index e009ec99e345..05bb381748fe 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -162,22 +162,6 @@ bool audio_is_playing_melody(void); */ #define PLAY_LOOP(note_array) audio_play_melody(¬e_array, NOTE_ARRAY_SIZE((note_array)), true) -// Vibrato rate functions - -// #define AUDIO_ENABLE_VIBRATO -// Enable vibrato strength/amplitude - slows down ISR too much (TODO: from/for/on avr only?) -// #define AUDIO_ENABLE_VIBRATO_STRENGTH - -#ifdef AUDIO_ENABLE_VIBRATO -void audio_set_vibrato_rate(float rate); -void audio_increase_vibrato_rate(float change); -void audio_decrease_vibrato_rate(float change); -# ifdef AUDIO_ENABLE_VIBRATO_STRENGTH -void audio_set_vibrato_strength(float strength); -void audio_increase_vibrato_strength(float change); -void audio_decrease_vibrato_strength(float change); -# endif -#endif // Tone-Multiplexing functions // this feature only makes sense for hardware setups which can't do proper @@ -194,17 +178,6 @@ void audio_increase_tone_multiplexing_rate(float change); void audio_decrease_tone_multiplexing_rate(float change); #endif -// Timbre function - -/** - * @brief set the global timbre for tones to be played - * @note: only applies to pwm implementations - where it adjusts the duty-cycle - * @note: using any instrument from voices.[ch] other than 'default' may override the set value - * @param[in]: timbre: valid range is (0.0,1.0) - */ -void audio_set_timbre(float timbre); -float audio_get_timbre(void); - // Tempo functions void audio_set_tempo(uint8_t tempo); diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 263bd62166bd..3862971ef4e1 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -17,16 +17,19 @@ #include "audio.h" #include -float note_timbre = TIMBRE_DEFAULT; -bool glissando = false; -#ifdef AUDIO_ENABLE_VIBRATO -bool vibrato = true; -#else -bool vibrato = false; -#endif +float note_timbre = TIMBRE_DEFAULT; +bool glissando = false; +bool vibrato = false; +float vibrato_strength = 0.5; +float vibrato_rate = 0.125; + uint16_t voices_timer = 0; +#ifdef AUDIO_VOICE_DEFAULT +voice_type voice = AUDIO_VOICE_DEFAULT; +#else voice_type voice = default_voice; +#endif void set_voice(voice_type v) { voice = v; } @@ -41,17 +44,10 @@ float mod(float a, int b) { return r < 0 ? r + b : r; } - float voice_add_vibrato(float average_freq) { float vibrato_counter = mod(timer_read() / (100 * vibrato_rate), VIBRATO_LUT_LENGTH); -# ifdef AUDIO_ENABLE_VIBRATO_STRENGTH - float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); -# else - float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; -# endif - //vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0 / average_freq)), VIBRATO_LUT_LENGTH); - return vibrated_freq; + return average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); } #endif @@ -72,6 +68,15 @@ float voice_envelope(float frequency) { #ifdef AUDIO_VOICES + case vibrating: + glissando = false; + vibrato = true; + + if (vibrato_strength > 0) { + frequency = voice_add_vibrato(frequency); + } + break; + case something: glissando = false; switch (compensated_index) { @@ -245,6 +250,7 @@ float voice_envelope(float frequency) { case 0 ... VOICE_VIBRATO_DELAY: break; default: + //TODO: merge/replace with voice_add_vibrato above frequency = frequency * vibrato_lut[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1)) / 1000 * VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)]; break; } @@ -298,3 +304,22 @@ float voice_envelope(float frequency) { return frequency; } + + +// Vibrato functions + +void voice_set_vibrato_rate(float rate) { vibrato_rate = rate; } +void voice_increase_vibrato_rate(float change) { vibrato_rate *= change; } +void voice_decrease_vibrato_rate(float change) { vibrato_rate /= change; } +void voice_set_vibrato_strength(float strength) { vibrato_strength = strength; } +void voice_increase_vibrato_strength(float change) { vibrato_strength *= change; } +void voice_decrease_vibrato_strength(float change) { vibrato_strength /= change; } + +// Timbre functions + +void voice_set_timbre(float timbre) { + if ((timbre > 0.0f) && (timbre < 1.0f)) { + note_timbre = timbre; + } +} +float voice_get_timbre(void) { return note_timbre; } diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h index abafa2b404ef..26440666ff9d 100644 --- a/quantum/audio/voices.h +++ b/quantum/audio/voices.h @@ -13,7 +13,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #pragma once #include @@ -28,7 +27,8 @@ float voice_envelope(float frequency); typedef enum { default_voice, -#ifdef AUDIO_VOICES +# ifdef AUDIO_VOICES + vibrating, something, drums, butts_fader, @@ -48,3 +48,21 @@ typedef enum { void set_voice(voice_type v); void voice_iterate(void); void voice_deiterate(void); + +// Vibrato functions +void voice_set_vibrato_rate(float rate); +void voice_increase_vibrato_rate(float change); +void voice_decrease_vibrato_rate(float change); +void voice_set_vibrato_strength(float strength); +void voice_increase_vibrato_strength(float change); +void voice_decrease_vibrato_strength(float change); + +// Timbre functions +/** + * @brief set the global timbre for tones to be played + * @note: only applies to pwm implementations - where it adjusts the duty-cycle + * @note: using any instrument from voices.[ch] other than 'default' may override the set value + * @param[in]: timbre: valid range is (0.0,1.0) + */ +void voice_set_timbre(float timbre); +float voice_get_timbre(void); From 5047505535167ce7bb398719103d72bf245f2073 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 11 Apr 2020 11:53:08 +0200 Subject: [PATCH 079/153] audio.c: use system-ticks instead of counters the drivers have to take care of for the internal state posision since there already is a system-tick with ms resolution, keeping count separatly with each driver implementation makes little sense; especially since they had to take special care to call audio_advance_state with the correct step/end parameters for the audio state to advance regularly and with the correct pace --- quantum/audio/audio.c | 191 ++++++++++++-------- quantum/audio/audio.h | 83 ++++++--- quantum/audio/driver_avr_pwm_hardware.c | 4 +- quantum/audio/driver_chibios_dac_additive.c | 6 +- quantum/audio/driver_chibios_dac_basic.c | 2 +- quantum/audio/driver_chibios_pwm_hardware.c | 7 +- quantum/audio/driver_chibios_pwm_software.c | 7 +- 7 files changed, 177 insertions(+), 123 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 3cf6f0bac40f..371b46fc2d10 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -28,15 +28,15 @@ * driver_[avr|chibios]_[dac|pwm] take care of the lower hardware dependent parts, * specific to each platform and the used subsystem/driver to drive * the output pins/channels with the calculated frequencies for each - * avtive tone + * active tone * as part of this, the driver has to trigger regular state updates by - * calling 'audio_advance_state' through some sort of timer - be it a + * calling 'audio_update_state' through some sort of timer - be it a * dedicated one or piggybacking on for example the timer used to * generate a pwm signal/clock. * * * A Note on terminology: - * tone and frequency are used somewhat interchangeably, in a strict wikipedia-sense: + * tone, pitch and frequency are used somewhat interchangeably, in a strict wikipedia-sense: * "(Musical) tone, a sound characterized by its duration, pitch (=frequency), * intensity (=volume), and timbre" * - intensity/volume is currently not handled at all, although the 'dac_additive' driver could do so @@ -45,7 +45,7 @@ * in musical_note.h a 'note' is the combination of a pitch and a duration * these are used to create SONG arrays; during playback their frequencies * are handled as single successive tones, while the durations are - * kept track of in 'audio_advance_state' + * kept track of in 'audio_update_state' * * 'voice' as it is used here, equates to a sort of instrument with its own * charactersitic sound and effects @@ -60,21 +60,19 @@ # define AUDIO_TONE_STACKSIZE 8 #endif uint8_t active_tones = 0; // number of tones pushed onto the stack by audio_play_tone - might be more than the harware is able to reproduce at any single time -float frequencies[AUDIO_TONE_STACKSIZE] = {-1.0}; // frequencies of each active tone -// TODO: array of musical_tone_t? +musical_tone_t tones[AUDIO_TONE_STACKSIZE]; // stack of currently active tones bool playing_melody = false; // playing a SONG? -bool playing_note = false; // or (possibly multiple simultaneous) tones TODO: should this be playing_tone instead, since we don't handle any duration (yet) +bool playing_note = false; // or (possibly multiple simultaneous) tones bool state_changed = false; // global flag, which is set if anything changes with the active_tones -float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs -uint16_t notes_count; // length of the notes_pointer array -bool notes_repeat; // PLAY_SONG or PLAY_LOOP? -float note_length = 0; // in 64 parts to a beat -uint8_t note_tempo = TEMPO_DEFAULT; // beats-per-minute -uint16_t current_note = 0; // index into the array at notes_pointer -uint32_t note_position = 0; // position in the currently playing note = "elapsed time" (with no specific unit, depends on how fast/slow the respective audio-driver/hardware ticks) -bool note_resting = false; // if a short pause was introduced between two notes with the same frequency while playing a melody +float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs +uint16_t notes_count; // length of the notes_pointer array +bool notes_repeat; // PLAY_SONG or PLAY_LOOP? +uint16_t melody_current_note_end = 0; // timestamp when the currently playing note in the melody will/should end +uint8_t note_tempo = TEMPO_DEFAULT; // beats-per-minute +uint16_t current_note = 0; // index into the array at notes_pointer +bool note_resting = false; // if a short pause was introduced between two notes with the same frequency while playing a melody #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING # ifndef AUDIO_MAX_SIMULTANEOUS_TONES @@ -126,6 +124,14 @@ void audio_init() { # endif #endif // ARM EEPROM + for (uint8_t i = 0; i < AUDIO_TONE_STACKSIZE; i++) { + tones[i] = (musical_tone_t){ + .time_started = 0, + .pitch = -1.0f, + .duration = -1.0f + }; + } + if (!audio_initialized) { audio_driver_initialize(); audio_initialized = true; @@ -178,14 +184,20 @@ void audio_stop_all() { playing_melody = false; playing_note = false; + melody_current_note_end = 0; + for (uint8_t i = 0; i < AUDIO_TONE_STACKSIZE; i++) { - frequencies[i] = -1.0f; + tones[i] = (musical_tone_t){ + .time_started = 0, + .pitch = -1.0f, + .duration = -1.0f + }; } } -void audio_stop_tone(float frequency) { - if (frequency < 0.0f) { - frequency = -1 * frequency; +void audio_stop_tone(float pitch) { + if (pitch < 0.0f) { + pitch = -1 * pitch; } if (playing_note) { @@ -194,12 +206,20 @@ void audio_stop_tone(float frequency) { } bool found = false; for (int i = AUDIO_TONE_STACKSIZE - 1; i >= 0; i--) { - found = (frequencies[i] == frequency); + found = (tones[i].pitch == pitch); if (found) { - frequencies[i] = -1.0f; + tones[i] = (musical_tone_t){ + .time_started = 0, + .pitch = -1.0f, + .duration = -1.0f + }; for (int j = i; (j < AUDIO_TONE_STACKSIZE - 1); j++) { - frequencies[j] = frequencies[j + 1]; - frequencies[j + 1] = -1.0f; + tones[j] = tones[j + 1]; + tones[j + 1] = (musical_tone_t){ + .time_started = 0, + .pitch = -1.0f, + .duration = -1.0f + }; } break; } @@ -224,7 +244,7 @@ void audio_stop_tone(float frequency) { } } -void audio_play_tone(float frequency) { +void audio_play_note(float pitch, float duration) { if (!audio_config.enable) { return; } @@ -233,26 +253,27 @@ void audio_play_tone(float frequency) { audio_init(); } - if (frequency < 0.0f) { - frequency = -1 * frequency; + if (pitch < 0.0f) { + pitch = -1 * pitch; } // roundrobin: shifting out old tones, keeping only unique ones // if the new frequency is already amongst the active tones, shift it to the top of the stack bool found = false; for (int i = active_tones - 1; i >= 0; i--) { - found = (frequencies[i] == frequency); + found = (tones[i].pitch == pitch); if (found) { for (int j = i; (j < active_tones - 1); j++) { - frequencies[j] = frequencies[j + 1]; - frequencies[j + 1] = frequency; + tones[j] = tones[j + 1]; + tones[j + 1] = (musical_tone_t){ + .time_started = timer_read32(), + .pitch = pitch, + .duration = duration + }; } - break; + return; // since this frequency played already, the hardware was already started } } - if (found) { // since this frequency played already, the hardware was already started - return; - } // frequency/tone is actually new, so we put it on the top of the stack active_tones++; @@ -260,23 +281,28 @@ void audio_play_tone(float frequency) { active_tones = AUDIO_TONE_STACKSIZE; // shift out the oldest tone to make room for (int i = 0; i < active_tones - 1; i++) { - frequencies[i] = frequencies[i + 1]; + tones[i] = tones[i + 1]; } } state_changed = true; playing_note = true; - frequencies[active_tones - 1] = frequency; + tones[active_tones - 1] = (musical_tone_t){ + .time_started = timer_read32(), + .pitch = pitch, + .duration = duration + }; - voices_timer = timer_read(); // reset to zero, for the effects added by voices.c + //TODO: needs to be handled per note/tone -> use its timestamp instead? + voices_timer = timer_read32(); // reset to zero, for the effects added by voices.c if (active_tones == 1) // sufficient to start when switching from 0 to 1 audio_driver_start(); } -/* - * the two ways to feed the audio system: - * - audio_play_tone to add (or start) playing notes simultaneously with multiple tones - * - audio_play_melody which gets passed a SONG = array of musical-notes (combinations of frequencies and durations) - */ + +void audio_play_tone(float pitch) { + audio_play_note(pitch, -1.0f); +} + void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) { if (!audio_config.enable) { return; @@ -298,21 +324,20 @@ void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) { current_note = 0; // note in the melody-array/list at note_pointer - note_length = ((*notes_pointer)[current_note][1]) * (60.0f / note_tempo); - note_position = 0; - // start first note manually, which also starts the audio_driver - // all following/remaining notes are played by 'audio_advance_state' - audio_play_tone((*notes_pointer)[current_note][0]); + // all following/remaining notes are played by 'audio_update_state' + audio_play_note((*notes_pointer)[current_note][0], audio_duration_to_ms ((*notes_pointer)[current_note][1]) +); + melody_current_note_end = timer_read32() + audio_duration_to_ms ((*notes_pointer)[current_note][1]); } float click[2][2]; -void audio_play_click(uint16_t delay, float frequency, uint16_t duration) { +void audio_play_click(uint16_t delay, float pitch, uint16_t duration) { float duration_tone = (64 / 60) * note_tempo * (duration / 1000.0f); float duration_delay = (64 / 60) * note_tempo * (delay / 1000.0f); if (delay <= 0.0f) { - click[0][0] = frequency; + click[0][0] = pitch; click[0][1] = duration_tone; click[1][0] = 0.0f; click[1][1] = 0.0f; @@ -322,7 +347,7 @@ void audio_play_click(uint16_t delay, float frequency, uint16_t duration) { click[0][0] = 0.0f; click[0][1] = duration_delay; // second note is the actual click - click[1][0] = frequency; + click[1][0] = pitch; click[1][1] = duration_tone; audio_play_melody(&click, 2, false); } @@ -338,11 +363,10 @@ float audio_get_frequency(uint8_t tone_index) { if (tone_index >= active_tones) { return 0.0f; } - return frequencies[active_tones - tone_index - 1]; + return tones[active_tones - tone_index - 1].pitch; } float audio_get_processed_frequency(uint8_t tone_index) { - float frequency = 0.0; if (tone_index >= active_tones) { return 0.0f; @@ -357,10 +381,11 @@ float audio_get_processed_frequency(uint8_t tone_index) { index += active_tones; #endif - if (frequencies[index] <= 0.0f) { + if (tones[index].pitch <= 0.0f) { return 0.0f; } +/* // TODO make it work and test, currently probably non-functional because it needs some state to keep track of previous tones, the current tone position ...? if (glissando) { // see voices.c if (frequency != 0 && frequency < frequencies[index] && frequency < frequencies[index] * pow(2, -440 / frequencies[index] / 12 / 2)) { @@ -377,15 +402,24 @@ float audio_get_processed_frequency(uint8_t tone_index) { frequency = voice_envelope(frequency); return frequency; +*/ + + return voice_envelope(tones[index].pitch); } -bool audio_advance_state(uint32_t step, float end) { +bool audio_update_state(void) { + + if (!playing_note && !playing_melody) { + return false; + } + bool goto_next_note = false; + uint32_t current_time = timer_read32(); if (playing_note) { #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING tone_multiplexing_index_shift = - (int)(timer_read() / tone_multiplexing_rate) + (int)(current_time / tone_multiplexing_rate) % MIN(AUDIO_MAX_SIMULTANEOUS_TONES, active_tones); goto_next_note = true; #endif @@ -393,24 +427,31 @@ bool audio_advance_state(uint32_t step, float end) { // force update on each cycle, since vibrato shifts the frequency slightly goto_next_note = true; } + + // housekeeping: stop notes that have no playtime left + for (int i=0; i < active_tones; i++) { + if (tones[i].duration > 0) { + if (current_time >= tones[i].time_started + tones[i].duration) { + audio_stop_tone(tones[i].pitch); + } + } + } } if (playing_melody) { - note_position += step; - goto_next_note = note_position >= (note_length * end); + goto_next_note = current_time >= melody_current_note_end; if (goto_next_note) { uint16_t previous_note = current_note; current_note++; - voices_timer = timer_read(); // reset to zero, for the effects added by voices.c + voices_timer = timer_read32(); // reset to zero, for the effects added by voices.c if (current_note >= notes_count) { if (notes_repeat) { current_note = 0; } else { - playing_melody = false; - audio_stop_tone((*notes_pointer)[previous_note][0]); - return true; + audio_stop_all(); + return false; } } @@ -419,39 +460,29 @@ bool audio_advance_state(uint32_t step, float end) { // special handling for successive notes of the same frequency: // insert a short pause to separate them audibly - current_note = previous_note; - float shortRest[2] = {0.0f, 2 /*duration of a THIRTYTWOTH_NOTE*/}; - audio_play_tone(shortRest[0]); audio_stop_tone((*notes_pointer)[previous_note][0]); - note_position = note_position - (note_length * end); - note_length = shortRest[1] * (60.0f / note_tempo); + current_note = previous_note; + melody_current_note_end = current_time + audio_duration_to_ms(2); } else { note_resting = false; - // need only to pass the frequency - the duration is handled by - // calling this function regularly and advancing the note_position - audio_play_tone((*notes_pointer)[current_note][0]); - // start the next note prior to stopping the previous one, to - // allow the hardware to do a clean transition; and avoid a brief - // state where active_tones==0 -> driver_stop - if ((*notes_pointer)[previous_note][0] != (*notes_pointer)[current_note][0]) { - audio_stop_tone((*notes_pointer)[previous_note][0]); - } + //TODO: handle glissando here (or remember previous and current tone) // Skip forward in the next note's length if we've over shot the last, so // the overall length of the song is the same - note_position = note_position - (note_length * end); + int delta = current_time - melody_current_note_end; // TODO: what about a timer overflow? + if (delta < 0) { + delta = 0; + } - note_length = ((*notes_pointer)[current_note][1]) * (60.0f / note_tempo); + uint16_t duration = audio_duration_to_ms((*notes_pointer)[current_note][1]) - delta; + audio_play_note((*notes_pointer)[current_note][0], duration); + melody_current_note_end = current_time + duration; } } } - if (!playing_note && !playing_melody) { - audio_stop_all(); - } - // state-changes have a higher priority, always triggering the hardware to update if (state_changed) { state_changed = false; diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 05bb381748fe..e4cc3f907383 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -49,6 +49,19 @@ typedef union { # define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif +/* + * a 'musical note' is represented by pitch and duration; a 'musical tone' adds intensity and timbre + * https://en.wikipedia.org/wiki/Musical_tone + * "A musical tone is characterized by its duration, pitch, intensity (or loudness), and timbre (or quality)" + */ +typedef struct { + uint32_t time_started; // timestamp the tone/note was started, systemtime runs with 1ms resolution -> 16bit timer overflows every ~64 seconds, long enough under normal circumstances; but might be too soon for long-duration notes when the note_tempo is set to a very low value + float pitch; // aka frequency + float duration; // in 64parts to a beats, -1 indicates an indefinitly played note + //float intensity; // aka volume [0,1] TODO: not used at the moment; pwm drivers can't handle it + //float timbre; // range: [0,1] TODO: this currently kept track of globally, should we do this per tone instead? +} musical_tone_t; + // ____ __ ___ // / __ \__ __/ /_ / (_)____ // / /_/ / / / / __ \/ / / ___/ @@ -82,35 +95,54 @@ void audio_off(void); */ bool audio_is_on(void); + +/** + * @bried start playback of a tone with the given frequency and duration + * + * @details starts the playback of a given note, wich is automatically stopped + * at the the end of its duration = fire&forget + * + * @param[in] pitch frequency of the tone be played + * @param[in] duration in milliseconds, use 'audio_duration_to_ms' to convert + * from the musical_notes.h unit to ms + */ +void audio_play_note(float pitch, float duration); +// TODO: audio_play_note(float pitch, float duration, float intensity, float timbre); +// audio_play_note_with_instrument ifdef AUDIO_ENABLE_VOICES + /** * @bried start playback of a tone with the given frequency - * @details the 'frequency' is appended to an internal stack of active tones, + * + * @details the 'frequency' is put ontop the internal stack of active tones, * as a new tone with indefinite duration. this tone is played by * the hardware until a call to 'audio_stop_tone'. * should a tone with that frequency already be active, its entry * is put on the top of said internal stack - so no duplicate * entries are kept. * 'hardware_start' is called upon the first note. - * @param[in] frequency frequency of the tone be played + * + * @param[in] pitch frequency of the tone be played */ -void audio_play_tone(float frequency); -// TODO: add audio_play_note(float pitch, float duration, float intensity, float timbre); -// audio_play_note_with_instrument ifdef AUDIO_ENABLE_VOICES -// audio_play_pulses(frequency, count, delay/initialpause) - for fauxclicky, have pwm output exactly $count pulses +void audio_play_tone(float pitch); /** * @brief stop a given tone/frequency - * @details removes the given frequency from the 'frequencies' array, stopping - * its playback, and the hardware in case this was the last/only frequency + * + * @details removes a tone matching the given frequency from the internal + * playback stack + * the hardware is stopped in case this was the last/only frequency * beeing played. - * @param[in] freq tone/frequenct to be stopped + * + * @param[in] pitch tone/frequenct to be stopped */ -void audio_stop_tone(float frequency); +void audio_stop_tone(float pitch); /** * @brief play a melody + * * @details starts playback of a melody passed in from a SONG definition - an - * array of {frequency, duration} float-tuples + * array of {pitch, duration} float-tuples + * * @param[in] np note-pointer to the SONG array * @param[in] n_count number of MUSICAL_NOTES of the SONG * @param[in] n_repeat false for onetime, true for looped playback @@ -125,13 +157,14 @@ void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat); * hardware limitations (DAC: added pulses from zero-crossing feature;...) * * @param[in] delay in milliseconds, lenght for the pause before the pulses, can be zero - * @param[in] frequency + * @param[in] pitch * @param[in] duration in milliseconds, length of the 'click' */ -void audio_play_click(uint16_t delay, float frequency, uint16_t duration); +void audio_play_click(uint16_t delay, float pitch, uint16_t duration); /** * @brief stops all playback + * * @details stops playback of both a meldoy as well as single tones, resetting * the internal state */ @@ -184,6 +217,10 @@ void audio_set_tempo(uint8_t tempo); void audio_increase_tempo(uint8_t tempo_change); void audio_decrease_tempo(uint8_t tempo_change); +// conversion macros, from 64parts-to-a-beat to milliseconds and back +#define audio_duration_to_ms(d) (d / 64 * (60 / note_tempo) * 1000) +#define audio_ms_to_duration(t) (t * 64 * (note_tempo / 60) / 1000) + // __ __ __ // / / / /___ __________/ / ______ __________ // / /_/ / __ `/ ___/ __ / | /| / / __ `/ ___/ _ / @@ -229,22 +266,14 @@ float audio_get_processed_frequency(uint8_t tone_index); /** * @brief update audio internal state: currently playing and active tones,... * @details This function is intended to be called by the audio-hardware - * specific implementation on a regular basis while a SONG is - * playing, to 'advance' the position/time/internal state - * - * @note: 'step' and 'end' can be used if the function is to be called from a - * timer/ISR with irregular period - say a pwm-isr - then one could use - * 'step=1' with 'end' set to the current pwm-frequency; and still have - * a somewhat regular state progression + * specific implementation on a somewhat regular basis while a SONG + * or notes (pitch+duration) are playing to 'advance' the internal + * state (current playing notes, position in the melody, ...) * - * @param[in] step arbitrary step value, audio.c keeps track of for the - * audio-driver - * @param[in] end scaling factor multiplied to the note_length. has to match - * step so that audio.c can determine when a tone has finished playing - * @return true if the melody advanced to its next tone, which the driver might - * need/choose to react to + * @return true if something changed in the currently active tones, which the + * hardware might need to react to */ -bool audio_advance_state(uint32_t step, float end); +bool audio_update_state(void); // __ // / / ___ ____ _____ ________ __ diff --git a/quantum/audio/driver_avr_pwm_hardware.c b/quantum/audio/driver_avr_pwm_hardware.c index 379875bb6006..093d8b7616e6 100644 --- a/quantum/audio/driver_avr_pwm_hardware.c +++ b/quantum/audio/driver_avr_pwm_hardware.c @@ -262,7 +262,7 @@ ISR(AUDIO1_TIMERx_COMPy_vect) { if (isr_counter < channel_1_frequency / (CPU_PRESCALER * 8)) return; isr_counter = 0; - bool state_changed = audio_advance_state(1, 1); + bool state_changed = audio_update_state(); if (!playing_note && !playing_melody) { channel_1_stop(); @@ -291,7 +291,7 @@ ISR(AUDIO2_TIMERx_COMPy_vect) { if (isr_counter < channel_2_frequency / (CPU_PRESCALER * 8)) return; isr_counter = 0; - bool state_changed = audio_advance_state(1, 1); + bool state_changed = audio_update_state(); if (!playing_note && !playing_melody) { channel_2_stop(); diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index 832f38e1891c..1bf614e03076 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -193,11 +193,7 @@ static void dac_end(DACDriver *dacp) { } // update audio internal state (note position, current_note, ...) - if (audio_advance_state(AUDIO_DAC_BUFFER_SIZE / 2, AUDIO_DAC_SAMPLE_RATE / (64 * 2.0f / 3))) { - /* End of the note: 64 is the number of 'units' of a whole note, 3 comes - * from the gpttimer: AUDIO_DAC_SAMPLE_RATE * 3; 2 from the callback beeing - * called twice per sample conversion. - */ + if (audio_update_state()) { if (OUTPUT_SHOULD_STOP != state) { state = OUTPUT_TONES_CHANGED; } diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index 79ec246d0361..bddffbc7c4ef 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -137,7 +137,7 @@ float channel_2_get_frequency(void) { return channel_2_frequency; } #endif // AUDIO_PIN(_ALT)_A5 static void gpt_cb8(GPTDriver *gptp) { - if (audio_advance_state(1, gpt8cfg1.frequency)) { + if (audio_update_state()) { #if defined(AUDIO_PIN_A4) channel_1_set_frequency(audio_get_processed_frequency(0)); # if defined(AUDIO_PIN_ALT_A5) diff --git a/quantum/audio/driver_chibios_pwm_hardware.c b/quantum/audio/driver_chibios_pwm_hardware.c index 7f0036490d3d..23a73a0b63af 100644 --- a/quantum/audio/driver_chibios_pwm_hardware.c +++ b/quantum/audio/driver_chibios_pwm_hardware.c @@ -125,9 +125,8 @@ GPTConfig gptCFG = { the longest note is BREAVE_DOT=128+64=192, the shortest SIXTEENTH=4 the tempo (which might vary!) is in bpm (beats per minute) therefore: if the timer ticks away at .frequency = (60*64)Hz, - and the .intervall counts from 64 downwards - all we need to do is increment the - note_position on each callback, and have the note_lengt = duration*tempo compare - against that; hence: audio_advance_state(step=1, end=1) + and the .intervall counts from 64 downwards - audio_update_state is + called just often enough to not miss any notes */ .frequency = 60 * 64, .callback = gpt_callback, @@ -166,7 +165,7 @@ void audio_driver_stop(void) { static void gpt_callback(GPTDriver *gptp) { float freq; // TODO: freq_alt - if (audio_advance_state(1, 1)) { + if (audio_update_state()) { freq = audio_get_processed_frequency(0); // freq_alt would be index=1 channel_1_set_frequency(freq); } diff --git a/quantum/audio/driver_chibios_pwm_software.c b/quantum/audio/driver_chibios_pwm_software.c index 9bc804c2da7a..4e81f2d0d3c6 100644 --- a/quantum/audio/driver_chibios_pwm_software.c +++ b/quantum/audio/driver_chibios_pwm_software.c @@ -105,9 +105,8 @@ GPTConfig gptCFG = { the longest note is BREAVE_DOT=128+64=192, the shortest SIXTEENTH=4 the tempo (which might vary!) is in bpm (beats per minute) therefore: if the timer ticks away at .frequency = (60*64)Hz, - and the .intervall counts from 64 downwards - all we need to do is increment the - note_position on each callback, and have the note_lengt = duration*tempo compare - against that; hence: audio_advance_state(step=1, end=1) + and the .intervall counts from 64 downwards - audio_update_state is + called just often enough to not miss anything */ .frequency = 60 * 64, .callback = gpt_callback, @@ -145,7 +144,7 @@ void audio_driver_stop(void) { static void gpt_callback(GPTDriver *gptp) { float freq; // TODO: freq_alt - if (audio_advance_state(1, 1)) { + if (audio_update_state()) { freq = audio_get_processed_frequency(0); // freq_alt would be index=1 channel_1_set_frequency(freq); } From bd37142d62c6449de06a246e383416f508bab709 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 11 Apr 2020 13:38:51 +0200 Subject: [PATCH 080/153] audio.c: stop notes after new ones have been started avoids brief states of with no notes playing that would otherwise stop the hardware and might lead to clicks --- quantum/audio/audio.c | 44 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 371b46fc2d10..7a3d763a9b0d 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -416,28 +416,6 @@ bool audio_update_state(void) { bool goto_next_note = false; uint32_t current_time = timer_read32(); - if (playing_note) { -#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING - tone_multiplexing_index_shift = - (int)(current_time / tone_multiplexing_rate) - % MIN(AUDIO_MAX_SIMULTANEOUS_TONES, active_tones); - goto_next_note = true; -#endif - if (vibrato || glissando) { - // force update on each cycle, since vibrato shifts the frequency slightly - goto_next_note = true; - } - - // housekeeping: stop notes that have no playtime left - for (int i=0; i < active_tones; i++) { - if (tones[i].duration > 0) { - if (current_time >= tones[i].time_started + tones[i].duration) { - audio_stop_tone(tones[i].pitch); - } - } - } - } - if (playing_melody) { goto_next_note = current_time >= melody_current_note_end; @@ -483,6 +461,28 @@ bool audio_update_state(void) { } } + if (playing_note) { +#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING + tone_multiplexing_index_shift = + (int)(current_time / tone_multiplexing_rate) + % MIN(AUDIO_MAX_SIMULTANEOUS_TONES, active_tones); + goto_next_note = true; +#endif + if (vibrato || glissando) { + // force update on each cycle, since vibrato shifts the frequency slightly + goto_next_note = true; + } + + // housekeeping: stop notes that have no playtime left + for (int i=0; i < active_tones; i++) { + if (tones[i].duration > 0) { + if (current_time >= tones[i].time_started + tones[i].duration) { + audio_stop_tone(tones[i].pitch); + } + } + } + } + // state-changes have a higher priority, always triggering the hardware to update if (state_changed) { state_changed = false; From 03a3534abec2522c04d5e0575c35cd628d27a17c Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 11 Apr 2020 13:55:50 +0200 Subject: [PATCH 081/153] audio.c: bugfix: actually play a pause instead of just idling/stopping which lead the pwm drivers to stop entirely... --- quantum/audio/audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 7a3d763a9b0d..e43d62229123 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -438,7 +438,7 @@ bool audio_update_state(void) { // special handling for successive notes of the same frequency: // insert a short pause to separate them audibly - audio_stop_tone((*notes_pointer)[previous_note][0]); + audio_play_note(0.0f, audio_duration_to_ms(2)); current_note = previous_note; melody_current_note_end = current_time + audio_duration_to_ms(2); From 29151ce74c626491668a87837c5a0a536fedd6ff Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 11 Apr 2020 15:42:18 +0200 Subject: [PATCH 082/153] audio-arm-pwm: pwm-software: add inverted output new define AUDIO_PIN_ALT_AS_NEGATIVE will generate an inverted signal on the alternate pin, which boosts the volume if a piezo is connected to both AUDIO_PIN and AUDIO_PIN_ALT --- quantum/audio/driver_chibios_pwm_software.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/quantum/audio/driver_chibios_pwm_software.c b/quantum/audio/driver_chibios_pwm_software.c index 4e81f2d0d3c6..3fa5e0bad781 100644 --- a/quantum/audio/driver_chibios_pwm_software.c +++ b/quantum/audio/driver_chibios_pwm_software.c @@ -87,16 +87,29 @@ void channel_1_stop(void) { pwmStop(&PWMD); palClearLine(AUDIO_PIN); // leave the line low, after last note was played + +#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT) + palClearLine(AUDIO_PIN_ALT); // leave the line low, after last note was played +#endif } // generate a PWM signal on any pin, not neccessarily the one connected to the timer static void pwm_audio_period_callback(PWMDriver *pwmp) { (void)pwmp; palClearLine(AUDIO_PIN); + +#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT) + palSetLine(AUDIO_PIN_ALT); +#endif } static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { (void)pwmp; - if (channel_1_frequency > 0) palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer + if (channel_1_frequency > 0) { + palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer +#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT) + palClearLine(AUDIO_PIN_ALT); +#endif + } } static void gpt_callback(GPTDriver *gptp); @@ -118,6 +131,11 @@ void audio_driver_initialize(void) { palSetLineMode(AUDIO_PIN, PAL_MODE_OUTPUT_PUSHPULL); palClearLine(AUDIO_PIN); +#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT) + palSetLineMode(AUDIO_PIN_ALT, PAL_MODE_OUTPUT_PUSHPULL); + palClearLine(AUDIO_PIN_ALT); +#endif + pwmEnablePeriodicNotification(&PWMD); // enable pwm callbacks pwmEnableChannelNotification(&PWMD, AUDIO_PWM_TIMERCHANNEL - 1); From 2c22d4ad32306e682c4909923496ad52ffdcf092 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 11 Apr 2020 16:39:16 +0200 Subject: [PATCH 083/153] audio-arm-dac: basic: handle piezo configured&wired to both audio pins --- quantum/audio/driver_chibios_dac_basic.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index bddffbc7c4ef..f72e553ea415 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -138,25 +138,33 @@ float channel_2_get_frequency(void) { return channel_2_frequency; } static void gpt_cb8(GPTDriver *gptp) { if (audio_update_state()) { -#if defined(AUDIO_PIN_A4) +#if (defined (AUDIO_PIN_A4) && defined(AUDIO_PIN_A5)) || (defined(AUDIO_PIN_A4) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT_A5) || (defined(AUDIO_PIN_A5) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT_A4)) + // one piezo/speaker connected to both audio pins, the generated squarewaves are inverted channel_1_set_frequency(audio_get_processed_frequency(0)); -# if defined(AUDIO_PIN_ALT_A5) + channel_2_set_frequency(audio_get_processed_frequency(0)); +#else // two separate audio outputs/speakers + // primary speaker on A4, optional secondary on A5 +#if defined(AUDIO_PIN_A4) + channel_1_set_frequency(audio_get_processed_frequency(0)); +# if defined(AUDIO_PIN_ALT_A5) if (audio_get_number_of_active_tones() > 1) { channel_2_set_frequency(audio_get_processed_frequency(1)); } else { channel_2_stop(); } +# endif # endif -#endif -#if defined(AUDIO_PIN_A5) + // primary speaker on A5, optional secondary on A4 +#if defined(AUDIO_PIN_A5) channel_2_set_frequency(audio_get_processed_frequency(0)); -# if defined(AUDIO_PIN_ALT_A4) +# if defined(AUDIO_PIN_ALT_A4) if (audio_get_number_of_active_tones() > 1) { channel_1_set_frequency(audio_get_processed_frequency(1)); } else { channel_1_stop(); } +# endif # endif #endif } From 77d333853b0891f9b15882b6f0937fea9a8bfcc0 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 11 Apr 2020 16:41:06 +0200 Subject: [PATCH 084/153] audio-refactoring: docs: update for AUDIO_PIN_ALT_AS_NEGATIVE and piezo wiring --- docs/feature_audio.md | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 0693e4d14788..1cb054857ff8 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -17,8 +17,12 @@ and *optionally*, a secondary speaker, using Timer 1, on ONE of these pins: `AUDIO_PIN_ALT = B6` `AUDIO_PIN_ALT = B7` +### Wiring +per speaker is - for example with a piezo buzzer - the black lead to Ground, and the red lead connected to the selected AUDIO_PIN for the primary; and similarly with AUDIO_PIN_ALT for the secondary. + ## ARM based boards +### DAC (basic) Most STM32 MCUs have DAC peripherals, with a notable exception of the STM32F1xx series. Generally, the DAC peripheral drives pins A4 or A5. To enable DAC-based audio output on STM32 devices, add `AUDIO_DRIVER = dac_basic` to `rules.mk` and set either:` `AUDIO_PIN = A4` OR @@ -29,6 +33,14 @@ the other DAC channel can optionally be used with a secondary speaker, just set: Do note though that the dac_basic driver is only capable of reproducing one tone per speaker/channel at a time, for more tones simultaneously, try the dac_additive driver. +#### Wiring: +for two piezos, for example configured as `AUDIO_PIN A4` and `AUDIO_PIN_ALT A5` would be: red lead to A4 and black to Ground, and similarly with the second one: A5 = red, and Ground = black + +another alternative is to drive *one* piezo with both DAC pins - for an extra "push". +wiring red to A4 and black to A5 (or the other way round) and add `#define AUDIO_PIN_ALT_AS_NEGATIVE` to `config.h` + + +### DAC (additive) Another option, besides dac_basic (which produces sound through a squarewave), is to use the DAC to do additive wave synthesis. With a number of predefined waveforms or by providing your own implementation to generate samples on the fly. To use this feature set `AUDIO_DRIVER = dac_additive` in your `rules.mk`. @@ -39,17 +51,23 @@ The used waveform defaults to a sine, but can be selected by adding one of the f `#define AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE` Should you rather choose to generate and use your own sample-table with the DAC unit, implement `uint16_t dac_value_generate(void)` with your keyboard - for an example implementation see keyboards/planck/keymaps/synth_sample or keyboards/planck/keymaps/synth_wavetable +### PWM (software) +if the DAC pins are unavailable (or the MCU has no usable DAC at all, like STM32F1xx); pwm can be an alternative. -STM32F1xx have to fall back to using PWM (on the up side: with any pin you choose), - -Either: set in `rules.mk`: -`AUDIO_SYSTEM = pwm_software` and +`AUDIO_DRIVER = pwm_software` and `AUDIO_PIN = C13` (can be any pin) to have the selected pin output a pwm signal, generated from a timer callback which toggles the pin in software. - OR -`AUDIO_SYSTEM = pwm_hardware` in `rules.mk` and in `config.h`: -`#define AUDIO_PIN A8` + +#### Wiring +the usual piezo wiring: red goes to the selected AUDIO_PIN, black goes to ground. + +OR if you can chose to drive one piezo with two pins, for example `AUDIO_PIN B1`, `AUDIO_PIN_ALT B2` in `rules.mk`, `#define AUDIO_PIN_ALT_AS_NEGATIVE` in `config.h` the red lead could go to B1, the black to B2. + +### PWM (hardware) +STM32F1xx have to fall back to using PWM, but can do so in hardware: + +`AUDIO_DRIVER = pwm_hardware` and `AUDIO_PIN A8` in `rules.mk` and in `config.h`: `#define AUDIO_PWM_TIMER 1` `#define AUDIO_PWM_TIMERCHANNEL 1` (as well as `#define AUDIO_PWM_PINALTERNATE_FUNCTION 42` if you are on STM32F2 or larger) From f64491211c493fed1a26bffb5b9441f4a9ddbf5f Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 13 Apr 2020 14:24:34 +0200 Subject: [PATCH 085/153] audio.c: bugfix: use timer_elapsed32 instad of keeping timestamps avoids running into issues when the uint32 of the timer overflows --- quantum/audio/audio.c | 52 +++++++++++++++---------- quantum/audio/audio.h | 2 +- quantum/audio/driver_avr_pwm_hardware.c | 1 - 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index e43d62229123..cfc1a7b40103 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -66,13 +66,15 @@ bool playing_melody = false; // playing a SONG? bool playing_note = false; // or (possibly multiple simultaneous) tones bool state_changed = false; // global flag, which is set if anything changes with the active_tones -float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs -uint16_t notes_count; // length of the notes_pointer array -bool notes_repeat; // PLAY_SONG or PLAY_LOOP? -uint16_t melody_current_note_end = 0; // timestamp when the currently playing note in the melody will/should end +// melody/SONG related state variables +float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs +uint16_t notes_count; // length of the notes_pointer array +bool notes_repeat; // PLAY_SONG or PLAY_LOOP? +uint16_t melody_current_note_duration = 0; // duration of the currently playing note from the active melody, in ms uint8_t note_tempo = TEMPO_DEFAULT; // beats-per-minute uint16_t current_note = 0; // index into the array at notes_pointer bool note_resting = false; // if a short pause was introduced between two notes with the same frequency while playing a melody +uint32_t last_timestamp = 0; #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING # ifndef AUDIO_MAX_SIMULTANEOUS_TONES @@ -102,7 +104,8 @@ float startup_song[][2] = STARTUP_SONG; float audio_on_song[][2] = AUDIO_ON_SONG; float audio_off_song[][2] = AUDIO_OFF_SONG; -static bool audio_initialized = false; +static bool audio_initialized = false; +static bool audio_driver_stopped = true; audio_config_t audio_config; void audio_init() { @@ -143,6 +146,8 @@ void audio_startup(void) { if (audio_config.enable) { PLAY_SONG(startup_song); } + + last_timestamp = timer_read32(); } void audio_toggle(void) { @@ -174,9 +179,10 @@ void audio_off(void) { bool audio_is_on(void) { return (audio_config.enable != 0); } void audio_stop_all() { - if (!audio_initialized) { - audio_init(); + if (audio_driver_stopped) { + return; } + active_tones = 0; audio_driver_stop(); @@ -184,7 +190,7 @@ void audio_stop_all() { playing_melody = false; playing_note = false; - melody_current_note_end = 0; + melody_current_note_duration = 0; for (uint8_t i = 0; i < AUDIO_TONE_STACKSIZE; i++) { tones[i] = (musical_tone_t){ @@ -193,6 +199,8 @@ void audio_stop_all() { .duration = -1.0f }; } + + audio_driver_stopped = true; } void audio_stop_tone(float pitch) { @@ -238,8 +246,8 @@ void audio_stop_tone(float pitch) { #endif if (active_tones == 0) { audio_driver_stop(); - - playing_note = false; + audio_driver_stopped = true; + playing_note = false; } } } @@ -295,8 +303,10 @@ void audio_play_note(float pitch, float duration) { //TODO: needs to be handled per note/tone -> use its timestamp instead? voices_timer = timer_read32(); // reset to zero, for the effects added by voices.c - if (active_tones == 1) // sufficient to start when switching from 0 to 1 + if (audio_driver_stopped) { audio_driver_start(); + audio_driver_stopped = false; + } } void audio_play_tone(float pitch) { @@ -305,6 +315,7 @@ void audio_play_tone(float pitch) { void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) { if (!audio_config.enable) { + audio_stop_all(); return; } @@ -328,7 +339,8 @@ void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) { // all following/remaining notes are played by 'audio_update_state' audio_play_note((*notes_pointer)[current_note][0], audio_duration_to_ms ((*notes_pointer)[current_note][1]) ); - melody_current_note_end = timer_read32() + audio_duration_to_ms ((*notes_pointer)[current_note][1]); + last_timestamp = timer_read32(); + melody_current_note_duration = audio_duration_to_ms ((*notes_pointer)[current_note][1]); } float click[2][2]; @@ -418,8 +430,9 @@ bool audio_update_state(void) { if (playing_melody) { - goto_next_note = current_time >= melody_current_note_end; + goto_next_note = timer_elapsed32(last_timestamp) >= melody_current_note_duration; if (goto_next_note) { + last_timestamp = current_time; uint16_t previous_note = current_note; current_note++; voices_timer = timer_read32(); // reset to zero, for the effects added by voices.c @@ -440,7 +453,7 @@ bool audio_update_state(void) { // insert a short pause to separate them audibly audio_play_note(0.0f, audio_duration_to_ms(2)); current_note = previous_note; - melody_current_note_end = current_time + audio_duration_to_ms(2); + melody_current_note_duration = audio_duration_to_ms(2); } else { note_resting = false; @@ -449,14 +462,11 @@ bool audio_update_state(void) { // Skip forward in the next note's length if we've over shot the last, so // the overall length of the song is the same - int delta = current_time - melody_current_note_end; // TODO: what about a timer overflow? - if (delta < 0) { - delta = 0; - } + int delta = timer_elapsed32(last_timestamp) - melody_current_note_duration; uint16_t duration = audio_duration_to_ms((*notes_pointer)[current_note][1]) - delta; audio_play_note((*notes_pointer)[current_note][0], duration); - melody_current_note_end = current_time + duration; + melody_current_note_duration = duration; } } } @@ -476,8 +486,8 @@ bool audio_update_state(void) { // housekeeping: stop notes that have no playtime left for (int i=0; i < active_tones; i++) { if (tones[i].duration > 0) { - if (current_time >= tones[i].time_started + tones[i].duration) { - audio_stop_tone(tones[i].pitch); + if (timer_elapsed32(tones[i].time_started) >= tones[i].duration) { + audio_stop_tone(tones[i].pitch); // also sets 'state_changed=true' } } } diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index e4cc3f907383..0c0c6435e08c 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -173,7 +173,7 @@ void audio_stop_all(void); /** * @brief query if one/multiple tones are playing */ -bool audio_is_playing_note(void); // TODO: is_playing_tone? +bool audio_is_playing_note(void); /** * @brief query if a melody/SONG is playing diff --git a/quantum/audio/driver_avr_pwm_hardware.c b/quantum/audio/driver_avr_pwm_hardware.c index 093d8b7616e6..c0d0ee8c758a 100644 --- a/quantum/audio/driver_avr_pwm_hardware.c +++ b/quantum/audio/driver_avr_pwm_hardware.c @@ -22,7 +22,6 @@ #include "audio.h" -// TODO: move into audio-common state extern bool playing_note; extern bool playing_melody; extern float note_timbre; From e09564109e863369596e7c53dd5e461a33a3785e Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 13 Apr 2020 14:26:41 +0200 Subject: [PATCH 086/153] audio-refactoring: add 'pragma once' and remove deprecated NOTE_REST --- quantum/audio/musical_notes.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/quantum/audio/musical_notes.h b/quantum/audio/musical_notes.h index d8d31427c25a..a47a6ec63652 100644 --- a/quantum/audio/musical_notes.h +++ b/quantum/audio/musical_notes.h @@ -13,7 +13,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - #pragma once // Tempo Placeholder @@ -71,13 +70,6 @@ #endif // Notes - # = Octave -/*TODO: huh?? -#ifdef __arm__ -# define NOTE_REST 1.00f -#else -# define NOTE_REST 0.00f -#endif -*/ #define NOTE_REST 0.00f #define NOTE_C0 16.35f From db230e99713296e897ac02085e87b0b88b2c269a Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 13 Apr 2020 15:29:08 +0200 Subject: [PATCH 087/153] audio_arm_dac: basic: add missing bracket --- quantum/audio/driver_chibios_dac_basic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index f72e553ea415..202cacff833e 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -138,7 +138,7 @@ float channel_2_get_frequency(void) { return channel_2_frequency; } static void gpt_cb8(GPTDriver *gptp) { if (audio_update_state()) { -#if (defined (AUDIO_PIN_A4) && defined(AUDIO_PIN_A5)) || (defined(AUDIO_PIN_A4) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT_A5) || (defined(AUDIO_PIN_A5) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT_A4)) +#if (defined (AUDIO_PIN_A4) && defined(AUDIO_PIN_A5)) || (defined(AUDIO_PIN_A4) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT_A5)) || (defined(AUDIO_PIN_A5) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT_A4)) // one piezo/speaker connected to both audio pins, the generated squarewaves are inverted channel_1_set_frequency(audio_get_processed_frequency(0)); channel_2_set_frequency(audio_get_processed_frequency(0)); From 0fe61834bd07a19fd812cee4e30a958157bcb659 Mon Sep 17 00:00:00 2001 From: Johannes Date: Tue, 14 Apr 2020 16:26:54 +0200 Subject: [PATCH 088/153] audio.c: fix delta calculation was in the wrong place, needs to use the 'last_timestamp' before it was reset --- quantum/audio/audio.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index cfc1a7b40103..e09050ac36c0 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -432,6 +432,8 @@ bool audio_update_state(void) { goto_next_note = timer_elapsed32(last_timestamp) >= melody_current_note_duration; if (goto_next_note) { + + uint16_t delta = timer_elapsed32(last_timestamp) - melody_current_note_duration; last_timestamp = current_time; uint16_t previous_note = current_note; current_note++; @@ -460,10 +462,8 @@ bool audio_update_state(void) { //TODO: handle glissando here (or remember previous and current tone) - // Skip forward in the next note's length if we've over shot the last, so - // the overall length of the song is the same - int delta = timer_elapsed32(last_timestamp) - melody_current_note_duration; - + // '- delta': Skip forward in the next note's length if we'vv over shot + // the last, so the overall length of the song is the same uint16_t duration = audio_duration_to_ms((*notes_pointer)[current_note][1]) - delta; audio_play_note((*notes_pointer)[current_note][0], duration); melody_current_note_duration = duration; From b47d7859e8827f70d9ec8454b36f514eec36f1f9 Mon Sep 17 00:00:00 2001 From: Johannes Date: Tue, 14 Apr 2020 16:34:03 +0200 Subject: [PATCH 089/153] audio-refactoring: buildfix: wrong legacy macro for set_timbre --- quantum/audio/audio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 0c0c6435e08c..6044da220147 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -328,8 +328,8 @@ bool audio_update_state(void); #define stop_note(f) audio_stop_tone(f) #define play_note(f, v) audio_play_tone(f) -#define set_timbre(t) audio_set_timbre(t) -#define set_tempo(t) audio_set_tempo(t) +#define set_timbre(t) voice_set_timbre(t) +#define set_tempo(t) voice_set_tempo(t) #define increase_tempo(t) audio_increase_tempo(t) #define decrease_tempo(t) audio_decrease_tempo(t) // vibrato functions are not used in any keyboards From 20d2af7ee723637612fa3b909fa53cbe4bbb8a1a Mon Sep 17 00:00:00 2001 From: Johannes Date: Tue, 14 Apr 2020 17:32:32 +0200 Subject: [PATCH 090/153] audio.c: 16bit timerstamps suffice --- quantum/audio/audio.c | 22 +++++++++++----------- quantum/audio/audio.h | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index e09050ac36c0..37dbb08363f8 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -74,7 +74,7 @@ uint16_t melody_current_note_duration = 0; // duration of the currently playing uint8_t note_tempo = TEMPO_DEFAULT; // beats-per-minute uint16_t current_note = 0; // index into the array at notes_pointer bool note_resting = false; // if a short pause was introduced between two notes with the same frequency while playing a melody -uint32_t last_timestamp = 0; +uint16_t last_timestamp = 0; #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING # ifndef AUDIO_MAX_SIMULTANEOUS_TONES @@ -147,7 +147,7 @@ void audio_startup(void) { PLAY_SONG(startup_song); } - last_timestamp = timer_read32(); + last_timestamp = timer_read(); } void audio_toggle(void) { @@ -274,7 +274,7 @@ void audio_play_note(float pitch, float duration) { for (int j = i; (j < active_tones - 1); j++) { tones[j] = tones[j + 1]; tones[j + 1] = (musical_tone_t){ - .time_started = timer_read32(), + .time_started = timer_read(), .pitch = pitch, .duration = duration }; @@ -295,13 +295,13 @@ void audio_play_note(float pitch, float duration) { state_changed = true; playing_note = true; tones[active_tones - 1] = (musical_tone_t){ - .time_started = timer_read32(), + .time_started = timer_read(), .pitch = pitch, .duration = duration }; //TODO: needs to be handled per note/tone -> use its timestamp instead? - voices_timer = timer_read32(); // reset to zero, for the effects added by voices.c + voices_timer = timer_read(); // reset to zero, for the effects added by voices.c if (audio_driver_stopped) { audio_driver_start(); @@ -339,7 +339,7 @@ void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) { // all following/remaining notes are played by 'audio_update_state' audio_play_note((*notes_pointer)[current_note][0], audio_duration_to_ms ((*notes_pointer)[current_note][1]) ); - last_timestamp = timer_read32(); + last_timestamp = timer_read(); melody_current_note_duration = audio_duration_to_ms ((*notes_pointer)[current_note][1]); } @@ -426,18 +426,18 @@ bool audio_update_state(void) { } bool goto_next_note = false; - uint32_t current_time = timer_read32(); + uint16_t current_time = timer_read(); if (playing_melody) { - goto_next_note = timer_elapsed32(last_timestamp) >= melody_current_note_duration; + goto_next_note = timer_elapsed(last_timestamp) >= melody_current_note_duration; if (goto_next_note) { - uint16_t delta = timer_elapsed32(last_timestamp) - melody_current_note_duration; + uint16_t delta = timer_elapsed(last_timestamp) - melody_current_note_duration; last_timestamp = current_time; uint16_t previous_note = current_note; current_note++; - voices_timer = timer_read32(); // reset to zero, for the effects added by voices.c + voices_timer = timer_read(); // reset to zero, for the effects added by voices.c if (current_note >= notes_count) { if (notes_repeat) { @@ -486,7 +486,7 @@ bool audio_update_state(void) { // housekeeping: stop notes that have no playtime left for (int i=0; i < active_tones; i++) { if (tones[i].duration > 0) { - if (timer_elapsed32(tones[i].time_started) >= tones[i].duration) { + if (timer_elapsed(tones[i].time_started) >= tones[i].duration) { audio_stop_tone(tones[i].pitch); // also sets 'state_changed=true' } } diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 6044da220147..76ad951759eb 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -55,7 +55,7 @@ typedef union { * "A musical tone is characterized by its duration, pitch, intensity (or loudness), and timbre (or quality)" */ typedef struct { - uint32_t time_started; // timestamp the tone/note was started, systemtime runs with 1ms resolution -> 16bit timer overflows every ~64 seconds, long enough under normal circumstances; but might be too soon for long-duration notes when the note_tempo is set to a very low value + uint16_t time_started; // timestamp the tone/note was started, systemtime runs with 1ms resolution -> 16bit timer overflows every ~64 seconds, long enough under normal circumstances; but might be too soon for long-duration notes when the note_tempo is set to a very low value float pitch; // aka frequency float duration; // in 64parts to a beats, -1 indicates an indefinitly played note //float intensity; // aka volume [0,1] TODO: not used at the moment; pwm drivers can't handle it From 6eecf2950e78c28d514c6f01252dd83dbbf78d6b Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 18 Apr 2020 07:56:26 +0200 Subject: [PATCH 091/153] audio-refactoring: separate includes for AVR and chibios --- quantum/audio/audio.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 76ad951759eb..3ad22bba8f4d 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -25,14 +25,17 @@ #if defined(__AVR__) # include -# include "driver_avr_pwm.h" +# if defined(AUDIO_DRIVER_PWM) +# include "driver_avr_pwm.h" +# endif #endif -#if defined(AUDIO_DRIVER_PWM) -# include "driver_chibios_pwm.h" -#endif -#if defined(AUDIO_DRIVER_DAC) -# include "driver_chibios_dac.h" +#if defined(PROTOCOL_CHIBIOS) +# if defined(AUDIO_DRIVER_PWM) +# include "driver_chibios_pwm.h" +# elif defined(AUDIO_DRIVER_DAC) +# include "driver_chibios_dac.h" +# endif #endif typedef union { From 775805dd39246627beb63c4e1a2b79d80d823e08 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 18 Apr 2020 13:31:33 +0200 Subject: [PATCH 092/153] audio-refactoring: timbre: use uint8 instead of float --- quantum/audio/audio.c | 2 +- quantum/audio/audio.h | 2 +- quantum/audio/driver_avr_pwm_hardware.c | 6 +- quantum/audio/driver_chibios_pwm_hardware.c | 8 +-- quantum/audio/driver_chibios_pwm_software.c | 8 +-- quantum/audio/musical_notes.h | 9 +-- quantum/audio/voices.c | 64 ++++++++++----------- quantum/audio/voices.h | 6 +- 8 files changed, 53 insertions(+), 52 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 37dbb08363f8..a972876ea97f 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -85,7 +85,7 @@ uint8_t tone_multiplexing_index_shift = 0; // offset used on active-tone arr #endif // proviced and used by voices.c -extern float note_timbre; +extern uint8_t note_timbre; extern bool glissando; extern bool vibrato; extern uint16_t voices_timer; diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 3ad22bba8f4d..9e5b53ff34f1 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -62,7 +62,7 @@ typedef struct { float pitch; // aka frequency float duration; // in 64parts to a beats, -1 indicates an indefinitly played note //float intensity; // aka volume [0,1] TODO: not used at the moment; pwm drivers can't handle it - //float timbre; // range: [0,1] TODO: this currently kept track of globally, should we do this per tone instead? + //uint8_t timbre; // range: [0,100] TODO: this currently kept track of globally, should we do this per tone instead? } musical_tone_t; // ____ __ ___ diff --git a/quantum/audio/driver_avr_pwm_hardware.c b/quantum/audio/driver_avr_pwm_hardware.c index c0d0ee8c758a..9675f39fce96 100644 --- a/quantum/audio/driver_avr_pwm_hardware.c +++ b/quantum/audio/driver_avr_pwm_hardware.c @@ -24,7 +24,7 @@ extern bool playing_note; extern bool playing_melody; -extern float note_timbre; +extern uint8_t note_timbre; #define CPU_PRESCALER 8 @@ -140,7 +140,7 @@ void channel_1_set_frequency(float freq) { // set pwm period AUDIO1_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); // and duty cycle - AUDIO1_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); + AUDIO1_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre/100); } void channel_1_start(void) { @@ -171,7 +171,7 @@ void channel_2_set_frequency(float freq) { channel_2_frequency = freq; AUDIO2_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); - AUDIO2_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); + AUDIO2_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre/100); } float channel_2_get_frequency(void) { return channel_2_frequency; } diff --git a/quantum/audio/driver_chibios_pwm_hardware.c b/quantum/audio/driver_chibios_pwm_hardware.c index 23a73a0b63af..33a85596e7b3 100644 --- a/quantum/audio/driver_chibios_pwm_hardware.c +++ b/quantum/audio/driver_chibios_pwm_hardware.c @@ -61,9 +61,9 @@ so adding to config.h: #define TO_CHIBIOS_PWMD_EVAL(t) TO_CHIBIOS_PWMD_PASTE(t) #define PWMD TO_CHIBIOS_PWMD_EVAL(AUDIO_PWM_TIMER) -extern bool playing_note; -extern bool playing_melody; -extern float note_timbre; +extern bool playing_note; +extern bool playing_melody; +extern uint8_t note_timbre; static PWMConfig pwmCFG = { .frequency = 100000, /* PWM clock frequency */ @@ -107,7 +107,7 @@ void channel_1_set_frequency(float freq) { pwmChangePeriod(&PWMD, period); pwmEnableChannel(&PWMD, AUDIO_PWM_TIMERCHANNEL - 1, // adjust the duty-cycle so that the output is for 'note_timbre' duration HIGH - PWM_PERCENTAGE_TO_WIDTH(&PWMD, (1.0f - note_timbre) * 10000)); + PWM_PERCENTAGE_TO_WIDTH(&PWMD, (100 - note_timbre) * 100)); } float channel_1_get_frequency(void) { return channel_1_frequency; } diff --git a/quantum/audio/driver_chibios_pwm_software.c b/quantum/audio/driver_chibios_pwm_software.c index 3fa5e0bad781..8b3bf5e1edda 100644 --- a/quantum/audio/driver_chibios_pwm_software.c +++ b/quantum/audio/driver_chibios_pwm_software.c @@ -36,9 +36,9 @@ this driver uses the chibios-PWM system to produce a squarewave on any given out #define TO_CHIBIOS_PWMD_EVAL(t) TO_CHIBIOS_PWMD_PASTE(t) #define PWMD TO_CHIBIOS_PWMD_EVAL(AUDIO_PWM_TIMER) -extern bool playing_note; -extern bool playing_melody; -extern float note_timbre; +extern bool playing_note; +extern bool playing_melody; +extern uint8_t note_timbre; static void pwm_audio_period_callback(PWMDriver *pwmp); static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp); @@ -70,7 +70,7 @@ void channel_1_set_frequency(float freq) { pwmEnableChannel(&PWMD, AUDIO_PWM_TIMERCHANNEL - 1, // adjust the duty-cycle so that the output is for 'note_timbre' duration HIGH - PWM_PERCENTAGE_TO_WIDTH(&PWMD, (1.0f - note_timbre) * 10000)); + PWM_PERCENTAGE_TO_WIDTH(&PWMD, (100 - note_timbre) * 100)); } float channel_1_get_frequency(void) { return channel_1_frequency; } diff --git a/quantum/audio/musical_notes.h b/quantum/audio/musical_notes.h index a47a6ec63652..4377638a237e 100644 --- a/quantum/audio/musical_notes.h +++ b/quantum/audio/musical_notes.h @@ -61,13 +61,14 @@ // Note Timbre // Changes how the notes sound -#define TIMBRE_12 0.125f -#define TIMBRE_25 0.250f -#define TIMBRE_50 0.500f -#define TIMBRE_75 0.750f +#define TIMBRE_12 12 +#define TIMBRE_25 25 +#define TIMBRE_50 50 +#define TIMBRE_75 75 #ifndef TIMBRE_DEFAULT # define TIMBRE_DEFAULT TIMBRE_50 #endif + // Notes - # = Octave #define NOTE_REST 0.00f diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 3862971ef4e1..43562b15d428 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -17,7 +17,7 @@ #include "audio.h" #include -float note_timbre = TIMBRE_DEFAULT; +uint8_t note_timbre = TIMBRE_DEFAULT; bool glissando = false; bool vibrato = false; float vibrato_strength = 0.5; @@ -89,11 +89,11 @@ float voice_envelope(float frequency) { break; case 20 ... 200: - note_timbre = .125 + .125; + note_timbre = 12 + 12; break; default: - note_timbre = .125; + note_timbre = 12; break; } break; @@ -102,10 +102,10 @@ float voice_envelope(float frequency) { glissando = false; // switch (compensated_index) { // case 0 ... 10: - // note_timbre = 0.5; + // note_timbre = 50; // break; // case 11 ... 20: - // note_timbre = 0.5 * (21 - compensated_index) / 10; + // note_timbre = 50 * (21 - compensated_index) / 10; // break; // default: // note_timbre = 0; @@ -119,10 +119,10 @@ float voice_envelope(float frequency) { frequency = (rand() % (int)(40)) + 60; switch (envelope_index) { case 0 ... 10: - note_timbre = 0.5; + note_timbre = 50; break; case 11 ... 20: - note_timbre = 0.5 * (21 - envelope_index) / 10; + note_timbre = 50 * (21 - envelope_index) / 10; break; default: note_timbre = 0; @@ -134,10 +134,10 @@ float voice_envelope(float frequency) { frequency = (rand() % (int)(1000)) + 1000; switch (envelope_index) { case 0 ... 5: - note_timbre = 0.5; + note_timbre = 50; break; case 6 ... 20: - note_timbre = 0.5 * (21 - envelope_index) / 15; + note_timbre = 50 * (21 - envelope_index) / 15; break; default: note_timbre = 0; @@ -149,10 +149,10 @@ float voice_envelope(float frequency) { frequency = (rand() % (int)(2000)) + 3000; switch (envelope_index) { case 0 ... 15: - note_timbre = 0.5; + note_timbre = 50; break; case 16 ... 20: - note_timbre = 0.5 * (21 - envelope_index) / 5; + note_timbre = 50 * (21 - envelope_index) / 5; break; default: note_timbre = 0; @@ -164,10 +164,10 @@ float voice_envelope(float frequency) { frequency = (rand() % (int)(2000)) + 3000; switch (envelope_index) { case 0 ... 35: - note_timbre = 0.5; + note_timbre = 50; break; case 36 ... 50: - note_timbre = 0.5 * (51 - envelope_index) / 15; + note_timbre = 50 * (51 - envelope_index) / 15; break; default: note_timbre = 0; @@ -189,7 +189,7 @@ float voice_envelope(float frequency) { break; case 20 ... 200: - note_timbre = .125 - pow(((float)compensated_index - 20) / (200 - 20), 2) * .125; + note_timbre = 12 - (uint8_t)(pow(((float)compensated_index - 20) / (200 - 20), 2) * 12.5); break; default: @@ -230,15 +230,15 @@ float voice_envelope(float frequency) { // sine wave is slow // note_timbre = (sin((float)compensated_index/10000*OCS_SPEED) * OCS_AMP / 2) + .5; // triangle wave is a bit faster - note_timbre = (float)abs((compensated_index * OCS_SPEED % 3000) - 1500) * (OCS_AMP / 1500) + (1 - OCS_AMP) / 2; + note_timbre = (uint8_t)abs((compensated_index * OCS_SPEED % 3000) - 1500) * (OCS_AMP / 1500) + (1 - OCS_AMP) / 2; break; } break; case duty_octave_down: glissando = true; - note_timbre = (envelope_index % 2) * .125 + .375 * 2; - if ((envelope_index % 4) == 0) note_timbre = 0.5; + note_timbre = (uint8_t)(100 * (envelope_index % 2) * .125 + .375 * 2); + if ((envelope_index % 4) == 0) note_timbre = 50; if ((envelope_index % 8) == 0) note_timbre = 0; break; case delayed_vibrato: @@ -257,9 +257,9 @@ float voice_envelope(float frequency) { break; // case delayed_vibrato_octave: // if ((envelope_index % 2) == 1) { - // note_timbre = 0.55; + // note_timbre = 55; // } else { - // note_timbre = 0.45; + // note_timbre = 45; // } // #define VOICE_VIBRATO_DELAY 150 // #define VOICE_VIBRATO_SPEED 50 @@ -272,28 +272,28 @@ float voice_envelope(float frequency) { // } // break; // case duty_fifth_down: - // note_timbre = 0.5; + // note_timbre = TIMBRE_50; // if ((envelope_index % 3) == 0) - // note_timbre = 0.75; + // note_timbre = TIMBRE_75; // break; // case duty_fourth_down: - // note_timbre = 0.0; + // note_timbre = 0; // if ((envelope_index % 12) == 0) - // note_timbre = 0.75; + // note_timbre = TIMBRE_75; // if (((envelope_index % 12) % 4) != 1) - // note_timbre = 0.75; + // note_timbre = TIMBRE_75; // break; // case duty_third_down: - // note_timbre = 0.5; + // note_timbre = TIMBRE_50; // if ((envelope_index % 5) == 0) - // note_timbre = 0.75; + // note_timbre = TIMBRE_75; // break; // case duty_fifth_third_down: - // note_timbre = 0.5; + // note_timbre = TIMBRE_50; // if ((envelope_index % 5) == 0) - // note_timbre = 0.75; + // note_timbre = TIMBRE_75; // if ((envelope_index % 3) == 0) - // note_timbre = 0.25; + // note_timbre = TIMBRE_25; // break; #endif // AUDIO_VOICES @@ -317,9 +317,9 @@ void voice_decrease_vibrato_strength(float change) { vibrato_strength /= change; // Timbre functions -void voice_set_timbre(float timbre) { - if ((timbre > 0.0f) && (timbre < 1.0f)) { +void voice_set_timbre(uint8_t timbre) { + if ((timbre > 0) && (timbre < 100)) { note_timbre = timbre; } } -float voice_get_timbre(void) { return note_timbre; } +uint8_t voice_get_timbre(void) { return note_timbre; } diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h index 26440666ff9d..f7668e6b5b4c 100644 --- a/quantum/audio/voices.h +++ b/quantum/audio/voices.h @@ -62,7 +62,7 @@ void voice_decrease_vibrato_strength(float change); * @brief set the global timbre for tones to be played * @note: only applies to pwm implementations - where it adjusts the duty-cycle * @note: using any instrument from voices.[ch] other than 'default' may override the set value - * @param[in]: timbre: valid range is (0.0,1.0) + * @param[in]: timbre: valid range is (0,100) */ -void voice_set_timbre(float timbre); -float voice_get_timbre(void); +void voice_set_timbre(uint8_t timbre); +uint8_t voice_get_timbre(void); From 7105f1a34f82b63a5825217aecb9070ed1a1d9ae Mon Sep 17 00:00:00 2001 From: Johannes Date: Tue, 21 Apr 2020 17:03:15 +0200 Subject: [PATCH 093/153] audio-refactoring: duration: use uint16 for internal per-tone/note state --- quantum/audio/audio.c | 32 +++++++++++++++++++++++--------- quantum/audio/audio.h | 16 ++++++++-------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index a972876ea97f..05564c75d9c6 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -54,6 +54,10 @@ * can be reproduced depends on the hardware/driver in use: pwm can only * reproduce one tone per output/speaker; DACs can reproduce/mix multiple * when doing additive synthese. + * + * 'duration' can either be in the beats-per-minute related unit found in + * musical_notes.h, OR in ms; keyboards create SONGs with the former, while + * the internal state of the audio system does its calculations with the later - ms */ #ifndef AUDIO_TONE_STACKSIZE @@ -131,7 +135,7 @@ void audio_init() { tones[i] = (musical_tone_t){ .time_started = 0, .pitch = -1.0f, - .duration = -1.0f + .duration = 0 }; } @@ -196,7 +200,7 @@ void audio_stop_all() { tones[i] = (musical_tone_t){ .time_started = 0, .pitch = -1.0f, - .duration = -1.0f + .duration = 0 }; } @@ -219,14 +223,14 @@ void audio_stop_tone(float pitch) { tones[i] = (musical_tone_t){ .time_started = 0, .pitch = -1.0f, - .duration = -1.0f + .duration = 0 }; for (int j = i; (j < AUDIO_TONE_STACKSIZE - 1); j++) { tones[j] = tones[j + 1]; tones[j + 1] = (musical_tone_t){ .time_started = 0, .pitch = -1.0f, - .duration = -1.0f + .duration = 0 }; } break; @@ -252,7 +256,7 @@ void audio_stop_tone(float pitch) { } } -void audio_play_note(float pitch, float duration) { +void audio_play_note(float pitch, uint16_t duration) { if (!audio_config.enable) { return; } @@ -310,7 +314,7 @@ void audio_play_note(float pitch, float duration) { } void audio_play_tone(float pitch) { - audio_play_note(pitch, -1.0f); + audio_play_note(pitch, 0xffff); } void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) { @@ -345,8 +349,8 @@ void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) { float click[2][2]; void audio_play_click(uint16_t delay, float pitch, uint16_t duration) { - float duration_tone = (64 / 60) * note_tempo * (duration / 1000.0f); - float duration_delay = (64 / 60) * note_tempo * (delay / 1000.0f); + uint16_t duration_tone = audio_ms_to_duration(duration); + uint16_t duration_delay = audio_ms_to_duration(delay); if (delay <= 0.0f) { click[0][0] = pitch; @@ -485,7 +489,9 @@ bool audio_update_state(void) { // housekeeping: stop notes that have no playtime left for (int i=0; i < active_tones; i++) { - if (tones[i].duration > 0) { + if ((tones[i].duration != 0xffff) // indefinetly playing notes, started by 'audio_play_tone' + && (tones[i].duration != 0) // 'uninitialized' + ) { if (timer_elapsed(tones[i].time_started) >= tones[i].duration) { audio_stop_tone(tones[i].pitch); // also sets 'state_changed=true' } @@ -536,3 +542,11 @@ void audio_decrease_tempo(uint8_t tempo_change) { else note_tempo -= tempo_change; } + + +uint16_t audio_duration_to_ms(uint16_t duration_bpm) { + return ((float)duration_bpm * 60 ) / (64 * note_tempo) * 1000; +} +uint16_t audio_ms_to_duration(uint16_t duration_ms) { + return ((float)duration_ms * 64 * note_tempo) / 60 / 1000; +} diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 9e5b53ff34f1..bf1305f1bdf0 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -59,10 +59,10 @@ typedef union { */ typedef struct { uint16_t time_started; // timestamp the tone/note was started, systemtime runs with 1ms resolution -> 16bit timer overflows every ~64 seconds, long enough under normal circumstances; but might be too soon for long-duration notes when the note_tempo is set to a very low value - float pitch; // aka frequency - float duration; // in 64parts to a beats, -1 indicates an indefinitly played note - //float intensity; // aka volume [0,1] TODO: not used at the moment; pwm drivers can't handle it - //uint8_t timbre; // range: [0,100] TODO: this currently kept track of globally, should we do this per tone instead? + float pitch; // aka frequency, in Hz + uint16_t duration; // in ms, converted from the musical_notes.h unit which has 64parts to a beat, factoring in the current tempo in beats-per-minute + //float intensity; // aka volume [0,1] TODO: not used at the moment; pwm drivers can't handle it + //uint8_t timbre; // range: [0,100] TODO: this currently kept track of globally, should we do this per tone instead? } musical_tone_t; // ____ __ ___ @@ -109,8 +109,8 @@ bool audio_is_on(void); * @param[in] duration in milliseconds, use 'audio_duration_to_ms' to convert * from the musical_notes.h unit to ms */ -void audio_play_note(float pitch, float duration); -// TODO: audio_play_note(float pitch, float duration, float intensity, float timbre); +void audio_play_note(float pitch, uint16_t duration); +// TODO: audio_play_note(float pitch, uint16_t duration, float intensity, float timbre); // audio_play_note_with_instrument ifdef AUDIO_ENABLE_VOICES /** @@ -221,8 +221,8 @@ void audio_increase_tempo(uint8_t tempo_change); void audio_decrease_tempo(uint8_t tempo_change); // conversion macros, from 64parts-to-a-beat to milliseconds and back -#define audio_duration_to_ms(d) (d / 64 * (60 / note_tempo) * 1000) -#define audio_ms_to_duration(t) (t * 64 * (note_tempo / 60) / 1000) +uint16_t audio_duration_to_ms(uint16_t duration_bpm); +uint16_t audio_ms_to_duration(uint16_t duration_ms); // __ __ __ // / / / /___ __________/ / ______ __________ From 15ee70d52f0f8a0bac5a35551249f63b751f5300 Mon Sep 17 00:00:00 2001 From: Johannes Date: Tue, 21 Apr 2020 19:01:43 +0200 Subject: [PATCH 094/153] audio-refactoring: tonemultiplexing: use uint16 instead of float --- quantum/audio/audio.c | 18 +++++++++++++----- quantum/audio/audio.h | 6 +++--- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 05564c75d9c6..3d906c7a2bf1 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -84,8 +84,8 @@ uint16_t last_timestamp = 0; # ifndef AUDIO_MAX_SIMULTANEOUS_TONES # define AUDIO_MAX_SIMULTANEOUS_TONES 3 # endif -float tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT; -uint8_t tone_multiplexing_index_shift = 0; // offset used on active-tone array access +uint16_t tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT; +uint8_t tone_multiplexing_index_shift = 0; // offset used on active-tone array access #endif // proviced and used by voices.c @@ -511,11 +511,19 @@ bool audio_update_state(void) { // Tone-multiplexing functions #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING -void audio_set_tone_multiplexing_rate(float rate) { tone_multiplexing_rate = rate; } +void audio_set_tone_multiplexing_rate(uint16_t rate) { tone_multiplexing_rate = rate; } void audio_enable_tone_multiplexing(void) { tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT; } void audio_disable_tone_multiplexing(void) { tone_multiplexing_rate = 0; } -void audio_increase_tone_multiplexing_rate(float change) { tone_multiplexing_rate *= change; } -void audio_decrease_tone_multiplexing_rate(float change) { tone_multiplexing_rate /= change; } +void audio_increase_tone_multiplexing_rate(uint16_t change) { + if ((0xffff - change) > tone_multiplexing_rate) { + tone_multiplexing_rate += change; + } +} +void audio_decrease_tone_multiplexing_rate(uint16_t change) { + if (change <= tone_multiplexing_rate) { + tone_multiplexing_rate -= change; + } +} #endif diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index bf1305f1bdf0..24c0b50c4bea 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -207,11 +207,11 @@ bool audio_is_playing_melody(void); # define AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT 0 // 0=off, good starting value is 4; the lower the value the higher the cpu-load # endif -void audio_set_tone_multiplexing_rate(float rate); +void audio_set_tone_multiplexing_rate(uint16_t rate); void audio_enable_tone_multiplexing(void); void audio_disable_tone_multiplexing(void); -void audio_increase_tone_multiplexing_rate(float change); -void audio_decrease_tone_multiplexing_rate(float change); +void audio_increase_tone_multiplexing_rate(uint16_t change); +void audio_decrease_tone_multiplexing_rate(uint16_t change); #endif // Tempo functions From 759fcccfa1565fbf0cbbd61099bb351509cadd98 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 22 Apr 2020 15:32:37 +0200 Subject: [PATCH 095/153] audio-arm-dac: additive: set second pin output-low used when a piezo is connected to AUDIO_PIN and AUDIO_PIN_ALT, with PIN_ALT_AS_NEGATIVE --- quantum/audio/driver_chibios_dac_additive.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index 1bf614e03076..cfbc81a4beb5 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -245,11 +245,11 @@ void audio_driver_initialize() { dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); #endif - /* - * Start the note timer - */ - gptStart(&GPTD8, &gpt8cfg1); - gptStartContinuous(&GPTD8, 2U); +#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) + // no inverted/out-of-phase waveform (yet?), only pulling AUDIO_PIN_ALT to ground + palSetLineMode(AUDIO_PIN_ALT, PAL_MODE_OUTPUT_PUSHPULL); + palClearLine(AUDIO_PIN_ALT); +#endif /* enable the output buffer, to directly drive external loads with no additional circuitry * From 5805704f621f5ac62cbc37d9e4d80d3095e90ef8 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 22 Apr 2020 15:38:04 +0200 Subject: [PATCH 096/153] audio-refactoring: move AUDIO_PIN selection from rules.mk to config.h to be consistent with how other features are handled in QMK --- common_features.mk | 6 --- docs/feature_audio.md | 44 +++++++++++---------- quantum/audio/audio.h | 8 ---- quantum/audio/driver_avr_pwm_hardware.c | 10 ++++- quantum/audio/driver_chibios_dac.h | 9 ----- quantum/audio/driver_chibios_dac_additive.c | 22 +++++++++-- quantum/audio/driver_chibios_dac_basic.c | 17 +++++++- quantum/audio/driver_chibios_pwm_software.c | 8 ++-- 8 files changed, 71 insertions(+), 53 deletions(-) diff --git a/common_features.mk b/common_features.mk index d6feb6ad7472..57cc743a59fc 100644 --- a/common_features.mk +++ b/common_features.mk @@ -61,12 +61,6 @@ ifeq ($(strip $(AUDIO_ENABLE)), yes) AUDIO_DRIVER ?= pwm_hardware OPT_DEFS += -DAUDIO_DRIVER_PWM endif - ifdef AUDIO_PIN - OPT_DEFS += -DAUDIO_PIN=$(AUDIO_PIN) -DAUDIO_PIN_$(AUDIO_PIN) - endif - ifdef AUDIO_PIN_ALT - OPT_DEFS += -DAUDIO_PIN_ALT=$(AUDIO_PIN_ALT) -DAUDIO_PIN_ALT_$(AUDIO_PIN_ALT) - endif OPT_DEFS += -DAUDIO_ENABLE MUSIC_ENABLE = yes SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 1cb054857ff8..fc8d8c9c09d9 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -5,36 +5,36 @@ Your keyboard can make sounds! If you've got a spare pin you can hook up a simpl To activate this feature, add `AUDIO_ENABLE = yes` to your `rules.mk`. ## AVR based boards -Up to two simultaneous tones can be rendered. with one speaker driven by timer 1 and another driven by timer 3. The following pins can be configured as audio outputs in `rules.mk`: +Up to two simultaneous tones can be rendered. with one speaker driven by timer 1 and another driven by timer 3. The following pins can be configured as audio outputs in `config.h`: for the primary speaker, with Timer 3, pick ONE these pins: -`AUDIO_PIN = C4` -`AUDIO_PIN = C5` -`AUDIO_PIN = C6` +`#define AUDIO_PIN_C4` +`#define AUDIO_PIN_C5` +`#define AUDIO_PIN_C6` and *optionally*, a secondary speaker, using Timer 1, on ONE of these pins: -`AUDIO_PIN_ALT = B5` -`AUDIO_PIN_ALT = B6` -`AUDIO_PIN_ALT = B7` +`#define AUDIO_PIN_ALT_B5` +`#define AUDIO_PIN_ALT_B6` +`#define AUDIO_PIN_ALT_B7` ### Wiring -per speaker is - for example with a piezo buzzer - the black lead to Ground, and the red lead connected to the selected AUDIO_PIN for the primary; and similarly with AUDIO_PIN_ALT for the secondary. +per speaker is - for example with a piezo buzzer - the black lead to Ground, and the red lead connected to the selected AUDIO_PIN_X for the primary; and similarly with AUDIO_PIN_ALT_X for the secondary. ## ARM based boards ### DAC (basic) -Most STM32 MCUs have DAC peripherals, with a notable exception of the STM32F1xx series. Generally, the DAC peripheral drives pins A4 or A5. To enable DAC-based audio output on STM32 devices, add `AUDIO_DRIVER = dac_basic` to `rules.mk` and set either:` -`AUDIO_PIN = A4` +Most STM32 MCUs have DAC peripherals, with a notable exception of the STM32F1xx series. Generally, the DAC peripheral drives pins A4 or A5. To enable DAC-based audio output on STM32 devices, add `AUDIO_DRIVER = dac_basic` to `rules.mk` and set in `config.h` either: +`#define AUDIO_PIN_A4` OR -`AUDIO_PIN = A5` +`#define AUDIO_PIN_A5` the other DAC channel can optionally be used with a secondary speaker, just set: -`AUDIO_PIN_ALT = A4` or `AUDIO_PIN_ALT = A5` +`#define AUDIO_PIN_ALT_A4` or `#define AUDIO_PIN_ALT_A5` Do note though that the dac_basic driver is only capable of reproducing one tone per speaker/channel at a time, for more tones simultaneously, try the dac_additive driver. #### Wiring: -for two piezos, for example configured as `AUDIO_PIN A4` and `AUDIO_PIN_ALT A5` would be: red lead to A4 and black to Ground, and similarly with the second one: A5 = red, and Ground = black +for two piezos, for example configured as `AUDIO_PIN_A4` and `AUDIO_PIN_ALT_A5` would be: red lead to A4 and black to Ground, and similarly with the second one: A5 = red, and Ground = black another alternative is to drive *one* piezo with both DAC pins - for an extra "push". wiring red to A4 and black to A5 (or the other way round) and add `#define AUDIO_PIN_ALT_AS_NEGATIVE` to `config.h` @@ -43,7 +43,8 @@ wiring red to A4 and black to A5 (or the other way round) and add `#define AUDIO ### DAC (additive) Another option, besides dac_basic (which produces sound through a squarewave), is to use the DAC to do additive wave synthesis. With a number of predefined waveforms or by providing your own implementation to generate samples on the fly. -To use this feature set `AUDIO_DRIVER = dac_additive` in your `rules.mk`. +To use this feature set `AUDIO_DRIVER = dac_additive` in your `rules.mk`, and select in `config.h` EITHER `#define AUDIO_PIN_A4` or `#define AUDIO_PIN_A5`. + The used waveform defaults to a sine, but can be selected by adding one of the following defines to `config.h`: `#define AUDIO_DAC_SAMPLE_WAVEFORM_SINE` `#define AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE` @@ -51,23 +52,26 @@ The used waveform defaults to a sine, but can be selected by adding one of the f `#define AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE` Should you rather choose to generate and use your own sample-table with the DAC unit, implement `uint16_t dac_value_generate(void)` with your keyboard - for an example implementation see keyboards/planck/keymaps/synth_sample or keyboards/planck/keymaps/synth_wavetable + ### PWM (software) -if the DAC pins are unavailable (or the MCU has no usable DAC at all, like STM32F1xx); pwm can be an alternative. +if the DAC pins are unavailable (or the MCU has no usable DAC at all, like STM32F1xx); PWM can be an alternative. +Note that there is currently only one speaker/pin supported. set in `rules.mk`: -`AUDIO_DRIVER = pwm_software` and -`AUDIO_PIN = C13` (can be any pin) +`AUDIO_DRIVER = pwm_software` and in `config.h` +`#define AUDIO_PIN C13` (can be any pin, NOTE the space in the define!) to have the selected pin output a pwm signal, generated from a timer callback which toggles the pin in software. #### Wiring the usual piezo wiring: red goes to the selected AUDIO_PIN, black goes to ground. -OR if you can chose to drive one piezo with two pins, for example `AUDIO_PIN B1`, `AUDIO_PIN_ALT B2` in `rules.mk`, `#define AUDIO_PIN_ALT_AS_NEGATIVE` in `config.h` the red lead could go to B1, the black to B2. +OR if you can chose to drive one piezo with two pins, for example `#define AUDIO_PIN B1`, `#define AUDIO_PIN_ALT B2` in `config.h`, with `#define AUDIO_PIN_ALT_AS_NEGATIVE` - then the red lead could go to B1, the black to B2. ### PWM (hardware) -STM32F1xx have to fall back to using PWM, but can do so in hardware: +STM32F1xx have to fall back to using PWM, but can do so in hardware; but again on currently only one speaker/pin. -`AUDIO_DRIVER = pwm_hardware` and `AUDIO_PIN A8` in `rules.mk` and in `config.h`: +`AUDIO_DRIVER = pwm_hardware` in `rules.mk`, and in `config.h`: +`#define AUDIO_PIN A8` `#define AUDIO_PWM_TIMER 1` `#define AUDIO_PWM_TIMERCHANNEL 1` (as well as `#define AUDIO_PWM_PINALTERNATE_FUNCTION 42` if you are on STM32F2 or larger) diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 24c0b50c4bea..26849f0d0247 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -293,35 +293,27 @@ bool audio_update_state(void); // LEGACY defines - TODO: remove and replace these in all keyboards using them #ifdef A4_AUDIO # define AUDIO_PIN_A4 -# define AUDIO_PIN A4 #endif #ifdef A5_AUDIO # define AUDIO_PIN_A5 -# define AUDIO_PIN A5 #endif #ifdef B5_AUDIO # define AUDIO_PIN_ALT_B5 -# define AUDIO_PIN_ALT B5 #endif #ifdef B6_AUDIO # define AUDIO_PIN_ALT_B6 -# define AUDIO_PIN_ALT B6 #endif #ifdef B7_AUDIO # define AUDIO_PIN_ALT_B7 -# define AUDIO_PIN_ALT B7 #endif #ifdef C4_AUDIO # define AUDIO_PIN_C4 -# define AUDIO_PIN C4 #endif #ifdef C5_AUDIO # define AUDIO_PIN_C5 -# define AUDIO_PIN C5 #endif #ifdef C6_AUDIO # define AUDIO_PIN_C6 -# define AUDIO_PIN C6 #endif #define is_audio_on() audio_is_on() diff --git a/quantum/audio/driver_avr_pwm_hardware.c b/quantum/audio/driver_avr_pwm_hardware.c index 9675f39fce96..844e08a36205 100644 --- a/quantum/audio/driver_avr_pwm_hardware.c +++ b/quantum/audio/driver_avr_pwm_hardware.c @@ -38,6 +38,10 @@ extern uint8_t note_timbre; in a pinch with only one of the PB pins available as speaker output, they can be used as the primary channel too - by only setting the AUDIO_PIN_ALT_Bx define, and *none* of the AUDIO_PIN_Cx defines */ +#if (defined(AUDIO_PIN_C4) && defined(AUDIO_PIN_C5)) || (defined(AUDIO_PIN_C5) && defined(AUDIO_PIN_C6)) || (defined(AUDIO_PIN_C4) && defined(AUDIO_PIN_C6)) || (defined(AUDIO_PIN_C4) && defined(AUDIO_PIN_C5) && defined(AUDIO_PIN_C6)) +# error "Audio feature: please set only one AUDIO_PIN_Cx." +#endif + #if defined(AUDIO_PIN_C4) || defined(AUDIO_PIN_C5) || defined(AUDIO_PIN_C6) # define AUDIO1_PIN_SET # define AUDIO1_TIMSKx TIMSK3 @@ -76,6 +80,10 @@ extern uint8_t note_timbre; # endif #endif +#if (defined(AUDIO_PIN_ALT_B5) && defined(AUDIO_PIN_ALT_B6)) || (defined(AUDIO_PIN_ALT_B6) && defined(AUDIO_PIN_ALT_B7)) || (defined(AUDIO_PIN_ALT_B5) && defined(AUDIO_PIN_ALT_B7)) || (defined(AUDIO_PIN_ALT_B5) && defined(AUDIO_PIN_ALT_B6) && defined(AUDIO_PIN_ALT_B7)) +# error "Audio feature: please set only one AUDIO_PIN_ALT_Bx." +#endif + #if defined(AUDIO_PIN_ALT_B5) || defined(AUDIO_PIN_ALT_B6) || defined(AUDIO_PIN_ALT_B7) # define AUDIO2_PIN_SET # define AUDIO2_TIMSKx TIMSK1 @@ -116,7 +124,7 @@ extern uint8_t note_timbre; // C6 seems to be the assumed default by many existing keyboard - but sill warn the user #if !defined(AUDIO1_PIN_SET) && !defined(AUDIO2_PIN_SET) -# pragma message "Audio feature enabled, but no pin selected - see docs/feature_audio under the AVR settings for available options. Don't expect to hear anything... :-)" +# pragma message "Audio feature enabled, but no suitable pin selected - see docs/feature_audio under the AVR settings for available options. Don't expect to hear anything... :-)" // TODO: make this an error - go through the breaking-change-process and change all keyboards to the new define #endif // ----------------------------------------------------------------------------- diff --git a/quantum/audio/driver_chibios_dac.h b/quantum/audio/driver_chibios_dac.h index d1d5313d22db..ee26ea3afb37 100644 --- a/quantum/audio/driver_chibios_dac.h +++ b/quantum/audio/driver_chibios_dac.h @@ -105,15 +105,6 @@ # define AUDIO_DAC_OFF_VALUE AUDIO_DAC_SAMPLE_MAX / 2 #endif -/** - * choose pins for the speaker - */ -#if !defined(AUDIO_PIN_A4) && !defined(AUDIO_PIN_A5) -# pragma message "Audio feature enabled, but no pin selected - see docs/feature_audio under the ARM DAC settings for available options. Falling back to A5" -# define AUDIO_PIN_A5 -// TODO: go through a breaking change, and add AUDIO_PIN=A5 to all keyboards currently using AUDIO on STM32 based boards -#endif - /** *user overridable sample generation/processing */ diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index cfbc81a4beb5..2188825f0925 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -28,6 +28,17 @@ this driver allows for multiple simultaneous tones to be played through one single channel by doing additive wave-synthesis */ +#if !defined(AUDIO_PIN_A4) && !defined(AUDIO_PIN_A5) +# error "Audio feature enabled, but no suitable pin selected as AUDIO_PIN_x - see docs/feature_audio under 'ARM (DAC additive)' for available options." +#endif +#if defined(AUDIO_PIN_A4) && defined(AUDIO_PIN_A5) +# error "Audio feature: please set either AUDIO_PIN_A4 or AUDIO_PIN_A5, not both." +#endif +#if defined(AUDIO_PIN_ALT_A4) && defined(AUDIO_PIN_ALT_A5) +# error "Audio feature: please set either AUDIO_PIN_ALT_A4 or AUDIO_PIN_ALT_A5, not both." +#endif + + #if !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID) # define AUDIO_DAC_SAMPLE_WAVEFORM_SINE #endif @@ -245,10 +256,13 @@ void audio_driver_initialize() { dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); #endif -#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) - // no inverted/out-of-phase waveform (yet?), only pulling AUDIO_PIN_ALT to ground - palSetLineMode(AUDIO_PIN_ALT, PAL_MODE_OUTPUT_PUSHPULL); - palClearLine(AUDIO_PIN_ALT); +// no inverted/out-of-phase waveform (yet?), only pulling AUDIO_PIN_ALT_x to ground +#if defined(AUDIO_PIN_ALT_A4) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) + palSetLineMode(AUDIO_PIN_ALT_A4, PAL_MODE_OUTPUT_PUSHPULL); + palClearLine(AUDIO_PIN_ALT_A4); +#elif defined(AUDIO_PIN_ALT_A5) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) + palSetLineMode(AUDIO_PIN_ALT_A5, PAL_MODE_OUTPUT_PUSHPULL); + palClearLine(AUDIO_PIN_ALT_A5); #endif /* enable the output buffer, to directly drive external loads with no additional circuitry diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index 202cacff833e..6639fc9d6d1c 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -23,11 +23,26 @@ which utilizes both channels of the DAC unit many STM32 are equipped with to output a modulated square-wave, from precomputed samples stored in a buffer, which is passed to the hardware through DMA + this driver can either be used to drive to separate speakers, wired to A4+Gnd and A5+Gnd, which allows two tones to be played simultaniously + OR + one speaker wired to A4+A5 with hte AUDIO_PIN_ALT_AS_NEGATIVE define set - see docs/feature_audio TODOS: - channel_X_stop should respect dac conversion buffer-complete; currently the output might end up 'high' = halfway through a sample conversion */ +#if !defined(AUDIO_PIN_A4) && !defined(AUDIO_PIN_A5) && !defined(AUDIO_PIN_ALT_A4) && !defined(AUDIO_PIN_ALT_A5) +# pragma message "Audio feature enabled, but no suitable pin selected as AUDIO_PIN_x or AUDIO_PIN_ALT_x - see docs/feature_audio under 'ARM (DAC basic)' for available options." +// TODO: make this an 'error' instead; go through a breaking change, and add AUDIO_PIN_A5 to all keyboards currently using AUDIO on STM32 based boards? +#endif +#if defined(AUDIO_PIN_A4) && defined(AUDIO_PIN_ALT_A4) +# error "Audio feature: please set either AUDIO_PIN_A4 or AUDIO_PIN_ALT_A4, not both." +#endif +#if defined(AUDIO_PIN_A5) && defined(AUDIO_PIN_ALT_A5) +# error "Audio feature: please set either AUDIO_PIN_A5 or AUDIO_PIN_ALT_A5, not both." +#endif + + #if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) // squarewave static const dacsample_t dac_buffer_1[AUDIO_DAC_BUFFER_SIZE] = { @@ -138,7 +153,7 @@ float channel_2_get_frequency(void) { return channel_2_frequency; } static void gpt_cb8(GPTDriver *gptp) { if (audio_update_state()) { -#if (defined (AUDIO_PIN_A4) && defined(AUDIO_PIN_A5)) || (defined(AUDIO_PIN_A4) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT_A5)) || (defined(AUDIO_PIN_A5) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT_A4)) +#if (defined(AUDIO_PIN_A4) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT_A5)) || (defined(AUDIO_PIN_A5) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT_A4)) // one piezo/speaker connected to both audio pins, the generated squarewaves are inverted channel_1_set_frequency(audio_get_processed_frequency(0)); channel_2_set_frequency(audio_get_processed_frequency(0)); diff --git a/quantum/audio/driver_chibios_pwm_software.c b/quantum/audio/driver_chibios_pwm_software.c index 8b3bf5e1edda..73e9eb4f587e 100644 --- a/quantum/audio/driver_chibios_pwm_software.c +++ b/quantum/audio/driver_chibios_pwm_software.c @@ -88,7 +88,7 @@ void channel_1_stop(void) { palClearLine(AUDIO_PIN); // leave the line low, after last note was played -#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT) +#if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) palClearLine(AUDIO_PIN_ALT); // leave the line low, after last note was played #endif } @@ -98,7 +98,7 @@ static void pwm_audio_period_callback(PWMDriver *pwmp) { (void)pwmp; palClearLine(AUDIO_PIN); -#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT) +#if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) palSetLine(AUDIO_PIN_ALT); #endif } @@ -106,7 +106,7 @@ static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { (void)pwmp; if (channel_1_frequency > 0) { palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer -#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT) +#if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) palClearLine(AUDIO_PIN_ALT); #endif } @@ -131,7 +131,7 @@ void audio_driver_initialize(void) { palSetLineMode(AUDIO_PIN, PAL_MODE_OUTPUT_PUSHPULL); palClearLine(AUDIO_PIN); -#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT) +#if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) palSetLineMode(AUDIO_PIN_ALT, PAL_MODE_OUTPUT_PUSHPULL); palClearLine(AUDIO_PIN_ALT); #endif From ee7401f91c8e427d722ec44717f6f6b750282a15 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 24 Apr 2020 20:24:01 +0200 Subject: [PATCH 097/153] audio-refactoring: buildfix: wrong legacy macro for set_tempo --- quantum/audio/audio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 26849f0d0247..e852ccf1582d 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -324,7 +324,7 @@ bool audio_update_state(void); #define play_note(f, v) audio_play_tone(f) #define set_timbre(t) voice_set_timbre(t) -#define set_tempo(t) voice_set_tempo(t) +#define set_tempo(t) audio_set_tempo(t) #define increase_tempo(t) audio_increase_tempo(t) #define decrease_tempo(t) audio_decrease_tempo(t) // vibrato functions are not used in any keyboards From 8d91bf9e094fe633bff7538e0c5a70dffd800c0a Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 25 Apr 2020 02:12:36 +0200 Subject: [PATCH 098/153] audio-arm-dac: additive: set second pin output-low -- FIXUP --- quantum/audio/driver_chibios_dac_additive.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index 2188825f0925..747232e40727 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -258,11 +258,11 @@ void audio_driver_initialize() { // no inverted/out-of-phase waveform (yet?), only pulling AUDIO_PIN_ALT_x to ground #if defined(AUDIO_PIN_ALT_A4) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) - palSetLineMode(AUDIO_PIN_ALT_A4, PAL_MODE_OUTPUT_PUSHPULL); - palClearLine(AUDIO_PIN_ALT_A4); + palSetLineMode(A4, PAL_MODE_OUTPUT_PUSHPULL); + palClearLine(A4); #elif defined(AUDIO_PIN_ALT_A5) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) - palSetLineMode(AUDIO_PIN_ALT_A5, PAL_MODE_OUTPUT_PUSHPULL); - palClearLine(AUDIO_PIN_ALT_A5); + palSetLineMode(A5, PAL_MODE_OUTPUT_PUSHPULL); + palClearLine(A5); #endif /* enable the output buffer, to directly drive external loads with no additional circuitry From 6ad86b8f6d1013c55938e62429d2bd8de5f17f81 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 25 Apr 2020 08:10:47 +0200 Subject: [PATCH 099/153] audio.c: do duration<>ms conversion in uint instead of float on AVR, to save a couple of bytes in the firmware size --- quantum/audio/audio.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 3d906c7a2bf1..7f4788eec978 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -552,9 +552,20 @@ void audio_decrease_tempo(uint8_t tempo_change) { } +// TODO in the int-math version are some bugs; songs sometimes abruptly end - maybe an issue with the timer/sysrtem-tick wrapping around? uint16_t audio_duration_to_ms(uint16_t duration_bpm) { +#if defined(__AVR__) + // doing int-math saves us some bytes in the overall firmware size, but the intermediate result is less accurate before beeing cast to/returned as uint + return ((uint32_t)duration_bpm * 60 * 1000) / (64 * note_tempo); + // NOTE: beware of uint16_t overflows when note_tempo is low and/or the duration is long +#else return ((float)duration_bpm * 60 ) / (64 * note_tempo) * 1000; +#endif } uint16_t audio_ms_to_duration(uint16_t duration_ms) { +#if defined(__AVR__) + return ((uint32_t)duration_ms * 64 * note_tempo) / 60 / 1000; +#else return ((float)duration_ms * 64 * note_tempo) / 60 / 1000; +#endif } From 9c0bbb2107f8964bcc196ea71aab7f78107dafab Mon Sep 17 00:00:00 2001 From: JohSchneider Date: Sun, 26 Apr 2020 05:22:01 +0000 Subject: [PATCH 100/153] audio-refactoring: cleanup eeprom defines/usage for ARM, avr is handled automagically through the avr libc and common_features.mk Co-Authored-By: Drashna Jaelre --- quantum/audio/audio.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 7f4788eec978..8fe720ebc4df 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -118,18 +118,17 @@ void audio_init() { } // Check EEPROM - // TODO: avr defines? -#if defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE) +#ifdef EEPROM_ENABLE if (!eeconfig_is_enabled()) { eeconfig_init(); } audio_config.raw = eeconfig_read_audio(); -#else // ARM EEPROM +#else // EEPROM settings audio_config.enable = true; # ifdef AUDIO_CLICKY_ON audio_config.clicky_enable = true; # endif -#endif // ARM EEPROM +#endif // EEPROM settings for (uint8_t i = 0; i < AUDIO_TONE_STACKSIZE; i++) { tones[i] = (musical_tone_t){ From 7e170f8dd67edcebfc2b1ed235df89f4cd346798 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sun, 26 Apr 2020 18:56:26 +0200 Subject: [PATCH 101/153] audio.h: throw an error if OFF is larger than MAX --- quantum/audio/driver_chibios_dac.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quantum/audio/driver_chibios_dac.h b/quantum/audio/driver_chibios_dac.h index ee26ea3afb37..5d0aac18dfcb 100644 --- a/quantum/audio/driver_chibios_dac.h +++ b/quantum/audio/driver_chibios_dac.h @@ -105,6 +105,10 @@ # define AUDIO_DAC_OFF_VALUE AUDIO_DAC_SAMPLE_MAX / 2 #endif +#if AUDIO_DAC_OFF_VALUE > AUDIO_DAC_SAMPLE_MAX +# error "AUDIO_DAC: OFF_VALUE may not be larger than SAMPLE_MAX" +#endif + /** *user overridable sample generation/processing */ From 90e517d0df8abc2cc1accb1d746a80c968399380 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sun, 26 Apr 2020 19:07:49 +0200 Subject: [PATCH 102/153] audio-arm-dac: basic: actually stop the dac-conversion on a audio_driver_stop to put the output pin in a known state == AUDIO_DAC_OFF_VALUE, instead of just leaving them where the last conversion was... with AUDIO_PIN_ALT_AS_NEGATIVE this meant one output was left HIGH while the other was left LOW one CAVEAT: due to this change the opposing squarewave when using both A4 and A5 with AUDIO_PIN_ALT_AS_NEGATIVE show extra pulses at the beginning/end on one of the outputs, the two waveforms are in sync otherwise. the extra pusles probably matter little, since this is no high-fidelity sound generation :P --- quantum/audio/driver_chibios_dac_basic.c | 27 +++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index 6639fc9d6d1c..d1b037650e49 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -189,12 +189,16 @@ void audio_driver_initialize() { #if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); dacStart(&DACD1, &dac_conf_ch1); - dacStartConversion(&DACD1, &dac_conv_grp_ch1, (dacsample_t *)dac_buffer_1, AUDIO_DAC_BUFFER_SIZE); + + // initial setup of the dac-triggering timer is still required, even + // though it gets reconfigured and restarted later on + gptStart(&GPTD6, &gpt6cfg1); #endif #if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); dacStart(&DACD2, &dac_conf_ch2); - dacStartConversion(&DACD2, &dac_conv_grp_ch2, (dacsample_t *)dac_buffer_2, AUDIO_DAC_BUFFER_SIZE); + + gptStart(&GPTD7, &gpt7cfg1); #endif /* enable the output buffer, to directly drive external loads with no additional circuitry @@ -208,11 +212,9 @@ void audio_driver_initialize() { */ #if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) DACD1.params->dac->CR &= ~DAC_CR_BOFF1; - gptStart(&GPTD6, &gpt6cfg1); // initialize the timer used to trigger the DAC conversions #endif #if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) DACD2.params->dac->CR &= ~DAC_CR_BOFF2; - gptStart(&GPTD7, &gpt7cfg1); #endif // start state-updater @@ -222,11 +224,26 @@ void audio_driver_initialize() { void audio_driver_stop(void) { #if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) gptStopTimer(&GPTD6); + + // stop the ongoing conversion and put the output in a known state + dacStopConversion(&DACD1); + dacPutChannelX(&DACD1, 0, AUDIO_DAC_OFF_VALUE); #endif #if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) gptStopTimer(&GPTD7); + + dacStopConversion(&DACD2); + dacPutChannelX(&DACD2, 0, AUDIO_DAC_OFF_VALUE); #endif gptStopTimer(&GPTD8); } -void audio_driver_start(void) { gptStartContinuous(&GPTD8, 2U); } +void audio_driver_start(void) { +#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) + dacStartConversion(&DACD1, &dac_conv_grp_ch1, (dacsample_t *)dac_buffer_1, AUDIO_DAC_BUFFER_SIZE); +#endif +#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) + dacStartConversion(&DACD2, &dac_conv_grp_ch2, (dacsample_t *)dac_buffer_2, AUDIO_DAC_BUFFER_SIZE); +#endif + gptStartContinuous(&GPTD8, 2U); +} From 9672e45ba40fc49e78ae51eeb734c022b72504ea Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 30 Apr 2020 17:25:35 +0200 Subject: [PATCH 103/153] audio-arm-dac: additive: move zero-crossing code out of dac_value_generate which is/should be user-overridable == simple, and doing one thing: providing sample values state-transitions necessary for the zero crossing are better handled in the surrounding loop in the dac_end callback --- quantum/audio/driver_chibios_dac_additive.c | 96 +++++++++++---------- 1 file changed, 50 insertions(+), 46 deletions(-) diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index 747232e40727..a7f88128f7f3 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -103,22 +103,16 @@ output_states_t state = OUTPUT_OFF; * can override it with their own waveforms/noises. */ __attribute__((weak)) uint16_t dac_value_generate(void) { - uint16_t value = AUDIO_DAC_OFF_VALUE; - - if (OUTPUT_OFF == state) return AUDIO_DAC_OFF_VALUE; - - if ((0 == active_tones_snapshot_length) && (OUTPUT_REACHED_ZERO_BEFORE_OFF == state)) { - state = OUTPUT_OFF; - return AUDIO_DAC_OFF_VALUE; - } /* doing additive wave synthesis over all currently playing tones = adding up * sine-wave-samples for each frequency, scaled by the number of active tones */ - uint16_t value_avg = 0; + uint16_t value = 0; float frequency = 0.0f; for (uint8_t i = 0; i < active_tones_snapshot_length; i++) { + /* Note: a user implementation does not have to rely on the active_tones_snapshot, but + * could directly query the active frequencies through audio_get_processed_frequency */ frequency = active_tones_snapshot[i]; dac_if[i] = dac_if[i] + ((frequency * AUDIO_DAC_BUFFER_SIZE) / AUDIO_DAC_SAMPLE_RATE) * 2 / 3; @@ -133,56 +127,28 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { uint16_t dac_i = (uint16_t)dac_if[i]; #if defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) - value_avg += dac_buffer_sine[dac_i] / active_tones_snapshot_length; + value += dac_buffer_sine[dac_i] / active_tones_snapshot_length; #elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE) - value_avg += dac_buffer_triangle[dac_i] / active_tones_snapshot_length; + value += dac_buffer_triangle[dac_i] / active_tones_snapshot_length; #elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID) - value_avg += dac_buffer_trapezoid[dac_i] / active_tones_snapshot_length; + value += dac_buffer_trapezoid[dac_i] / active_tones_snapshot_length; #elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE) - value_avg += dac_buffer_square[dac_i] / active_tones_snapshot_length; + value += dac_buffer_square[dac_i] / active_tones_snapshot_length; #endif /* // SINE - value_avg += dac_buffer_sine[dac_i] / active_tones_snapshot_length / 3; + value += dac_buffer_sine[dac_i] / active_tones_snapshot_length / 3; // TRIANGLE - value_avg += dac_buffer_triangle[dac_i] / active_tones_snapshot_length / 3; + value += dac_buffer_triangle[dac_i] / active_tones_snapshot_length / 3; // SQUARE - value_avg += dac_buffer_square[dac_i] / active_tones_snapshot_length / 3; + value += dac_buffer_square[dac_i] / active_tones_snapshot_length / 3; //NOTE: combination of these three waveforms is more exemplary - and doesn't sound particularly good :-P */ // STAIRS (mostly usefull as test-pattern) // value_avg = dac_buffer_staircase[dac_i] / active_tones_snapshot_length; } - value = value_avg; - - /* zero crossing (or approach) - * - * TODO: what about different values, other than AUDIO_DAC_OFF_VALUE=0, AUDIO_DAC_SAMPLE_MAX or AUDIO_DAC_SAMPLE_MAX/2 ? - */ - if ((OUTPUT_SHOULD_STOP == state) && (value < AUDIO_DAC_SAMPLE_MAX / 100)) { // TODO: works only if DAC_OFF_VALUE = 0! - state = OUTPUT_REACHED_ZERO_BEFORE_OFF; - } else if ((OUTPUT_TONES_CHANGED == state) && (value < AUDIO_DAC_SAMPLE_MAX / 100)) { // TODO: works only if DAC_OFF_VALUE = 0! - state = OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE; - } - - if ((OUTPUT_REACHED_ZERO_BEFORE_OFF == state) || (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state)) { - uint8_t active_tones = MIN(AUDIO_MAX_SIMULTANEOUS_TONES, audio_get_number_of_active_tones()); - - active_tones_snapshot_length = 0; - // update the snapshot - once, and only on occasion that something changed; - // -> saves cpu cycles (?) - for (uint8_t i = 0; i < active_tones; i++) { - float freq = audio_get_processed_frequency(i); - if (freq > 0) { // disregard 'rest' notes, with valid frequency 0.0f; which would only lower the resulting waveform volume during the additive synthesis step - active_tones_snapshot[active_tones_snapshot_length++] = freq; - } - } - if (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state) { - state = OUTPUT_RUN_NORMALY; - } - } return value; } @@ -200,7 +166,44 @@ static void dac_end(DACDriver *dacp) { } for (uint8_t s = 0; s < AUDIO_DAC_BUFFER_SIZE / 2; s++) { - sample_p[s] = dac_value_generate(); + if ((0 == active_tones_snapshot_length) && (OUTPUT_REACHED_ZERO_BEFORE_OFF == state)) { + state = OUTPUT_OFF; + } + if (OUTPUT_OFF == state) { + sample_p[s] = AUDIO_DAC_OFF_VALUE; + continue; + } else { + sample_p[s] = dac_value_generate(); + } + + // zero crossing (or approach, whereas zero == DAC_OFF_VALUE, which can be configured to anything from 0 to DAC_SAMPLE_MAX) + if (((sample_p[s] + (AUDIO_DAC_SAMPLE_MAX / 100)) > AUDIO_DAC_OFF_VALUE) && // value approaches from below + (sample_p[s] < (AUDIO_DAC_OFF_VALUE + (AUDIO_DAC_SAMPLE_MAX / 100))) // or above + ) { + if (OUTPUT_SHOULD_STOP == state) { + state = OUTPUT_REACHED_ZERO_BEFORE_OFF; + } else if (OUTPUT_TONES_CHANGED == state) { + state = OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE; + } + } + + if ((OUTPUT_REACHED_ZERO_BEFORE_OFF == state) || (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state)) { + uint8_t active_tones = MIN(AUDIO_MAX_SIMULTANEOUS_TONES, audio_get_number_of_active_tones()); + + active_tones_snapshot_length = 0; + // update the snapshot - once, and only on occasion that something changed; + // -> saves cpu cycles (?) + for (uint8_t i = 0; i < active_tones; i++) { + float freq = audio_get_processed_frequency(i); + if (freq > 0) { // disregard 'rest' notes, with valid frequency 0.0f; which would only lower the resulting waveform volume during the additive synthesis step + active_tones_snapshot[active_tones_snapshot_length++] = freq; + } + } + + if (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state) { + state = OUTPUT_RUN_NORMALY; + } + } } // update audio internal state (note position, current_note, ...) @@ -292,5 +295,6 @@ void audio_driver_start(void) { active_tones_snapshot[i] = 0.0f; } active_tones_snapshot_length = 0; - state = OUTPUT_RUN_NORMALY; + state = OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE; + // = have the first conversion update/populate the initial snapshot } From fedd7ffc7b6cb4dc578fbdaf0ef1855cf8bab73b Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 30 Apr 2020 17:31:28 +0200 Subject: [PATCH 104/153] audio-arm-dac: dac-additive: zero-crossing: ramping up or down after a start trigger ramp up: generate values until zero=OFF_VALUE is reached, then continue normally same in reverse for strop trigger: output values until zero is reached/crossed, then keep OFF_VALUE on the output --- quantum/audio/driver_chibios_dac_additive.c | 56 +++++++++++++++------ 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index a7f88128f7f3..c117c34414f3 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -86,6 +86,7 @@ static float active_tones_snapshot[AUDIO_MAX_SIMULTANEOUS_TONES] = {0, 0}; static uint8_t active_tones_snapshot_length = 0; typedef enum { + OUTPUT_SHOULD_START, OUTPUT_RUN_NORMALY, // path 1: wait for zero, then change/update active tones OUTPUT_TONES_CHANGED, @@ -94,6 +95,8 @@ typedef enum { OUTPUT_SHOULD_STOP, OUTPUT_REACHED_ZERO_BEFORE_OFF, OUTPUT_OFF, + OUTPUT_OFF_1, + OUTPUT_OFF_2, // trailing off: giving the DAC two more conversion cycles until the AUDIO_DAC_OFF_VALUE reaches the output, then turn the timer off, which leaves the output at that level number_of_output_states } output_states_t; output_states_t state = OUTPUT_OFF; @@ -166,30 +169,46 @@ static void dac_end(DACDriver *dacp) { } for (uint8_t s = 0; s < AUDIO_DAC_BUFFER_SIZE / 2; s++) { - if ((0 == active_tones_snapshot_length) && (OUTPUT_REACHED_ZERO_BEFORE_OFF == state)) { - state = OUTPUT_OFF; - } - if (OUTPUT_OFF == state) { + if (OUTPUT_OFF <= state) { sample_p[s] = AUDIO_DAC_OFF_VALUE; continue; } else { sample_p[s] = dac_value_generate(); } - // zero crossing (or approach, whereas zero == DAC_OFF_VALUE, which can be configured to anything from 0 to DAC_SAMPLE_MAX) + /* zero crossing (or approach, whereas zero == DAC_OFF_VALUE, which can be configured to anything from 0 to DAC_SAMPLE_MAX) + * ============================*=*========================== AUDIO_DAC_SAMPLE_MAX + * * * + * * * + * --------------------------------------------------------- + * * * } AUDIO_DAC_SAMPLE_MAX/100 + * --------------------------------------------------------- AUDIO_DAC_OFF_VALUE + * * * } AUDIO_DAC_SAMPLE_MAX/100 + * --------------------------------------------------------- + * * + * * * + * * * + * =====*=*================================================= 0x0 + */ if (((sample_p[s] + (AUDIO_DAC_SAMPLE_MAX / 100)) > AUDIO_DAC_OFF_VALUE) && // value approaches from below (sample_p[s] < (AUDIO_DAC_OFF_VALUE + (AUDIO_DAC_SAMPLE_MAX / 100))) // or above ) { - if (OUTPUT_SHOULD_STOP == state) { - state = OUTPUT_REACHED_ZERO_BEFORE_OFF; + if (OUTPUT_SHOULD_START == state) { + state = OUTPUT_RUN_NORMALY; } else if (OUTPUT_TONES_CHANGED == state) { state = OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE; + } else if (OUTPUT_SHOULD_STOP == state) { + state = OUTPUT_REACHED_ZERO_BEFORE_OFF; } } - if ((OUTPUT_REACHED_ZERO_BEFORE_OFF == state) || (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state)) { - uint8_t active_tones = MIN(AUDIO_MAX_SIMULTANEOUS_TONES, audio_get_number_of_active_tones()); + // still 'ramping up', reset the output to OFF_VALUE until the generated values reach that value, to do a smooth handover + if (OUTPUT_SHOULD_START == state) { + sample_p[s] = AUDIO_DAC_OFF_VALUE; + } + if ((OUTPUT_SHOULD_START == state) || (OUTPUT_REACHED_ZERO_BEFORE_OFF == state) || (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state)) { + uint8_t active_tones = MIN(AUDIO_MAX_SIMULTANEOUS_TONES, audio_get_number_of_active_tones()); active_tones_snapshot_length = 0; // update the snapshot - once, and only on occasion that something changed; // -> saves cpu cycles (?) @@ -200,6 +219,9 @@ static void dac_end(DACDriver *dacp) { } } + if ((0 == active_tones_snapshot_length) && (OUTPUT_REACHED_ZERO_BEFORE_OFF == state)) { + state = OUTPUT_OFF; + } if (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state) { state = OUTPUT_RUN_NORMALY; } @@ -213,8 +235,14 @@ static void dac_end(DACDriver *dacp) { } } - if (OUTPUT_OFF == state) { - gptStopTimer(&GPTD6); + + if (OUTPUT_OFF <= state) { + if (OUTPUT_OFF_2 == state) { + // stopping timer6 = stopping the DAC at whatever value it is currently pushing to the output = AUDIO_DAC_OFF_VALUE + gptStopTimer(&GPTD6); + } else { + state++; + } } } @@ -282,12 +310,13 @@ void audio_driver_initialize() { #elif defined(AUDIO_PIN_A5) DACD2.params->dac->CR &= ~DAC_CR_BOFF2; #endif + + gptStart(&GPTD6, &gpt6cfg1); } void audio_driver_stop(void) { state = OUTPUT_SHOULD_STOP; } void audio_driver_start(void) { - gptStart(&GPTD6, &gpt6cfg1); gptStartContinuous(&GPTD6, 2U); for (uint8_t i = 0; i < AUDIO_MAX_SIMULTANEOUS_TONES; i++) { @@ -295,6 +324,5 @@ void audio_driver_start(void) { active_tones_snapshot[i] = 0.0f; } active_tones_snapshot_length = 0; - state = OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE; - // = have the first conversion update/populate the initial snapshot + state = OUTPUT_SHOULD_START; } From c8b643420cd13b11bfdcfc9f8b7a8b02ef2cc987 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 30 Apr 2020 17:27:17 +0200 Subject: [PATCH 105/153] audio-arm-dac: dac-additive: BUGFIX: return OFF_VALUE when a pause is playing fixes a bug during SONG playback, which suddenly stopped when it encoutnered a pause --- quantum/audio/driver_chibios_dac_additive.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index c117c34414f3..05d76875472b 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -99,7 +99,7 @@ typedef enum { OUTPUT_OFF_2, // trailing off: giving the DAC two more conversion cycles until the AUDIO_DAC_OFF_VALUE reaches the output, then turn the timer off, which leaves the output at that level number_of_output_states } output_states_t; -output_states_t state = OUTPUT_OFF; +output_states_t state = OUTPUT_OFF_2; /** * Generation of the waveform being passed to the callback. Declared weak so users @@ -107,6 +107,11 @@ output_states_t state = OUTPUT_OFF; */ __attribute__((weak)) uint16_t dac_value_generate(void) { + // DAC is running/asking for values but snapshot length is zero -> must be playing a pause + if (active_tones_snapshot_length == 0) { + return AUDIO_DAC_OFF_VALUE; + } + /* doing additive wave synthesis over all currently playing tones = adding up * sine-wave-samples for each frequency, scaled by the number of active tones */ @@ -193,7 +198,7 @@ static void dac_end(DACDriver *dacp) { if (((sample_p[s] + (AUDIO_DAC_SAMPLE_MAX / 100)) > AUDIO_DAC_OFF_VALUE) && // value approaches from below (sample_p[s] < (AUDIO_DAC_OFF_VALUE + (AUDIO_DAC_SAMPLE_MAX / 100))) // or above ) { - if (OUTPUT_SHOULD_START == state) { + if ((OUTPUT_SHOULD_START == state) && (active_tones_snapshot_length > 0)) { state = OUTPUT_RUN_NORMALY; } else if (OUTPUT_TONES_CHANGED == state) { state = OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE; From 25a7b82845d6d50963dff424664aaef774d98336 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 30 Apr 2020 17:27:23 +0200 Subject: [PATCH 106/153] audio-arm-dac: set a sensible default for AUDIO_DAC_VALUE_OFF 1/2 MAX was probably exemplary, can't think of a setup where that would make sense :-P --- quantum/audio/driver_chibios_dac.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/quantum/audio/driver_chibios_dac.h b/quantum/audio/driver_chibios_dac.h index 5d0aac18dfcb..b2a2f5a40eb5 100644 --- a/quantum/audio/driver_chibios_dac.h +++ b/quantum/audio/driver_chibios_dac.h @@ -100,9 +100,10 @@ /** * The default value of the DAC when not playing anything. Certain hardware * setups may require a high (AUDIO_DAC_SAMPLE_MAX) or low (0) value here. + * A value in between might also make sense (e.g. AUDIO_DAC_SAMPLE_MAX / 2 ). */ #ifndef AUDIO_DAC_OFF_VALUE -# define AUDIO_DAC_OFF_VALUE AUDIO_DAC_SAMPLE_MAX / 2 +# define AUDIO_DAC_OFF_VALUE 0 #endif #if AUDIO_DAC_OFF_VALUE > AUDIO_DAC_SAMPLE_MAX From 1daacefd74f574197837bcfe22711bbc8f7a3b81 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 30 Apr 2020 17:55:33 +0200 Subject: [PATCH 107/153] audio-arm-dac: update synth_sample/_wavetable for new pin-defines --- keyboards/planck/keymaps/synth_sample/config.h | 1 + keyboards/planck/keymaps/synth_sample/rules.mk | 1 - keyboards/planck/keymaps/synth_wavetable/config.h | 1 + keyboards/planck/keymaps/synth_wavetable/rules.mk | 1 - 4 files changed, 2 insertions(+), 2 deletions(-) diff --git a/keyboards/planck/keymaps/synth_sample/config.h b/keyboards/planck/keymaps/synth_sample/config.h index 6fa31cc8a76f..23687603560f 100644 --- a/keyboards/planck/keymaps/synth_sample/config.h +++ b/keyboards/planck/keymaps/synth_sample/config.h @@ -1,6 +1,7 @@ #pragma once #ifdef AUDIO_ENABLE + #define AUDIO_PIN_A5 #define STARTUP_SONG SONG(PLANCK_SOUND) // #define STARTUP_SONG SONG(NO_SOUND) diff --git a/keyboards/planck/keymaps/synth_sample/rules.mk b/keyboards/planck/keymaps/synth_sample/rules.mk index 56fb6bed2bf2..ebfcda221435 100644 --- a/keyboards/planck/keymaps/synth_sample/rules.mk +++ b/keyboards/planck/keymaps/synth_sample/rules.mk @@ -1,3 +1,2 @@ AUDIO_ENABLE = yes AUDIO_DRIVER = dac_additive -AUDIO_PIN = A5 diff --git a/keyboards/planck/keymaps/synth_wavetable/config.h b/keyboards/planck/keymaps/synth_wavetable/config.h index 6fa31cc8a76f..23687603560f 100644 --- a/keyboards/planck/keymaps/synth_wavetable/config.h +++ b/keyboards/planck/keymaps/synth_wavetable/config.h @@ -1,6 +1,7 @@ #pragma once #ifdef AUDIO_ENABLE + #define AUDIO_PIN_A5 #define STARTUP_SONG SONG(PLANCK_SOUND) // #define STARTUP_SONG SONG(NO_SOUND) diff --git a/keyboards/planck/keymaps/synth_wavetable/rules.mk b/keyboards/planck/keymaps/synth_wavetable/rules.mk index 56fb6bed2bf2..ebfcda221435 100644 --- a/keyboards/planck/keymaps/synth_wavetable/rules.mk +++ b/keyboards/planck/keymaps/synth_wavetable/rules.mk @@ -1,3 +1,2 @@ AUDIO_ENABLE = yes AUDIO_DRIVER = dac_additive -AUDIO_PIN = A5 From 6ed0a904277eb41944c3c4afb28fd4958c6d170a Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 30 Apr 2020 18:42:28 +0200 Subject: [PATCH 108/153] audio-arm-dac: default for AUDIO_DAC_VALUE_OFF turned out that zero or max are bad default choices: when multiple tones are played (>>5) and released at the same time (!), due to the complex waveform never reaching 'zero' the output can take quite a while to reach zero, and hence the zero-crossing code only "releases" the output waaay to late --- quantum/audio/driver_chibios_dac.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/quantum/audio/driver_chibios_dac.h b/quantum/audio/driver_chibios_dac.h index b2a2f5a40eb5..5ed47806c70c 100644 --- a/quantum/audio/driver_chibios_dac.h +++ b/quantum/audio/driver_chibios_dac.h @@ -100,10 +100,12 @@ /** * The default value of the DAC when not playing anything. Certain hardware * setups may require a high (AUDIO_DAC_SAMPLE_MAX) or low (0) value here. - * A value in between might also make sense (e.g. AUDIO_DAC_SAMPLE_MAX / 2 ). + * Since multiple added sine waves tend to oscillate around the midpoint, + * and possibly never/rarely reach either 0 of MAX, 1/2 MAX can be a + * reasonable default value. */ #ifndef AUDIO_DAC_OFF_VALUE -# define AUDIO_DAC_OFF_VALUE 0 +# define AUDIO_DAC_OFF_VALUE AUDIO_DAC_SAMPLE_MAX / 2 #endif #if AUDIO_DAC_OFF_VALUE > AUDIO_DAC_SAMPLE_MAX From 6d8a113b114d6bb1a3ab8709481324602468cfea Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 1 May 2020 05:18:29 +0200 Subject: [PATCH 109/153] audio-arm-dac: additive: use DAC for negative pin instead of PAL, which only allows the pin to be configured as output; LOW or HIGH --- quantum/audio/driver_chibios_dac_additive.c | 30 ++++++++++++--------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index 05d76875472b..a0a3655bd25e 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -282,23 +282,13 @@ static const DACConfig dac_conf = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_ static const DACConversionGroup dac_conv_cfg = {.num_channels = 1U, .end_cb = dac_end, .error_cb = dac_error, .trigger = DAC_TRG(0b000)}; void audio_driver_initialize() { -#if defined(AUDIO_PIN_A4) +#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) palSetLineMode(A4, PAL_MODE_INPUT_ANALOG); dacStart(&DACD1, &dac_conf); - dacStartConversion(&DACD1, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); -#elif defined(AUDIO_PIN_A5) +#endif +#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) palSetLineMode(A5, PAL_MODE_INPUT_ANALOG); dacStart(&DACD2, &dac_conf); - dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); -#endif - -// no inverted/out-of-phase waveform (yet?), only pulling AUDIO_PIN_ALT_x to ground -#if defined(AUDIO_PIN_ALT_A4) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) - palSetLineMode(A4, PAL_MODE_OUTPUT_PUSHPULL); - palClearLine(A4); -#elif defined(AUDIO_PIN_ALT_A5) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) - palSetLineMode(A5, PAL_MODE_OUTPUT_PUSHPULL); - palClearLine(A5); #endif /* enable the output buffer, to directly drive external loads with no additional circuitry @@ -316,6 +306,20 @@ void audio_driver_initialize() { DACD2.params->dac->CR &= ~DAC_CR_BOFF2; #endif + +#if defined(AUDIO_PIN_A4) + dacStartConversion(&DACD1, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); +#elif defined(AUDIO_PIN_A5) + dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); +#endif + + // no inverted/out-of-phase waveform (yet?), only pulling AUDIO_PIN_ALT_x to AUDIO_DAC_OFF_VALUE +#if defined(AUDIO_PIN_ALT_A4) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) + dacPutChannelX(&DACD1, 0, AUDIO_DAC_OFF_VALUE); +#elif defined(AUDIO_PIN_ALT_A5) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) + dacPutChannelX(&DACD2, 0, AUDIO_DAC_OFF_VALUE); +#endif + gptStart(&GPTD6, &gpt6cfg1); } From 3e613af262319deb74f6579267a6813bf55d5440 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 1 May 2020 05:20:16 +0200 Subject: [PATCH 110/153] audio-arm-dac: more compile-time configuration checks --- quantum/audio/driver_chibios_dac_additive.c | 3 +++ quantum/audio/driver_chibios_dac_basic.c | 19 +++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index a0a3655bd25e..60f9aa663130 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -37,6 +37,9 @@ #if defined(AUDIO_PIN_ALT_A4) && defined(AUDIO_PIN_ALT_A5) # error "Audio feature: please set either AUDIO_PIN_ALT_A4 or AUDIO_PIN_ALT_A5, not both." #endif +#if !defined(AUDIO_PIN_ALT_AS_NEGATIVE) && (defined (AUDIO_PIN_ALT_A4) || defined(AUDIO_PIN_ALT_A5)) +# pragma message "Audio feature: AUDIO_PIN_ALT_x set, but not AUDIO_PIN_ALT_AS_NEGATIVE - pin will be left unused; audio might still work though." +#endif #if !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID) diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index d1b037650e49..73502a534b6f 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -25,16 +25,27 @@ this driver can either be used to drive to separate speakers, wired to A4+Gnd and A5+Gnd, which allows two tones to be played simultaniously OR - one speaker wired to A4+A5 with hte AUDIO_PIN_ALT_AS_NEGATIVE define set - see docs/feature_audio + one speaker wired to A4+A5 with the AUDIO_PIN_ALT_AS_NEGATIVE define set - see docs/feature_audio -TODOS: -- channel_X_stop should respect dac conversion buffer-complete; currently the output might end up 'high' = halfway through a sample conversion */ -#if !defined(AUDIO_PIN_A4) && !defined(AUDIO_PIN_A5) && !defined(AUDIO_PIN_ALT_A4) && !defined(AUDIO_PIN_ALT_A5) +#if !defined(AUDIO_PIN_A4) && !defined(AUDIO_PIN_A5) # pragma message "Audio feature enabled, but no suitable pin selected as AUDIO_PIN_x or AUDIO_PIN_ALT_x - see docs/feature_audio under 'ARM (DAC basic)' for available options." // TODO: make this an 'error' instead; go through a breaking change, and add AUDIO_PIN_A5 to all keyboards currently using AUDIO on STM32 based boards? #endif +// check configuration for ONE speaker, connected to both DAC pins +#if defined (AUDIO_PIN_ALT_AS_NEGATIVE) +# if !defined(AUDIO_PIN_ALT_A4) && !defined(AUDIO_PIN_ALT_A5) +# error "Audio feature: AUDIO_PIN_ALT_AS_NEGATIVE set, but no pin configured as AUDIO_PIN_ALT_x." +# endif +# if defined (AUDIO_PIN_A4) && defined (AUDIO_PIN_A5) +# error "Audio feature: with AUDIO_PIN_ALT_AS_NEGATIVE, only one pin can be configured as AUDIO_PIN_x." +# endif +# if defined (AUDIO_PIN_ALT_A4) && defined (AUDIO_PIN_ALT_A5) +# error "Audio feature: with AUDIO_PIN_ALT_AS_NEGATIVE, only one pin can be configured as AUDIO_PIN_ALT_x." +# endif +#endif +// check configuration for TWO speaker setup #if defined(AUDIO_PIN_A4) && defined(AUDIO_PIN_ALT_A4) # error "Audio feature: please set either AUDIO_PIN_A4 or AUDIO_PIN_ALT_A4, not both." #endif From f1d9be100a153f4ae5385617be72d32524442492 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 1 May 2020 11:25:18 +0200 Subject: [PATCH 111/153] audio-refactoring: typo fixed --- quantum/audio/audio.h | 4 ++-- quantum/audio/driver_chibios_dac_additive.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index e852ccf1582d..48a458c4522a 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -100,7 +100,7 @@ bool audio_is_on(void); /** - * @bried start playback of a tone with the given frequency and duration + * @brief start playback of a tone with the given frequency and duration * * @details starts the playback of a given note, wich is automatically stopped * at the the end of its duration = fire&forget @@ -114,7 +114,7 @@ void audio_play_note(float pitch, uint16_t duration); // audio_play_note_with_instrument ifdef AUDIO_ENABLE_VOICES /** - * @bried start playback of a tone with the given frequency + * @brief start playback of a tone with the given frequency * * @details the 'frequency' is put ontop the internal stack of active tones, * as a new tone with indefinite duration. this tone is played by diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index 60f9aa663130..bf3e30911d67 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -90,7 +90,7 @@ static uint8_t active_tones_snapshot_length = 0; typedef enum { OUTPUT_SHOULD_START, - OUTPUT_RUN_NORMALY, + OUTPUT_RUN_NORMALLY, // path 1: wait for zero, then change/update active tones OUTPUT_TONES_CHANGED, OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE, @@ -202,7 +202,7 @@ static void dac_end(DACDriver *dacp) { (sample_p[s] < (AUDIO_DAC_OFF_VALUE + (AUDIO_DAC_SAMPLE_MAX / 100))) // or above ) { if ((OUTPUT_SHOULD_START == state) && (active_tones_snapshot_length > 0)) { - state = OUTPUT_RUN_NORMALY; + state = OUTPUT_RUN_NORMALLY; } else if (OUTPUT_TONES_CHANGED == state) { state = OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE; } else if (OUTPUT_SHOULD_STOP == state) { @@ -231,7 +231,7 @@ static void dac_end(DACDriver *dacp) { state = OUTPUT_OFF; } if (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state) { - state = OUTPUT_RUN_NORMALY; + state = OUTPUT_RUN_NORMALLY; } } } From 64d5833fa1d6b0a51ecd9e24932db5961eb55628 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 1 May 2020 11:27:37 +0200 Subject: [PATCH 112/153] audio-refactoring: clang-format on quantum/audio/* --- quantum/audio/audio.c | 145 ++++++++------------ quantum/audio/audio.h | 12 +- quantum/audio/driver_avr_pwm_hardware.c | 8 +- quantum/audio/driver_chibios_dac_additive.c | 18 +-- quantum/audio/driver_chibios_dac_basic.c | 15 +- quantum/audio/voices.c | 17 +-- quantum/audio/voices.h | 2 +- 7 files changed, 85 insertions(+), 132 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 8fe720ebc4df..98fbc584d12f 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -63,7 +63,7 @@ #ifndef AUDIO_TONE_STACKSIZE # define AUDIO_TONE_STACKSIZE 8 #endif -uint8_t active_tones = 0; // number of tones pushed onto the stack by audio_play_tone - might be more than the harware is able to reproduce at any single time +uint8_t active_tones = 0; // number of tones pushed onto the stack by audio_play_tone - might be more than the harware is able to reproduce at any single time musical_tone_t tones[AUDIO_TONE_STACKSIZE]; // stack of currently active tones bool playing_melody = false; // playing a SONG? @@ -71,21 +71,21 @@ bool playing_note = false; // or (possibly multiple simultaneous) tones bool state_changed = false; // global flag, which is set if anything changes with the active_tones // melody/SONG related state variables -float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs -uint16_t notes_count; // length of the notes_pointer array -bool notes_repeat; // PLAY_SONG or PLAY_LOOP? -uint16_t melody_current_note_duration = 0; // duration of the currently playing note from the active melody, in ms -uint8_t note_tempo = TEMPO_DEFAULT; // beats-per-minute -uint16_t current_note = 0; // index into the array at notes_pointer -bool note_resting = false; // if a short pause was introduced between two notes with the same frequency while playing a melody -uint16_t last_timestamp = 0; +float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs +uint16_t notes_count; // length of the notes_pointer array +bool notes_repeat; // PLAY_SONG or PLAY_LOOP? +uint16_t melody_current_note_duration = 0; // duration of the currently playing note from the active melody, in ms +uint8_t note_tempo = TEMPO_DEFAULT; // beats-per-minute +uint16_t current_note = 0; // index into the array at notes_pointer +bool note_resting = false; // if a short pause was introduced between two notes with the same frequency while playing a melody +uint16_t last_timestamp = 0; #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING # ifndef AUDIO_MAX_SIMULTANEOUS_TONES # define AUDIO_MAX_SIMULTANEOUS_TONES 3 # endif uint16_t tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT; -uint8_t tone_multiplexing_index_shift = 0; // offset used on active-tone array access +uint8_t tone_multiplexing_index_shift = 0; // offset used on active-tone array access #endif // proviced and used by voices.c @@ -94,7 +94,6 @@ extern bool glissando; extern bool vibrato; extern uint16_t voices_timer; - #ifndef STARTUP_SONG # define STARTUP_SONG SONG(STARTUP_SOUND) #endif @@ -131,11 +130,7 @@ void audio_init() { #endif // EEPROM settings for (uint8_t i = 0; i < AUDIO_TONE_STACKSIZE; i++) { - tones[i] = (musical_tone_t){ - .time_started = 0, - .pitch = -1.0f, - .duration = 0 - }; + tones[i] = (musical_tone_t){.time_started = 0, .pitch = -1.0f, .duration = 0}; } if (!audio_initialized) { @@ -196,11 +191,7 @@ void audio_stop_all() { melody_current_note_duration = 0; for (uint8_t i = 0; i < AUDIO_TONE_STACKSIZE; i++) { - tones[i] = (musical_tone_t){ - .time_started = 0, - .pitch = -1.0f, - .duration = 0 - }; + tones[i] = (musical_tone_t){.time_started = 0, .pitch = -1.0f, .duration = 0}; } audio_driver_stopped = true; @@ -219,18 +210,10 @@ void audio_stop_tone(float pitch) { for (int i = AUDIO_TONE_STACKSIZE - 1; i >= 0; i--) { found = (tones[i].pitch == pitch); if (found) { - tones[i] = (musical_tone_t){ - .time_started = 0, - .pitch = -1.0f, - .duration = 0 - }; + tones[i] = (musical_tone_t){.time_started = 0, .pitch = -1.0f, .duration = 0}; for (int j = i; (j < AUDIO_TONE_STACKSIZE - 1); j++) { tones[j] = tones[j + 1]; - tones[j + 1] = (musical_tone_t){ - .time_started = 0, - .pitch = -1.0f, - .duration = 0 - }; + tones[j + 1] = (musical_tone_t){.time_started = 0, .pitch = -1.0f, .duration = 0}; } break; } @@ -250,7 +233,7 @@ void audio_stop_tone(float pitch) { if (active_tones == 0) { audio_driver_stop(); audio_driver_stopped = true; - playing_note = false; + playing_note = false; } } } @@ -276,13 +259,9 @@ void audio_play_note(float pitch, uint16_t duration) { if (found) { for (int j = i; (j < active_tones - 1); j++) { tones[j] = tones[j + 1]; - tones[j + 1] = (musical_tone_t){ - .time_started = timer_read(), - .pitch = pitch, - .duration = duration - }; + tones[j + 1] = (musical_tone_t){.time_started = timer_read(), .pitch = pitch, .duration = duration}; } - return; // since this frequency played already, the hardware was already started + return; // since this frequency played already, the hardware was already started } } @@ -295,16 +274,12 @@ void audio_play_note(float pitch, uint16_t duration) { tones[i] = tones[i + 1]; } } - state_changed = true; - playing_note = true; - tones[active_tones - 1] = (musical_tone_t){ - .time_started = timer_read(), - .pitch = pitch, - .duration = duration - }; + state_changed = true; + playing_note = true; + tones[active_tones - 1] = (musical_tone_t){.time_started = timer_read(), .pitch = pitch, .duration = duration}; - //TODO: needs to be handled per note/tone -> use its timestamp instead? - voices_timer = timer_read(); // reset to zero, for the effects added by voices.c + // TODO: needs to be handled per note/tone -> use its timestamp instead? + voices_timer = timer_read(); // reset to zero, for the effects added by voices.c if (audio_driver_stopped) { audio_driver_start(); @@ -312,9 +287,7 @@ void audio_play_note(float pitch, uint16_t duration) { } } -void audio_play_tone(float pitch) { - audio_play_note(pitch, 0xffff); -} +void audio_play_tone(float pitch) { audio_play_note(pitch, 0xffff); } void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) { if (!audio_config.enable) { @@ -340,10 +313,9 @@ void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) { // start first note manually, which also starts the audio_driver // all following/remaining notes are played by 'audio_update_state' - audio_play_note((*notes_pointer)[current_note][0], audio_duration_to_ms ((*notes_pointer)[current_note][1]) -); - last_timestamp = timer_read(); - melody_current_note_duration = audio_duration_to_ms ((*notes_pointer)[current_note][1]); + audio_play_note((*notes_pointer)[current_note][0], audio_duration_to_ms((*notes_pointer)[current_note][1])); + last_timestamp = timer_read(); + melody_current_note_duration = audio_duration_to_ms((*notes_pointer)[current_note][1]); } float click[2][2]; @@ -382,7 +354,6 @@ float audio_get_frequency(uint8_t tone_index) { } float audio_get_processed_frequency(uint8_t tone_index) { - if (tone_index >= active_tones) { return 0.0f; } @@ -400,47 +371,44 @@ float audio_get_processed_frequency(uint8_t tone_index) { return 0.0f; } -/* - // TODO make it work and test, currently probably non-functional because it needs some state to keep track of previous tones, the current tone position ...? - if (glissando) { // see voices.c - if (frequency != 0 && frequency < frequencies[index] && frequency < frequencies[index] * pow(2, -440 / frequencies[index] / 12 / 2)) { - frequency = frequency * pow(2, 440 / frequency / 12 / 2); - } else if (frequency != 0 && frequency > frequencies[index] && frequency > frequencies[index] * pow(2, 440 / frequencies[index] / 12 / 2)) { - frequency = frequency * pow(2, -440 / frequency / 12 / 2); + /* + // TODO make it work and test, currently probably non-functional because it needs some state to keep track of previous tones, the current tone position ...? + if (glissando) { // see voices.c + if (frequency != 0 && frequency < frequencies[index] && frequency < frequencies[index] * pow(2, -440 / frequencies[index] / 12 / 2)) { + frequency = frequency * pow(2, 440 / frequency / 12 / 2); + } else if (frequency != 0 && frequency > frequencies[index] && frequency > frequencies[index] * pow(2, 440 / frequencies[index] / 12 / 2)) { + frequency = frequency * pow(2, -440 / frequency / 12 / 2); + } else { + frequency = frequencies[index]; + } } else { frequency = frequencies[index]; } - } else { - frequency = frequencies[index]; - } - frequency = voice_envelope(frequency); + frequency = voice_envelope(frequency); - return frequency; -*/ + return frequency; + */ return voice_envelope(tones[index].pitch); } bool audio_update_state(void) { - if (!playing_note && !playing_melody) { return false; } - bool goto_next_note = false; - uint16_t current_time = timer_read(); + bool goto_next_note = false; + uint16_t current_time = timer_read(); if (playing_melody) { - goto_next_note = timer_elapsed(last_timestamp) >= melody_current_note_duration; if (goto_next_note) { - - uint16_t delta = timer_elapsed(last_timestamp) - melody_current_note_duration; - last_timestamp = current_time; + uint16_t delta = timer_elapsed(last_timestamp) - melody_current_note_duration; + last_timestamp = current_time; uint16_t previous_note = current_note; current_note++; - voices_timer = timer_read(); // reset to zero, for the effects added by voices.c + voices_timer = timer_read(); // reset to zero, for the effects added by voices.c if (current_note >= notes_count) { if (notes_repeat) { @@ -457,13 +425,13 @@ bool audio_update_state(void) { // special handling for successive notes of the same frequency: // insert a short pause to separate them audibly audio_play_note(0.0f, audio_duration_to_ms(2)); - current_note = previous_note; + current_note = previous_note; melody_current_note_duration = audio_duration_to_ms(2); } else { note_resting = false; - //TODO: handle glissando here (or remember previous and current tone) + // TODO: handle glissando here (or remember previous and current tone) // '- delta': Skip forward in the next note's length if we'vv over shot // the last, so the overall length of the song is the same @@ -476,10 +444,8 @@ bool audio_update_state(void) { if (playing_note) { #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING - tone_multiplexing_index_shift = - (int)(current_time / tone_multiplexing_rate) - % MIN(AUDIO_MAX_SIMULTANEOUS_TONES, active_tones); - goto_next_note = true; + tone_multiplexing_index_shift = (int)(current_time / tone_multiplexing_rate) % MIN(AUDIO_MAX_SIMULTANEOUS_TONES, active_tones); + goto_next_note = true; #endif if (vibrato || glissando) { // force update on each cycle, since vibrato shifts the frequency slightly @@ -487,12 +453,12 @@ bool audio_update_state(void) { } // housekeeping: stop notes that have no playtime left - for (int i=0; i < active_tones; i++) { - if ((tones[i].duration != 0xffff) // indefinetly playing notes, started by 'audio_play_tone' - && (tones[i].duration != 0) // 'uninitialized' - ) { + for (int i = 0; i < active_tones; i++) { + if ((tones[i].duration != 0xffff) // indefinetly playing notes, started by 'audio_play_tone' + && (tones[i].duration != 0) // 'uninitialized' + ) { if (timer_elapsed(tones[i].time_started) >= tones[i].duration) { - audio_stop_tone(tones[i].pitch); // also sets 'state_changed=true' + audio_stop_tone(tones[i].pitch); // also sets 'state_changed=true' } } } @@ -507,7 +473,6 @@ bool audio_update_state(void) { return goto_next_note; } - // Tone-multiplexing functions #ifdef AUDIO_ENABLE_TONE_MULTIPLEXING void audio_set_tone_multiplexing_rate(uint16_t rate) { tone_multiplexing_rate = rate; } @@ -525,7 +490,6 @@ void audio_decrease_tone_multiplexing_rate(uint16_t change) { } #endif - // Tempo functions void audio_set_tempo(uint8_t tempo) { @@ -550,7 +514,6 @@ void audio_decrease_tempo(uint8_t tempo_change) { note_tempo -= tempo_change; } - // TODO in the int-math version are some bugs; songs sometimes abruptly end - maybe an issue with the timer/sysrtem-tick wrapping around? uint16_t audio_duration_to_ms(uint16_t duration_bpm) { #if defined(__AVR__) @@ -558,7 +521,7 @@ uint16_t audio_duration_to_ms(uint16_t duration_bpm) { return ((uint32_t)duration_bpm * 60 * 1000) / (64 * note_tempo); // NOTE: beware of uint16_t overflows when note_tempo is low and/or the duration is long #else - return ((float)duration_bpm * 60 ) / (64 * note_tempo) * 1000; + return ((float)duration_bpm * 60) / (64 * note_tempo) * 1000; #endif } uint16_t audio_ms_to_duration(uint16_t duration_ms) { diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 48a458c4522a..e8771795b1df 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -58,11 +58,11 @@ typedef union { * "A musical tone is characterized by its duration, pitch, intensity (or loudness), and timbre (or quality)" */ typedef struct { - uint16_t time_started; // timestamp the tone/note was started, systemtime runs with 1ms resolution -> 16bit timer overflows every ~64 seconds, long enough under normal circumstances; but might be too soon for long-duration notes when the note_tempo is set to a very low value - float pitch; // aka frequency, in Hz - uint16_t duration; // in ms, converted from the musical_notes.h unit which has 64parts to a beat, factoring in the current tempo in beats-per-minute - //float intensity; // aka volume [0,1] TODO: not used at the moment; pwm drivers can't handle it - //uint8_t timbre; // range: [0,100] TODO: this currently kept track of globally, should we do this per tone instead? + uint16_t time_started; // timestamp the tone/note was started, systemtime runs with 1ms resolution -> 16bit timer overflows every ~64 seconds, long enough under normal circumstances; but might be too soon for long-duration notes when the note_tempo is set to a very low value + float pitch; // aka frequency, in Hz + uint16_t duration; // in ms, converted from the musical_notes.h unit which has 64parts to a beat, factoring in the current tempo in beats-per-minute + // float intensity; // aka volume [0,1] TODO: not used at the moment; pwm drivers can't handle it + // uint8_t timbre; // range: [0,100] TODO: this currently kept track of globally, should we do this per tone instead? } musical_tone_t; // ____ __ ___ @@ -98,7 +98,6 @@ void audio_off(void); */ bool audio_is_on(void); - /** * @brief start playback of a tone with the given frequency and duration * @@ -198,7 +197,6 @@ bool audio_is_playing_melody(void); */ #define PLAY_LOOP(note_array) audio_play_melody(¬e_array, NOTE_ARRAY_SIZE((note_array)), true) - // Tone-Multiplexing functions // this feature only makes sense for hardware setups which can't do proper // audio-wave synthesis = have no DAC and need to use PWM for tone generation diff --git a/quantum/audio/driver_avr_pwm_hardware.c b/quantum/audio/driver_avr_pwm_hardware.c index 844e08a36205..cdaba5eab463 100644 --- a/quantum/audio/driver_avr_pwm_hardware.c +++ b/quantum/audio/driver_avr_pwm_hardware.c @@ -22,8 +22,8 @@ #include "audio.h" -extern bool playing_note; -extern bool playing_melody; +extern bool playing_note; +extern bool playing_melody; extern uint8_t note_timbre; #define CPU_PRESCALER 8 @@ -148,7 +148,7 @@ void channel_1_set_frequency(float freq) { // set pwm period AUDIO1_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); // and duty cycle - AUDIO1_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre/100); + AUDIO1_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre / 100); } void channel_1_start(void) { @@ -179,7 +179,7 @@ void channel_2_set_frequency(float freq) { channel_2_frequency = freq; AUDIO2_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); - AUDIO2_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre/100); + AUDIO2_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre / 100); } float channel_2_get_frequency(void) { return channel_2_frequency; } diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index bf3e30911d67..3bd256467517 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -37,11 +37,10 @@ #if defined(AUDIO_PIN_ALT_A4) && defined(AUDIO_PIN_ALT_A5) # error "Audio feature: please set either AUDIO_PIN_ALT_A4 or AUDIO_PIN_ALT_A5, not both." #endif -#if !defined(AUDIO_PIN_ALT_AS_NEGATIVE) && (defined (AUDIO_PIN_ALT_A4) || defined(AUDIO_PIN_ALT_A5)) +#if !defined(AUDIO_PIN_ALT_AS_NEGATIVE) && (defined(AUDIO_PIN_ALT_A4) || defined(AUDIO_PIN_ALT_A5)) # pragma message "Audio feature: AUDIO_PIN_ALT_x set, but not AUDIO_PIN_ALT_AS_NEGATIVE - pin will be left unused; audio might still work though." #endif - #if !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID) # define AUDIO_DAC_SAMPLE_WAVEFORM_SINE #endif @@ -99,7 +98,7 @@ typedef enum { OUTPUT_REACHED_ZERO_BEFORE_OFF, OUTPUT_OFF, OUTPUT_OFF_1, - OUTPUT_OFF_2, // trailing off: giving the DAC two more conversion cycles until the AUDIO_DAC_OFF_VALUE reaches the output, then turn the timer off, which leaves the output at that level + OUTPUT_OFF_2, // trailing off: giving the DAC two more conversion cycles until the AUDIO_DAC_OFF_VALUE reaches the output, then turn the timer off, which leaves the output at that level number_of_output_states } output_states_t; output_states_t state = OUTPUT_OFF_2; @@ -109,7 +108,6 @@ output_states_t state = OUTPUT_OFF_2; * can override it with their own waveforms/noises. */ __attribute__((weak)) uint16_t dac_value_generate(void) { - // DAC is running/asking for values but snapshot length is zero -> must be playing a pause if (active_tones_snapshot_length == 0) { return AUDIO_DAC_OFF_VALUE; @@ -118,7 +116,7 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { /* doing additive wave synthesis over all currently playing tones = adding up * sine-wave-samples for each frequency, scaled by the number of active tones */ - uint16_t value = 0; + uint16_t value = 0; float frequency = 0.0f; for (uint8_t i = 0; i < active_tones_snapshot_length; i++) { @@ -198,9 +196,9 @@ static void dac_end(DACDriver *dacp) { * * * * =====*=*================================================= 0x0 */ - if (((sample_p[s] + (AUDIO_DAC_SAMPLE_MAX / 100)) > AUDIO_DAC_OFF_VALUE) && // value approaches from below - (sample_p[s] < (AUDIO_DAC_OFF_VALUE + (AUDIO_DAC_SAMPLE_MAX / 100))) // or above - ) { + if (((sample_p[s] + (AUDIO_DAC_SAMPLE_MAX / 100)) > AUDIO_DAC_OFF_VALUE) && // value approaches from below + (sample_p[s] < (AUDIO_DAC_OFF_VALUE + (AUDIO_DAC_SAMPLE_MAX / 100))) // or above + ) { if ((OUTPUT_SHOULD_START == state) && (active_tones_snapshot_length > 0)) { state = OUTPUT_RUN_NORMALLY; } else if (OUTPUT_TONES_CHANGED == state) { @@ -216,7 +214,7 @@ static void dac_end(DACDriver *dacp) { } if ((OUTPUT_SHOULD_START == state) || (OUTPUT_REACHED_ZERO_BEFORE_OFF == state) || (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state)) { - uint8_t active_tones = MIN(AUDIO_MAX_SIMULTANEOUS_TONES, audio_get_number_of_active_tones()); + uint8_t active_tones = MIN(AUDIO_MAX_SIMULTANEOUS_TONES, audio_get_number_of_active_tones()); active_tones_snapshot_length = 0; // update the snapshot - once, and only on occasion that something changed; // -> saves cpu cycles (?) @@ -243,7 +241,6 @@ static void dac_end(DACDriver *dacp) { } } - if (OUTPUT_OFF <= state) { if (OUTPUT_OFF_2 == state) { // stopping timer6 = stopping the DAC at whatever value it is currently pushing to the output = AUDIO_DAC_OFF_VALUE @@ -309,7 +306,6 @@ void audio_driver_initialize() { DACD2.params->dac->CR &= ~DAC_CR_BOFF2; #endif - #if defined(AUDIO_PIN_A4) dacStartConversion(&DACD1, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); #elif defined(AUDIO_PIN_A5) diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index 73502a534b6f..f3bd6f6348e2 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -34,14 +34,14 @@ // TODO: make this an 'error' instead; go through a breaking change, and add AUDIO_PIN_A5 to all keyboards currently using AUDIO on STM32 based boards? #endif // check configuration for ONE speaker, connected to both DAC pins -#if defined (AUDIO_PIN_ALT_AS_NEGATIVE) +#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) # if !defined(AUDIO_PIN_ALT_A4) && !defined(AUDIO_PIN_ALT_A5) # error "Audio feature: AUDIO_PIN_ALT_AS_NEGATIVE set, but no pin configured as AUDIO_PIN_ALT_x." # endif -# if defined (AUDIO_PIN_A4) && defined (AUDIO_PIN_A5) +# if defined(AUDIO_PIN_A4) && defined(AUDIO_PIN_A5) # error "Audio feature: with AUDIO_PIN_ALT_AS_NEGATIVE, only one pin can be configured as AUDIO_PIN_x." # endif -# if defined (AUDIO_PIN_ALT_A4) && defined (AUDIO_PIN_ALT_A5) +# if defined(AUDIO_PIN_ALT_A4) && defined(AUDIO_PIN_ALT_A5) # error "Audio feature: with AUDIO_PIN_ALT_AS_NEGATIVE, only one pin can be configured as AUDIO_PIN_ALT_x." # endif #endif @@ -53,7 +53,6 @@ # error "Audio feature: please set either AUDIO_PIN_A5 or AUDIO_PIN_ALT_A5, not both." #endif - #if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) // squarewave static const dacsample_t dac_buffer_1[AUDIO_DAC_BUFFER_SIZE] = { @@ -168,9 +167,9 @@ static void gpt_cb8(GPTDriver *gptp) { // one piezo/speaker connected to both audio pins, the generated squarewaves are inverted channel_1_set_frequency(audio_get_processed_frequency(0)); channel_2_set_frequency(audio_get_processed_frequency(0)); -#else // two separate audio outputs/speakers - // primary speaker on A4, optional secondary on A5 -#if defined(AUDIO_PIN_A4) +#else // two separate audio outputs/speakers + // primary speaker on A4, optional secondary on A5 +# if defined(AUDIO_PIN_A4) channel_1_set_frequency(audio_get_processed_frequency(0)); # if defined(AUDIO_PIN_ALT_A5) if (audio_get_number_of_active_tones() > 1) { @@ -182,7 +181,7 @@ static void gpt_cb8(GPTDriver *gptp) { # endif // primary speaker on A5, optional secondary on A4 -#if defined(AUDIO_PIN_A5) +# if defined(AUDIO_PIN_A5) channel_2_set_frequency(audio_get_processed_frequency(0)); # if defined(AUDIO_PIN_ALT_A4) if (audio_get_number_of_active_tones() > 1) { diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 43562b15d428..8a9f5fbc2192 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -18,10 +18,10 @@ #include uint8_t note_timbre = TIMBRE_DEFAULT; -bool glissando = false; -bool vibrato = false; -float vibrato_strength = 0.5; -float vibrato_rate = 0.125; +bool glissando = false; +bool vibrato = false; +float vibrato_strength = 0.5; +float vibrato_rate = 0.125; uint16_t voices_timer = 0; @@ -37,7 +37,6 @@ void voice_iterate() { voice = (voice + 1) % number_of_voices; } void voice_deiterate() { voice = (voice - 1 + number_of_voices) % number_of_voices; } - #ifdef AUDIO_VOICES float mod(float a, int b) { float r = fmod(a, b); @@ -51,13 +50,12 @@ float voice_add_vibrato(float average_freq) { } #endif - float voice_envelope(float frequency) { // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz // __attribute__((unused)) uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency)); #ifdef AUDIO_VOICES - uint16_t envelope_index = timer_elapsed(voices_timer); //TODO: multiply in some factor? - uint16_t compensated_index = envelope_index / 100; // TODO: correct factor would be? + uint16_t envelope_index = timer_elapsed(voices_timer); // TODO: multiply in some factor? + uint16_t compensated_index = envelope_index / 100; // TODO: correct factor would be? #endif switch (voice) { @@ -250,7 +248,7 @@ float voice_envelope(float frequency) { case 0 ... VOICE_VIBRATO_DELAY: break; default: - //TODO: merge/replace with voice_add_vibrato above + // TODO: merge/replace with voice_add_vibrato above frequency = frequency * vibrato_lut[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1)) / 1000 * VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)]; break; } @@ -305,7 +303,6 @@ float voice_envelope(float frequency) { return frequency; } - // Vibrato functions void voice_set_vibrato_rate(float rate) { vibrato_rate = rate; } diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h index f7668e6b5b4c..52892e61fbc1 100644 --- a/quantum/audio/voices.h +++ b/quantum/audio/voices.h @@ -27,7 +27,7 @@ float voice_envelope(float frequency); typedef enum { default_voice, -# ifdef AUDIO_VOICES +#ifdef AUDIO_VOICES vibrating, something, drums, From 34755187e5add931f30d6db2563fcdcf89f7d4a3 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 1 May 2020 14:50:04 +0200 Subject: [PATCH 113/153] audio-avr-pwm: add defines for B-pin as primary/only speaker also updates documentation. --- docs/feature_audio.md | 7 ++++++- quantum/audio/driver_avr_pwm_hardware.c | 22 ++++++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index fc8d8c9c09d9..4e5e65dbb0e1 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -5,7 +5,7 @@ Your keyboard can make sounds! If you've got a spare pin you can hook up a simpl To activate this feature, add `AUDIO_ENABLE = yes` to your `rules.mk`. ## AVR based boards -Up to two simultaneous tones can be rendered. with one speaker driven by timer 1 and another driven by timer 3. The following pins can be configured as audio outputs in `config.h`: +On Atmega32U4 based boards, up to two simultaneous tones can be rendered, with one speaker driven by timer 1 and another driven by timer 3. The following pins can be configured as audio outputs in `config.h`: for the primary speaker, with Timer 3, pick ONE these pins: `#define AUDIO_PIN_C4` @@ -17,6 +17,11 @@ and *optionally*, a secondary speaker, using Timer 1, on ONE of these pins: `#define AUDIO_PIN_ALT_B6` `#define AUDIO_PIN_ALT_B7` +another alternative is to configure only one primary speaker, which is connected to one of the pwm capable PORTB pins. `config.h` would then include ONE of these defines: +`#define AUDIO_PIN_B5` +`#define AUDIO_PIN_B6` +`#define AUDIO_PIN_B7` + ### Wiring per speaker is - for example with a piezo buzzer - the black lead to Ground, and the red lead connected to the selected AUDIO_PIN_X for the primary; and similarly with AUDIO_PIN_ALT_X for the secondary. diff --git a/quantum/audio/driver_avr_pwm_hardware.c b/quantum/audio/driver_avr_pwm_hardware.c index cdaba5eab463..baa16637374e 100644 --- a/quantum/audio/driver_avr_pwm_hardware.c +++ b/quantum/audio/driver_avr_pwm_hardware.c @@ -31,11 +31,12 @@ extern uint8_t note_timbre; /* Audio Driver: PWM - drive up to two speakers, with the primary channel_1 on either pin PC4 PC5 or PC6 (the later beeing used by most AVR based keyboards) with a PMW signal generated by timer3 in hardware + drive up to two speakers through the AVR PWM hardware-peripheral, using timer1 and/or timer3 on Atmega32U4. + the primary channel_1 can be connected to either pin PC4 PC5 or PC6 (the later beeing used by most AVR based keyboards) with a PMW signal generated by timer3 and an optional secondary channel_2 on either pin PB5, PB6 or PB7, with a PWM signal from timer1 - in a pinch with only one of the PB pins available as speaker output, they can be used as the primary channel too - by only setting the AUDIO_PIN_ALT_Bx define, and *none* of the AUDIO_PIN_Cx defines + alternatively, the PWM pins on PORTB can be used as only/primary speaker */ #if (defined(AUDIO_PIN_C4) && defined(AUDIO_PIN_C5)) || (defined(AUDIO_PIN_C5) && defined(AUDIO_PIN_C6)) || (defined(AUDIO_PIN_C4) && defined(AUDIO_PIN_C6)) || (defined(AUDIO_PIN_C4) && defined(AUDIO_PIN_C5) && defined(AUDIO_PIN_C6)) @@ -80,11 +81,20 @@ extern uint8_t note_timbre; # endif #endif +// not super necessary, but for the sake of consistency with other drivers +#if (defined(AUDIO1_PIN_SET) && (defined(AUDIO_PIN_B5) || defined(AUDIO_PIN_B6) || defined(AUDIO_PIN_B7))) +# error "Audio feature: with AUDIO_PIN_Cx set up as primary, please configure the secondary output as AUDIO_PIN_ALT_Bx instead of AUDIO_PIN_Bx." +#endif + +#if (defined(AUDIO_PIN_B5) && defined(AUDIO_PIN_B6)) || (defined(AUDIO_PIN_B6) && defined(AUDIO_PIN_B7)) || (defined(AUDIO_PIN_B5) && defined(AUDIO_PIN_B7)) || (defined(AUDIO_PIN_B5) && defined(AUDIO_PIN_B6) && defined(AUDIO_PIN_B7)) +# error "Audio feature: please set only one AUDIO_PIN_Bx." +#endif + #if (defined(AUDIO_PIN_ALT_B5) && defined(AUDIO_PIN_ALT_B6)) || (defined(AUDIO_PIN_ALT_B6) && defined(AUDIO_PIN_ALT_B7)) || (defined(AUDIO_PIN_ALT_B5) && defined(AUDIO_PIN_ALT_B7)) || (defined(AUDIO_PIN_ALT_B5) && defined(AUDIO_PIN_ALT_B6) && defined(AUDIO_PIN_ALT_B7)) # error "Audio feature: please set only one AUDIO_PIN_ALT_Bx." #endif -#if defined(AUDIO_PIN_ALT_B5) || defined(AUDIO_PIN_ALT_B6) || defined(AUDIO_PIN_ALT_B7) +#if defined(AUDIO_PIN_B5) || defined(AUDIO_PIN_B6) || defined(AUDIO_PIN_B7) || defined(AUDIO_PIN_ALT_B5) || defined(AUDIO_PIN_ALT_B6) || defined(AUDIO_PIN_ALT_B7) # define AUDIO2_PIN_SET # define AUDIO2_TIMSKx TIMSK1 # define AUDIO2_TCCRxA TCCR1A @@ -98,21 +108,21 @@ extern uint8_t note_timbre; # define AUDIO2_CSx1 CS11 # define AUDIO2_CSx2 CS12 -# if defined(AUDIO_PIN_ALT_B5) +# if defined(AUDIO_PIN_B5) || defined(AUDIO_PIN_ALT_B5) # define AUDIO2_COMxy0 COM1A0 # define AUDIO2_COMxy1 COM1A1 # define AUDIO2_OCIExy OCIE1A # define AUDIO2_OCRxy OCR1A # define AUDIO2_PIN B5 # define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPA_vect -# elif defined(AUDIO_PIN_ALT_B6) +# elif defined(AUDIO_PIN_B6) || defined(AUDIO_PIN_ALT_B6) # define AUDIO2_COMxy0 COM1B0 # define AUDIO2_COMxy1 COM1B1 # define AUDIO2_OCIExy OCIE1B # define AUDIO2_OCRxy OCR1B # define AUDIO2_PIN B6 # define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPB_vect -# elif defined(AUDIO_PIN_ALT_B7) +# elif defined(AUDIO_PIN_B7) || defined(AUDIO_PIN_ALT_B7) # define AUDIO2_COMxy0 COM1C0 # define AUDIO2_COMxy1 COM1C1 # define AUDIO2_OCIExy OCIE1C From 31f27fdfe3545009ea82a2b7f71fe85da04457bf Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 1 May 2020 15:02:45 +0200 Subject: [PATCH 114/153] audio-refactoring: update documentation with proton-c config.h example --- docs/feature_audio.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 4e5e65dbb0e1..5b659c5b84fe 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -44,6 +44,13 @@ for two piezos, for example configured as `AUDIO_PIN_A4` and `AUDIO_PIN_ALT_A5` another alternative is to drive *one* piezo with both DAC pins - for an extra "push". wiring red to A4 and black to A5 (or the other way round) and add `#define AUDIO_PIN_ALT_AS_NEGATIVE` to `config.h` +##### Proton-C Example: +The Proton-C comes (optionally) with one 'builtin' piezo, which is wired to A4+A5. +For this board `config.h` would include these defines: +`#define AUDIO_PIN_A5` +`#define AUDIO_PIN_ALT_A4` +`#define AUDIO_PIN_ALT_AS_NEGATIVE` + ### DAC (additive) Another option, besides dac_basic (which produces sound through a squarewave), is to use the DAC to do additive wave synthesis. From 2876ebd4dacb57c676fe396bd0abf4e70dd2c0e5 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 1 May 2020 16:22:29 +0200 Subject: [PATCH 115/153] audio-refactoring: move glissando (TODO) to voices.c refactored/saved from the original glissando implementation in then upstream-master:audio_avr.c still needs some work though, as it is now the calculation *should* work, but the start-frequency needs to be tracked somewhere/somehow; not only during a SONG playback but also with user input? --- quantum/audio/audio.c | 27 ++++++++------------------- quantum/audio/voices.c | 27 +++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 98fbc584d12f..260e60d754a0 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -371,25 +371,6 @@ float audio_get_processed_frequency(uint8_t tone_index) { return 0.0f; } - /* - // TODO make it work and test, currently probably non-functional because it needs some state to keep track of previous tones, the current tone position ...? - if (glissando) { // see voices.c - if (frequency != 0 && frequency < frequencies[index] && frequency < frequencies[index] * pow(2, -440 / frequencies[index] / 12 / 2)) { - frequency = frequency * pow(2, 440 / frequency / 12 / 2); - } else if (frequency != 0 && frequency > frequencies[index] && frequency > frequencies[index] * pow(2, 440 / frequencies[index] / 12 / 2)) { - frequency = frequency * pow(2, -440 / frequency / 12 / 2); - } else { - frequency = frequencies[index]; - } - } else { - frequency = frequencies[index]; - } - - frequency = voice_envelope(frequency); - - return frequency; - */ - return voice_envelope(tones[index].pitch); } @@ -432,6 +413,14 @@ bool audio_update_state(void) { note_resting = false; // TODO: handle glissando here (or remember previous and current tone) + /* there would need to be a freq(here we are) -> freq(next note) + * and do slide/glissando inbetween problem here is to know which + * frequency on the stack relates to what other? e.g. a melody starts + * tones in a sequence, and stops expiring one, so the most recently + * stopped is the starting point for a glissando to the most recently started? + * how to detect and preserve this relation? + * and what about user input, chords, ...? + */ // '- delta': Skip forward in the next note's length if we'vv over shot // the last, so the overall length of the song is the same diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 8a9f5fbc2192..4999402b0f25 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -43,11 +43,23 @@ float mod(float a, int b) { return r < 0 ? r + b : r; } +// Effect: 'vibrate' a given target frequency slightly above/below its initial value float voice_add_vibrato(float average_freq) { float vibrato_counter = mod(timer_read() / (100 * vibrato_rate), VIBRATO_LUT_LENGTH); return average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); } + +// Effect: 'slides' the 'frequency' from the starting-point, to the target frequency +float voice_add_glissando(float from_freq, float to_freq) { + if (to_freq != 0 && from_freq < to_freq && from_freq < to_freq * pow(2, -440 / to_freq / 12 / 2)) { + return from_freq * pow(2, 440 / from_freq / 12 / 2); + } else if (to_freq != 0 && from_freq > to_freq && from_freq > to_freq * pow(2, 440 / to_freq / 12 / 2)) { + return from_freq * pow(2, -440 / from_freq / 12 / 2); + } else { + return to_freq; + } +} #endif float voice_envelope(float frequency) { @@ -69,10 +81,6 @@ float voice_envelope(float frequency) { case vibrating: glissando = false; vibrato = true; - - if (vibrato_strength > 0) { - frequency = voice_add_vibrato(frequency); - } break; case something: @@ -300,6 +308,17 @@ float voice_envelope(float frequency) { break; } +#ifdef AUDIO_VOICES + if (vibrato && (vibrato_strength > 0)) { + frequency = voice_add_vibrato(frequency); + } + + if (glissando) { + // TODO: where to keep track of the start-frequency? + // frequency = voice_add_glissando(??, frequency); + } +#endif // AUDIO_VOICES + return frequency; } From 01550956494a6e084d8aa28feec73cee9424852b Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 2 May 2020 05:55:16 +0200 Subject: [PATCH 116/153] audio-refactoring: cleanup: one round of aspell -c --- docs/feature_audio.md | 6 ++--- quantum/audio/audio.c | 22 ++++++++-------- quantum/audio/audio.h | 28 ++++++++++----------- quantum/audio/driver_avr_pwm_hardware.c | 4 +-- quantum/audio/driver_chibios_dac.h | 12 ++++----- quantum/audio/driver_chibios_dac_additive.c | 8 +++--- quantum/audio/driver_chibios_dac_basic.c | 8 +++--- quantum/audio/driver_chibios_pwm.h | 4 +-- quantum/audio/driver_chibios_pwm_hardware.c | 10 ++++---- quantum/audio/driver_chibios_pwm_software.c | 10 ++++---- 10 files changed, 56 insertions(+), 56 deletions(-) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 5b659c5b84fe..62222210512e 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -53,8 +53,8 @@ For this board `config.h` would include these defines: ### DAC (additive) -Another option, besides dac_basic (which produces sound through a squarewave), is to use the DAC to do additive wave synthesis. -With a number of predefined waveforms or by providing your own implementation to generate samples on the fly. +Another option, besides dac_basic (which produces sound through a square-wave), is to use the DAC to do additive wave synthesis. +With a number of predefined wave-forms or by providing your own implementation to generate samples on the fly. To use this feature set `AUDIO_DRIVER = dac_additive` in your `rules.mk`, and select in `config.h` EITHER `#define AUDIO_PIN_A4` or `#define AUDIO_PIN_A5`. The used waveform defaults to a sine, but can be selected by adding one of the following defines to `config.h`: @@ -88,7 +88,7 @@ STM32F1xx have to fall back to using PWM, but can do so in hardware; but again o `#define AUDIO_PWM_TIMERCHANNEL 1` (as well as `#define AUDIO_PWM_PINALTERNATE_FUNCTION 42` if you are on STM32F2 or larger) which will use Timer 1 to directly drive pin PA8 through the PWM hardware (TIM1_CH1 = PA8). -Should you want to use the pwm-hardware on another pin and timer - be ready to dig into the STM32 datasheet to pick the right TIMx_CHy and pin-alternate function. +Should you want to use the pwm-hardware on another pin and timer - be ready to dig into the STM32 data-sheet to pick the right TIMx_CHy and pin-alternate function. ## Songs diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 260e60d754a0..0beb56482509 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -36,7 +36,7 @@ * * * A Note on terminology: - * tone, pitch and frequency are used somewhat interchangeably, in a strict wikipedia-sense: + * tone, pitch and frequency are used somewhat interchangeably, in a strict Wikipedia-sense: * "(Musical) tone, a sound characterized by its duration, pitch (=frequency), * intensity (=volume), and timbre" * - intensity/volume is currently not handled at all, although the 'dac_additive' driver could do so @@ -48,12 +48,12 @@ * kept track of in 'audio_update_state' * * 'voice' as it is used here, equates to a sort of instrument with its own - * charactersitic sound and effects + * characteristics sound and effects * the audio system as-is deals only with (possibly multiple) tones of one * instrument/voice at a time (think: chords). since the number of tones that * can be reproduced depends on the hardware/driver in use: pwm can only * reproduce one tone per output/speaker; DACs can reproduce/mix multiple - * when doing additive synthese. + * when doing additive synthesis. * * 'duration' can either be in the beats-per-minute related unit found in * musical_notes.h, OR in ms; keyboards create SONGs with the former, while @@ -63,7 +63,7 @@ #ifndef AUDIO_TONE_STACKSIZE # define AUDIO_TONE_STACKSIZE 8 #endif -uint8_t active_tones = 0; // number of tones pushed onto the stack by audio_play_tone - might be more than the harware is able to reproduce at any single time +uint8_t active_tones = 0; // number of tones pushed onto the stack by audio_play_tone - might be more than the hardware is able to reproduce at any single time musical_tone_t tones[AUDIO_TONE_STACKSIZE]; // stack of currently active tones bool playing_melody = false; // playing a SONG? @@ -88,7 +88,7 @@ uint16_t tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT; uint8_t tone_multiplexing_index_shift = 0; // offset used on active-tone array access #endif -// proviced and used by voices.c +// provided and used by voices.c extern uint8_t note_timbre; extern bool glissando; extern bool vibrato; @@ -251,7 +251,7 @@ void audio_play_note(float pitch, uint16_t duration) { pitch = -1 * pitch; } - // roundrobin: shifting out old tones, keeping only unique ones + // round-robin: shifting out old tones, keeping only unique ones // if the new frequency is already amongst the active tones, shift it to the top of the stack bool found = false; for (int i = active_tones - 1; i >= 0; i--) { @@ -414,7 +414,7 @@ bool audio_update_state(void) { // TODO: handle glissando here (or remember previous and current tone) /* there would need to be a freq(here we are) -> freq(next note) - * and do slide/glissando inbetween problem here is to know which + * and do slide/glissando in between problem here is to know which * frequency on the stack relates to what other? e.g. a melody starts * tones in a sequence, and stops expiring one, so the most recently * stopped is the starting point for a glissando to the most recently started? @@ -422,7 +422,7 @@ bool audio_update_state(void) { * and what about user input, chords, ...? */ - // '- delta': Skip forward in the next note's length if we'vv over shot + // '- delta': Skip forward in the next note's length if we've over shot // the last, so the overall length of the song is the same uint16_t duration = audio_duration_to_ms((*notes_pointer)[current_note][1]) - delta; audio_play_note((*notes_pointer)[current_note][0], duration); @@ -443,7 +443,7 @@ bool audio_update_state(void) { // housekeeping: stop notes that have no playtime left for (int i = 0; i < active_tones; i++) { - if ((tones[i].duration != 0xffff) // indefinetly playing notes, started by 'audio_play_tone' + if ((tones[i].duration != 0xffff) // indefinitely playing notes, started by 'audio_play_tone' && (tones[i].duration != 0) // 'uninitialized' ) { if (timer_elapsed(tones[i].time_started) >= tones[i].duration) { @@ -503,10 +503,10 @@ void audio_decrease_tempo(uint8_t tempo_change) { note_tempo -= tempo_change; } -// TODO in the int-math version are some bugs; songs sometimes abruptly end - maybe an issue with the timer/sysrtem-tick wrapping around? +// TODO in the int-math version are some bugs; songs sometimes abruptly end - maybe an issue with the timer/system-tick wrapping around? uint16_t audio_duration_to_ms(uint16_t duration_bpm) { #if defined(__AVR__) - // doing int-math saves us some bytes in the overall firmware size, but the intermediate result is less accurate before beeing cast to/returned as uint + // doing int-math saves us some bytes in the overall firmware size, but the intermediate result is less accurate before being cast to/returned as uint return ((uint32_t)duration_bpm * 60 * 1000) / (64 * note_tempo); // NOTE: beware of uint16_t overflows when note_tempo is low and/or the duration is long #else diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index e8771795b1df..3dbf4d0259a7 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -58,7 +58,7 @@ typedef union { * "A musical tone is characterized by its duration, pitch, intensity (or loudness), and timbre (or quality)" */ typedef struct { - uint16_t time_started; // timestamp the tone/note was started, systemtime runs with 1ms resolution -> 16bit timer overflows every ~64 seconds, long enough under normal circumstances; but might be too soon for long-duration notes when the note_tempo is set to a very low value + uint16_t time_started; // timestamp the tone/note was started, system time runs with 1ms resolution -> 16bit timer overflows every ~64 seconds, long enough under normal circumstances; but might be too soon for long-duration notes when the note_tempo is set to a very low value float pitch; // aka frequency, in Hz uint16_t duration; // in ms, converted from the musical_notes.h unit which has 64parts to a beat, factoring in the current tempo in beats-per-minute // float intensity; // aka volume [0,1] TODO: not used at the moment; pwm drivers can't handle it @@ -86,11 +86,11 @@ void audio_startup(void); */ void audio_toggle(void); /** - * @brief ensable audio output, save this choice to the eeprom + * @brief enable audio output, save this choice to the eeprom */ void audio_on(void); /** - * @brief dissable audio output, save this choice to the eeprom + * @brief disable audio output, save this choice to the eeprom */ void audio_off(void); /** @@ -101,7 +101,7 @@ bool audio_is_on(void); /** * @brief start playback of a tone with the given frequency and duration * - * @details starts the playback of a given note, wich is automatically stopped + * @details starts the playback of a given note, which is automatically stopped * at the the end of its duration = fire&forget * * @param[in] pitch frequency of the tone be played @@ -115,7 +115,7 @@ void audio_play_note(float pitch, uint16_t duration); /** * @brief start playback of a tone with the given frequency * - * @details the 'frequency' is put ontop the internal stack of active tones, + * @details the 'frequency' is put on-top the internal stack of active tones, * as a new tone with indefinite duration. this tone is played by * the hardware until a call to 'audio_stop_tone'. * should a tone with that frequency already be active, its entry @@ -133,9 +133,9 @@ void audio_play_tone(float pitch); * @details removes a tone matching the given frequency from the internal * playback stack * the hardware is stopped in case this was the last/only frequency - * beeing played. + * being played. * - * @param[in] pitch tone/frequenct to be stopped + * @param[in] pitch tone/frequency to be stopped */ void audio_stop_tone(float pitch); @@ -158,7 +158,7 @@ void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat); * audio_play_melody. very short durations might not quite work due to * hardware limitations (DAC: added pulses from zero-crossing feature;...) * - * @param[in] delay in milliseconds, lenght for the pause before the pulses, can be zero + * @param[in] delay in milliseconds, length for the pause before the pulses, can be zero * @param[in] pitch * @param[in] duration in milliseconds, length of the 'click' */ @@ -167,7 +167,7 @@ void audio_play_click(uint16_t delay, float pitch, uint16_t duration); /** * @brief stops all playback * - * @details stops playback of both a meldoy as well as single tones, resetting + * @details stops playback of both a melody as well as single tones, resetting * the internal state */ void audio_stop_all(void); @@ -246,7 +246,7 @@ uint8_t audio_get_number_of_active_tones(void); * the internal state keeps track of, and is usually influenced * by various effects * @param[in] tone_index, ranging from 0 to number_of_active_tones-1, with the - * first beeing the most recent and each increment yielding the next + * first being the most recent and each increment yielding the next * older one * @return a positive frequency, in Hz; or zero if the tone is a pause */ @@ -254,11 +254,11 @@ float audio_get_frequency(uint8_t tone_index); /** * @brief calculate and return the frequency for the requested tone - * @details effects like glissando, vibrato, ... are postprocessed onto the + * @details effects like glissando, vibrato, ... are post-processed onto the * each active tones 'base'-frequency; this function returns the - * postprocessed result. + * post-processed result. * @param[in] tone_index, ranging from 0 to number_of_active_tones-1, with the - * first beeing the most recent and each increment yielding the next + * first being the most recent and each increment yielding the next * older one * @return a positive frequency, in Hz; or zero if the tone is a pause */ @@ -282,7 +282,7 @@ bool audio_update_state(void); // / /___/ __/ /_/ / /_/ / /__/ /_/ / // /_____/\___/\__, /\__,_/\___/\__, / // /____/ /____/ -// legacy and backwarts compatibility stuff +// legacy and back-warts compatibility stuff #define PLAY_NOTE_ARRAY(note_array, note_repeat, deprecated_arg) \ audio_play_melody(¬e_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat)); \ diff --git a/quantum/audio/driver_avr_pwm_hardware.c b/quantum/audio/driver_avr_pwm_hardware.c index baa16637374e..fb2ad0572a16 100644 --- a/quantum/audio/driver_avr_pwm_hardware.c +++ b/quantum/audio/driver_avr_pwm_hardware.c @@ -33,7 +33,7 @@ extern uint8_t note_timbre; drive up to two speakers through the AVR PWM hardware-peripheral, using timer1 and/or timer3 on Atmega32U4. - the primary channel_1 can be connected to either pin PC4 PC5 or PC6 (the later beeing used by most AVR based keyboards) with a PMW signal generated by timer3 + the primary channel_1 can be connected to either pin PC4 PC5 or PC6 (the later being used by most AVR based keyboards) with a PMW signal generated by timer3 and an optional secondary channel_2 on either pin PB5, PB6 or PB7, with a PWM signal from timer1 alternatively, the PWM pins on PORTB can be used as only/primary speaker @@ -146,7 +146,7 @@ void channel_1_set_frequency(float freq) { { // disable the output, but keep the pwm-ISR going (with the previous // frequency) so the audio-state keeps getting updated - // Note: setting the duty-cycle 0 is not possible on non-inverting PWM mode - see the AVR datasheet + // Note: setting the duty-cycle 0 is not possible on non-inverting PWM mode - see the AVR data-sheet AUDIO1_TCCRxA &= ~(_BV(AUDIO1_COMxy1) | _BV(AUDIO1_COMxy0)); return; } else { diff --git a/quantum/audio/driver_chibios_dac.h b/quantum/audio/driver_chibios_dac.h index 5ed47806c70c..14c9a90000e3 100644 --- a/quantum/audio/driver_chibios_dac.h +++ b/quantum/audio/driver_chibios_dac.h @@ -26,7 +26,7 @@ * since the DAC is limited to 12 bit, the absolute max is 0xfff = 4095U; * lower values adjust the peak-voltage aka volume down. * adjusting this value has only an effect on a sample-buffer whose values are - * are NOT pregenerated - see squarewave + * are NOT pregenerated - see square-wave */ #ifndef AUDIO_DAC_SAMPLE_MAX # define AUDIO_DAC_SAMPLE_MAX 4095U @@ -41,9 +41,9 @@ * the DAC. The sample rate and maximum number of simultaneous tones roughly * has an inverse relationship - slightly higher sample rates may be possible. * - * NOTE: a high samplerate results in a higher cpu-load, which might lead to + * NOTE: a high sample-rate results in a higher cpu-load, which might lead to * (audible) discontinuities and/or starve other processes of cpu-time - * (like RGB-led backlighting, ...) + * (like RGB-led back-lighting, ...) */ #ifdef AUDIO_DAC_QUALITY_VERY_LOW # define AUDIO_DAC_SAMPLE_RATE 11025U @@ -66,10 +66,10 @@ #endif #ifdef AUDIO_DAC_QUALITY_SANE_MINIMUM -/* a sane-minimum config: with a tradeoff between cpu-load and tone-range +/* a sane-minimum config: with a trade-off between cpu-load and tone-range * * the (currently) highest defined note is NOTE_B8 with 7902Hz; if we now - * aim for an even even multiple of the buffersize, we end up with: + * aim for an even even multiple of the buffer-size, we end up with: * ( roundUptoPow2(highest note / AUDIO_DAC_BUFFER_SIZE) * nyquist-rate * AUDIO_DAC_BUFFER_SIZE) * 7902/256 = 30.867 * 2 * 256 ~= 16384 * which works out (but the 'scope shows some sampling artifacts with lower harmonics :-P) @@ -79,7 +79,7 @@ #endif /** - * Effective bitrate of the DAC. 44.1khz is the standard for most audio - any + * Effective bit-rate of the DAC. 44.1khz is the standard for most audio - any * lower will sacrifice perceptible audio quality. Any higher will limit the * number of simultaneous tones. In most situations, a tenth (1/10) of the * sample rate is where notes become unbearable. diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index 3bd256467517..8fc5ed0d06de 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -23,7 +23,7 @@ which utilizes the dac unit many STM32 are equipped with, to output a modulated waveform from samples stored in the dac_buffer_* array who are passed to the hardware through DMA - it ia also possible to have a custom sample-LUT by implementing/overriding 'dac_value_generate' + it is also possible to have a custom sample-LUT by implementing/overriding 'dac_value_generate' this driver allows for multiple simultaneous tones to be played through one single channel by doing additive wave-synthesis */ @@ -105,7 +105,7 @@ output_states_t state = OUTPUT_OFF_2; /** * Generation of the waveform being passed to the callback. Declared weak so users - * can override it with their own waveforms/noises. + * can override it with their own wave-forms/noises. */ __attribute__((weak)) uint16_t dac_value_generate(void) { // DAC is running/asking for values but snapshot length is zero -> must be playing a pause @@ -151,10 +151,10 @@ __attribute__((weak)) uint16_t dac_value_generate(void) { value += dac_buffer_triangle[dac_i] / active_tones_snapshot_length / 3; // SQUARE value += dac_buffer_square[dac_i] / active_tones_snapshot_length / 3; - //NOTE: combination of these three waveforms is more exemplary - and doesn't sound particularly good :-P + //NOTE: combination of these three wave-forms is more exemplary - and doesn't sound particularly good :-P */ - // STAIRS (mostly usefull as test-pattern) + // STAIRS (mostly usefully as test-pattern) // value_avg = dac_buffer_staircase[dac_i] / active_tones_snapshot_length; } diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index f3bd6f6348e2..50d257080765 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -23,7 +23,7 @@ which utilizes both channels of the DAC unit many STM32 are equipped with to output a modulated square-wave, from precomputed samples stored in a buffer, which is passed to the hardware through DMA - this driver can either be used to drive to separate speakers, wired to A4+Gnd and A5+Gnd, which allows two tones to be played simultaniously + this driver can either be used to drive to separate speakers, wired to A4+Gnd and A5+Gnd, which allows two tones to be played simultaneously OR one speaker wired to A4+A5 with the AUDIO_PIN_ALT_AS_NEGATIVE define set - see docs/feature_audio @@ -54,7 +54,7 @@ #endif #if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) -// squarewave +// square-wave static const dacsample_t dac_buffer_1[AUDIO_DAC_BUFFER_SIZE] = { // First half is max, second half is 0 [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1] = AUDIO_DAC_SAMPLE_MAX, @@ -62,7 +62,7 @@ static const dacsample_t dac_buffer_1[AUDIO_DAC_BUFFER_SIZE] = { }; #endif #if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) -// squarewave +// square-wave static const dacsample_t dac_buffer_2[AUDIO_DAC_BUFFER_SIZE] = { // opposite of dac_buffer above [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1] = 0, @@ -164,7 +164,7 @@ float channel_2_get_frequency(void) { return channel_2_frequency; } static void gpt_cb8(GPTDriver *gptp) { if (audio_update_state()) { #if (defined(AUDIO_PIN_A4) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT_A5)) || (defined(AUDIO_PIN_A5) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT_A4)) - // one piezo/speaker connected to both audio pins, the generated squarewaves are inverted + // one piezo/speaker connected to both audio pins, the generated square-waves are inverted channel_1_set_frequency(audio_get_processed_frequency(0)); channel_2_set_frequency(audio_get_processed_frequency(0)); #else // two separate audio outputs/speakers diff --git a/quantum/audio/driver_chibios_pwm.h b/quantum/audio/driver_chibios_pwm.h index 56fec0d20c47..4ffea7d20afe 100644 --- a/quantum/audio/driver_chibios_pwm.h +++ b/quantum/audio/driver_chibios_pwm.h @@ -21,13 +21,13 @@ #endif #if !defined(AUDIO_PWM_TIMERCHANNEL) -// NOTE: sticking to the STM datasheet numbering: TIMxCH1 to TIMxCH4 +// NOTE: sticking to the STM data-sheet numbering: TIMxCH1 to TIMxCH4 // default: STM32F303CC PA8+TIM1_CH1 -> 1 # define AUDIO_PWM_TIMERCHANNEL 1 #endif #if !defined(AUDIO_PWM_PINALTERNATE_FUNCTION) -// pin-alternate function: see the datasheet for which pin needs what AF to connect to TIMx_CHy +// pin-alternate function: see the data-sheet for which pin needs what AF to connect to TIMx_CHy // default: STM32F303CC PA8+TIM1_CH1 -> 6 # define AUDIO_PWM_PINALTERNATE_FUNCTION 6 #endif diff --git a/quantum/audio/driver_chibios_pwm_hardware.c b/quantum/audio/driver_chibios_pwm_hardware.c index 33a85596e7b3..c33d1b330bbb 100644 --- a/quantum/audio/driver_chibios_pwm_hardware.c +++ b/quantum/audio/driver_chibios_pwm_hardware.c @@ -19,8 +19,8 @@ Audio Driver: PWM the duty-cycle is always kept at 50%, and the pwm-period is adjusted to match the frequency of a note to be played back. -this driver uses the chibios-PWM system to produce a squarewave on specific output pins that are connected to the PWM hardware. -The hardware directly toggles the pin via its alternate function. see your MCUs datasheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function. +this driver uses the chibios-PWM system to produce a square-wave on specific output pins that are connected to the PWM hardware. +The hardware directly toggles the pin via its alternate function. see your MCUs data-sheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function. */ @@ -36,7 +36,7 @@ mcuconf.h: used pin: PA8 (alternate0: TIM1_CH1) -from the datasheet for STM32F103C8: alternate function of pin +from the data-sheet for STM32F103C8: alternate function of pin TIM1_CH1 = PA8 <- TIM1_CH2 = PA9 TIM1_CH3 = PA10 @@ -67,7 +67,7 @@ extern uint8_t note_timbre; static PWMConfig pwmCFG = { .frequency = 100000, /* PWM clock frequency */ - // CHIBIOS-BUG? can't set the initial period to <2, or the pwm (hard or software) takes ~130ms with .frequency=500000 for a pwmChangePeriod to take effect; with no ouput=silence in the meantime + // CHIBIOS-BUG? can't set the initial period to <2, or the pwm (hard or software) takes ~130ms with .frequency=500000 for a pwmChangePeriod to take effect; with no output=silence in the meantime .period = 2, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ .callback = NULL, /* no callback, the hardware directly toggles the pin */ .channels = @@ -125,7 +125,7 @@ GPTConfig gptCFG = { the longest note is BREAVE_DOT=128+64=192, the shortest SIXTEENTH=4 the tempo (which might vary!) is in bpm (beats per minute) therefore: if the timer ticks away at .frequency = (60*64)Hz, - and the .intervall counts from 64 downwards - audio_update_state is + and the .interval counts from 64 downwards - audio_update_state is called just often enough to not miss any notes */ .frequency = 60 * 64, diff --git a/quantum/audio/driver_chibios_pwm_software.c b/quantum/audio/driver_chibios_pwm_software.c index 73e9eb4f587e..358327be61f3 100644 --- a/quantum/audio/driver_chibios_pwm_software.c +++ b/quantum/audio/driver_chibios_pwm_software.c @@ -19,7 +19,7 @@ Audio Driver: PWM the duty-cycle is always kept at 50%, and the pwm-period is adjusted to match the frequency of a note to be played back. -this driver uses the chibios-PWM system to produce a squarewave on any given output pin in software +this driver uses the chibios-PWM system to produce a square-wave on any given output pin in software - a pwm callback is used to set/clear the configured pin. */ @@ -45,7 +45,7 @@ static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp); static PWMConfig pwmCFG = { .frequency = 100000, /* PWM clock frequency */ - // CHIBIOS-BUG? can't set the initial period to <2, or the pwm (hard or software) takes ~130ms with .frequency=500000 for a pwmChangePeriod to take effect; with no ouput=silence in the meantime + // CHIBIOS-BUG? can't set the initial period to <2, or the pwm (hard or software) takes ~130ms with .frequency=500000 for a pwmChangePeriod to take effect; with no output=silence in the meantime .period = 2, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ .callback = pwm_audio_period_callback, .channels = @@ -93,7 +93,7 @@ void channel_1_stop(void) { #endif } -// generate a PWM signal on any pin, not neccessarily the one connected to the timer +// generate a PWM signal on any pin, not necessarily the one connected to the timer static void pwm_audio_period_callback(PWMDriver *pwmp) { (void)pwmp; palClearLine(AUDIO_PIN); @@ -105,7 +105,7 @@ static void pwm_audio_period_callback(PWMDriver *pwmp) { static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { (void)pwmp; if (channel_1_frequency > 0) { - palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not neccessarily the one connected to the timer + palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not necessarily the one connected to the timer #if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) palClearLine(AUDIO_PIN_ALT); #endif @@ -118,7 +118,7 @@ GPTConfig gptCFG = { the longest note is BREAVE_DOT=128+64=192, the shortest SIXTEENTH=4 the tempo (which might vary!) is in bpm (beats per minute) therefore: if the timer ticks away at .frequency = (60*64)Hz, - and the .intervall counts from 64 downwards - audio_update_state is + and the .interval counts from 64 downwards - audio_update_state is called just often enough to not miss anything */ .frequency = 60 * 64, From 90184f6ef92d042863ccfa0eb4fc415b4153cea3 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 2 May 2020 19:20:55 +0200 Subject: [PATCH 117/153] audio-avr-pwm: back to AUDIO_PIN since config_common.h expands them to plain integers, the AUDIO_PIN define can directly be compared to e.g. B5 so there is no need to deal with separate defines like AUDIO_PIN_B5 --- docs/feature_audio.md | 35 ++++++++++++------------- quantum/audio/driver_avr_pwm_hardware.c | 33 +++++++++++------------ 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 62222210512e..c4e0be4306e1 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -5,25 +5,24 @@ Your keyboard can make sounds! If you've got a spare pin you can hook up a simpl To activate this feature, add `AUDIO_ENABLE = yes` to your `rules.mk`. ## AVR based boards -On Atmega32U4 based boards, up to two simultaneous tones can be rendered, with one speaker driven by timer 1 and another driven by timer 3. The following pins can be configured as audio outputs in `config.h`: - -for the primary speaker, with Timer 3, pick ONE these pins: -`#define AUDIO_PIN_C4` -`#define AUDIO_PIN_C5` -`#define AUDIO_PIN_C6` - -and *optionally*, a secondary speaker, using Timer 1, on ONE of these pins: -`#define AUDIO_PIN_ALT_B5` -`#define AUDIO_PIN_ALT_B6` -`#define AUDIO_PIN_ALT_B7` - -another alternative is to configure only one primary speaker, which is connected to one of the pwm capable PORTB pins. `config.h` would then include ONE of these defines: -`#define AUDIO_PIN_B5` -`#define AUDIO_PIN_B6` -`#define AUDIO_PIN_B7` +On Atmega32U4 based boards, up to two simultaneous tones can be rendered. +With one speaker connected to a PWM capable pin on PORTC driven by timer 3 and the other on one of the PWM pins on PORTB driven by timer 1. + +The following pins can be configured as audio outputs in `config.h` - for one speaker set eiter one out of: +`#define AUDIO_PIN C4` +`#define AUDIO_PIN C5` +`#define AUDIO_PIN C6` +`#define AUDIO_PIN B5` +`#define AUDIO_PIN B6` +`#define AUDIO_PIN B7` + +and *optionally*, for a second speaker, one of: +`#define AUDIO_PIN_ALT B5` +`#define AUDIO_PIN_ALT B6` +`#define AUDIO_PIN_ALT B7` ### Wiring -per speaker is - for example with a piezo buzzer - the black lead to Ground, and the red lead connected to the selected AUDIO_PIN_X for the primary; and similarly with AUDIO_PIN_ALT_X for the secondary. +per speaker is - for example with a piezo buzzer - the black lead to Ground, and the red lead connected to the selected AUDIO_PIN for the primary; and similarly with AUDIO_PIN_ALT for the secondary. ## ARM based boards @@ -71,7 +70,7 @@ Note that there is currently only one speaker/pin supported. set in `rules.mk`: `AUDIO_DRIVER = pwm_software` and in `config.h` -`#define AUDIO_PIN C13` (can be any pin, NOTE the space in the define!) +`#define AUDIO_PIN C13` (can be any pin) to have the selected pin output a pwm signal, generated from a timer callback which toggles the pin in software. #### Wiring diff --git a/quantum/audio/driver_avr_pwm_hardware.c b/quantum/audio/driver_avr_pwm_hardware.c index fb2ad0572a16..a1fe60cde913 100644 --- a/quantum/audio/driver_avr_pwm_hardware.c +++ b/quantum/audio/driver_avr_pwm_hardware.c @@ -39,11 +39,11 @@ extern uint8_t note_timbre; alternatively, the PWM pins on PORTB can be used as only/primary speaker */ -#if (defined(AUDIO_PIN_C4) && defined(AUDIO_PIN_C5)) || (defined(AUDIO_PIN_C5) && defined(AUDIO_PIN_C6)) || (defined(AUDIO_PIN_C4) && defined(AUDIO_PIN_C6)) || (defined(AUDIO_PIN_C4) && defined(AUDIO_PIN_C5) && defined(AUDIO_PIN_C6)) -# error "Audio feature: please set only one AUDIO_PIN_Cx." +#if defined(AUDIO_PIN) && (AUDIO_PIN != C4) && (AUDIO_PIN != C5) && (AUDIO_PIN != C6) && (AUDIO_PIN != B5) && (AUDIO_PIN != B6) && (AUDIO_PIN != B7) +# error "Audio feature enabled, but no suitable pin selected as AUDIO_PIN - see docs/feature_audio under the AVR settings for available options." #endif -#if defined(AUDIO_PIN_C4) || defined(AUDIO_PIN_C5) || defined(AUDIO_PIN_C6) +#if (AUDIO_PIN == C4) || (AUDIO_PIN == C5) || (AUDIO_PIN == C6) # define AUDIO1_PIN_SET # define AUDIO1_TIMSKx TIMSK3 # define AUDIO1_TCCRxA TCCR3A @@ -57,21 +57,21 @@ extern uint8_t note_timbre; # define AUDIO1_CSx1 CS31 # define AUDIO1_CSx2 CS32 -# if defined(AUDIO_PIN_C6) +# if (AUDIO_PIN == C6) # define AUDIO1_COMxy0 COM3A0 # define AUDIO1_COMxy1 COM3A1 # define AUDIO1_OCIExy OCIE3A # define AUDIO1_OCRxy OCR3A # define AUDIO1_PIN C6 # define AUDIO1_TIMERx_COMPy_vect TIMER3_COMPA_vect -# elif defined(AUDIO_PIN_C5) +# elif (AUDIO_PIN == C5) # define AUDIO1_COMxy0 COM3B0 # define AUDIO1_COMxy1 COM3B1 # define AUDIO1_OCIExy OCIE3B # define AUDIO1_OCRxy OCR3B # define AUDIO1_PIN C5 # define AUDIO1_TIMERx_COMPy_vect TIMER3_COMPB_vect -# elif defined(AUDIO_PIN_C4) +# elif (AUDIO_PIN == C4) # define AUDIO1_COMxy0 COM3C0 # define AUDIO1_COMxy1 COM3C1 # define AUDIO1_OCIExy OCIE3C @@ -81,20 +81,19 @@ extern uint8_t note_timbre; # endif #endif -// not super necessary, but for the sake of consistency with other drivers -#if (defined(AUDIO1_PIN_SET) && (defined(AUDIO_PIN_B5) || defined(AUDIO_PIN_B6) || defined(AUDIO_PIN_B7))) -# error "Audio feature: with AUDIO_PIN_Cx set up as primary, please configure the secondary output as AUDIO_PIN_ALT_Bx instead of AUDIO_PIN_Bx." +#if defined(AUDIO_PIN) && defined(AUDIO_PIN_ALT) && (AUDIO_PIN == AUDIO_PIN_ALT) +# error "Audio feature: AUDIO_PIN and AUDIO_PIN_ALT on the same pin makes no sense." #endif -#if (defined(AUDIO_PIN_B5) && defined(AUDIO_PIN_B6)) || (defined(AUDIO_PIN_B6) && defined(AUDIO_PIN_B7)) || (defined(AUDIO_PIN_B5) && defined(AUDIO_PIN_B7)) || (defined(AUDIO_PIN_B5) && defined(AUDIO_PIN_B6) && defined(AUDIO_PIN_B7)) -# error "Audio feature: please set only one AUDIO_PIN_Bx." +#if ((AUDIO_PIN == B5) && ((AUDIO_PIN_ALT == B6) || (AUDIO_PIN_ALT == B7))) || ((AUDIO_PIN == B6) && ((AUDIO_PIN_ALT == B5) || (AUDIO_PIN_ALT == B7))) || ((AUDIO_PIN == B7) && ((AUDIO_PIN_ALT == B5) || (AUDIO_PIN_ALT == B6))) +# error "Audio feature: PORTB as AUDIO_PIN and AUDIO_PIN_ALT at the same time is not supported." #endif -#if (defined(AUDIO_PIN_ALT_B5) && defined(AUDIO_PIN_ALT_B6)) || (defined(AUDIO_PIN_ALT_B6) && defined(AUDIO_PIN_ALT_B7)) || (defined(AUDIO_PIN_ALT_B5) && defined(AUDIO_PIN_ALT_B7)) || (defined(AUDIO_PIN_ALT_B5) && defined(AUDIO_PIN_ALT_B6) && defined(AUDIO_PIN_ALT_B7)) -# error "Audio feature: please set only one AUDIO_PIN_ALT_Bx." +#if defined(AUDIO_PIN_ALT) && (AUDIO_PIN_ALT != B5) && (AUDIO_PIN_ALT != B6) && (AUDIO_PIN_ALT != B7) +# error "Audio feature: the pin selected as AUDIO_PIN_ALT is not supported." #endif -#if defined(AUDIO_PIN_B5) || defined(AUDIO_PIN_B6) || defined(AUDIO_PIN_B7) || defined(AUDIO_PIN_ALT_B5) || defined(AUDIO_PIN_ALT_B6) || defined(AUDIO_PIN_ALT_B7) +#if (AUDIO_PIN == B5) || (AUDIO_PIN == B6) || (AUDIO_PIN == B7) || (AUDIO_PIN_ALT == B5) || (AUDIO_PIN_ALT == B6) || (AUDIO_PIN_ALT == B7) # define AUDIO2_PIN_SET # define AUDIO2_TIMSKx TIMSK1 # define AUDIO2_TCCRxA TCCR1A @@ -108,21 +107,21 @@ extern uint8_t note_timbre; # define AUDIO2_CSx1 CS11 # define AUDIO2_CSx2 CS12 -# if defined(AUDIO_PIN_B5) || defined(AUDIO_PIN_ALT_B5) +# if (AUDIO_PIN == B5) || (AUDIO_PIN_ALT == B5) # define AUDIO2_COMxy0 COM1A0 # define AUDIO2_COMxy1 COM1A1 # define AUDIO2_OCIExy OCIE1A # define AUDIO2_OCRxy OCR1A # define AUDIO2_PIN B5 # define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPA_vect -# elif defined(AUDIO_PIN_B6) || defined(AUDIO_PIN_ALT_B6) +# elif (AUDIO_PIN == B6) || (AUDIO_PIN_ALT == B6) # define AUDIO2_COMxy0 COM1B0 # define AUDIO2_COMxy1 COM1B1 # define AUDIO2_OCIExy OCIE1B # define AUDIO2_OCRxy OCR1B # define AUDIO2_PIN B6 # define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPB_vect -# elif defined(AUDIO_PIN_B7) || defined(AUDIO_PIN_ALT_B7) +# elif (AUDIO_PIN == B7) || (AUDIO_PIN_ALT == B7) # define AUDIO2_COMxy0 COM1C0 # define AUDIO2_COMxy1 COM1C1 # define AUDIO2_OCIExy OCIE1C From a23ce2840e04c68791c0a399662534feca4fb946 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sun, 3 May 2020 17:30:55 +0200 Subject: [PATCH 118/153] audio-refactoring: add technical documentation audio_driver.md which moves some in-code documentation there --- docs/_summary.md | 1 + docs/audio_driver.md | 122 ++++++++++++++++++++ docs/feature_audio.md | 12 +- quantum/audio/driver_chibios_pwm_hardware.c | 24 ---- 4 files changed, 131 insertions(+), 28 deletions(-) create mode 100644 docs/audio_driver.md diff --git a/docs/_summary.md b/docs/_summary.md index 526caf926f1f..acbfcfaeda5a 100644 --- a/docs/_summary.md +++ b/docs/_summary.md @@ -133,6 +133,7 @@ * [Compatible Microcontrollers](compatible_microcontrollers.md) * [Drivers](hardware_drivers.md) * [ADC Driver](adc_driver.md) + * [Audio Driver](audio_driver.md) * [I2C Driver](i2c_driver.md) * [SPI Driver](spi_driver.md) * [WS2812 Driver](ws2812_driver.md) diff --git a/docs/audio_driver.md b/docs/audio_driver.md new file mode 100644 index 000000000000..ef09f83f610b --- /dev/null +++ b/docs/audio_driver.md @@ -0,0 +1,122 @@ +# Audio Driver + +The [Audio feature](feature_audio.md) breaks the hardware specifics out into separate, exchangeable driver units, with a common interface to the audio-"core" - which itself handles playing songs and notes while tracking their progress in an internal state, initializing/starting/stopping the driver as needed. + +Not all MCUs support every available driver, either the platform-support is not there (yet?) or the MCU simply does not have the required hardware peripheral. + + +## AVR + +Boards build around an Atmega32U4 can use two sets of PWM capable pins, each driving a separate speaker. +The possible configurations are: + +| | Timer3 | Timer1 | +| one speaker | C4,C5 or C6 | | +| one speaker | | B4, B5 or B7 | +| two speakers | C4,C5 or C6 | B4, B5 or B7 | + +Currently there is only one/default driver for AVR based boards, which is automatically configured to: +```make +AUDIO_DRIVER = pwm_hardware +``` + + +## ARM + +For Arm based boards, QMK depends on ChibiOS - hence any MCU supported by the later is likely usable, as long as certain hardware peripherals are available. + +Supported wiring configurations, with their ChibiOS/MCU peripheral requirement are listed below; +piezo speakers are marked with :one: for the first/primary and :two: for the secondary. + + | driver | GPTD6 | GPTD7 | GPTD8 | PWMD1 [^1] | + | | Tim6 | Tim7 | Tim8 | Tim1_Ch1 | + |--------------|----------------------------------|------------------------|-------|-----------------| + | dac_basic | A4+DACD1 = :one: | A5+DACD2 = :one: | state | | + | | A4+DACD1 = :one: + Gnd | A5+DACD2 = :two: + Gnd | state | | + | | A4+DACD1 = :two: + Gnd | A5+DACD2 = :one: + Gnd | state | | + | | A4+DACD1 = :one: + Gnd | | state | | + | | | A5+DACD2 = :one: + Gnd | state | | + | dac_additive | A4+DACD1 = :one: + Gnd | | | | + | | A5+DACD2 = :one: + Gnd | | | | + | | A4+DACD1 + A5+DACD2 = :one: [^2] | | | | + | pwm_software | state-update | | | any = :one: | + | pwm hardware | state-update | | | A8 = :one: [^3] | + + +[^1]: the routing and alternate functions for PWM differ sometimes between STM32 MCUs, if in doubt consult the data-sheet +[^2]: one piezo connected to A4 and A5, with AUDIO_PIN_ALT_AS_NEGATIVE set +[^3]: TIM1_CH1 = A8 on STM32F103C8, other combinations are possible, see Data-sheet. configured with: AUDIO_PWM_TIMER and AUDIO_PWM_TIMERCHANNEL + + + +### DAC basic + +The default driver for ARM boards, in absence of an overriding configuration. +This driver needs one Timer per enabled/used DAC channel, to trigger conversion; and a third timer to trigger state updates with the audio-core. + + +### DAC additive + +only needs one timer (GPTD6, Tim6) to trigger the DAC unit to do a conversion; the audio state updates are in turn triggered during the DAC callback. + + +### PWM hardware + +this driver uses the ChibiOS-PWM system to produce a square-wave on specific output pins that are connected to the PWM hardware. +The hardware directly toggles the pin via its alternate function. see your MCUs data-sheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function. + +a configuration example for the STM32F103C8 would be: +``` c +//halconf.h: +#define HAL_USE_PWM TRUE +#define HAL_USE_PAL TRUE +#define HAL_USE_GPT TRUE +``` + +``` c +// mcuconf.h: +#define STM32_PWM_USE_TIM1 TRUE +#define STM32_GPT_USE_TIM3 TRUE +``` + +If we now target pin A8, looking trough the data-sheet of the STM32F103C8, for the timers and alternate functions +TIM1_CH1 = PA8 <- alternate0 +TIM1_CH2 = PA9 +TIM1_CH3 = PA10 +TIM1_CH4 = PA11 + +with all this information, the configuration would contain these lines: +``` c +//config.h: +#define AUDIO_PIN A8 +#define AUDIO_PWM_TIMER 1 +#define AUDIO_PWM_TIMERCHANNEL 1 +``` + +ChibiOS uses GPIOv1 for the F103, which only knows of one alternate function. +On 'larger' STM32s, GPIOv2 or GPIOv3 are used; with them it is also necessary to configure `AUDIO_PWM_PINALTERNATE_FUNCTION` to the correct alternate function for the selected pin, timer and timer-channel. + + +### PWM software + +This driver uses the PWM callbacks from PWMD1 with TIM1_CH1 to toggle the selected AUDIO_PIN in software. +During the same callback, with AUDIO_PIN_ALT_AS_NEGATIVE set, the AUDIO_PIN_ALT is toggled inversely to AUDIO_PIN. This is useful for setups that drive a piezo from two pins (instead of one and Gnd). + + +### Testing Notes + +While not an exhaustive list, the following table provides the scenarios that have been partially validated: + +| | DAC basic | DAC additive | PWM hardware | PWM software | +| Atmega43U4 | :o: | :o: | :heavy_check_mark: | :o: | +| STM32F103C8 (bluepill) | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | +| STM32F303CCT6 (proton-c) | :heavy_check_mark: | :heavy_check_mark: | ? | :heavy_check_mark: | +| STM32F405VG | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| L0xx | :x: (no Tim8) | ? | ? | ? | + + +:heavy_check_mark: : works and was tested +:o: : does not apply +:x: : not supported by MCU + +*Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.* diff --git a/docs/feature_audio.md b/docs/feature_audio.md index c4e0be4306e1..e89c0903e186 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -26,6 +26,8 @@ per speaker is - for example with a piezo buzzer - the black lead to Ground, and ## ARM based boards +for more technical details, see the notes on [Audio driver](audio_driver.md). + ### DAC (basic) Most STM32 MCUs have DAC peripherals, with a notable exception of the STM32F1xx series. Generally, the DAC peripheral drives pins A4 or A5. To enable DAC-based audio output on STM32 devices, add `AUDIO_DRIVER = dac_basic` to `rules.mk` and set in `config.h` either: `#define AUDIO_PIN_A4` @@ -46,9 +48,11 @@ wiring red to A4 and black to A5 (or the other way round) and add `#define AUDIO ##### Proton-C Example: The Proton-C comes (optionally) with one 'builtin' piezo, which is wired to A4+A5. For this board `config.h` would include these defines: -`#define AUDIO_PIN_A5` -`#define AUDIO_PIN_ALT_A4` -`#define AUDIO_PIN_ALT_AS_NEGATIVE` +```c +#define AUDIO_PIN_A5 +#define AUDIO_PIN_ALT_A4 +#define AUDIO_PIN_ALT_AS_NEGATIVE +``` ### DAC (additive) @@ -56,7 +60,7 @@ Another option, besides dac_basic (which produces sound through a square-wave), With a number of predefined wave-forms or by providing your own implementation to generate samples on the fly. To use this feature set `AUDIO_DRIVER = dac_additive` in your `rules.mk`, and select in `config.h` EITHER `#define AUDIO_PIN_A4` or `#define AUDIO_PIN_A5`. -The used waveform defaults to a sine, but can be selected by adding one of the following defines to `config.h`: +The used waveform *defaults* to sine, but others can be selected by adding one of the following defines to `config.h`: `#define AUDIO_DAC_SAMPLE_WAVEFORM_SINE` `#define AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE` `#define AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID` diff --git a/quantum/audio/driver_chibios_pwm_hardware.c b/quantum/audio/driver_chibios_pwm_hardware.c index c33d1b330bbb..205bccafb0b0 100644 --- a/quantum/audio/driver_chibios_pwm_hardware.c +++ b/quantum/audio/driver_chibios_pwm_hardware.c @@ -24,30 +24,6 @@ The hardware directly toggles the pin via its alternate function. see your MCUs */ -/* STM32F103C8 Setup: -halconf.h: -#define HAL_USE_PWM TRUE -#define HAL_USE_PAL TRUE -#define HAL_USE_GPT TRUE - -mcuconf.h: -#define STM32_PWM_USE_TIM1 TRUE -#define STM32_GPT_USE_TIM3 TRUE - -used pin: PA8 (alternate0: TIM1_CH1) - -from the data-sheet for STM32F103C8: alternate function of pin -TIM1_CH1 = PA8 <- -TIM1_CH2 = PA9 -TIM1_CH3 = PA10 -TIM1_CH4 = PA11 - -so adding to config.h: -#define AUDIO_PIN A8 -#define AUDIO_PWM_TIMER 1 -#define AUDIO_PWM_TIMERCHANNEL 1 -*/ - #include "audio.h" #include "ch.h" #include "hal.h" From 54d17f4174597f42c3a633e25cfc4ebc5e6758ad Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 4 May 2020 07:07:39 +0200 Subject: [PATCH 119/153] audio-arm-dac: move AUDIO_PIN checks into c-code instead of doing everything with the preprocessor, since A4/A5 do not expand to simple integers, preprocessor int-comparison is not possible. but necessary to get a consistent configuration scheme going throughout the audio-code... solution: let c-code handle the different AUDIO_PIN configurations instead (and leave code/size optimizations to the compiler) --- docs/feature_audio.md | 14 +- .../planck/keymaps/synth_sample/config.h | 2 +- .../planck/keymaps/synth_wavetable/config.h | 2 +- quantum/audio/audio.h | 16 +- quantum/audio/driver_chibios_dac_additive.c | 55 +++---- quantum/audio/driver_chibios_dac_basic.c | 147 +++++++----------- 6 files changed, 99 insertions(+), 137 deletions(-) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index e89c0903e186..5e090bb90c42 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -30,17 +30,17 @@ for more technical details, see the notes on [Audio driver](audio_driver.md). ### DAC (basic) Most STM32 MCUs have DAC peripherals, with a notable exception of the STM32F1xx series. Generally, the DAC peripheral drives pins A4 or A5. To enable DAC-based audio output on STM32 devices, add `AUDIO_DRIVER = dac_basic` to `rules.mk` and set in `config.h` either: -`#define AUDIO_PIN_A4` +`#define AUDIO_PIN A4` OR -`#define AUDIO_PIN_A5` +`#define AUDIO_PIN A5` the other DAC channel can optionally be used with a secondary speaker, just set: -`#define AUDIO_PIN_ALT_A4` or `#define AUDIO_PIN_ALT_A5` +`#define AUDIO_PIN_ALT A4` or `#define AUDIO_PIN_ALT A5` Do note though that the dac_basic driver is only capable of reproducing one tone per speaker/channel at a time, for more tones simultaneously, try the dac_additive driver. #### Wiring: -for two piezos, for example configured as `AUDIO_PIN_A4` and `AUDIO_PIN_ALT_A5` would be: red lead to A4 and black to Ground, and similarly with the second one: A5 = red, and Ground = black +for two piezos, for example configured as `AUDIO_PIN A4` and `AUDIO_PIN_ALT A5` would be: red lead to A4 and black to Ground, and similarly with the second one: A5 = red, and Ground = black another alternative is to drive *one* piezo with both DAC pins - for an extra "push". wiring red to A4 and black to A5 (or the other way round) and add `#define AUDIO_PIN_ALT_AS_NEGATIVE` to `config.h` @@ -49,8 +49,8 @@ wiring red to A4 and black to A5 (or the other way round) and add `#define AUDIO The Proton-C comes (optionally) with one 'builtin' piezo, which is wired to A4+A5. For this board `config.h` would include these defines: ```c -#define AUDIO_PIN_A5 -#define AUDIO_PIN_ALT_A4 +#define AUDIO_PIN A5 +#define AUDIO_PIN_ALT A4 #define AUDIO_PIN_ALT_AS_NEGATIVE ``` @@ -58,7 +58,7 @@ For this board `config.h` would include these defines: ### DAC (additive) Another option, besides dac_basic (which produces sound through a square-wave), is to use the DAC to do additive wave synthesis. With a number of predefined wave-forms or by providing your own implementation to generate samples on the fly. -To use this feature set `AUDIO_DRIVER = dac_additive` in your `rules.mk`, and select in `config.h` EITHER `#define AUDIO_PIN_A4` or `#define AUDIO_PIN_A5`. +To use this feature set `AUDIO_DRIVER = dac_additive` in your `rules.mk`, and select in `config.h` EITHER `#define AUDIO_PIN A4` or `#define AUDIO_PIN A5`. The used waveform *defaults* to sine, but others can be selected by adding one of the following defines to `config.h`: `#define AUDIO_DAC_SAMPLE_WAVEFORM_SINE` diff --git a/keyboards/planck/keymaps/synth_sample/config.h b/keyboards/planck/keymaps/synth_sample/config.h index 23687603560f..77d0c445c0ed 100644 --- a/keyboards/planck/keymaps/synth_sample/config.h +++ b/keyboards/planck/keymaps/synth_sample/config.h @@ -1,7 +1,7 @@ #pragma once #ifdef AUDIO_ENABLE - #define AUDIO_PIN_A5 + #define AUDIO_PIN A5 #define STARTUP_SONG SONG(PLANCK_SOUND) // #define STARTUP_SONG SONG(NO_SOUND) diff --git a/keyboards/planck/keymaps/synth_wavetable/config.h b/keyboards/planck/keymaps/synth_wavetable/config.h index 23687603560f..77d0c445c0ed 100644 --- a/keyboards/planck/keymaps/synth_wavetable/config.h +++ b/keyboards/planck/keymaps/synth_wavetable/config.h @@ -1,7 +1,7 @@ #pragma once #ifdef AUDIO_ENABLE - #define AUDIO_PIN_A5 + #define AUDIO_PIN A5 #define STARTUP_SONG SONG(PLANCK_SOUND) // #define STARTUP_SONG SONG(NO_SOUND) diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 3dbf4d0259a7..d5f81a7d19f5 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -290,28 +290,28 @@ bool audio_update_state(void); // LEGACY defines - TODO: remove and replace these in all keyboards using them #ifdef A4_AUDIO -# define AUDIO_PIN_A4 +# define AUDIO_PIN A4 #endif #ifdef A5_AUDIO -# define AUDIO_PIN_A5 +# define AUDIO_PIN A5 #endif #ifdef B5_AUDIO -# define AUDIO_PIN_ALT_B5 +# define AUDIO_PIN_ALT B5 #endif #ifdef B6_AUDIO -# define AUDIO_PIN_ALT_B6 +# define AUDIO_PIN_ALT B6 #endif #ifdef B7_AUDIO -# define AUDIO_PIN_ALT_B7 +# define AUDIO_PIN_ALT B7 #endif #ifdef C4_AUDIO -# define AUDIO_PIN_C4 +# define AUDIO_PIN C4 #endif #ifdef C5_AUDIO -# define AUDIO_PIN_C5 +# define AUDIO_PIN C5 #endif #ifdef C6_AUDIO -# define AUDIO_PIN_C6 +# define AUDIO_PIN C6 #endif #define is_audio_on() audio_is_on() diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index 8fc5ed0d06de..46a1aa926353 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -28,17 +28,11 @@ this driver allows for multiple simultaneous tones to be played through one single channel by doing additive wave-synthesis */ -#if !defined(AUDIO_PIN_A4) && !defined(AUDIO_PIN_A5) -# error "Audio feature enabled, but no suitable pin selected as AUDIO_PIN_x - see docs/feature_audio under 'ARM (DAC additive)' for available options." +#if !defined(AUDIO_PIN) +# error "Audio feature enabled, but no suitable pin selected as AUDIO_PIN - see docs/feature_audio under 'ARM (DAC additive)' for available options." #endif -#if defined(AUDIO_PIN_A4) && defined(AUDIO_PIN_A5) -# error "Audio feature: please set either AUDIO_PIN_A4 or AUDIO_PIN_A5, not both." -#endif -#if defined(AUDIO_PIN_ALT_A4) && defined(AUDIO_PIN_ALT_A5) -# error "Audio feature: please set either AUDIO_PIN_ALT_A4 or AUDIO_PIN_ALT_A5, not both." -#endif -#if !defined(AUDIO_PIN_ALT_AS_NEGATIVE) && (defined(AUDIO_PIN_ALT_A4) || defined(AUDIO_PIN_ALT_A5)) -# pragma message "Audio feature: AUDIO_PIN_ALT_x set, but not AUDIO_PIN_ALT_AS_NEGATIVE - pin will be left unused; audio might still work though." +#if !defined(AUDIO_PIN_ALT_AS_NEGATIVE) && !defined(AUDIO_PIN_ALT) +# pragma message "Audio feature: AUDIO_PIN_ALT set, but not AUDIO_PIN_ALT_AS_NEGATIVE - pin will be left unused; audio might still work though." #endif #if !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID) @@ -282,14 +276,14 @@ static const DACConfig dac_conf = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_ static const DACConversionGroup dac_conv_cfg = {.num_channels = 1U, .end_cb = dac_end, .error_cb = dac_error, .trigger = DAC_TRG(0b000)}; void audio_driver_initialize() { -#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) - palSetLineMode(A4, PAL_MODE_INPUT_ANALOG); - dacStart(&DACD1, &dac_conf); -#endif -#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) - palSetLineMode(A5, PAL_MODE_INPUT_ANALOG); - dacStart(&DACD2, &dac_conf); -#endif + if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) { + palSetLineMode(A4, PAL_MODE_INPUT_ANALOG); + dacStart(&DACD1, &dac_conf); + } + if ((AUDIO_PIN == A5) || (AUDIO_PIN_ALT == A5)) { + palSetLineMode(A5, PAL_MODE_INPUT_ANALOG); + dacStart(&DACD2, &dac_conf); + } /* enable the output buffer, to directly drive external loads with no additional circuitry * @@ -300,23 +294,22 @@ void audio_driver_initialize() { * this is done here, reaching directly into the stm32 registers since chibios has not implemented BOFF handling yet * (see: chibios/os/hal/ports/STM32/todo.txt '- BOFF handling in DACv1.' */ -#if defined(AUDIO_PIN_A4) DACD1.params->dac->CR &= ~DAC_CR_BOFF1; -#elif defined(AUDIO_PIN_A5) DACD2.params->dac->CR &= ~DAC_CR_BOFF2; -#endif -#if defined(AUDIO_PIN_A4) - dacStartConversion(&DACD1, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); -#elif defined(AUDIO_PIN_A5) - dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); -#endif + if (AUDIO_PIN == A4) { + dacStartConversion(&DACD1, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); + } else if (AUDIO_PIN == A5) { + dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); + } - // no inverted/out-of-phase waveform (yet?), only pulling AUDIO_PIN_ALT_x to AUDIO_DAC_OFF_VALUE -#if defined(AUDIO_PIN_ALT_A4) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) - dacPutChannelX(&DACD1, 0, AUDIO_DAC_OFF_VALUE); -#elif defined(AUDIO_PIN_ALT_A5) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) - dacPutChannelX(&DACD2, 0, AUDIO_DAC_OFF_VALUE); + // no inverted/out-of-phase waveform (yet?), only pulling AUDIO_PIN_ALT to AUDIO_DAC_OFF_VALUE +#if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) + if (AUDIO_PIN_ALT == A4) { + dacPutChannelX(&DACD1, 0, AUDIO_DAC_OFF_VALUE); + } else if (AUDIO_PIN == A5) { + dacPutChannelX(&DACD2, 0, AUDIO_DAC_OFF_VALUE); + } #endif gptStart(&GPTD6, &gpt6cfg1); diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index 50d257080765..f3ef555eecae 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -29,59 +29,37 @@ */ -#if !defined(AUDIO_PIN_A4) && !defined(AUDIO_PIN_A5) -# pragma message "Audio feature enabled, but no suitable pin selected as AUDIO_PIN_x or AUDIO_PIN_ALT_x - see docs/feature_audio under 'ARM (DAC basic)' for available options." +#if !defined(AUDIO_PIN) && !defined(AUDIO_PIN_ALT) +# pragma message "Audio feature enabled, but no suitable pin selected as AUDIO_PIN or AUDIO_PIN_ALT - see docs/feature_audio under 'ARM (DAC basic)' for available options." // TODO: make this an 'error' instead; go through a breaking change, and add AUDIO_PIN_A5 to all keyboards currently using AUDIO on STM32 based boards? #endif // check configuration for ONE speaker, connected to both DAC pins -#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) -# if !defined(AUDIO_PIN_ALT_A4) && !defined(AUDIO_PIN_ALT_A5) -# error "Audio feature: AUDIO_PIN_ALT_AS_NEGATIVE set, but no pin configured as AUDIO_PIN_ALT_x." -# endif -# if defined(AUDIO_PIN_A4) && defined(AUDIO_PIN_A5) -# error "Audio feature: with AUDIO_PIN_ALT_AS_NEGATIVE, only one pin can be configured as AUDIO_PIN_x." -# endif -# if defined(AUDIO_PIN_ALT_A4) && defined(AUDIO_PIN_ALT_A5) -# error "Audio feature: with AUDIO_PIN_ALT_AS_NEGATIVE, only one pin can be configured as AUDIO_PIN_ALT_x." -# endif -#endif -// check configuration for TWO speaker setup -#if defined(AUDIO_PIN_A4) && defined(AUDIO_PIN_ALT_A4) -# error "Audio feature: please set either AUDIO_PIN_A4 or AUDIO_PIN_ALT_A4, not both." -#endif -#if defined(AUDIO_PIN_A5) && defined(AUDIO_PIN_ALT_A5) -# error "Audio feature: please set either AUDIO_PIN_A5 or AUDIO_PIN_ALT_A5, not both." +#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) && !defined(AUDIO_PIN_ALT) +# error "Audio feature: AUDIO_PIN_ALT_AS_NEGATIVE set, but no pin configured as AUDIO_PIN_ALT" #endif -#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) // square-wave static const dacsample_t dac_buffer_1[AUDIO_DAC_BUFFER_SIZE] = { // First half is max, second half is 0 [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1] = AUDIO_DAC_SAMPLE_MAX, [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = 0, }; -#endif -#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) + // square-wave static const dacsample_t dac_buffer_2[AUDIO_DAC_BUFFER_SIZE] = { // opposite of dac_buffer above [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1] = 0, [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = AUDIO_DAC_SAMPLE_MAX, }; -#endif -#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) GPTConfig gpt6cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE, .callback = NULL, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U}; -#endif -#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) GPTConfig gpt7cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE, .callback = NULL, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U}; -#endif static void gpt_cb8(GPTDriver *gptp); GPTConfig gpt8cfg1 = {.frequency = 10, @@ -89,12 +67,8 @@ GPTConfig gpt8cfg1 = {.frequency = 10, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U}; -#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) static const DACConfig dac_conf_ch1 = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_DHRM_12BIT_RIGHT}; -#endif -#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) static const DACConfig dac_conf_ch2 = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_DHRM_12BIT_RIGHT}; -#endif /** * @note The DAC_TRG(0) here selects the Timer 6 TRGO event, which is triggered @@ -110,14 +84,9 @@ static const DACConfig dac_conf_ch2 = {.init = AUDIO_DAC_OFF_VALUE, .datamode = * EXTI9 0b110 * SWTRIG 0b111 */ -#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) static const DACConversionGroup dac_conv_grp_ch1 = {.num_channels = 1U, .trigger = DAC_TRG(0b000)}; -#endif -#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) static const DACConversionGroup dac_conv_grp_ch2 = {.num_channels = 1U, .trigger = DAC_TRG(0b010)}; -#endif -#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) void channel_1_start(void) { gptStart(&GPTD6, &gpt6cfg1); gptStartContinuous(&GPTD6, 2U); @@ -137,9 +106,7 @@ void channel_1_set_frequency(float freq) { channel_1_start(); } float channel_1_get_frequency(void) { return channel_1_frequency; } -#endif // AUDIO_PIN(_ALT)_A4 -#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) void channel_2_start(void) { gptStart(&GPTD7, &gpt7cfg1); gptStartContinuous(&GPTD7, 2U); @@ -159,57 +126,62 @@ void channel_2_set_frequency(float freq) { channel_2_start(); } float channel_2_get_frequency(void) { return channel_2_frequency; } -#endif // AUDIO_PIN(_ALT)_A5 static void gpt_cb8(GPTDriver *gptp) { if (audio_update_state()) { -#if (defined(AUDIO_PIN_A4) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT_A5)) || (defined(AUDIO_PIN_A5) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT_A4)) +#if (defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT)) // one piezo/speaker connected to both audio pins, the generated square-waves are inverted channel_1_set_frequency(audio_get_processed_frequency(0)); channel_2_set_frequency(audio_get_processed_frequency(0)); + #else // two separate audio outputs/speakers // primary speaker on A4, optional secondary on A5 -# if defined(AUDIO_PIN_A4) - channel_1_set_frequency(audio_get_processed_frequency(0)); -# if defined(AUDIO_PIN_ALT_A5) - if (audio_get_number_of_active_tones() > 1) { - channel_2_set_frequency(audio_get_processed_frequency(1)); - } else { - channel_2_stop(); + if (AUDIO_PIN == A4) { + channel_1_set_frequency(audio_get_processed_frequency(0)); +# if defined(AUDIO_PIN_ALT) + if (AUDIO_PIN_ALT == A5) { + if (audio_get_number_of_active_tones() > 1) { + channel_2_set_frequency(audio_get_processed_frequency(1)); + } else { + channel_2_stop(); + } + } } -# endif # endif // primary speaker on A5, optional secondary on A4 -# if defined(AUDIO_PIN_A5) - channel_2_set_frequency(audio_get_processed_frequency(0)); -# if defined(AUDIO_PIN_ALT_A4) - if (audio_get_number_of_active_tones() > 1) { - channel_1_set_frequency(audio_get_processed_frequency(1)); - } else { - channel_1_stop(); + if (AUDIO_PIN == A5) { + channel_2_set_frequency(audio_get_processed_frequency(0)); +# if defined(AUDIO_PIN_ALT) + if (AUDIO_PIN_ALT == A4) { + if (audio_get_number_of_active_tones() > 1) { + channel_1_set_frequency(audio_get_processed_frequency(1)); + } else { + channel_1_stop(); + } + } } -# endif # endif #endif } } void audio_driver_initialize() { -#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) - palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); - dacStart(&DACD1, &dac_conf_ch1); + if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) { + palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); + dacStart(&DACD1, &dac_conf_ch1); - // initial setup of the dac-triggering timer is still required, even - // though it gets reconfigured and restarted later on - gptStart(&GPTD6, &gpt6cfg1); -#endif -#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) - palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); - dacStart(&DACD2, &dac_conf_ch2); + // initial setup of the dac-triggering timer is still required, even + // though it gets reconfigured and restarted later on + gptStart(&GPTD6, &gpt6cfg1); + } - gptStart(&GPTD7, &gpt7cfg1); -#endif + if ((AUDIO_PIN == A5) || (AUDIO_PIN_ALT == A5)) { + palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); + dacStart(&DACD2, &dac_conf_ch2); + + gptStart(&GPTD7, &gpt7cfg1); + } /* enable the output buffer, to directly drive external loads with no additional circuitry * @@ -220,40 +192,37 @@ void audio_driver_initialize() { * this is done here, reaching directly into the stm32 registers since chibios has not implemented BOFF handling yet * (see: chibios/os/hal/ports/STM32/todo.txt '- BOFF handling in DACv1.' */ -#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) DACD1.params->dac->CR &= ~DAC_CR_BOFF1; -#endif -#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) DACD2.params->dac->CR &= ~DAC_CR_BOFF2; -#endif // start state-updater gptStart(&GPTD8, &gpt8cfg1); } void audio_driver_stop(void) { -#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) - gptStopTimer(&GPTD6); + if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) { + gptStopTimer(&GPTD6); - // stop the ongoing conversion and put the output in a known state - dacStopConversion(&DACD1); - dacPutChannelX(&DACD1, 0, AUDIO_DAC_OFF_VALUE); -#endif -#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) - gptStopTimer(&GPTD7); + // stop the ongoing conversion and put the output in a known state + dacStopConversion(&DACD1); + dacPutChannelX(&DACD1, 0, AUDIO_DAC_OFF_VALUE); + } - dacStopConversion(&DACD2); - dacPutChannelX(&DACD2, 0, AUDIO_DAC_OFF_VALUE); -#endif + if ((AUDIO_PIN == A5) || (AUDIO_PIN_ALT == A5)) { + gptStopTimer(&GPTD7); + + dacStopConversion(&DACD2); + dacPutChannelX(&DACD2, 0, AUDIO_DAC_OFF_VALUE); + } gptStopTimer(&GPTD8); } void audio_driver_start(void) { -#if defined(AUDIO_PIN_A4) || defined(AUDIO_PIN_ALT_A4) - dacStartConversion(&DACD1, &dac_conv_grp_ch1, (dacsample_t *)dac_buffer_1, AUDIO_DAC_BUFFER_SIZE); -#endif -#if defined(AUDIO_PIN_A5) || defined(AUDIO_PIN_ALT_A5) - dacStartConversion(&DACD2, &dac_conv_grp_ch2, (dacsample_t *)dac_buffer_2, AUDIO_DAC_BUFFER_SIZE); -#endif + if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) { + dacStartConversion(&DACD1, &dac_conv_grp_ch1, (dacsample_t *)dac_buffer_1, AUDIO_DAC_BUFFER_SIZE); + } + if ((AUDIO_PIN == A5) || (AUDIO_PIN_ALT == A5)) { + dacStartConversion(&DACD2, &dac_conv_grp_ch2, (dacsample_t *)dac_buffer_2, AUDIO_DAC_BUFFER_SIZE); + } gptStartContinuous(&GPTD8, 2U); } From 5a39a34633999c48c8778998e04025b355ad8b60 Mon Sep 17 00:00:00 2001 From: Johannes Date: Mon, 4 May 2020 09:04:58 +0200 Subject: [PATCH 120/153] audio-arm-dac: compile-fix: set AUDIO_PIN if unset workaround to get the build going again, and be backwarts compatible to arm-keyboards which not yet set the AUDIO_PIN define. until the define is enforced through an '#error" --- quantum/audio/driver_chibios_dac_additive.c | 7 ++++++- quantum/audio/driver_chibios_dac_basic.c | 18 ++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index 46a1aa926353..9d9dc8b181cc 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -35,6 +35,11 @@ # pragma message "Audio feature: AUDIO_PIN_ALT set, but not AUDIO_PIN_ALT_AS_NEGATIVE - pin will be left unused; audio might still work though." #endif +#if !defined(AUDIO_PIN_ALT) +// no ALT pin defined is valid, but the c-ifs below need some value set +# define(AUDIO_PIN_ALT) -1 +#endif + #if !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID) # define AUDIO_DAC_SAMPLE_WAVEFORM_SINE #endif @@ -304,7 +309,7 @@ void audio_driver_initialize() { } // no inverted/out-of-phase waveform (yet?), only pulling AUDIO_PIN_ALT to AUDIO_DAC_OFF_VALUE -#if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) +#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) if (AUDIO_PIN_ALT == A4) { dacPutChannelX(&DACD1, 0, AUDIO_DAC_OFF_VALUE); } else if (AUDIO_PIN == A5) { diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index f3ef555eecae..ccc43f508c4f 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -29,15 +29,21 @@ */ -#if !defined(AUDIO_PIN) && !defined(AUDIO_PIN_ALT) -# pragma message "Audio feature enabled, but no suitable pin selected as AUDIO_PIN or AUDIO_PIN_ALT - see docs/feature_audio under 'ARM (DAC basic)' for available options." -// TODO: make this an 'error' instead; go through a breaking change, and add AUDIO_PIN_A5 to all keyboards currently using AUDIO on STM32 based boards? +#if !defined(AUDIO_PIN) +# pragma message "Audio feature enabled, but no suitable pin selected as AUDIO_PIN - see docs/feature_audio under 'ARM (DAC basic)' for available options." +// TODO: make this an 'error' instead; go through a breaking change, and add AUDIO_PIN A5 to all keyboards currently using AUDIO on STM32 based boards? - for now: set the define here +# define AUDIO_PIN A5 #endif // check configuration for ONE speaker, connected to both DAC pins #if defined(AUDIO_PIN_ALT_AS_NEGATIVE) && !defined(AUDIO_PIN_ALT) # error "Audio feature: AUDIO_PIN_ALT_AS_NEGATIVE set, but no pin configured as AUDIO_PIN_ALT" #endif +#ifndef AUDIO_PIN_ALT +// no ALT pin defined is valid, but the c-ifs below need some value set +# define AUDIO_PIN_ALT -1 +#endif + // square-wave static const dacsample_t dac_buffer_1[AUDIO_DAC_BUFFER_SIZE] = { // First half is max, second half is 0 @@ -129,7 +135,7 @@ float channel_2_get_frequency(void) { return channel_2_frequency; } static void gpt_cb8(GPTDriver *gptp) { if (audio_update_state()) { -#if (defined(AUDIO_PIN_ALT_AS_NEGATIVE) && defined(AUDIO_PIN_ALT)) +#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) // one piezo/speaker connected to both audio pins, the generated square-waves are inverted channel_1_set_frequency(audio_get_processed_frequency(0)); channel_2_set_frequency(audio_get_processed_frequency(0)); @@ -138,7 +144,6 @@ static void gpt_cb8(GPTDriver *gptp) { // primary speaker on A4, optional secondary on A5 if (AUDIO_PIN == A4) { channel_1_set_frequency(audio_get_processed_frequency(0)); -# if defined(AUDIO_PIN_ALT) if (AUDIO_PIN_ALT == A5) { if (audio_get_number_of_active_tones() > 1) { channel_2_set_frequency(audio_get_processed_frequency(1)); @@ -147,12 +152,10 @@ static void gpt_cb8(GPTDriver *gptp) { } } } -# endif // primary speaker on A5, optional secondary on A4 if (AUDIO_PIN == A5) { channel_2_set_frequency(audio_get_processed_frequency(0)); -# if defined(AUDIO_PIN_ALT) if (AUDIO_PIN_ALT == A4) { if (audio_get_number_of_active_tones() > 1) { channel_1_set_frequency(audio_get_processed_frequency(1)); @@ -161,7 +164,6 @@ static void gpt_cb8(GPTDriver *gptp) { } } } -# endif #endif } } From 85d04f26c6f96415626ddf5187c42360ab3dc0b7 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 7 May 2020 03:03:24 +0200 Subject: [PATCH 121/153] audio-refactoring: document tone-multiplexing feature --- docs/feature_audio.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 5e090bb90c42..89cd57640837 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -94,6 +94,18 @@ which will use Timer 1 to directly drive pin PA8 through the PWM hardware (TIM1_ Should you want to use the pwm-hardware on another pin and timer - be ready to dig into the STM32 data-sheet to pick the right TIMx_CHy and pin-alternate function. +## Tone Multiplexing +Since most drivers can only render one tone per speaker at a time (with the one exception: arm dac-additive) there also exists a "workaround-feature" that does time-slicing/multiplexing - which does what the name implies: cycle through a set of active tones (e.g. when playing chords in Music Mode) at a given rate, and put one tone at a time out through the one/few speakers that are available. + +To enable this feature, and configure a starting-rate, add the following defines to `config.h`: +```c +#define AUDIO_ENABLE_TONE_MULTIPLEXING +#define AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT 10 +``` + +The audio core offers interface functions to get/set/change the tone multiplexing rate from within `keymap.c`. + + ## Songs There's a couple of different sounds that will automatically be enabled without any other configuration: ``` From d75a3c4d4e353b587749a72841d76d573732de4a Mon Sep 17 00:00:00 2001 From: JohSchneider Date: Fri, 8 May 2020 13:50:57 +0000 Subject: [PATCH 122/153] audio-refactoring: Apply suggestions from documentation review Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com> --- docs/audio_driver.md | 61 ++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/docs/audio_driver.md b/docs/audio_driver.md index ef09f83f610b..a9ea344c693c 100644 --- a/docs/audio_driver.md +++ b/docs/audio_driver.md @@ -1,16 +1,17 @@ -# Audio Driver +# Audio Driver :id=audio-driver The [Audio feature](feature_audio.md) breaks the hardware specifics out into separate, exchangeable driver units, with a common interface to the audio-"core" - which itself handles playing songs and notes while tracking their progress in an internal state, initializing/starting/stopping the driver as needed. Not all MCUs support every available driver, either the platform-support is not there (yet?) or the MCU simply does not have the required hardware peripheral. -## AVR +## AVR :id=avr -Boards build around an Atmega32U4 can use two sets of PWM capable pins, each driving a separate speaker. +Boards built around an Atmega32U4 can use two sets of PWM capable pins, each driving a separate speaker. The possible configurations are: | | Timer3 | Timer1 | +|--------------|-------------|--------------| | one speaker | C4,C5 or C6 | | | one speaker | | B4, B5 or B7 | | two speakers | C4,C5 or C6 | B4, B5 or B7 | @@ -21,51 +22,50 @@ AUDIO_DRIVER = pwm_hardware ``` -## ARM +## ARM :id=arm For Arm based boards, QMK depends on ChibiOS - hence any MCU supported by the later is likely usable, as long as certain hardware peripherals are available. Supported wiring configurations, with their ChibiOS/MCU peripheral requirement are listed below; piezo speakers are marked with :one: for the first/primary and :two: for the secondary. - | driver | GPTD6 | GPTD7 | GPTD8 | PWMD1 [^1] | - | | Tim6 | Tim7 | Tim8 | Tim1_Ch1 | - |--------------|----------------------------------|------------------------|-------|-----------------| - | dac_basic | A4+DACD1 = :one: | A5+DACD2 = :one: | state | | - | | A4+DACD1 = :one: + Gnd | A5+DACD2 = :two: + Gnd | state | | - | | A4+DACD1 = :two: + Gnd | A5+DACD2 = :one: + Gnd | state | | - | | A4+DACD1 = :one: + Gnd | | state | | - | | | A5+DACD2 = :one: + Gnd | state | | - | dac_additive | A4+DACD1 = :one: + Gnd | | | | - | | A5+DACD2 = :one: + Gnd | | | | - | | A4+DACD1 + A5+DACD2 = :one: [^2] | | | | - | pwm_software | state-update | | | any = :one: | - | pwm hardware | state-update | | | A8 = :one: [^3] | + | driver | GPTD6
Tim6 | GPTD7
Tim7 | GPTD8
Tim8 | PWMD11
Tim1_Ch1 | + |--------------|------------------------------------------|------------------------|---------------|-------------------------------| + | dac_basic | A4+DACD1 = :one: | A5+DACD2 = :one: | state | | + | | A4+DACD1 = :one: + Gnd | A5+DACD2 = :two: + Gnd | state | | + | | A4+DACD1 = :two: + Gnd | A5+DACD2 = :one: + Gnd | state | | + | | A4+DACD1 = :one: + Gnd | | state | | + | | | A5+DACD2 = :one: + Gnd | state | | + | dac_additive | A4+DACD1 = :one: + Gnd | | | | + | | A5+DACD2 = :one: + Gnd | | | | + | | A4+DACD1 + A5+DACD2 = :one: 2 | | | | + | pwm_software | state-update | | | any = :one: | + | pwm hardware | state-update | | | A8 = :one: 3 | -[^1]: the routing and alternate functions for PWM differ sometimes between STM32 MCUs, if in doubt consult the data-sheet -[^2]: one piezo connected to A4 and A5, with AUDIO_PIN_ALT_AS_NEGATIVE set -[^3]: TIM1_CH1 = A8 on STM32F103C8, other combinations are possible, see Data-sheet. configured with: AUDIO_PWM_TIMER and AUDIO_PWM_TIMERCHANNEL +1: the routing and alternate functions for PWM differ sometimes between STM32 MCUs, if in doubt consult the data-sheet +2: one piezo connected to A4 and A5, with AUDIO_PIN_ALT_AS_NEGATIVE set +3: TIM1_CH1 = A8 on STM32F103C8, other combinations are possible, see Data-sheet. configured with: AUDIO_PWM_TIMER and AUDIO_PWM_TIMERCHANNEL -### DAC basic +### DAC basic :id=dac-basic The default driver for ARM boards, in absence of an overriding configuration. This driver needs one Timer per enabled/used DAC channel, to trigger conversion; and a third timer to trigger state updates with the audio-core. -### DAC additive +### DAC additive :id=dac-additive only needs one timer (GPTD6, Tim6) to trigger the DAC unit to do a conversion; the audio state updates are in turn triggered during the DAC callback. -### PWM hardware +### PWM hardware :id=pwm-hardware -this driver uses the ChibiOS-PWM system to produce a square-wave on specific output pins that are connected to the PWM hardware. -The hardware directly toggles the pin via its alternate function. see your MCUs data-sheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function. +This driver uses the ChibiOS-PWM system to produce a square-wave on specific output pins that are connected to the PWM hardware. +The hardware directly toggles the pin via its alternate function. See your MCU's data-sheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function. -a configuration example for the STM32F103C8 would be: +A configuration example for the STM32F103C8 would be: ``` c //halconf.h: #define HAL_USE_PWM TRUE @@ -79,7 +79,7 @@ a configuration example for the STM32F103C8 would be: #define STM32_GPT_USE_TIM3 TRUE ``` -If we now target pin A8, looking trough the data-sheet of the STM32F103C8, for the timers and alternate functions +If we now target pin A8, looking through the data-sheet of the STM32F103C8, for the timers and alternate functions TIM1_CH1 = PA8 <- alternate0 TIM1_CH2 = PA9 TIM1_CH3 = PA10 @@ -97,18 +97,19 @@ ChibiOS uses GPIOv1 for the F103, which only knows of one alternate function. On 'larger' STM32s, GPIOv2 or GPIOv3 are used; with them it is also necessary to configure `AUDIO_PWM_PINALTERNATE_FUNCTION` to the correct alternate function for the selected pin, timer and timer-channel. -### PWM software +### PWM software :id=pwm-software This driver uses the PWM callbacks from PWMD1 with TIM1_CH1 to toggle the selected AUDIO_PIN in software. During the same callback, with AUDIO_PIN_ALT_AS_NEGATIVE set, the AUDIO_PIN_ALT is toggled inversely to AUDIO_PIN. This is useful for setups that drive a piezo from two pins (instead of one and Gnd). -### Testing Notes +### Testing Notes :id=testing-notes While not an exhaustive list, the following table provides the scenarios that have been partially validated: | | DAC basic | DAC additive | PWM hardware | PWM software | -| Atmega43U4 | :o: | :o: | :heavy_check_mark: | :o: | +|--------------------------|--------------------|--------------------|--------------------|--------------------| +| Atmega32U4 | :o: | :o: | :heavy_check_mark: | :o: | | STM32F103C8 (bluepill) | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | | STM32F303CCT6 (proton-c) | :heavy_check_mark: | :heavy_check_mark: | ? | :heavy_check_mark: | | STM32F405VG | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | From 39161f22a4a34ccd118adc17db30430c7013a8cb Mon Sep 17 00:00:00 2001 From: JohSchneider Date: Fri, 8 May 2020 13:54:53 +0000 Subject: [PATCH 123/153] audio-refactoring: Update docs/audio_driver.md --- docs/audio_driver.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/audio_driver.md b/docs/audio_driver.md index a9ea344c693c..b26cb0a27797 100644 --- a/docs/audio_driver.md +++ b/docs/audio_driver.md @@ -80,10 +80,10 @@ A configuration example for the STM32F103C8 would be: ``` If we now target pin A8, looking through the data-sheet of the STM32F103C8, for the timers and alternate functions -TIM1_CH1 = PA8 <- alternate0 -TIM1_CH2 = PA9 -TIM1_CH3 = PA10 -TIM1_CH4 = PA11 +- TIM1_CH1 = PA8 <- alternate0 +- TIM1_CH2 = PA9 +- TIM1_CH3 = PA10 +- TIM1_CH4 = PA11 with all this information, the configuration would contain these lines: ``` c From cbdc711d007cd9673a464643acb8f2b89fe62756 Mon Sep 17 00:00:00 2001 From: JohSchneider Date: Sat, 9 May 2020 03:48:12 +0000 Subject: [PATCH 124/153] audio-refactoring: docs: fix markdown newlines Terminating a line in Markdown with -- creates an HTML single-line break (
). Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com> --- docs/audio_driver.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/audio_driver.md b/docs/audio_driver.md index b26cb0a27797..26e3e8213a19 100644 --- a/docs/audio_driver.md +++ b/docs/audio_driver.md @@ -43,8 +43,8 @@ piezo speakers are marked with :one: for the first/primary and :two: for the sec | pwm hardware | state-update | | | A8 = :one: 3 | -1: the routing and alternate functions for PWM differ sometimes between STM32 MCUs, if in doubt consult the data-sheet -2: one piezo connected to A4 and A5, with AUDIO_PIN_ALT_AS_NEGATIVE set +1: the routing and alternate functions for PWM differ sometimes between STM32 MCUs, if in doubt consult the data-sheet +2: one piezo connected to A4 and A5, with AUDIO_PIN_ALT_AS_NEGATIVE set 3: TIM1_CH1 = A8 on STM32F103C8, other combinations are possible, see Data-sheet. configured with: AUDIO_PWM_TIMER and AUDIO_PWM_TIMERCHANNEL @@ -116,8 +116,8 @@ While not an exhaustive list, the following table provides the scenarios that ha | L0xx | :x: (no Tim8) | ? | ? | ? | -:heavy_check_mark: : works and was tested -:o: : does not apply +:heavy_check_mark: : works and was tested +:o: : does not apply :x: : not supported by MCU *Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.* From 6f7d18521903bec15385d0c2ea26490df665f1f2 Mon Sep 17 00:00:00 2001 From: Johannes Date: Tue, 19 May 2020 19:31:28 +0200 Subject: [PATCH 125/153] audio-arm-dac: additive: fix AUDIO_PIN_ALT handling --- quantum/audio/driver_chibios_dac_additive.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index 9d9dc8b181cc..91b13dbb71e0 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -31,13 +31,13 @@ #if !defined(AUDIO_PIN) # error "Audio feature enabled, but no suitable pin selected as AUDIO_PIN - see docs/feature_audio under 'ARM (DAC additive)' for available options." #endif -#if !defined(AUDIO_PIN_ALT_AS_NEGATIVE) && !defined(AUDIO_PIN_ALT) +#if defined(AUDIO_PIN_ALT) && !defined(AUDIO_PIN_ALT_AS_NEGATIVE) # pragma message "Audio feature: AUDIO_PIN_ALT set, but not AUDIO_PIN_ALT_AS_NEGATIVE - pin will be left unused; audio might still work though." #endif #if !defined(AUDIO_PIN_ALT) // no ALT pin defined is valid, but the c-ifs below need some value set -# define(AUDIO_PIN_ALT) -1 +# define AUDIO_PIN_ALT PAL_NOLINE #endif #if !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID) @@ -312,7 +312,7 @@ void audio_driver_initialize() { #if defined(AUDIO_PIN_ALT_AS_NEGATIVE) if (AUDIO_PIN_ALT == A4) { dacPutChannelX(&DACD1, 0, AUDIO_DAC_OFF_VALUE); - } else if (AUDIO_PIN == A5) { + } else if (AUDIO_PIN_ALT == A5) { dacPutChannelX(&DACD2, 0, AUDIO_DAC_OFF_VALUE); } #endif From e870e4d5676443c243c4b482d0bee3ffcffc6820 Mon Sep 17 00:00:00 2001 From: JohSchneider Date: Thu, 21 May 2020 09:31:02 +0000 Subject: [PATCH 126/153] audio-arm-pwm: align define naming with other drivers Co-authored-by: Joel Challis --- docs/audio_driver.md | 2 +- docs/feature_audio.md | 2 +- quantum/audio/driver_chibios_pwm.h | 4 ++-- quantum/audio/driver_chibios_pwm_hardware.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/audio_driver.md b/docs/audio_driver.md index 26e3e8213a19..7b32c1b29c20 100644 --- a/docs/audio_driver.md +++ b/docs/audio_driver.md @@ -94,7 +94,7 @@ with all this information, the configuration would contain these lines: ``` ChibiOS uses GPIOv1 for the F103, which only knows of one alternate function. -On 'larger' STM32s, GPIOv2 or GPIOv3 are used; with them it is also necessary to configure `AUDIO_PWM_PINALTERNATE_FUNCTION` to the correct alternate function for the selected pin, timer and timer-channel. +On 'larger' STM32s, GPIOv2 or GPIOv3 are used; with them it is also necessary to configure `AUDIO_PWM_PAL_MODE` to the correct alternate function for the selected pin, timer and timer-channel. ### PWM software :id=pwm-software diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 89cd57640837..e9ce373daa2c 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -89,7 +89,7 @@ STM32F1xx have to fall back to using PWM, but can do so in hardware; but again o `#define AUDIO_PIN A8` `#define AUDIO_PWM_TIMER 1` `#define AUDIO_PWM_TIMERCHANNEL 1` -(as well as `#define AUDIO_PWM_PINALTERNATE_FUNCTION 42` if you are on STM32F2 or larger) +(as well as `#define AUDIO_PWM_PAL_MODE 42` if you are on STM32F2 or larger) which will use Timer 1 to directly drive pin PA8 through the PWM hardware (TIM1_CH1 = PA8). Should you want to use the pwm-hardware on another pin and timer - be ready to dig into the STM32 data-sheet to pick the right TIMx_CHy and pin-alternate function. diff --git a/quantum/audio/driver_chibios_pwm.h b/quantum/audio/driver_chibios_pwm.h index 4ffea7d20afe..7862ee03cb5b 100644 --- a/quantum/audio/driver_chibios_pwm.h +++ b/quantum/audio/driver_chibios_pwm.h @@ -26,8 +26,8 @@ # define AUDIO_PWM_TIMERCHANNEL 1 #endif -#if !defined(AUDIO_PWM_PINALTERNATE_FUNCTION) +#if !defined(AUDIO_PWM_PAL_MODE) // pin-alternate function: see the data-sheet for which pin needs what AF to connect to TIMx_CHy // default: STM32F303CC PA8+TIM1_CH1 -> 6 -# define AUDIO_PWM_PINALTERNATE_FUNCTION 6 +# define AUDIO_PWM_PAL_MODE 6 #endif diff --git a/quantum/audio/driver_chibios_pwm_hardware.c b/quantum/audio/driver_chibios_pwm_hardware.c index 205bccafb0b0..6fa508b56c53 100644 --- a/quantum/audio/driver_chibios_pwm_hardware.c +++ b/quantum/audio/driver_chibios_pwm_hardware.c @@ -115,7 +115,7 @@ void audio_driver_initialize(void) { #if defined(USE_GPIOV1) // STM32F103C8 palSetLineMode(AUDIO_PIN, PAL_MODE_STM32_ALTERNATE_PUSHPULL); #else // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command) - palSetLineMode(AUDIO_PIN, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(AUDIO_PWM_PINALTERNATE_FUNCTION)); + palSetLineMode(AUDIO_PIN, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(AUDIO_PWM_PAL_MODE)); #endif gptStart(&GPTD6, &gptCFG); From 44a45b3b1c38d0fd796435ee60397befa9bf62a2 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 4 Jun 2020 12:53:54 +0200 Subject: [PATCH 127/153] audio-refactoring: set detault tempo to 120 and add documentation for the override --- docs/feature_audio.md | 12 +++++++++++- quantum/audio/musical_notes.h | 5 +++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index e9ce373daa2c..0f4a26e59c80 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -159,7 +159,17 @@ The available keycodes for audio are: * `AU_OFF` - Turn Audio Feature off * `AU_TOG` - Toggle Audio Feature state -!> These keycodes turn all of the audio functionality on and off. Turning it off means that audio feedback, audio clicky, music mode, etc. are disabled, completely. +!> These keycodes turn all of the audio functionality on and off. Turning it off means that audio feedback, audio clicky, music mode, etc. are disabled, completely. + +## Tempo +the 'speed' at which SONGs are played is dictated by the set Tempo, which is measured in beats-per-minute. Note lenghts are defined relative to that. +The initial/default tempo is set to 120 bpm, but can be configured by setting `TEMPO_DEFAULT` in `config.c`. +There is also a set of functions to modify the tempo from within the user/keymap code: +```c +void audio_set_tempo(uint8_t tempo); +void audio_increase_tempo(uint8_t tempo_change); +void audio_decrease_tempo(uint8_t tempo_change); +``` ## ARM Audio Volume diff --git a/quantum/audio/musical_notes.h b/quantum/audio/musical_notes.h index 4377638a237e..e75878ff3d37 100644 --- a/quantum/audio/musical_notes.h +++ b/quantum/audio/musical_notes.h @@ -15,9 +15,10 @@ */ #pragma once -// Tempo Placeholder -#define TEMPO_DEFAULT 60 +#ifndef TEMPO_DEFAULT +# define TEMPO_DEFAULT 120 // in beats-per-minute +#endif #define SONG(notes...) \ { notes } From d4d651b555406915de2a4a935d04da2c068c423b Mon Sep 17 00:00:00 2001 From: JohSchneider Date: Thu, 4 Jun 2020 11:06:34 +0000 Subject: [PATCH 128/153] audio-refactoring: update backlight define checks to new AUDIO_PIN names --- quantum/backlight/backlight_avr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quantum/backlight/backlight_avr.c b/quantum/backlight/backlight_avr.c index 18fb8cf43808..e47192de3421 100644 --- a/quantum/backlight/backlight_avr.c +++ b/quantum/backlight/backlight_avr.c @@ -126,7 +126,7 @@ # define COMxx1 COM1B1 # define OCRxx OCR1B # endif -#elif !defined(AUDIO_PIN_ALT_B5) && !defined(AUDIO_PIN_ALT_B6) && !defined(AUDIO_PIN_ALT_B7) +#elif (AUDIO_PIN != B5) && (AUDIO_PIN != B6) && (AUDIO_PIN != B7) && (AUDIO_PIN_ALT != B5) && (AUDIO_PIN_ALT != B6) && (AUDIO_PIN_ALT != B7) // Timer 1 is not in use by Audio feature, Backlight can use it # pragma message "Using hardware timer 1 with software PWM" # define HARDWARE_PWM @@ -145,7 +145,7 @@ # define OCIExA OCIE1A # define OCRxx OCR1A -#elif !defined(AUDIO_PIN_C6) && !defined(AUDIO_PIN_C5) && !defined(AUDIO_PIN_C4) +#elif (AUDIO_PIN != C4) && (AUDIO_PIN != C5) && (AUDIO_PIN != C6) # pragma message "Using hardware timer 3 with software PWM" // Timer 3 is not in use by Audio feature, Backlight can use it # define HARDWARE_PWM From a1442e0b1dc32efde100a21692e64a60cdcaf0e7 Mon Sep 17 00:00:00 2001 From: JohSchneider Date: Thu, 4 Jun 2020 11:14:29 +0000 Subject: [PATCH 129/153] audio-refactoring: reworking PWM related defines to be more consistent with other QMK code Co-authored-by: Joel Challis --- docs/audio_driver.md | 6 ++--- docs/feature_audio.md | 4 +-- quantum/audio/driver_chibios_pwm.h | 8 +++--- quantum/audio/driver_chibios_pwm_hardware.c | 25 ++++++++---------- quantum/audio/driver_chibios_pwm_software.c | 28 ++++++++------------- 5 files changed, 30 insertions(+), 41 deletions(-) diff --git a/docs/audio_driver.md b/docs/audio_driver.md index 7b32c1b29c20..bedb2969e1b3 100644 --- a/docs/audio_driver.md +++ b/docs/audio_driver.md @@ -45,7 +45,7 @@ piezo speakers are marked with :one: for the first/primary and :two: for the sec 1: the routing and alternate functions for PWM differ sometimes between STM32 MCUs, if in doubt consult the data-sheet 2: one piezo connected to A4 and A5, with AUDIO_PIN_ALT_AS_NEGATIVE set -3: TIM1_CH1 = A8 on STM32F103C8, other combinations are possible, see Data-sheet. configured with: AUDIO_PWM_TIMER and AUDIO_PWM_TIMERCHANNEL +3: TIM1_CH1 = A8 on STM32F103C8, other combinations are possible, see Data-sheet. configured with: AUDIO_PWM_DRIVER and AUDIO_PWM_CHANNEL @@ -89,8 +89,8 @@ with all this information, the configuration would contain these lines: ``` c //config.h: #define AUDIO_PIN A8 -#define AUDIO_PWM_TIMER 1 -#define AUDIO_PWM_TIMERCHANNEL 1 +#define AUDIO_PWM_DRIVER PWMD1 +#define AUDIO_PWM_CHANNEL 1 ``` ChibiOS uses GPIOv1 for the F103, which only knows of one alternate function. diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 0f4a26e59c80..355593bd7d99 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -87,8 +87,8 @@ STM32F1xx have to fall back to using PWM, but can do so in hardware; but again o `AUDIO_DRIVER = pwm_hardware` in `rules.mk`, and in `config.h`: `#define AUDIO_PIN A8` -`#define AUDIO_PWM_TIMER 1` -`#define AUDIO_PWM_TIMERCHANNEL 1` +`#define AUDIO_PWM_DRIVER PWMD1` +`#define AUDIO_PWM_CHANNEL 1` (as well as `#define AUDIO_PWM_PAL_MODE 42` if you are on STM32F2 or larger) which will use Timer 1 to directly drive pin PA8 through the PWM hardware (TIM1_CH1 = PA8). Should you want to use the pwm-hardware on another pin and timer - be ready to dig into the STM32 data-sheet to pick the right TIMx_CHy and pin-alternate function. diff --git a/quantum/audio/driver_chibios_pwm.h b/quantum/audio/driver_chibios_pwm.h index 7862ee03cb5b..2d19e7a3b490 100644 --- a/quantum/audio/driver_chibios_pwm.h +++ b/quantum/audio/driver_chibios_pwm.h @@ -15,15 +15,15 @@ */ #pragma once -#if !defined(AUDIO_PWM_TIMER) +#if !defined(AUDIO_PWM_DRIVER) // NOTE: Timer2 seems to be used otherwise in QMK, otherwise we could default to A5 (= TIM2_CH1, with PWMD2 and alternate-function(1)) -# define AUDIO_PWM_TIMER 1 +# define AUDIO_PWM_DRIVER PWMD1 #endif -#if !defined(AUDIO_PWM_TIMERCHANNEL) +#if !defined(AUDIO_PWM_CHANNEL) // NOTE: sticking to the STM data-sheet numbering: TIMxCH1 to TIMxCH4 // default: STM32F303CC PA8+TIM1_CH1 -> 1 -# define AUDIO_PWM_TIMERCHANNEL 1 +# define AUDIO_PWM_CHANNEL 1 #endif #if !defined(AUDIO_PWM_PAL_MODE) diff --git a/quantum/audio/driver_chibios_pwm_hardware.c b/quantum/audio/driver_chibios_pwm_hardware.c index 6fa508b56c53..721ffb9e51c8 100644 --- a/quantum/audio/driver_chibios_pwm_hardware.c +++ b/quantum/audio/driver_chibios_pwm_hardware.c @@ -32,11 +32,6 @@ The hardware directly toggles the pin via its alternate function. see your MCUs # error "Audio feature enabled, but no pin selected - see docs/feature_audio under the ARM PWM settings" #endif -// some preprocessor trickery to get the corresponding chibios-PWMDriver -#define TO_CHIBIOS_PWMD_PASTE(t) (PWMD##t) -#define TO_CHIBIOS_PWMD_EVAL(t) TO_CHIBIOS_PWMD_PASTE(t) -#define PWMD TO_CHIBIOS_PWMD_EVAL(AUDIO_PWM_TIMER) - extern bool playing_note; extern bool playing_melody; extern uint8_t note_timbre; @@ -48,17 +43,17 @@ static PWMConfig pwmCFG = { .callback = NULL, /* no callback, the hardware directly toggles the pin */ .channels = { -#if AUDIO_PWM_TIMERCHANNEL == 4 +#if AUDIO_PWM_CHANNEL == 4 {PWM_OUTPUT_DISABLED, NULL}, /* channel 0 -> TIMx_CH1 */ {PWM_OUTPUT_DISABLED, NULL}, /* channel 1 -> TIMx_CH2 */ {PWM_OUTPUT_DISABLED, NULL}, /* channel 2 -> TIMx_CH3 */ {PWM_OUTPUT_ACTIVE_HIGH, NULL} /* channel 3 -> TIMx_CH4 */ -#elif AUDIO_PWM_TIMERCHANNEL == 3 +#elif AUDIO_PWM_CHANNEL == 3 {PWM_OUTPUT_DISABLED, NULL}, {PWM_OUTPUT_DISABLED, NULL}, {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH3 */ {PWM_OUTPUT_DISABLED, NULL} -#elif AUDIO_PWM_TIMERCHANNEL == 2 +#elif AUDIO_PWM_CHANNEL == 2 {PWM_OUTPUT_DISABLED, NULL}, {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH2 */ {PWM_OUTPUT_DISABLED, NULL}, @@ -80,20 +75,20 @@ void channel_1_set_frequency(float freq) { return; pwmcnt_t period = (pwmCFG.frequency / freq); - pwmChangePeriod(&PWMD, period); - pwmEnableChannel(&PWMD, AUDIO_PWM_TIMERCHANNEL - 1, + pwmChangePeriod(&AUDIO_PWM_DRIVER, period); + pwmEnableChannel(&AUDIO_PWM_DRIVER, AUDIO_PWM_CHANNEL - 1, // adjust the duty-cycle so that the output is for 'note_timbre' duration HIGH - PWM_PERCENTAGE_TO_WIDTH(&PWMD, (100 - note_timbre) * 100)); + PWM_PERCENTAGE_TO_WIDTH(&AUDIO_PWM_DRIVER, (100 - note_timbre) * 100)); } float channel_1_get_frequency(void) { return channel_1_frequency; } void channel_1_start(void) { - pwmStop(&PWMD); - pwmStart(&PWMD, &pwmCFG); + pwmStop(&AUDIO_PWM_DRIVER); + pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); } -void channel_1_stop(void) { pwmStop(&PWMD); } +void channel_1_stop(void) { pwmStop(&AUDIO_PWM_DRIVER); } static void gpt_callback(GPTDriver *gptp); GPTConfig gptCFG = { @@ -109,7 +104,7 @@ GPTConfig gptCFG = { }; void audio_driver_initialize(void) { - pwmStart(&PWMD, &pwmCFG); + pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); // connect the AUDIO_PIN to the PWM hardware #if defined(USE_GPIOV1) // STM32F103C8 diff --git a/quantum/audio/driver_chibios_pwm_software.c b/quantum/audio/driver_chibios_pwm_software.c index 358327be61f3..563e9ab558c9 100644 --- a/quantum/audio/driver_chibios_pwm_software.c +++ b/quantum/audio/driver_chibios_pwm_software.c @@ -30,12 +30,6 @@ this driver uses the chibios-PWM system to produce a square-wave on any given ou #if !defined(AUDIO_PIN) # error "Audio feature enabled, but no pin selected - see docs/feature_audio under the ARM PWM settings" #endif - -// some preprocessor trickery to get the corresponding chibios-PWMDriver -#define TO_CHIBIOS_PWMD_PASTE(t) (PWMD##t) -#define TO_CHIBIOS_PWMD_EVAL(t) TO_CHIBIOS_PWMD_PASTE(t) -#define PWMD TO_CHIBIOS_PWMD_EVAL(AUDIO_PWM_TIMER) - extern bool playing_note; extern bool playing_melody; extern uint8_t note_timbre; @@ -66,25 +60,25 @@ void channel_1_set_frequency(float freq) { return; pwmcnt_t period = (pwmCFG.frequency / freq); - pwmChangePeriod(&PWMD, period); + pwmChangePeriod(&AUDIO_PWM_DRIVER, period); - pwmEnableChannel(&PWMD, AUDIO_PWM_TIMERCHANNEL - 1, + pwmEnableChannel(&AUDIO_PWM_DRIVER, AUDIO_PWM_CHANNEL - 1, // adjust the duty-cycle so that the output is for 'note_timbre' duration HIGH - PWM_PERCENTAGE_TO_WIDTH(&PWMD, (100 - note_timbre) * 100)); + PWM_PERCENTAGE_TO_WIDTH(&AUDIO_PWM_DRIVER, (100 - note_timbre) * 100)); } float channel_1_get_frequency(void) { return channel_1_frequency; } void channel_1_start(void) { - pwmStop(&PWMD); - pwmStart(&PWMD, &pwmCFG); + pwmStop(&AUDIO_PWM_DRIVER); + pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); - pwmEnablePeriodicNotification(&PWMD); - pwmEnableChannelNotification(&PWMD, AUDIO_PWM_TIMERCHANNEL - 1); + pwmEnablePeriodicNotification(&AUDIO_PWM_DRIVER); + pwmEnableChannelNotification(&AUDIO_PWM_DRIVER, AUDIO_PWM_CHANNEL - 1); } void channel_1_stop(void) { - pwmStop(&PWMD); + pwmStop(&AUDIO_PWM_DRIVER); palClearLine(AUDIO_PIN); // leave the line low, after last note was played @@ -126,7 +120,7 @@ GPTConfig gptCFG = { }; void audio_driver_initialize(void) { - pwmStart(&PWMD, &pwmCFG); + pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); palSetLineMode(AUDIO_PIN, PAL_MODE_OUTPUT_PUSHPULL); palClearLine(AUDIO_PIN); @@ -136,8 +130,8 @@ void audio_driver_initialize(void) { palClearLine(AUDIO_PIN_ALT); #endif - pwmEnablePeriodicNotification(&PWMD); // enable pwm callbacks - pwmEnableChannelNotification(&PWMD, AUDIO_PWM_TIMERCHANNEL - 1); + pwmEnablePeriodicNotification(&AUDIO_PWM_DRIVER); // enable pwm callbacks + pwmEnableChannelNotification(&AUDIO_PWM_DRIVER, AUDIO_PWM_CHANNEL - 1); gptStart(&GPTD6, &gptCFG); } From e9eb7b59e2a54c69a205e32c250e46d0665d8f30 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 4 Jun 2020 16:42:32 +0200 Subject: [PATCH 130/153] audio-arm: have the state-update-timer user configurable defaulting to GPTD6 or GPTD8 for stm32f2+ (=proton-c) stm32f1 might need to set this to GPTD4, since 6 and 8 are not available --- docs/audio_driver.md | 3 ++- quantum/audio/driver_chibios_dac_basic.c | 18 +++++++++++------- quantum/audio/driver_chibios_pwm.h | 6 ++++++ quantum/audio/driver_chibios_pwm_hardware.c | 6 +++--- quantum/audio/driver_chibios_pwm_software.c | 6 +++--- 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/docs/audio_driver.md b/docs/audio_driver.md index bedb2969e1b3..997f20bfb1ac 100644 --- a/docs/audio_driver.md +++ b/docs/audio_driver.md @@ -76,7 +76,7 @@ A configuration example for the STM32F103C8 would be: ``` c // mcuconf.h: #define STM32_PWM_USE_TIM1 TRUE -#define STM32_GPT_USE_TIM3 TRUE +#define STM32_GPT_USE_TIM4 TRUE ``` If we now target pin A8, looking through the data-sheet of the STM32F103C8, for the timers and alternate functions @@ -91,6 +91,7 @@ with all this information, the configuration would contain these lines: #define AUDIO_PIN A8 #define AUDIO_PWM_DRIVER PWMD1 #define AUDIO_PWM_CHANNEL 1 +#define AUDIO_STATE_TIMER GPTD4 ``` ChibiOS uses GPIOv1 for the F103, which only knows of one alternate function. diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index ccc43f508c4f..a27c8d475210 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -44,6 +44,10 @@ # define AUDIO_PIN_ALT -1 #endif +#if !defined(AUDIO_STATE_TIMER) +# define AUDIO_STATE_TIMER GPTD8 +#endif + // square-wave static const dacsample_t dac_buffer_1[AUDIO_DAC_BUFFER_SIZE] = { // First half is max, second half is 0 @@ -67,9 +71,9 @@ GPTConfig gpt7cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U}; -static void gpt_cb8(GPTDriver *gptp); -GPTConfig gpt8cfg1 = {.frequency = 10, - .callback = gpt_cb8, +static void gpt_audio_state_cb(GPTDriver *gptp); +GPTConfig gptStateUpdateCfg = {.frequency = 10, + .callback = gpt_audio_state_cb, .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ .dier = 0U}; @@ -133,7 +137,7 @@ void channel_2_set_frequency(float freq) { } float channel_2_get_frequency(void) { return channel_2_frequency; } -static void gpt_cb8(GPTDriver *gptp) { +static void gpt_audio_state_cb(GPTDriver *gptp) { if (audio_update_state()) { #if defined(AUDIO_PIN_ALT_AS_NEGATIVE) // one piezo/speaker connected to both audio pins, the generated square-waves are inverted @@ -198,7 +202,7 @@ void audio_driver_initialize() { DACD2.params->dac->CR &= ~DAC_CR_BOFF2; // start state-updater - gptStart(&GPTD8, &gpt8cfg1); + gptStart(&AUDIO_STATE_TIMER, &gptStateUpdateCfg); } void audio_driver_stop(void) { @@ -216,7 +220,7 @@ void audio_driver_stop(void) { dacStopConversion(&DACD2); dacPutChannelX(&DACD2, 0, AUDIO_DAC_OFF_VALUE); } - gptStopTimer(&GPTD8); + gptStopTimer(&AUDIO_STATE_TIMER); } void audio_driver_start(void) { @@ -226,5 +230,5 @@ void audio_driver_start(void) { if ((AUDIO_PIN == A5) || (AUDIO_PIN_ALT == A5)) { dacStartConversion(&DACD2, &dac_conv_grp_ch2, (dacsample_t *)dac_buffer_2, AUDIO_DAC_BUFFER_SIZE); } - gptStartContinuous(&GPTD8, 2U); + gptStartContinuous(&AUDIO_STATE_TIMER, 2U); } diff --git a/quantum/audio/driver_chibios_pwm.h b/quantum/audio/driver_chibios_pwm.h index 2d19e7a3b490..25b08e38a2bd 100644 --- a/quantum/audio/driver_chibios_pwm.h +++ b/quantum/audio/driver_chibios_pwm.h @@ -31,3 +31,9 @@ // default: STM32F303CC PA8+TIM1_CH1 -> 6 # define AUDIO_PWM_PAL_MODE 6 #endif + +#if !defined(AUDIO_STATE_TIMER) +// timer used to trigger updates in the audio-system, configured/enabled in chibios mcuconf. +// Tim6 is the default for "larger" STMs, smaller ones might not have this one (enabled) and need to switch to a different one (e.g.: STM32F103 has only Tim1-Tim4) +# define AUDIO_STATE_TIMER GPTD6 +#endif diff --git a/quantum/audio/driver_chibios_pwm_hardware.c b/quantum/audio/driver_chibios_pwm_hardware.c index 721ffb9e51c8..64c0598fdd33 100644 --- a/quantum/audio/driver_chibios_pwm_hardware.c +++ b/quantum/audio/driver_chibios_pwm_hardware.c @@ -113,7 +113,7 @@ void audio_driver_initialize(void) { palSetLineMode(AUDIO_PIN, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(AUDIO_PWM_PAL_MODE)); #endif - gptStart(&GPTD6, &gptCFG); + gptStart(&AUDIO_STATE_TIMER, &gptCFG); } void audio_driver_start(void) { @@ -121,13 +121,13 @@ void audio_driver_start(void) { channel_1_start(); if (playing_note || playing_melody) { - gptStartContinuous(&GPTD6, 64); + gptStartContinuous(&AUDIO_STATE_TIMER, 64); } } void audio_driver_stop(void) { channel_1_stop(); - gptStopTimer(&GPTD6); + gptStopTimer(&AUDIO_STATE_TIMER); } /* a regular timer task, that checks the note to be currently played diff --git a/quantum/audio/driver_chibios_pwm_software.c b/quantum/audio/driver_chibios_pwm_software.c index 563e9ab558c9..c4051deb4032 100644 --- a/quantum/audio/driver_chibios_pwm_software.c +++ b/quantum/audio/driver_chibios_pwm_software.c @@ -133,7 +133,7 @@ void audio_driver_initialize(void) { pwmEnablePeriodicNotification(&AUDIO_PWM_DRIVER); // enable pwm callbacks pwmEnableChannelNotification(&AUDIO_PWM_DRIVER, AUDIO_PWM_CHANNEL - 1); - gptStart(&GPTD6, &gptCFG); + gptStart(&AUDIO_STATE_TIMER, &gptCFG); } void audio_driver_start(void) { @@ -141,13 +141,13 @@ void audio_driver_start(void) { channel_1_start(); if (playing_note || playing_melody) { - gptStartContinuous(&GPTD6, 64); + gptStartContinuous(&AUDIO_STATE_TIMER, 64); } } void audio_driver_stop(void) { channel_1_stop(); - gptStopTimer(&GPTD6); + gptStopTimer(&AUDIO_STATE_TIMER); } /* a regular timer task, that checks the note to be currently played From 61df59d0d6172926eeb84869731b569e9ac93c9a Mon Sep 17 00:00:00 2001 From: JohSchneider Date: Thu, 4 Jun 2020 17:10:36 +0000 Subject: [PATCH 131/153] audio-refactoring: PLAY_NOTE_ARRAY was already removed in master --- quantum/audio/audio.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index d5f81a7d19f5..ade6b3f47b48 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -284,9 +284,6 @@ bool audio_update_state(void); // /____/ /____/ // legacy and back-warts compatibility stuff -#define PLAY_NOTE_ARRAY(note_array, note_repeat, deprecated_arg) \ - audio_play_melody(¬e_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat)); \ - _Pragma("message \"'PLAY_NOTE_ARRAY' macro is deprecated\"") // LEGACY defines - TODO: remove and replace these in all keyboards using them #ifdef A4_AUDIO From 4294fa436f4ccde61218c13c02511e42f2e47b12 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Wed, 3 Feb 2021 21:09:21 -0800 Subject: [PATCH 132/153] Add prototype for startup --- quantum/audio/audio.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index ade6b3f47b48..b4096a46e883 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -222,6 +222,8 @@ void audio_decrease_tempo(uint8_t tempo_change); uint16_t audio_duration_to_ms(uint16_t duration_bpm); uint16_t audio_ms_to_duration(uint16_t duration_ms); +void audio_startup(void); + // __ __ __ // / / / /___ __________/ / ______ __________ // / /_/ / __ `/ ___/ __ / | /| / / __ `/ ___/ _ / From 8da02d23b22143ef8623707c466114dff47df082 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Wed, 3 Feb 2021 21:16:29 -0800 Subject: [PATCH 133/153] Update chibiOS dac basic to disable pins on stop --- quantum/audio/driver_chibios_dac_basic.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index a27c8d475210..b763ea2886b9 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -100,9 +100,14 @@ static const DACConversionGroup dac_conv_grp_ch2 = {.num_channels = 1U, .trigger void channel_1_start(void) { gptStart(&GPTD6, &gpt6cfg1); gptStartContinuous(&GPTD6, 2U); + palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); } -void channel_1_stop(void) { gptStopTimer(&GPTD6); } +void channel_1_stop(void) { + gptStopTimer(&GPTD6); + palSetPadMode(GPIOA, 4, PAL_MODE_OUTPUT_PUSHPULL); + palSetPad(GPIOA, 4); +} static float channel_1_frequency = 0.0f; void channel_1_set_frequency(float freq) { @@ -120,9 +125,14 @@ float channel_1_get_frequency(void) { return channel_1_frequency; } void channel_2_start(void) { gptStart(&GPTD7, &gpt7cfg1); gptStartContinuous(&GPTD7, 2U); + palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); } -void channel_2_stop(void) { gptStopTimer(&GPTD7); } +void channel_2_stop(void) { + gptStopTimer(&GPTD7); + palSetPadMode(GPIOA, 5, PAL_MODE_OUTPUT_PUSHPULL); \ + palSetPad(GPIOA, 5); +} static float channel_2_frequency = 0.0f; void channel_2_set_frequency(float freq) { From 60ed1914ec45c46bc62914b5b764365510334233 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Wed, 3 Feb 2021 21:50:10 -0800 Subject: [PATCH 134/153] Add defaults for Proton C --- platforms/chibios/QMK_PROTON_C/configs/config.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/platforms/chibios/QMK_PROTON_C/configs/config.h b/platforms/chibios/QMK_PROTON_C/configs/config.h index a73f0c0b475a..5e29d1fce154 100644 --- a/platforms/chibios/QMK_PROTON_C/configs/config.h +++ b/platforms/chibios/QMK_PROTON_C/configs/config.h @@ -18,3 +18,10 @@ #ifndef EARLY_INIT_PERFORM_BOOTLOADER_JUMP # define EARLY_INIT_PERFORM_BOOTLOADER_JUMP TRUE #endif + + +#if defined(AUDIO_ENABLE) && defined(AUDIO_DRIVER_DAC) && !defined(AUDIO_PIN) +# define AUDIO_PIN A5 +# define AUDIO_PIN_ALT A4 +# define AUDIO_PIN_ALT_AS_NEGATIVE +#endif From 0cf5829d8676a998075faa14d76b34936e698d17 Mon Sep 17 00:00:00 2001 From: Joshua Diamond Date: Sun, 7 Feb 2021 14:46:19 -0500 Subject: [PATCH 135/153] avoid hanging audio if note is completely missed --- quantum/audio/audio.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 0beb56482509..8f13d65dce5e 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -424,7 +424,23 @@ bool audio_update_state(void) { // '- delta': Skip forward in the next note's length if we've over shot // the last, so the overall length of the song is the same - uint16_t duration = audio_duration_to_ms((*notes_pointer)[current_note][1]) - delta; + uint16_t duration = audio_duration_to_ms((*notes_pointer)[current_note][1]); + + // Skip forward past any completely missed notes + while (delta > duration && current_note < notes_count - 1) { + delta -= duration; + current_note++; + duration = audio_duration_to_ms((*notes_pointer)[current_note][1]); + } + + if (delta < duration) { + duration -= delta; + } else { + // Only way to get here is if it is the last note and + // we have completely missed it. Play it for 1ms... + duration = 1; + } + audio_play_note((*notes_pointer)[current_note][0], duration); melody_current_note_duration = duration; } From bb05c3c32de76a8c12e81fc9ff429d5e673c09f8 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Sun, 7 Feb 2021 13:47:13 -0800 Subject: [PATCH 136/153] Don't redefine pins if they're already defined --- quantum/audio/audio.h | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index b4096a46e883..140fc92f3143 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -286,7 +286,6 @@ bool audio_update_state(void); // /____/ /____/ // legacy and back-warts compatibility stuff - // LEGACY defines - TODO: remove and replace these in all keyboards using them #ifdef A4_AUDIO # define AUDIO_PIN A4 @@ -294,23 +293,27 @@ bool audio_update_state(void); #ifdef A5_AUDIO # define AUDIO_PIN A5 #endif -#ifdef B5_AUDIO -# define AUDIO_PIN_ALT B5 -#endif -#ifdef B6_AUDIO -# define AUDIO_PIN_ALT B6 -#endif -#ifdef B7_AUDIO -# define AUDIO_PIN_ALT B7 -#endif -#ifdef C4_AUDIO -# define AUDIO_PIN C4 -#endif -#ifdef C5_AUDIO -# define AUDIO_PIN C5 +#if !defined(AUDIO_PIN_ALT) +# ifdef B5_AUDIO +# define AUDIO_PIN_ALT B5 +# endif +# ifdef B6_AUDIO +# define AUDIO_PIN_ALT B6 +# endif +# ifdef B7_AUDIO +# define AUDIO_PIN_ALT B7 +# endif #endif -#ifdef C6_AUDIO -# define AUDIO_PIN C6 +#if !defined(AUDIO_PIN) +# ifdef C4_AUDIO +# define AUDIO_PIN C4 +# endif +# ifdef C5_AUDIO +# define AUDIO_PIN C5 +# endif +# ifdef C6_AUDIO +# define AUDIO_PIN C6 +# endif #endif #define is_audio_on() audio_is_on() From 52f68c4e6b106fb719c1523ca97b25dc058f9582 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Sun, 7 Feb 2021 15:11:25 -0800 Subject: [PATCH 137/153] Define A4 and A5 for CTPC support --- quantum/audio/driver_chibios_dac.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/quantum/audio/driver_chibios_dac.h b/quantum/audio/driver_chibios_dac.h index 14c9a90000e3..c2761e85bbf7 100644 --- a/quantum/audio/driver_chibios_dac.h +++ b/quantum/audio/driver_chibios_dac.h @@ -15,6 +15,13 @@ */ #pragma once +#ifndef A4 +# define A4 PAL_LINE(GPIOA, 4) +#endif +#ifndef A5 +# define A5 PAL_LINE(GPIOA, 5) +#endif + /** * Size of the dac_buffer arrays. All must be the same size. */ From 62942f58d4ffcb372f7e2df793e2b8037aa767bf Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Sun, 7 Feb 2021 15:33:49 -0800 Subject: [PATCH 138/153] Add license headers to keymap files --- .../planck/keymaps/synth_sample/config.h | 18 +- .../planck/keymaps/synth_sample/keymap.c | 2 - .../planck/keymaps/synth_sample/sample.h | 7567 +++++++++-------- .../planck/keymaps/synth_wavetable/config.h | 18 +- .../planck/keymaps/synth_wavetable/keymap.c | 3 - .../keymaps/synth_wavetable/wavetable.h | 3983 ++++----- 6 files changed, 5826 insertions(+), 5765 deletions(-) diff --git a/keyboards/planck/keymaps/synth_sample/config.h b/keyboards/planck/keymaps/synth_sample/config.h index 77d0c445c0ed..930b26b00016 100644 --- a/keyboards/planck/keymaps/synth_sample/config.h +++ b/keyboards/planck/keymaps/synth_sample/config.h @@ -1,3 +1,20 @@ +/* +Copyright 2020 Jack Humbert + +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 2 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 . +*/ + #pragma once #ifdef AUDIO_ENABLE @@ -37,4 +54,3 @@ // Most tactile encoders have detents every 4 stages #define ENCODER_RESOLUTION 4 - diff --git a/keyboards/planck/keymaps/synth_sample/keymap.c b/keyboards/planck/keymaps/synth_sample/keymap.c index 3015b174b7c9..87a7479cef85 100644 --- a/keyboards/planck/keymaps/synth_sample/keymap.c +++ b/keyboards/planck/keymaps/synth_sample/keymap.c @@ -16,8 +16,6 @@ #include QMK_KEYBOARD_H -extern keymap_config_t keymap_config; - enum planck_layers { _QWERTY, _COLEMAK, diff --git a/keyboards/planck/keymaps/synth_sample/sample.h b/keyboards/planck/keymaps/synth_sample/sample.h index fa63dd5d067c..71c1b87e7622 100644 --- a/keyboards/planck/keymaps/synth_sample/sample.h +++ b/keyboards/planck/keymaps/synth_sample/sample.h @@ -1,3780 +1,3797 @@ +/* +Copyright 2020 Jack Humbert + +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 2 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 . +*/ + #define AUDIO_DAC_SAMPLE_CUSTOM_LENGTH 30208 static const dacsample_t dac_sample_custom[30208] = { - 2041, 2039, 2039, 2037, 2035, 2037, 2037, 2037, - 2038, 2037, 2037, 2040, 2039, 2038, 2036, 2035, - 2036, 2036, 2036, 2034, 2034, 2034, 2032, 2032, - 2033, 2034, 2032, 2030, 2029, 2031, 2030, 2029, - 2029, 2030, 2029, 2030, 2030, 2031, 2028, 2028, - 2028, 2027, 2025, 2026, 2027, 2026, 2025, 2026, - 2026, 2025, 2023, 2022, 2023, 2021, 2021, 2023, - 2020, 2023, 2023, 2022, 2022, 2021, 2021, 2020, - 2022, 2020, 2017, 2016, 2015, 2018, 2017, 2015, - 2013, 2012, 2015, 2013, 2011, 2012, 2011, 2011, - 2010, 2008, 2008, 2010, 2010, 2006, 2006, 2006, - 2004, 2005, 2006, 2006, 2005, 2002, 2005, 2003, - 2003, 2004, 2002, 2001, 2003, 2003, 2002, 2003, - 2003, 2000, 2000, 2000, 1998, 1997, 1998, 1999, - 1997, 1995, 1995, 1996, 1996, 1992, 1995, 1995, - 1994, 1994, 1995, 1997, 1996, 1996, 1997, 1997, - 1997, 1996, 1996, 1995, 1997, 1997, 1996, 1998, - 1995, 1996, 1996, 1996, 1996, 1994, 1990, 1991, - 1992, 1991, 1994, 1992, 1993, 1995, 1994, 1995, - 1992, 1991, 1991, 1992, 1993, 1992, 1992, 1993, - 1993, 1992, 1990, 1989, 1991, 1992, 1991, 1991, - 1990, 1990, 1992, 1992, 1991, 1992, 1992, 1994, - 1992, 1992, 1992, 1993, 1993, 1994, 1995, 1993, - 1991, 1992, 1990, 1989, 1990, 1988, 1988, 1987, - 1989, 1989, 1985, 1986, 1987, 1985, 1986, 1986, - 1987, 1988, 1988, 1989, 1989, 1988, 1988, 1990, - 1991, 1991, 1990, 1991, 1992, 1994, 1994, 1995, - 1994, 1995, 1997, 1995, 1995, 1995, 1997, 1997, - 1997, 1996, 1999, 2000, 1997, 1998, 1999, 2002, - 2001, 2001, 2001, 2002, 2000, 1998, 2000, 2004, - 2002, 2001, 2003, 2005, 2004, 2004, 2002, 2004, - 2004, 2001, 2000, 2001, 2003, 2005, 2005, 2005, - 2005, 2006, 2010, 2010, 2009, 2007, 2006, 2008, - 2006, 2007, 2007, 2005, 2005, 2005, 2007, 2005, - 2006, 2007, 2009, 2010, 2008, 2007, 2006, 2006, - 2005, 2005, 2005, 2004, 2005, 2004, 2004, 2003, - 2007, 2006, 2006, 2004, 2005, 2006, 2007, 2007, - 2006, 2010, 2007, 2008, 2009, 2012, 2012, 2010, - 2011, 2010, 2014, 2012, 2013, 2013, 2014, 2014, - 2013, 2012, 2012, 2012, 2010, 2013, 2012, 2010, - 2011, 2011, 2012, 2012, 2013, 2013, 2015, 2016, - 2015, 2015, 2015, 2015, 2015, 2014, 2012, 2014, - 2016, 2017, 2016, 2015, 2018, 2019, 2017, 2017, - 2017, 2017, 2016, 2016, 2017, 2017, 2018, 2021, - 2020, 2019, 2019, 2022, 2022, 2024, 2024, 2023, - 2023, 2023, 2024, 2025, 2026, 2025, 2024, 2025, - 2025, 2026, 2026, 2023, 2023, 2023, 2023, 2023, - 2023, 2024, 2024, 2025, 2024, 2022, 2022, 2021, - 2021, 2022, 2022, 2024, 2023, 2023, 2023, 2021, - 2023, 2023, 2024, 2024, 2025, 2024, 2026, 2027, - 2025, 2026, 2028, 2026, 2027, 2027, 2025, 2024, - 2027, 2028, 2027, 2028, 2027, 2027, 2028, 2028, - 2030, 2029, 2032, 2031, 2030, 2029, 2028, 2030, - 2027, 2028, 2028, 2028, 2026, 2027, 2028, 2027, - 2029, 2032, 2030, 2030, 2032, 2033, 2030, 2030, - 2032, 2030, 2030, 2030, 2032, 2032, 2033, 2031, - 2034, 2032, 2029, 2028, 2028, 2030, 2028, 2029, - 2030, 2028, 2029, 2029, 2029, 2030, 2032, 2033, - 2031, 2036, 2034, 2032, 2032, 2031, 2032, 2031, - 2032, 2033, 2035, 2033, 2032, 2034, 2035, 2036, - 2037, 2038, 2039, 2038, 2038, 2038, 2040, 2040, - 2041, 2041, 2041, 2043, 2041, 2041, 2043, 2043, - 2041, 2040, 2042, 2042, 2042, 2044, 2044, 2041, - 2042, 2043, 2042, 2044, 2043, 2044, 2044, 2045, - 2045, 2044, 2045, 2044, 2045, 2043, 2042, 2043, - 2043, 2043, 2043, 2044, 2044, 2044, 2045, 2044, - 2044, 2043, 2042, 2045, 2046, 2045, 2046, 2048, - 2048, 2046, 2046, 2046, 2049, 2048, 2050, 2049, - 2049, 2050, 2053, 2051, 2049, 2050, 2047, 2050, - 2048, 2052, 2050, 2051, 2053, 2051, 2051, 2048, - 2051, 2050, 2049, 2051, 2052, 2051, 2050, 2051, - 2050, 2050, 2051, 2050, 2048, 2049, 2049, 2048, - 2050, 2050, 2050, 2049, 2048, 2048, 2048, 2048, - 2049, 2049, 2049, 2050, 2051, 2050, 2053, 2051, - 2051, 2053, 2052, 2052, 2052, 2051, 2053, 2055, - 2056, 2056, 2055, 2056, 2056, 2056, 2059, 2058, - 2055, 2057, 2059, 2057, 2056, 2056, 2056, 2057, - 2059, 2060, 2060, 2059, 2059, 2059, 2059, 2061, - 2059, 2059, 2060, 2061, 2059, 2057, 2058, 2060, - 2060, 2061, 2060, 2061, 2062, 2063, 2062, 2060, - 2062, 2060, 2061, 2061, 2060, 2060, 2061, 2062, - 2062, 2062, 2061, 2059, 2062, 2063, 2062, 2063, - 2063, 2063, 2063, 2063, 2063, 2063, 2065, 2063, - 2063, 2065, 2065, 2066, 2065, 2067, 2067, 2066, - 2065, 2065, 2065, 2066, 2066, 2063, 2064, 2062, - 2063, 2062, 2062, 2061, 2062, 2063, 2062, 2061, - 2061, 2062, 2058, 2059, 2061, 2062, 2062, 2062, - 2062, 2064, 2063, 2063, 2062, 2061, 2061, 2063, - 2060, 2059, 2059, 2058, 2059, 2059, 2059, 2062, - 2063, 2063, 2062, 2061, 2061, 2061, 2061, 2062, - 2060, 2058, 2059, 2060, 2060, 2059, 2059, 2057, - 2059, 2059, 2056, 2057, 2056, 2057, 2056, 2056, - 2056, 2057, 2057, 2057, 2055, 2055, 2055, 2053, - 2054, 2054, 2054, 2054, 2052, 2051, 2054, 2055, - 2055, 2053, 2055, 2054, 2055, 2055, 2053, 2053, - 2054, 2052, 2051, 2053, 2051, 2052, 2052, 2054, - 2054, 2053, 2051, 2051, 2053, 2052, 2051, 2050, - 2049, 2049, 2048, 2049, 2049, 2047, 2046, 2047, - 2047, 2047, 2046, 2048, 2046, 2046, 2046, 2044, - 2043, 2044, 2045, 2046, 2043, 2044, 2043, 2046, - 2044, 2044, 2043, 2043, 2042, 2039, 2037, 2039, - 2038, 2039, 2039, 2038, 2038, 2038, 2039, 2036, - 2034, 2034, 2033, 2035, 2034, 2032, 2031, 2034, - 2035, 2033, 2034, 2032, 2032, 2033, 2031, 2031, - 2031, 2032, 2032, 2032, 2030, 2030, 2029, 2029, - 2029, 2025, 2024, 2024, 2024, 2025, 2025, 2028, - 2028, 2025, 2024, 2026, 2025, 2022, 2023, 2021, - 2018, 2019, 2020, 2020, 2020, 2021, 2021, 2018, - 2017, 2019, 2017, 2016, 2018, 2019, 2018, 2016, - 2017, 2016, 2014, 2017, 2017, 2017, 2016, 2014, - 2012, 2011, 2011, 2011, 2011, 2012, 2011, 2009, - 2011, 2011, 2011, 2012, 2009, 2009, 2010, 2011, - 2011, 2011, 2008, 2008, 2010, 2009, 2009, 2008, - 2007, 2010, 2009, 2011, 2012, 2011, 2012, 2012, - 2010, 2010, 2011, 2009, 2010, 2010, 2010, 2012, - 2011, 2011, 2011, 2010, 2010, 2009, 2012, 2008, - 2009, 2010, 2010, 2008, 2008, 2009, 2007, 2007, - 2007, 2007, 2009, 2008, 2006, 2006, 2010, 2011, - 2011, 2009, 2010, 2007, 2008, 2007, 2009, 2011, - 2009, 2009, 2008, 2009, 2009, 2009, 2007, 2010, - 2008, 2009, 2013, 2011, 2011, 2009, 2010, 2009, - 2007, 2007, 2008, 2008, 2009, 2010, 2008, 2009, - 2009, 2010, 2010, 2010, 2009, 2007, 2008, 2007, - 2011, 2012, 2010, 2009, 2009, 2010, 2008, 2010, - 2011, 2010, 2010, 2012, 2011, 2010, 2013, 2014, - 2013, 2014, 2016, 2015, 2016, 2017, 2016, 2020, - 2022, 2022, 2020, 2022, 2023, 2024, 2023, 2022, - 2021, 2020, 2023, 2022, 2023, 2022, 2023, 2024, - 2022, 2021, 2021, 2021, 2021, 2021, 2021, 2023, - 2024, 2024, 2022, 2022, 2023, 2026, 2027, 2024, - 2025, 2029, 2027, 2029, 2030, 2029, 2029, 2028, - 2029, 2029, 2028, 2031, 2031, 2029, 2027, 2026, - 2026, 2028, 2025, 2025, 2021, 2022, 2025, 2025, - 2028, 2026, 2025, 2025, 2023, 2024, 2024, 2027, - 2027, 2029, 2028, 2025, 2027, 2029, 2031, 2028, - 2026, 2028, 2028, 2028, 2028, 2030, 2026, 2028, - 2029, 2029, 2030, 2030, 2030, 2032, 2032, 2032, - 2031, 2030, 2031, 2031, 2033, 2035, 2033, 2032, - 2031, 2032, 2032, 2032, 2032, 2031, 2030, 2030, - 2028, 2030, 2029, 2027, 2029, 2028, 2027, 2029, - 2032, 2031, 2031, 2032, 2030, 2029, 2032, 2033, - 2032, 2027, 2026, 2029, 2030, 2031, 2033, 2033, - 2033, 2035, 2035, 2034, 2035, 2034, 2035, 2036, - 2037, 2035, 2035, 2034, 2034, 2034, 2037, 2036, - 2035, 2033, 2033, 2034, 2033, 2035, 2035, 2036, - 2038, 2037, 2035, 2038, 2038, 2033, 2033, 2035, - 2036, 2036, 2038, 2037, 2037, 2038, 2038, 2039, - 2039, 2038, 2038, 2040, 2041, 2040, 2042, 2042, - 2042, 2043, 2042, 2040, 2041, 2040, 2041, 2043, - 2040, 2042, 2042, 2041, 2044, 2045, 2043, 2043, - 2045, 2045, 2047, 2045, 2044, 2046, 2045, 2048, - 2049, 2050, 2050, 2050, 2050, 2048, 2050, 2051, - 2050, 2050, 2052, 2053, 2053, 2055, 2054, 2053, - 2055, 2053, 2053, 2052, 2050, 2052, 2052, 2053, - 2053, 2054, 2053, 2055, 2056, 2055, 2053, 2053, - 2054, 2054, 2056, 2054, 2054, 2056, 2054, 2053, - 2054, 2057, 2055, 2054, 2056, 2057, 2056, 2058, - 2057, 2058, 2059, 2057, 2058, 2057, 2057, 2055, - 2056, 2056, 2055, 2059, 2057, 2055, 2052, 2050, - 2053, 2054, 2052, 2053, 2055, 2056, 2055, 2054, - 2055, 2055, 2053, 2053, 2053, 2054, 2055, 2055, - 2055, 2052, 2054, 2056, 2057, 2059, 2058, 2055, - 2056, 2057, 2056, 2056, 2056, 2057, 2057, 2056, - 2057, 2056, 2057, 2055, 2056, 2057, 2057, 2058, - 2057, 2055, 2055, 2056, 2057, 2056, 2056, 2056, - 2057, 2057, 2058, 2058, 2058, 2059, 2057, 2056, - 2057, 2055, 2053, 2055, 2056, 2056, 2056, 2057, - 2059, 2058, 2058, 2058, 2057, 2060, 2058, 2058, - 2058, 2059, 2059, 2060, 2061, 2060, 2058, 2059, - 2060, 2060, 2058, 2058, 2059, 2058, 2056, 2058, - 2059, 2059, 2058, 2058, 2057, 2059, 2060, 2058, - 2058, 2058, 2057, 2059, 2058, 2056, 2061, 2061, - 2060, 2059, 2061, 2062, 2062, 2062, 2059, 2061, - 2059, 2058, 2060, 2061, 2058, 2058, 2058, 2059, - 2059, 2057, 2060, 2058, 2058, 2057, 2055, 2054, - 2056, 2056, 2059, 2056, 2056, 2059, 2059, 2057, - 2055, 2052, 2051, 2052, 2052, 2052, 2053, 2051, - 2052, 2052, 2051, 2050, 2048, 2049, 2050, 2052, - 2050, 2052, 2051, 2052, 2053, 2052, 2050, 2050, - 2052, 2051, 2051, 2053, 2052, 2051, 2053, 2055, - 2055, 2054, 2053, 2054, 2051, 2052, 2052, 2053, - 2053, 2052, 2052, 2053, 2053, 2049, 2048, 2051, - 2048, 2048, 2049, 2050, 2051, 2049, 2047, 2047, - 2049, 2050, 2051, 2049, 2048, 2045, 2045, 2046, - 2046, 2046, 2045, 2046, 2045, 2043, 2044, 2043, - 2043, 2043, 2044, 2042, 2042, 2042, 2044, 2046, - 2044, 2039, 2040, 2039, 2038, 2040, 2040, 2040, - 2040, 2039, 2039, 2039, 2037, 2036, 2036, 2037, - 2037, 2034, 2036, 2035, 2034, 2033, 2033, 2031, - 2029, 2027, 2029, 2028, 2028, 2029, 2030, 2029, - 2027, 2027, 2026, 2028, 2028, 2026, 2026, 2024, - 2025, 2028, 2027, 2025, 2026, 2027, 2023, 2018, - 2017, 2021, 2020, 2019, 2018, 2016, 2014, 2013, - 2011, 2010, 2007, 2010, 2009, 2006, 2008, 2008, - 2004, 2005, 2006, 2009, 2009, 2010, 2009, 2007, - 2007, 2008, 2007, 2006, 2008, 2009, 2008, 2008, - 2006, 2007, 2009, 2008, 2007, 2007, 2008, 2007, - 2007, 2009, 2008, 2007, 2008, 2009, 2007, 2006, - 2005, 2004, 2007, 2006, 2006, 2004, 2004, 2003, - 2001, 2001, 2002, 2004, 2003, 2003, 2001, 2001, - 2002, 1998, 2000, 1999, 2000, 2001, 2001, 1999, - 2000, 1999, 1998, 1998, 2001, 2000, 1998, 1997, - 1996, 1995, 1994, 1994, 1995, 1995, 1993, 1996, - 1996, 1994, 1992, 1992, 1993, 1991, 1990, 1989, - 1991, 1987, 1988, 1989, 1989, 1989, 1992, 1990, - 1992, 1993, 1992, 1993, 1992, 1990, 1989, 1991, - 1990, 1990, 1988, 1989, 1991, 1991, 1992, 1991, - 1994, 1993, 1991, 1991, 1991, 1991, 1989, 1990, - 1990, 1991, 1989, 1991, 1990, 1991, 1989, 1988, - 1988, 1987, 1987, 1990, 1990, 1988, 1988, 1988, - 1988, 1987, 1987, 1984, 1986, 1985, 1986, 1988, - 1988, 1987, 1987, 1988, 1987, 1988, 1989, 1988, - 1989, 1991, 1990, 1988, 1990, 1989, 1987, 1987, - 1987, 1985, 1986, 1987, 1988, 1985, 1987, 1985, - 1986, 1988, 1988, 1988, 1988, 1987, 1988, 1988, - 1988, 1988, 1989, 1987, 1988, 1989, 1989, 1991, - 1990, 1992, 1990, 1990, 1991, 1991, 1993, 1994, - 1994, 1996, 1993, 1995, 1995, 1998, 1997, 1996, - 1997, 1997, 1998, 1998, 1997, 1999, 1999, 2000, - 2001, 2003, 2004, 2004, 2006, 2005, 2003, 2008, - 2006, 2005, 2005, 2005, 2008, 2009, 2011, 2011, - 2009, 2008, 2010, 2010, 2012, 2013, 2014, 2015, - 2015, 2014, 2015, 2015, 2013, 2013, 2013, 2013, - 2014, 2015, 2018, 2018, 2016, 2016, 2018, 2019, - 2017, 2015, 2017, 2016, 2016, 2016, 2015, 2017, - 2018, 2018, 2017, 2016, 2018, 2017, 2019, 2018, - 2016, 2015, 2014, 2014, 2016, 2018, 2018, 2015, - 2016, 2016, 2017, 2017, 2016, 2015, 2015, 2015, - 2015, 2018, 2016, 2017, 2016, 2014, 2016, 2017, - 2020, 2019, 2018, 2018, 2016, 2017, 2019, 2017, - 2017, 2013, 2015, 2016, 2015, 2015, 2016, 2016, - 2017, 2015, 2013, 2016, 2016, 2017, 2018, 2017, - 2016, 2017, 2016, 2016, 2017, 2019, 2019, 2021, - 2020, 2018, 2019, 2019, 2019, 2018, 2018, 2018, - 2020, 2021, 2022, 2023, 2019, 2018, 2022, 2022, - 2022, 2022, 2023, 2024, 2021, 2022, 2023, 2024, - 2024, 2024, 2025, 2027, 2028, 2029, 2030, 2028, - 2029, 2027, 2028, 2026, 2029, 2028, 2029, 2030, - 2029, 2031, 2029, 2030, 2029, 2028, 2028, 2030, - 2029, 2029, 2031, 2029, 2029, 2030, 2029, 2030, - 2030, 2029, 2027, 2026, 2025, 2024, 2024, 2023, - 2024, 2024, 2024, 2023, 2024, 2024, 2025, 2029, - 2027, 2025, 2027, 2029, 2029, 2033, 2034, 2035, - 2034, 2036, 2038, 2035, 2035, 2036, 2037, 2038, - 2036, 2038, 2038, 2037, 2038, 2039, 2039, 2033, - 2031, 2031, 2030, 2030, 2029, 2031, 2031, 2031, - 2031, 2032, 2034, 2034, 2037, 2038, 2038, 2039, - 2038, 2037, 2040, 2039, 2041, 2040, 2039, 2039, - 2038, 2041, 2038, 2035, 2037, 2037, 2037, 2035, - 2033, 2036, 2037, 2037, 2037, 2036, 2036, 2037, - 2035, 2036, 2038, 2039, 2040, 2039, 2039, 2038, - 2039, 2041, 2042, 2042, 2044, 2042, 2042, 2041, - 2041, 2040, 2041, 2041, 2040, 2041, 2041, 2042, - 2042, 2039, 2041, 2040, 2040, 2038, 2030, 2025, - 2024, 2015, 1982, 1933, 1910, 1911, 1896, 1878, - 1888, 1889, 1882, 1894, 1915, 1938, 1950, 1959, - 1977, 1987, 1989, 2008, 2032, 2054, 2074, 2093, - 2112, 2129, 2145, 2158, 2166, 2164, 2146, 2135, - 2129, 2105, 2079, 2064, 2040, 2017, 1999, 1987, - 1980, 1972, 1963, 1962, 1963, 1965, 1968, 1974, - 1982, 1991, 2001, 2014, 2031, 2043, 2058, 2074, - 2089, 2102, 2120, 2136, 2134, 2127, 2123, 2121, - 2116, 2102, 2092, 2087, 2073, 2048, 2032, 2017, - 1998, 1986, 1973, 1960, 1956, 1949, 1945, 1951, - 1957, 1960, 1964, 1976, 1985, 1994, 2014, 2031, - 2039, 2059, 2079, 2089, 2104, 2113, 2117, 2118, - 2114, 2115, 2117, 2112, 2108, 2106, 2085, 2057, - 2049, 2039, 2026, 2019, 2006, 1988, 1975, 1961, - 1958, 1961, 1957, 1956, 1962, 1965, 1966, 1975, - 1988, 1997, 2008, 2012, 2018, 2029, 2036, 2047, - 2059, 2063, 2061, 2057, 2059, 2065, 2062, 2053, - 2048, 2042, 2029, 2024, 2023, 2023, 2023, 2020, - 2015, 2015, 2020, 2021, 2028, 2040, 2042, 2043, - 2049, 2053, 2053, 2058, 2066, 2068, 2061, 2071, - 2089, 2081, 2072, 2088, 2089, 2074, 2061, 2052, - 2049, 2041, 2027, 2014, 2011, 2007, 2010, 2025, - 2026, 2000, 1982, 1984, 1991, 1993, 1992, 1998, - 1997, 2001, 2015, 2038, 2052, 2052, 2057, 2068, - 2070, 2067, 2071, 2084, 2092, 2087, 2079, 2086, - 2089, 2076, 2091, 2106, 2076, 2063, 2079, 2070, - 2058, 2064, 2060, 2040, 2022, 2035, 2043, 2023, - 2024, 2042, 2037, 2022, 2026, 2044, 2030, 2014, - 2025, 2029, 2023, 2034, 2043, 2048, 2051, 2031, - 2030, 2043, 2037, 2039, 2046, 2041, 2033, 2026, - 2038, 2050, 2044, 2050, 2056, 2047, 2041, 2035, - 2036, 2044, 2035, 2028, 2033, 2028, 2029, 2031, - 2038, 2048, 2027, 2017, 2036, 2036, 2033, 2036, - 2039, 2039, 2031, 2034, 2049, 2050, 2045, 2033, - 2032, 2037, 2022, 2021, 2036, 2032, 2031, 2028, - 2032, 2038, 2028, 2028, 2036, 2025, 2017, 2013, - 2017, 2021, 2014, 2018, 2027, 2020, 2021, 2038, - 2042, 2032, 2021, 2026, 2036, 2026, 2014, 2021, - 2023, 2009, 2001, 2003, 2002, 1998, 1986, 1985, - 1992, 1981, 1979, 2006, 2013, 2003, 2013, 2026, - 2027, 2029, 2047, 2064, 2055, 2040, 2052, 2069, - 2069, 2063, 2053, 2052, 2046, 2028, 2007, 1999, - 1993, 1985, 1981, 1977, 1976, 1971, 1976, 1986, - 1977, 1973, 1984, 1996, 2006, 2018, 2029, 2038, - 2045, 2052, 2073, 2092, 2105, 2115, 2106, 2063, - 2025, 2028, 2033, 1998, 1963, 1962, 1957, 1928, - 1932, 1964, 1977, 1980, 1979, 1996, 2011, 2003, - 2001, 2012, 2028, 2039, 2041, 2060, 2086, 2091, - 2093, 2112, 2108, 2078, 2072, 2073, 2047, 2018, - 1989, 1972, 1968, 1939, 1916, 1928, 1925, 1906, - 1904, 1923, 1950, 1953, 1945, 1974, 2006, 2012, - 2042, 2095, 2105, 2098, 2110, 2108, 2097, 2111, - 2111, 2067, 2035, 2022, 1989, 1970, 1956, 1929, - 1915, 1889, 1861, 1867, 1873, 1875, 1893, 1898, - 1916, 1937, 1945, 1985, 2034, 2062, 2080, 2101, - 2113, 2117, 2142, 2178, 2174, 2152, 2142, 2126, - 2110, 2077, 2040, 2046, 2017, 1943, 1932, 1944, - 1911, 1882, 1892, 1928, 1922, 1899, 1949, 1987, - 1968, 1974, 2010, 2042, 2041, 2024, 2063, 2094, - 2082, 2105, 2114, 2114, 2123, 2111, 2131, 2121, - 2064, 2060, 2046, 2015, 2001, 1965, 1958, 1953, - 1938, 1957, 1955, 1979, 2008, 1983, 2027, 2079, - 2038, 2052, 2115, 2120, 2093, 2092, 2122, 2126, - 2103, 2103, 2109, 2106, 2073, 2025, 2035, 2018, - 1956, 1950, 1939, 1887, 1861, 1850, 1851, 1873, - 1863, 1870, 1912, 1936, 1960, 1994, 2022, 2060, - 2082, 2081, 2114, 2142, 2132, 2146, 2165, 2166, - 2156, 2137, 2143, 2144, 2100, 2076, 2083, 2051, - 2018, 2004, 1984, 1971, 1946, 1935, 1955, 1962, - 1973, 1991, 1990, 2012, 2041, 2054, 2094, 2122, - 2104, 2120, 2135, 2114, 2136, 2152, 2137, 2137, - 2123, 2128, 2127, 2082, 2083, 2077, 2017, 1986, - 1969, 1938, 1910, 1894, 1901, 1896, 1905, 1928, - 1921, 1958, 2016, 2007, 2012, 2046, 2031, 2038, - 2079, 2074, 2074, 2093, 2091, 2102, 2131, 2117, - 2102, 2109, 2101, 2084, 2076, 2073, 2058, 2032, - 2016, 2006, 2004, 2009, 1990, 1981, 2006, 1996, - 1982, 2010, 2035, 2023, 2021, 2040, 2045, 2035, - 2033, 2065, 2079, 2050, 2047, 2074, 2093, 2116, - 2124, 2123, 2129, 2117, 2126, 2145, 2157, 2161, - 2115, 2056, 2011, 1943, 1899, 1882, 1861, 1837, - 1795, 1781, 1812, 1825, 1842, 1895, 1920, 1929, - 1948, 1966, 1998, 2039, 2072, 2100, 2139, 2179, - 2230, 2299, 2359, 2371, 2355, 2347, 2345, 2314, - 2274, 2244, 2183, 2096, 2018, 1968, 1954, 1911, - 1860, 1868, 1870, 1850, 1854, 1874, 1916, 1951, - 1948, 1976, 2058, 2103, 2106, 2166, 2246, 2250, - 2237, 2292, 2361, 2357, 2314, 2333, 2334, 2254, - 2225, 2223, 2161, 2099, 2047, 2009, 2004, 1971, - 1936, 1926, 1887, 1852, 1883, 1911, 1896, 1942, - 1999, 1955, 1965, 2055, 2063, 2096, 2166, 2165, - 2156, 2152, 2153, 2179, 2174, 2160, 2142, 2090, - 2086, 2085, 2045, 2052, 2047, 2003, 1985, 1996, - 2024, 2019, 2009, 2035, 2003, 1957, 1988, 2028, - 2047, 2039, 2015, 2029, 2040, 2024, 2046, 2086, - 2086, 2049, 2036, 2066, 2056, 2031, 2046, 2058, - 2024, 2008, 2029, 2032, 2023, 2038, 2043, 2026, - 2034, 2052, 2059, 2071, 2082, 2069, 2042, 2059, - 2091, 2079, 2065, 2085, 2086, 2066, 2100, 2140, - 2106, 2090, 2131, 2120, 2080, 2087, 2088, 2031, - 1987, 1986, 1965, 1930, 1928, 1957, 1972, 1962, - 1969, 2023, 2075, 2066, 2085, 2149, 2139, 2113, - 2166, 2204, 2159, 2145, 2185, 2183, 2164, 2192, - 2207, 2198, 2220, 2226, 2194, 2186, 2185, 2160, - 2127, 2116, 2092, 2018, 1990, 2024, 2011, 1975, - 2015, 2069, 2056, 2051, 2112, 2149, 2131, 2136, - 2165, 2167, 2147, 2143, 2161, 2183, 2178, 2173, - 2217, 2237, 2217, 2227, 2217, 2182, 2153, 2107, - 2080, 2073, 2026, 1969, 1939, 1909, 1879, 1869, - 1888, 1899, 1891, 1904, 1935, 1966, 1995, 2030, - 2069, 2105, 2107, 2085, 2107, 2134, 2109, 2104, - 2149, 2159, 2133, 2156, 2196, 2187, 2184, 2200, - 2191, 2162, 2140, 2110, 2059, 1991, 1940, 1916, - 1882, 1870, 1864, 1831, 1829, 1866, 1889, 1900, - 1928, 1948, 1934, 1917, 1941, 1954, 1934, 1942, - 1953, 1937, 1957, 1998, 2036, 2076, 2104, 2124, - 2126, 2111, 2113, 2116, 2079, 2029, 1992, 1945, - 1883, 1881, 1918, 1894, 1878, 1928, 1936, 1936, - 1997, 2025, 2012, 2037, 2053, 2045, 2058, 2068, - 2078, 2105, 2120, 2110, 2107, 2116, 2123, 2133, - 2150, 2145, 2135, 2139, 2111, 2106, 2141, 2125, - 2099, 2107, 2100, 2097, 2109, 2113, 2126, 2133, - 2135, 2158, 2179, 2177, 2167, 2177, 2189, 2156, - 2127, 2146, 2115, 2068, 2098, 2095, 2055, 2055, - 2064, 2077, 2086, 2096, 2135, 2152, 2148, 2171, - 2176, 2162, 2172, 2168, 2159, 2144, 2126, 2121, - 2095, 2097, 2110, 2083, 2090, 2108, 2094, 2086, - 2083, 2064, 2042, 2027, 2022, 2000, 1986, 1994, - 1989, 1997, 2002, 2004, 2048, 2075, 2066, 2096, - 2114, 2096, 2102, 2113, 2081, 2049, 2051, 2061, - 2039, 2025, 2034, 2017, 2016, 2032, 2055, 2065, - 2063, 2080, 2084, 2063, 2042, 2053, 2030, 1987, - 2002, 1986, 1928, 1937, 1953, 1924, 1937, 1982, - 1985, 1973, 1983, 1989, 1971, 1963, 1975, 1953, - 1915, 1900, 1906, 1928, 1934, 1936, 1935, 1944, - 1964, 1966, 1954, 1945, 1926, 1895, 1876, 1856, - 1826, 1814, 1808, 1791, 1785, 1797, 1802, 1819, - 1840, 1849, 1875, 1900, 1890, 1886, 1908, 1923, - 1913, 1891, 1897, 1915, 1902, 1902, 1923, 1935, - 1960, 1988, 2021, 2066, 2093, 2121, 2153, 2175, - 2204, 2227, 2229, 2241, 2257, 2266, 2270, 2291, - 2314, 2318, 2338, 2362, 2337, 2306, 2310, 2309, - 2272, 2231, 2194, 2176, 2193, 2173, 2148, 2166, - 2180, 2188, 2212, 2244, 2271, 2300, 2316, 2313, - 2346, 2371, 2353, 2356, 2371, 2361, 2340, 2332, - 2340, 2330, 2322, 2329, 2336, 2339, 2331, 2337, - 2354, 2328, 2297, 2297, 2276, 2254, 2251, 2251, - 2267, 2287, 2299, 2312, 2353, 2396, 2393, 2380, - 2388, 2374, 2323, 2274, 2243, 2211, 2164, 2120, - 2103, 2099, 2073, 2055, 2068, 2065, 2049, 2043, - 2037, 2025, 2017, 2011, 2000, 1995, 1992, 1977, - 1967, 1979, 1977, 1955, 1948, 1951, 1946, 1923, - 1905, 1895, 1864, 1815, 1765, 1733, 1683, 1627, - 1593, 1563, 1542, 1544, 1551, 1563, 1590, 1613, - 1631, 1654, 1676, 1692, 1698, 1703, 1716, 1731, - 1743, 1767, 1789, 1802, 1817, 1839, 1859, 1863, - 1856, 1843, 1827, 1801, 1774, 1754, 1727, 1695, - 1677, 1654, 1635, 1635, 1625, 1610, 1618, 1634, - 1634, 1643, 1665, 1681, 1689, 1711, 1726, 1742, - 1774, 1815, 1880, 1951, 2022, 2119, 2197, 2263, - 2363, 2462, 2534, 2609, 2666, 2684, 2710, 2746, - 2766, 2776, 2767, 2757, 2763, 2765, 2770, 2760, - 2731, 2718, 2701, 2673, 2666, 2653, 2622, 2604, - 2616, 2632, 2630, 2655, 2718, 2777, 2832, 2873, - 2915, 2982, 3039, 3059, 3076, 3083, 3031, 2947, - 2886, 2790, 2659, 2541, 2422, 2298, 2187, 2089, - 2012, 1960, 1912, 1862, 1820, 1812, 1835, 1854, - 1884, 1926, 1963, 1992, 2034, 2093, 2133, 2162, - 2205, 2232, 2233, 2245, 2258, 2252, 2247, 2228, - 2184, 2136, 2088, 2040, 1994, 1963, 1932, 1898, - 1889, 1908, 1931, 1964, 2010, 2050, 2083, 2116, - 2151, 2177, 2197, 2209, 2200, 2178, 2150, 2115, - 2066, 2015, 1957, 1883, 1804, 1730, 1654, 1568, - 1487, 1408, 1326, 1253, 1202, 1167, 1145, 1151, - 1180, 1227, 1295, 1377, 1462, 1555, 1648, 1727, - 1796, 1855, 1892, 1913, 1929, 1931, 1916, 1892, - 1856, 1820, 1784, 1738, 1689, 1637, 1584, 1541, - 1504, 1470, 1443, 1431, 1421, 1422, 1454, 1496, - 1546, 1619, 1694, 1765, 1857, 1957, 2043, 2126, - 2187, 2228, 2280, 2307, 2307, 2322, 2309, 2280, - 2262, 2240, 2227, 2237, 2241, 2254, 2279, 2311, - 2352, 2392, 2436, 2473, 2505, 2567, 2638, 2668, - 2697, 2757, 2812, 2856, 2902, 2928, 2945, 2967, - 2985, 2986, 2985, 2982, 2970, 2957, 2932, 2917, - 2937, 2958, 2961, 2977, 3007, 3023, 3065, 3135, - 3154, 3137, 3091, 2996, 2881, 2762, 2607, 2430, - 2270, 2102, 1967, 1888, 1827, 1784, 1774, 1771, - 1771, 1779, 1790, 1792, 1788, 1781, 1776, 1780, - 1798, 1843, 1889, 1941, 2014, 2092, 2170, 2242, - 2299, 2344, 2381, 2408, 2411, 2392, 2350, 2297, - 2244, 2188, 2151, 2119, 2096, 2080, 2086, 2108, - 2139, 2178, 2208, 2221, 2219, 2211, 2187, 2143, - 2087, 2017, 1940, 1863, 1792, 1733, 1681, 1631, - 1583, 1530, 1478, 1435, 1393, 1353, 1316, 1282, - 1257, 1246, 1248, 1269, 1308, 1345, 1390, 1452, - 1515, 1573, 1631, 1676, 1708, 1738, 1755, 1752, - 1740, 1718, 1678, 1636, 1597, 1560, 1527, 1500, - 1476, 1460, 1463, 1478, 1487, 1506, 1540, 1576, - 1612, 1668, 1726, 1786, 1863, 1927, 1999, 2116, - 2199, 2257, 2356, 2424, 2455, 2493, 2514, 2529, - 2536, 2529, 2516, 2496, 2487, 2480, 2468, 2461, - 2452, 2449, 2466, 2501, 2527, 2557, 2594, 2636, - 2682, 2733, 2769, 2807, 2872, 2910, 2921, 2966, - 3030, 3088, 3147, 3185, 3218, 3259, 3314, 3374, - 3388, 3375, 3362, 3368, 3375, 3366, 3338, 3227, - 3059, 2936, 2802, 2623, 2447, 2265, 2083, 1951, - 1873, 1837, 1819, 1812, 1806, 1806, 1824, 1841, - 1851, 1853, 1825, 1786, 1762, 1759, 1778, 1799, - 1811, 1841, 1898, 1971, 2050, 2110, 2151, 2179, - 2195, 2203, 2203, 2192, 2176, 2146, 2138, 2149, - 2172, 2204, 2235, 2273, 2315, 2363, 2418, 2466, - 2496, 2505, 2495, 2469, 2439, 2397, 2321, 2217, - 2109, 2007, 1915, 1837, 1772, 1708, 1649, 1602, - 1566, 1526, 1470, 1398, 1324, 1250, 1186, 1129, - 1086, 1072, 1075, 1104, 1155, 1226, 1311, 1390, - 1462, 1520, 1560, 1586, 1597, 1584, 1562, 1537, - 1500, 1471, 1448, 1423, 1402, 1392, 1403, 1417, - 1436, 1462, 1497, 1531, 1571, 1613, 1654, 1693, - 1722, 1758, 1814, 1873, 1932, 1999, 2068, 2129, - 2200, 2288, 2360, 2394, 2415, 2415, 2392, 2377, - 2356, 2314, 2263, 2220, 2206, 2218, 2251, 2294, - 2337, 2363, 2393, 2438, 2495, 2547, 2566, 2559, - 2562, 2588, 2624, 2666, 2709, 2732, 2741, 2785, - 2857, 2907, 2948, 2987, 3028, 3078, 3140, 3206, - 3255, 3286, 3297, 3318, 3359, 3381, 3376, 3373, - 3353, 3261, 3141, 3049, 2919, 2735, 2553, 2360, - 2188, 2078, 2000, 1936, 1890, 1861, 1845, 1848, - 1861, 1863, 1847, 1832, 1817, 1805, 1799, 1786, - 1774, 1775, 1787, 1792, 1805, 1849, 1912, 1961, - 1996, 2042, 2087, 2111, 2118, 2115, 2101, 2083, - 2073, 2081, 2105, 2128, 2151, 2186, 2238, 2297, - 2350, 2399, 2441, 2474, 2487, 2480, 2458, 2418, - 2344, 2245, 2137, 2031, 1931, 1843, 1758, 1680, - 1623, 1574, 1514, 1466, 1423, 1358, 1288, 1243, - 1198, 1146, 1111, 1103, 1113, 1150, 1195, 1244, - 1311, 1383, 1443, 1495, 1540, 1567, 1569, 1559, - 1540, 1517, 1485, 1447, 1408, 1367, 1337, 1320, - 1311, 1321, 1340, 1356, 1389, 1459, 1526, 1582, - 1659, 1739, 1799, 1864, 1928, 1978, 2035, 2088, - 2126, 2179, 2241, 2284, 2325, 2368, 2389, 2399, - 2414, 2406, 2385, 2367, 2333, 2295, 2294, 2309, - 2314, 2334, 2371, 2399, 2441, 2502, 2553, 2596, - 2635, 2651, 2679, 2731, 2789, 2823, 2844, 2861, - 2884, 2921, 2960, 3004, 3027, 3029, 3057, 3111, - 3181, 3251, 3291, 3320, 3363, 3407, 3433, 3458, - 3475, 3419, 3287, 3161, 3060, 2925, 2788, 2641, - 2459, 2316, 2249, 2211, 2185, 2170, 2134, 2079, - 2044, 2037, 2017, 1964, 1880, 1795, 1725, 1681, - 1658, 1653, 1655, 1661, 1694, 1754, 1843, 1947, - 2015, 2054, 2081, 2102, 2127, 2137, 2118, 2081, - 2049, 2039, 2058, 2094, 2124, 2144, 2165, 2204, - 2265, 2332, 2388, 2414, 2420, 2416, 2411, 2405, - 2381, 2315, 2216, 2133, 2069, 2004, 1955, 1909, - 1847, 1795, 1757, 1709, 1660, 1607, 1516, 1410, - 1330, 1252, 1168, 1113, 1080, 1063, 1082, 1126, - 1180, 1255, 1338, 1398, 1449, 1496, 1523, 1519, - 1495, 1465, 1438, 1404, 1357, 1317, 1292, 1272, - 1262, 1270, 1293, 1314, 1343, 1394, 1447, 1498, - 1554, 1607, 1645, 1702, 1762, 1800, 1846, 1912, - 1975, 2039, 2110, 2189, 2264, 2336, 2396, 2435, - 2467, 2473, 2457, 2433, 2402, 2364, 2333, 2317, - 2315, 2329, 2356, 2391, 2441, 2503, 2557, 2593, - 2632, 2678, 2718, 2738, 2745, 2762, 2784, 2803, - 2835, 2876, 2895, 2927, 2997, 3046, 3098, 3186, - 3242, 3273, 3344, 3410, 3434, 3453, 3465, 3456, - 3444, 3411, 3316, 3201, 3100, 2979, 2842, 2716, - 2594, 2480, 2382, 2314, 2287, 2267, 2228, 2179, - 2143, 2119, 2086, 2047, 2013, 1979, 1939, 1893, - 1847, 1832, 1837, 1824, 1802, 1801, 1828, 1864, - 1900, 1931, 1955, 1974, 1982, 1989, 1997, 2002, - 1990, 1983, 2001, 2040, 2081, 2108, 2145, 2201, - 2261, 2317, 2368, 2413, 2445, 2458, 2460, 2458, - 2449, 2422, 2357, 2270, 2201, 2148, 2088, 2020, - 1948, 1869, 1802, 1737, 1670, 1617, 1554, 1464, - 1386, 1338, 1296, 1250, 1212, 1189, 1191, 1213, - 1236, 1271, 1320, 1364, 1392, 1423, 1454, 1468, - 1455, 1429, 1400, 1373, 1340, 1305, 1263, 1234, - 1211, 1192, 1197, 1219, 1242, 1268, 1303, 1353, - 1421, 1491, 1555, 1618, 1679, 1757, 1830, 1879, - 1944, 2019, 2070, 2119, 2181, 2235, 2279, 2319, - 2346, 2361, 2380, 2383, 2365, 2357, 2355, 2347, - 2335, 2344, 2368, 2396, 2431, 2472, 2520, 2574, - 2619, 2666, 2725, 2772, 2805, 2838, 2875, 2914, - 2949, 2979, 3001, 3024, 3055, 3082, 3106, 3134, - 3177, 3221, 3258, 3312, 3367, 3408, 3456, 3495, - 3502, 3481, 3419, 3321, 3218, 3105, 2971, 2827, - 2692, 2583, 2498, 2440, 2404, 2379, 2350, 2316, - 2286, 2255, 2220, 2176, 2115, 2057, 1997, 1929, - 1867, 1819, 1781, 1752, 1726, 1714, 1726, 1754, - 1793, 1837, 1879, 1922, 1953, 1968, 1976, 1982, - 1979, 1967, 1966, 1976, 1985, 1999, 2030, 2074, - 2130, 2188, 2247, 2309, 2355, 2385, 2403, 2412, - 2403, 2378, 2338, 2284, 2218, 2152, 2109, 2076, - 2025, 1959, 1898, 1840, 1775, 1715, 1658, 1580, - 1500, 1425, 1356, 1307, 1269, 1221, 1177, 1165, - 1162, 1160, 1184, 1220, 1250, 1276, 1309, 1337, - 1359, 1372, 1375, 1364, 1345, 1319, 1288, 1252, - 1217, 1188, 1163, 1152, 1157, 1178, 1204, 1244, - 1288, 1344, 1407, 1466, 1524, 1589, 1649, 1710, - 1771, 1834, 1901, 1960, 2014, 2073, 2125, 2176, - 2223, 2261, 2295, 2329, 2348, 2362, 2376, 2384, - 2391, 2403, 2417, 2418, 2421, 2439, 2465, 2501, - 2540, 2581, 2624, 2676, 2722, 2765, 2824, 2870, - 2891, 2916, 2943, 2961, 2993, 3028, 3063, 3097, - 3136, 3183, 3238, 3300, 3345, 3372, 3400, 3428, - 3440, 3420, 3379, 3313, 3222, 3138, 3059, 2955, - 2843, 2738, 2634, 2561, 2514, 2465, 2418, 2379, - 2338, 2299, 2283, 2268, 2230, 2181, 2127, 2056, - 1974, 1906, 1857, 1802, 1741, 1704, 1690, 1699, - 1727, 1761, 1793, 1825, 1850, 1868, 1881, 1891, - 1887, 1875, 1873, 1881, 1885, 1895, 1920, 1950, - 1988, 2035, 2085, 2133, 2175, 2214, 2248, 2264, - 2275, 2286, 2280, 2258, 2233, 2198, 2148, 2109, - 2083, 2027, 1964, 1908, 1840, 1773, 1732, 1686, - 1620, 1566, 1512, 1443, 1392, 1359, 1301, 1247, - 1218, 1187, 1163, 1171, 1189, 1205, 1224, 1252, - 1279, 1300, 1323, 1338, 1335, 1319, 1303, 1288, - 1265, 1238, 1213, 1189, 1181, 1186, 1187, 1195, - 1223, 1250, 1283, 1334, 1388, 1436, 1500, 1563, - 1619, 1679, 1740, 1802, 1859, 1914, 1962, 2008, - 2057, 2107, 2156, 2209, 2258, 2293, 2321, 2359, - 2388, 2407, 2427, 2442, 2446, 2445, 2452, 2471, - 2494, 2516, 2543, 2579, 2620, 2666, 2717, 2769, - 2816, 2854, 2889, 2933, 2971, 3001, 3042, 3079, - 3106, 3147, 3185, 3217, 3254, 3285, 3299, 3323, - 3344, 3334, 3313, 3300, 3253, 3184, 3133, 3067, - 2976, 2893, 2808, 2725, 2666, 2615, 2555, 2509, - 2470, 2425, 2393, 2374, 2345, 2315, 2282, 2231, - 2180, 2124, 2060, 2004, 1955, 1900, 1851, 1821, - 1799, 1792, 1804, 1815, 1827, 1841, 1848, 1860, - 1876, 1881, 1882, 1888, 1893, 1893, 1898, 1914, - 1932, 1951, 1980, 2011, 2047, 2082, 2116, 2147, - 2170, 2184, 2199, 2208, 2201, 2187, 2157, 2122, - 2101, 2066, 2014, 1960, 1903, 1839, 1794, 1760, - 1711, 1669, 1632, 1587, 1555, 1537, 1503, 1467, - 1444, 1412, 1372, 1358, 1353, 1341, 1344, 1350, - 1354, 1363, 1384, 1393, 1401, 1402, 1397, 1393, - 1383, 1358, 1334, 1310, 1288, 1273, 1266, 1266, - 1268, 1275, 1299, 1334, 1370, 1415, 1467, 1515, - 1564, 1620, 1676, 1722, 1775, 1825, 1861, 1903, - 1945, 1981, 2024, 2073, 2109, 2143, 2190, 2241, - 2276, 2320, 2372, 2402, 2426, 2457, 2481, 2498, - 2521, 2544, 2563, 2584, 2603, 2629, 2662, 2696, - 2729, 2758, 2785, 2808, 2839, 2876, 2907, 2936, - 2972, 3010, 3045, 3083, 3121, 3150, 3175, 3200, - 3217, 3234, 3245, 3238, 3220, 3201, 3178, 3145, - 3107, 3061, 3001, 2936, 2877, 2827, 2774, 2718, - 2665, 2610, 2561, 2522, 2484, 2447, 2410, 2366, - 2317, 2266, 2210, 2155, 2110, 2059, 2010, 1968, - 1935, 1910, 1905, 1903, 1896, 1898, 1906, 1903, - 1903, 1912, 1912, 1910, 1919, 1926, 1926, 1927, - 1937, 1948, 1952, 1965, 1980, 1986, 2000, 2015, - 2021, 2031, 2046, 2058, 2061, 2059, 2048, 2036, - 2025, 2005, 1976, 1943, 1905, 1860, 1823, 1798, - 1772, 1745, 1719, 1685, 1659, 1644, 1621, 1597, - 1580, 1550, 1511, 1484, 1466, 1451, 1450, 1453, - 1443, 1434, 1441, 1454, 1460, 1458, 1453, 1445, - 1434, 1423, 1406, 1386, 1371, 1360, 1343, 1334, - 1335, 1333, 1336, 1350, 1370, 1394, 1429, 1471, - 1509, 1546, 1585, 1641, 1696, 1740, 1781, 1824, - 1865, 1905, 1950, 1988, 2018, 2056, 2093, 2130, - 2176, 2220, 2252, 2289, 2337, 2370, 2389, 2427, - 2464, 2479, 2504, 2542, 2566, 2591, 2627, 2654, - 2677, 2712, 2753, 2788, 2812, 2841, 2886, 2932, - 2976, 3012, 3042, 3078, 3118, 3143, 3160, 3180, - 3197, 3204, 3206, 3206, 3202, 3195, 3183, 3166, - 3140, 3105, 3074, 3045, 3003, 2952, 2903, 2859, - 2823, 2780, 2725, 2682, 2646, 2608, 2573, 2532, - 2486, 2443, 2399, 2342, 2287, 2244, 2199, 2152, - 2109, 2065, 2033, 2022, 2002, 1975, 1960, 1952, - 1938, 1935, 1934, 1928, 1921, 1922, 1924, 1924, - 1933, 1944, 1947, 1958, 1973, 1981, 1985, 1992, - 2002, 2004, 2004, 2013, 2020, 2019, 2009, 1999, - 1993, 1984, 1969, 1945, 1904, 1864, 1831, 1797, - 1768, 1741, 1709, 1678, 1655, 1641, 1628, 1613, - 1605, 1595, 1572, 1557, 1554, 1547, 1537, 1535, - 1531, 1522, 1520, 1525, 1520, 1512, 1509, 1497, - 1480, 1465, 1446, 1427, 1406, 1392, 1378, 1364, - 1360, 1354, 1347, 1355, 1374, 1390, 1413, 1439, - 1471, 1510, 1558, 1606, 1657, 1707, 1748, 1791, - 1834, 1869, 1906, 1940, 1965, 1998, 2029, 2063, - 2099, 2138, 2175, 2211, 2250, 2283, 2310, 2340, - 2370, 2396, 2422, 2455, 2477, 2504, 2533, 2565, - 2596, 2632, 2667, 2695, 2730, 2768, 2806, 2845, - 2889, 2920, 2951, 2991, 3035, 3069, 3094, 3113, - 3129, 3141, 3149, 3150, 3145, 3139, 3127, 3111, - 3102, 3091, 3065, 3039, 3017, 2982, 2948, 2918, - 2886, 2846, 2807, 2770, 2729, 2696, 2669, 2632, - 2587, 2544, 2495, 2441, 2389, 2344, 2289, 2232, - 2189, 2143, 2101, 2072, 2048, 2023, 2002, 1987, - 1970, 1954, 1949, 1935, 1922, 1923, 1914, 1906, - 1911, 1919, 1927, 1936, 1946, 1950, 1955, 1959, - 1959, 1950, 1942, 1930, 1922, 1916, 1905, 1889, - 1879, 1871, 1854, 1836, 1807, 1772, 1738, 1707, - 1679, 1653, 1632, 1608, 1582, 1569, 1559, 1542, - 1534, 1531, 1515, 1497, 1492, 1487, 1482, 1485, - 1487, 1481, 1478, 1482, 1484, 1479, 1473, 1458, - 1437, 1416, 1395, 1372, 1348, 1332, 1317, 1303, - 1295, 1293, 1294, 1301, 1313, 1328, 1347, 1367, - 1390, 1421, 1458, 1496, 1534, 1576, 1621, 1660, - 1696, 1734, 1765, 1797, 1829, 1853, 1877, 1910, - 1939, 1970, 2010, 2049, 2077, 2111, 2144, 2166, - 2196, 2231, 2253, 2281, 2309, 2331, 2361, 2403, - 2436, 2469, 2507, 2536, 2567, 2600, 2636, 2673, - 2707, 2743, 2776, 2812, 2856, 2893, 2921, 2950, - 2976, 2994, 3003, 3010, 3014, 3014, 3015, 3013, - 3005, 2999, 2989, 2978, 2966, 2953, 2939, 2915, - 2891, 2861, 2835, 2809, 2781, 2758, 2734, 2705, - 2666, 2628, 2588, 2532, 2478, 2426, 2371, 2312, - 2257, 2206, 2159, 2124, 2094, 2064, 2034, 2016, - 1990, 1973, 1967, 1947, 1929, 1921, 1907, 1890, - 1888, 1892, 1893, 1897, 1902, 1908, 1907, 1908, - 1906, 1893, 1879, 1864, 1849, 1830, 1814, 1803, - 1789, 1775, 1765, 1748, 1722, 1693, 1662, 1629, - 1597, 1568, 1539, 1512, 1496, 1481, 1467, 1458, - 1452, 1437, 1425, 1412, 1399, 1390, 1389, 1391, - 1394, 1392, 1394, 1404, 1406, 1410, 1411, 1403, - 1383, 1364, 1345, 1318, 1294, 1276, 1257, 1238, - 1231, 1226, 1222, 1227, 1234, 1240, 1255, 1274, - 1291, 1314, 1346, 1384, 1420, 1460, 1504, 1544, - 1583, 1622, 1651, 1679, 1707, 1733, 1750, 1773, - 1802, 1829, 1857, 1892, 1927, 1955, 1985, 2014, - 2040, 2061, 2090, 2114, 2132, 2160, 2194, 2226, - 2265, 2306, 2346, 2383, 2419, 2459, 2497, 2534, - 2571, 2603, 2633, 2671, 2709, 2742, 2778, 2811, - 2836, 2864, 2886, 2902, 2915, 2925, 2924, 2932, - 2938, 2943, 2943, 2944, 2945, 2942, 2941, 2935, - 2923, 2914, 2897, 2878, 2861, 2840, 2818, 2800, - 2779, 2755, 2726, 2693, 2651, 2602, 2556, 2504, - 2453, 2399, 2341, 2291, 2243, 2208, 2172, 2138, - 2111, 2082, 2053, 2035, 2022, 2002, 1987, 1977, - 1958, 1944, 1939, 1934, 1931, 1932, 1934, 1930, - 1928, 1925, 1916, 1898, 1883, 1861, 1839, 1824, - 1810, 1800, 1787, 1775, 1762, 1741, 1714, 1682, - 1650, 1616, 1578, 1545, 1514, 1482, 1464, 1449, - 1430, 1420, 1414, 1396, 1380, 1373, 1367, 1355, - 1352, 1349, 1345, 1346, 1352, 1360, 1362, 1365, - 1366, 1355, 1341, 1332, 1317, 1294, 1277, 1255, - 1233, 1221, 1215, 1209, 1208, 1212, 1212, 1219, - 1233, 1250, 1270, 1293, 1319, 1353, 1388, 1425, - 1469, 1515, 1552, 1580, 1612, 1636, 1655, 1678, - 1698, 1712, 1734, 1769, 1789, 1813, 1848, 1878, - 1901, 1929, 1952, 1969, 1991, 2013, 2035, 2059, - 2092, 2123, 2156, 2192, 2233, 2275, 2314, 2360, - 2404, 2440, 2479, 2518, 2555, 2595, 2632, 2669, - 2705, 2739, 2766, 2794, 2818, 2836, 2861, 2881, - 2889, 2901, 2915, 2929, 2946, 2966, 2973, 2975, - 2988, 2990, 2982, 2985, 2976, 2953, 2937, 2926, - 2910, 2889, 2876, 2858, 2831, 2800, 2767, 2722, - 2670, 2624, 2575, 2517, 2462, 2414, 2361, 2314, - 2276, 2243, 2208, 2180, 2156, 2125, 2099, 2085, - 2068, 2051, 2041, 2029, 2015, 2008, 2007, 2011, - 2013, 2010, 2007, 1996, 1985, 1972, 1958, 1933, - 1908, 1892, 1873, 1855, 1845, 1836, 1821, 1807, - 1790, 1762, 1733, 1706, 1674, 1638, 1604, 1576, - 1547, 1521, 1503, 1483, 1462, 1449, 1431, 1410, - 1396, 1383, 1366, 1360, 1355, 1346, 1343, 1343, - 1343, 1343, 1342, 1340, 1334, 1323, 1311, 1297, - 1283, 1268, 1251, 1236, 1220, 1209, 1204, 1200, - 1201, 1202, 1208, 1215, 1227, 1244, 1262, 1287, - 1318, 1352, 1385, 1424, 1459, 1490, 1522, 1554, - 1578, 1598, 1620, 1637, 1656, 1680, 1711, 1740, - 1764, 1797, 1826, 1854, 1884, 1916, 1945, 1967, - 1994, 2019, 2044, 2074, 2108, 2145, 2178, 2217, - 2253, 2294, 2334, 2374, 2419, 2463, 2506, 2552, - 2594, 2640, 2681, 2717, 2756, 2793, 2820, 2849, - 2878, 2903, 2924, 2948, 2968, 2982, 3009, 3030, - 3045, 3064, 3082, 3095, 3100, 3105, 3103, 3093, - 3089, 3073, 3057, 3045, 3028, 3009, 2985, 2956, - 2922, 2881, 2833, 2776, 2716, 2661, 2599, 2537, - 2483, 2428, 2378, 2336, 2295, 2260, 2229, 2206, - 2178, 2153, 2136, 2116, 2102, 2092, 2084, 2069, - 2061, 2058, 2057, 2055, 2056, 2054, 2046, 2036, - 2025, 2008, 1990, 1969, 1946, 1923, 1903, 1888, - 1873, 1860, 1852, 1833, 1811, 1788, 1760, 1735, - 1711, 1686, 1662, 1634, 1608, 1593, 1569, 1541, - 1518, 1491, 1454, 1426, 1406, 1382, 1369, 1364, - 1347, 1326, 1324, 1318, 1307, 1298, 1290, 1277, - 1261, 1252, 1242, 1229, 1219, 1211, 1195, 1178, - 1171, 1163, 1149, 1145, 1145, 1137, 1139, 1149, - 1159, 1173, 1191, 1215, 1239, 1265, 1293, 1321, - 1353, 1382, 1414, 1446, 1469, 1497, 1524, 1551, - 1583, 1614, 1642, 1665, 1697, 1727, 1753, 1787, - 1818, 1840, 1868, 1896, 1921, 1948, 1980, 2009, - 2040, 2077, 2113, 2149, 2187, 2226, 2267, 2309, - 2357, 2405, 2452, 2501, 2549, 2596, 2644, 2685, - 2722, 2759, 2797, 2831, 2863, 2900, 2934, 2958, - 2993, 3021, 3042, 3068, 3094, 3116, 3134, 3152, - 3165, 3173, 3181, 3180, 3173, 3164, 3154, 3139, - 3123, 3103, 3075, 3049, 3014, 2979, 2933, 2869, - 2798, 2732, 2669, 2597, 2532, 2466, 2396, 2341, - 2299, 2259, 2228, 2201, 2176, 2148, 2125, 2107, - 2094, 2082, 2076, 2066, 2044, 2034, 2033, 2031, - 2033, 2038, 2032, 2023, 2020, 2010, 1995, 1976, - 1956, 1932, 1907, 1887, 1870, 1854, 1843, 1834, - 1811, 1788, 1770, 1748, 1728, 1712, 1700, 1684, - 1667, 1652, 1636, 1615, 1592, 1569, 1534, 1489, - 1447, 1408, 1380, 1354, 1328, 1301, 1280, 1260, - 1242, 1231, 1219, 1201, 1179, 1159, 1137, 1121, - 1108, 1095, 1087, 1077, 1069, 1064, 1058, 1055, - 1057, 1054, 1051, 1059, 1064, 1070, 1081, 1096, - 1113, 1134, 1158, 1179, 1200, 1218, 1240, 1267, - 1293, 1322, 1349, 1373, 1409, 1452, 1491, 1529, - 1570, 1605, 1632, 1663, 1693, 1718, 1749, 1780, - 1799, 1822, 1858, 1896, 1928, 1963, 2001, 2033, - 2066, 2107, 2141, 2177, 2223, 2264, 2301, 2351, - 2400, 2449, 2498, 2546, 2593, 2636, 2683, 2730, - 2769, 2810, 2858, 2901, 2939, 2986, 3032, 3065, - 3101, 3137, 3164, 3193, 3219, 3236, 3257, 3273, - 3275, 3276, 3281, 3273, 3258, 3247, 3225, 3201, - 3173, 3143, 3108, 3061, 3009, 2947, 2872, 2788, - 2704, 2627, 2545, 2457, 2380, 2310, 2243, 2191, - 2156, 2123, 2094, 2072, 2046, 2025, 2014, 2002, - 1984, 1972, 1967, 1955, 1950, 1958, 1961, 1965, - 1970, 1975, 1972, 1964, 1960, 1943, 1920, 1898, - 1872, 1844, 1816, 1799, 1781, 1767, 1757, 1748, - 1733, 1716, 1706, 1700, 1701, 1704, 1706, 1710, - 1710, 1702, 1692, 1675, 1648, 1616, 1578, 1536, - 1492, 1453, 1411, 1382, 1356, 1321, 1289, 1266, - 1241, 1208, 1179, 1152, 1115, 1085, 1062, 1038, - 1020, 1006, 997, 994, 988, 987, 986, 993, - 998, 1002, 1012, 1021, 1036, 1049, 1060, 1076, - 1091, 1109, 1128, 1149, 1166, 1179, 1193, 1215, - 1245, 1276, 1307, 1339, 1374, 1413, 1456, 1500, - 1540, 1574, 1602, 1635, 1670, 1709, 1747, 1783, - 1820, 1860, 1899, 1941, 1988, 2035, 2076, 2112, - 2146, 2181, 2215, 2252, 2287, 2320, 2360, 2401, - 2450, 2498, 2546, 2597, 2649, 2697, 2747, 2800, - 2851, 2901, 2953, 3010, 3057, 3100, 3144, 3182, - 3221, 3265, 3301, 3327, 3359, 3385, 3406, 3427, - 3442, 3454, 3457, 3447, 3431, 3412, 3385, 3351, - 3320, 3284, 3234, 3187, 3136, 3076, 3012, 2935, - 2845, 2749, 2654, 2562, 2465, 2374, 2289, 2216, - 2153, 2100, 2059, 2020, 1990, 1968, 1946, 1926, - 1911, 1899, 1891, 1889, 1887, 1887, 1894, 1902, - 1915, 1926, 1932, 1937, 1932, 1922, 1911, 1893, - 1876, 1861, 1845, 1827, 1808, 1794, 1784, 1779, - 1776, 1762, 1745, 1734, 1725, 1730, 1743, 1757, - 1771, 1783, 1787, 1790, 1792, 1781, 1756, 1720, - 1674, 1624, 1580, 1541, 1498, 1459, 1422, 1384, - 1352, 1326, 1281, 1230, 1189, 1144, 1086, 1040, - 1005, 966, 939, 923, 915, 908, 911, 917, - 919, 922, 931, 944, 948, 952, 961, 972, - 981, 1004, 1031, 1046, 1060, 1074, 1088, 1104, - 1126, 1151, 1174, 1203, 1239, 1279, 1322, 1376, - 1421, 1457, 1494, 1528, 1559, 1586, 1625, 1665, - 1702, 1747, 1794, 1851, 1909, 1968, 2021, 2064, - 2103, 2136, 2169, 2198, 2223, 2252, 2281, 2316, - 2356, 2398, 2446, 2496, 2543, 2593, 2645, 2697, - 2748, 2803, 2862, 2919, 2979, 3036, 3090, 3140, - 3185, 3221, 3251, 3278, 3300, 3323, 3348, 3375, - 3398, 3422, 3441, 3464, 3489, 3504, 3505, 3499, - 3489, 3467, 3440, 3414, 3375, 3335, 3309, 3270, - 3221, 3180, 3122, 3038, 2947, 2844, 2737, 2623, - 2503, 2388, 2277, 2176, 2098, 2039, 1989, 1943, - 1901, 1864, 1828, 1809, 1791, 1762, 1748, 1749, - 1745, 1753, 1780, 1804, 1828, 1854, 1876, 1889, - 1902, 1911, 1910, 1896, 1888, 1889, 1886, 1879, - 1876, 1875, 1866, 1859, 1857, 1841, 1817, 1795, - 1771, 1753, 1754, 1763, 1769, 1785, 1813, 1843, - 1868, 1885, 1883, 1853, 1819, 1786, 1750, 1709, - 1667, 1624, 1580, 1548, 1525, 1496, 1462, 1419, - 1361, 1298, 1228, 1154, 1083, 1016, 951, 889, - 843, 808, 789, 778, 772, 776, 785, 797, - 812, 830, 841, 858, 880, 893, 912, 938, - 960, 985, 1021, 1052, 1081, 1115, 1145, 1182, - 1227, 1268, 1313, 1356, 1390, 1424, 1460, 1487, - 1507, 1530, 1547, 1561, 1586, 1620, 1659, 1709, - 1764, 1823, 1885, 1945, 1994, 2039, 2079, 2113, - 2138, 2162, 2190, 2211, 2237, 2270, 2316, 2368, - 2419, 2473, 2530, 2584, 2638, 2705, 2766, 2821, - 2877, 2941, 2995, 3046, 3103, 3157, 3202, 3240, - 3280, 3322, 3364, 3401, 3433, 3476, 3516, 3548, - 3588, 3630, 3656, 3656, 3652, 3650, 3629, 3599, - 3563, 3524, 3479, 3434, 3398, 3367, 3334, 3294, - 3252, 3205, 3128, 3029, 2911, 2771, 2633, 2492, - 2352, 2209, 2076, 1972, 1887, 1824, 1787, 1752, - 1719, 1689, 1660, 1634, 1620, 1605, 1591, 1586, - 1588, 1592, 1610, 1642, 1675, 1703, 1733, 1762, - 1787, 1819, 1843, 1856, 1865, 1872, 1877, 1878, - 1867, 1854, 1840, 1821, 1804, 1786, 1765, 1743, - 1726, 1723, 1741, 1769, 1793, 1828, 1861, 1902, - 1944, 1976, 1994, 2000, 1988, 1959, 1929, 1908, - 1883, 1843, 1800, 1754, 1711, 1658, 1596, 1535, - 1455, 1354, 1259, 1171, 1075, 977, 877, 780, - 701, 638, 580, 545, 531, 516, 513, 548, - 590, 623, 669, 724, 767, 808, 859, 898, - 925, 951, 978, 1007, 1033, 1070, 1111, 1141, - 1169, 1209, 1251, 1287, 1318, 1342, 1356, 1376, - 1397, 1415, 1431, 1450, 1475, 1504, 1544, 1595, - 1645, 1687, 1739, 1799, 1853, 1903, 1953, 1994, - 2023, 2052, 2082, 2102, 2123, 2147, 2168, 2184, - 2213, 2256, 2294, 2331, 2382, 2434, 2480, 2536, - 2592, 2645, 2699, 2760, 2820, 2878, 2951, 3015, - 3072, 3132, 3193, 3263, 3327, 3380, 3423, 3474, - 3526, 3562, 3598, 3642, 3672, 3691, 3711, 3728, - 3735, 3723, 3700, 3678, 3657, 3608, 3548, 3499, - 3457, 3382, 3313, 3273, 3208, 3142, 3075, 2959, - 2817, 2667, 2519, 2370, 2221, 2069, 1919, 1806, - 1717, 1645, 1604, 1570, 1528, 1489, 1456, 1427, - 1402, 1369, 1344, 1348, 1363, 1373, 1404, 1457, - 1507, 1553, 1606, 1660, 1709, 1755, 1788, 1814, - 1831, 1842, 1851, 1841, 1823, 1812, 1799, 1787, - 1788, 1790, 1774, 1756, 1750, 1751, 1765, 1798, - 1819, 1836, 1865, 1907, 1947, 1986, 2017, 2027, - 2025, 2025, 2033, 2050, 2070, 2073, 2068, 2054, - 2022, 1971, 1907, 1814, 1695, 1575, 1452, 1322, - 1207, 1104, 999, 907, 833, 756, 684, 625, - 552, 482, 446, 421, 396, 394, 417, 445, - 486, 556, 636, 709, 784, 863, 927, 986, - 1044, 1096, 1138, 1182, 1228, 1277, 1328, 1379, - 1423, 1452, 1474, 1484, 1485, 1486, 1495, 1510, - 1525, 1544, 1574, 1609, 1638, 1671, 1709, 1738, - 1758, 1777, 1800, 1826, 1856, 1892, 1932, 1975, - 2014, 2050, 2083, 2116, 2140, 2148, 2151, 2157, - 2161, 2170, 2187, 2210, 2240, 2284, 2344, 2409, - 2477, 2550, 2624, 2702, 2778, 2854, 2938, 3026, - 3115, 3202, 3281, 3353, 3429, 3507, 3561, 3601, - 3650, 3683, 3706, 3747, 3797, 3830, 3873, 3924, - 3949, 3972, 3978, 3955, 3922, 3887, 3821, 3732, - 3655, 3579, 3479, 3401, 3352, 3285, 3209, 3141, - 3040, 2876, 2688, 2517, 2355, 2168, 1979, 1819, - 1679, 1564, 1495, 1459, 1424, 1386, 1344, 1301, - 1274, 1256, 1223, 1201, 1210, 1236, 1261, 1312, - 1384, 1449, 1511, 1577, 1641, 1695, 1750, 1801, - 1834, 1853, 1880, 1912, 1919, 1911, 1910, 1906, - 1897, 1903, 1903, 1884, 1856, 1834, 1824, 1842, - 1887, 1927, 1954, 1992, 2046, 2096, 2142, 2177, - 2194, 2185, 2167, 2166, 2186, 2213, 2246, 2277, - 2306, 2334, 2333, 2288, 2207, 2101, 1966, 1800, - 1634, 1475, 1312, 1164, 1042, 941, 857, 784, - 716, 654, 599, 541, 481, 435, 405, 384, - 379, 399, 446, 520, 616, 713, 806, 898, - 986, 1072, 1150, 1217, 1280, 1331, 1368, 1404, - 1442, 1478, 1507, 1520, 1518, 1506, 1489, 1474, - 1482, 1505, 1526, 1549, 1577, 1614, 1655, 1687, - 1707, 1719, 1719, 1711, 1715, 1727, 1744, 1767, - 1803, 1848, 1899, 1953, 1994, 2024, 2043, 2045, - 2035, 2020, 2002, 1986, 1975, 1971, 1987, 2018, - 2059, 2111, 2166, 2228, 2299, 2377, 2464, 2553, - 2637, 2724, 2814, 2914, 3028, 3140, 3240, 3332, - 3412, 3474, 3542, 3616, 3671, 3720, 3764, 3805, - 3855, 3908, 3953, 3986, 4025, 4042, 4044, 4048, - 4038, 3998, 3961, 3927, 3885, 3828, 3774, 3712, - 3639, 3573, 3491, 3406, 3320, 3221, 3102, 2943, - 2742, 2530, 2346, 2173, 1982, 1799, 1648, 1520, - 1422, 1366, 1330, 1297, 1248, 1199, 1170, 1160, - 1130, 1098, 1100, 1128, 1156, 1198, 1264, 1342, - 1427, 1518, 1601, 1680, 1763, 1838, 1889, 1930, - 1965, 1996, 2010, 2003, 1990, 1980, 1974, 1977, - 1988, 1997, 1998, 1992, 1984, 2002, 2047, 2085, - 2102, 2124, 2152, 2181, 2216, 2246, 2262, 2268, - 2263, 2275, 2302, 2335, 2376, 2413, 2447, 2483, - 2511, 2513, 2494, 2446, 2364, 2246, 2118, 1985, - 1833, 1679, 1530, 1383, 1250, 1135, 1038, 947, - 858, 776, 700, 640, 579, 518, 464, 420, - 396, 395, 421, 465, 520, 577, 648, 746, - 848, 938, 1029, 1115, 1188, 1256, 1322, 1372, - 1413, 1441, 1448, 1443, 1450, 1461, 1469, 1480, - 1500, 1528, 1562, 1606, 1649, 1675, 1692, 1699, - 1687, 1682, 1680, 1671, 1665, 1675, 1693, 1724, - 1764, 1809, 1853, 1888, 1915, 1933, 1945, 1947, - 1929, 1901, 1866, 1838, 1823, 1814, 1817, 1829, - 1846, 1875, 1915, 1969, 2030, 2093, 2161, 2232, - 2308, 2389, 2471, 2554, 2644, 2731, 2823, 2918, - 3032, 3147, 3228, 3317, 3411, 3490, 3582, 3674, - 3736, 3781, 3821, 3846, 3882, 3932, 3947, 3947, - 3976, 4000, 4013, 4047, 4080, 4083, 4083, 4079, - 4052, 4025, 3978, 3903, 3825, 3745, 3646, 3543, - 3457, 3355, 3229, 3081, 2872, 2637, 2440, 2233, - 2004, 1804, 1624, 1462, 1332, 1234, 1156, 1091, - 1036, 971, 913, 884, 848, 800, 797, 850, - 917, 990, 1081, 1192, 1306, 1426, 1536, 1625, - 1715, 1785, 1832, 1867, 1904, 1953, 1978, 1982, - 1993, 2014, 2031, 2047, 2067, 2072, 2064, 2041, - 2013, 2008, 2027, 2043, 2045, 2054, 2088, 2131, - 2168, 2198, 2230, 2248, 2259, 2287, 2329, 2375, - 2421, 2470, 2517, 2569, 2613, 2619, 2593, 2547, - 2484, 2404, 2326, 2256, 2172, 2065, 1941, 1812, - 1679, 1549, 1416, 1271, 1127, 994, 860, 747, - 663, 577, 491, 424, 376, 356, 342, 336, - 334, 347, 378, 429, 509, 594, 677, 766, - 867, 969, 1064, 1145, 1220, 1288, 1342, 1389, - 1428, 1461, 1481, 1503, 1528, 1554, 1589, 1622, - 1627, 1615, 1602, 1584, 1577, 1569, 1559, 1560, - 1566, 1571, 1585, 1614, 1640, 1660, 1670, 1685, - 1706, 1720, 1723, 1727, 1731, 1736, 1740, 1743, - 1747, 1745, 1731, 1709, 1690, 1678, 1671, 1667, - 1676, 1700, 1740, 1787, 1841, 1903, 1965, 2033, - 2109, 2189, 2267, 2352, 2441, 2527, 2626, 2743, - 2857, 2965, 3071, 3173, 3259, 3334, 3404, 3461, - 3530, 3603, 3653, 3704, 3752, 3795, 3834, 3883, - 3935, 3970, 4002, 4038, 4052, 4058, 4075, 4095, - 4094, 4084, 4076, 4046, 4017, 3989, 3933, 3855, - 3773, 3674, 3558, 3452, 3351, 3209, 3023, 2797, - 2555, 2342, 2122, 1878, 1665, 1482, 1308, 1166, - 1067, 979, 909, 855, 779, 731, 714, 658, - 615, 635, 679, 744, 832, 920, 1027, 1152, - 1272, 1387, 1507, 1618, 1709, 1767, 1810, 1867, - 1929, 1956, 1961, 1974, 1984, 1992, 2018, 2034, - 2038, 2044, 2024, 2000, 2018, 2051, 2063, 2059, - 2067, 2090, 2128, 2158, 2185, 2209, 2224, 2237, - 2277, 2334, 2395, 2452, 2504, 2562, 2627, 2677, - 2694, 2677, 2632, 2570, 2504, 2446, 2397, 2332, - 2259, 2182, 2109, 2034, 1951, 1852, 1732, 1593, - 1437, 1291, 1167, 1047, 926, 810, 706, 632, - 577, 522, 487, 465, 427, 397, 412, 435, - 454, 488, 532, 593, 675, 760, 828, 903, - 980, 1041, 1108, 1181, 1249, 1306, 1354, 1402, - 1465, 1533, 1578, 1605, 1614, 1611, 1609, 1603, - 1592, 1592, 1597, 1588, 1594, 1620, 1651, 1686, - 1702, 1700, 1696, 1700, 1695, 1694, 1695, 1690, - 1693, 1699, 1717, 1743, 1753, 1754, 1754, 1751, - 1742, 1731, 1719, 1702, 1688, 1687, 1693, 1706, - 1723, 1741, 1767, 1803, 1851, 1905, 1964, 2034, - 2106, 2183, 2272, 2373, 2471, 2564, 2660, 2756, - 2847, 2947, 3037, 3120, 3209, 3289, 3362, 3432, - 3508, 3576, 3621, 3668, 3712, 3749, 3784, 3803, - 3821, 3862, 3892, 3900, 3928, 3973, 3988, 4005, - 4037, 4047, 4036, 4022, 3988, 3946, 3912, 3858, - 3784, 3710, 3633, 3546, 3446, 3344, 3221, 3046, - 2803, 2566, 2353, 2113, 1878, 1678, 1481, 1308, - 1191, 1088, 989, 921, 837, 727, 653, 596, - 519, 479, 498, 538, 606, 699, 799, 919, - 1049, 1174, 1286, 1387, 1485, 1579, 1642, 1695, - 1788, 1878, 1921, 1960, 2014, 2042, 2065, 2100, - 2117, 2128, 2133, 2116, 2104, 2123, 2160, 2166, - 2160, 2179, 2208, 2224, 2237, 2255, 2260, 2261, - 2285, 2325, 2381, 2455, 2530, 2598, 2674, 2751, - 2806, 2823, 2811, 2779, 2726, 2681, 2652, 2618, - 2569, 2519, 2465, 2408, 2352, 2286, 2196, 2075, - 1944, 1798, 1652, 1527, 1395, 1256, 1133, 1024, - 935, 856, 784, 704, 619, 550, 509, 485, - 458, 435, 419, 429, 462, 503, 547, 591, - 633, 673, 727, 792, 851, 912, 984, 1059, - 1136, 1222, 1305, 1377, 1427, 1460, 1488, 1512, - 1532, 1549, 1570, 1601, 1635, 1683, 1734, 1790, - 1841, 1867, 1888, 1905, 1912, 1910, 1904, 1894, - 1890, 1904, 1926, 1936, 1943, 1950, 1957, 1959, - 1952, 1930, 1901, 1864, 1822, 1795, 1773, 1754, - 1730, 1700, 1677, 1663, 1646, 1629, 1627, 1634, - 1652, 1687, 1739, 1801, 1868, 1938, 2004, 2077, - 2152, 2223, 2290, 2356, 2436, 2523, 2615, 2721, - 2831, 2939, 3034, 3118, 3199, 3263, 3307, 3338, - 3360, 3385, 3412, 3443, 3484, 3532, 3590, 3636, - 3678, 3741, 3795, 3823, 3843, 3860, 3869, 3883, - 3905, 3922, 3931, 3949, 3961, 3967, 3971, 3950, - 3917, 3867, 3796, 3725, 3641, 3527, 3364, 3145, - 2925, 2727, 2501, 2257, 2038, 1833, 1624, 1458, - 1332, 1208, 1102, 997, 875, 772, 695, 608, - 539, 519, 519, 538, 589, 658, 758, 881, - 1002, 1121, 1249, 1370, 1484, 1576, 1646, 1729, - 1821, 1872, 1910, 1966, 2011, 2047, 2093, 2135, - 2168, 2194, 2196, 2185, 2192, 2210, 2209, 2187, - 2176, 2179, 2183, 2183, 2191, 2198, 2198, 2214, - 2249, 2296, 2358, 2432, 2503, 2580, 2662, 2731, - 2778, 2798, 2799, 2781, 2760, 2744, 2719, 2690, - 2660, 2627, 2593, 2566, 2531, 2471, 2388, 2293, - 2188, 2074, 1965, 1850, 1725, 1591, 1448, 1321, - 1214, 1114, 1024, 945, 875, 819, 781, 749, - 711, 677, 640, 606, 595, 587, 579, 581, - 595, 622, 669, 735, 803, 875, 950, 1028, - 1106, 1177, 1229, 1266, 1295, 1321, 1350, 1381, - 1407, 1440, 1481, 1528, 1587, 1654, 1716, 1771, - 1812, 1836, 1853, 1871, 1877, 1876, 1877, 1878, - 1887, 1903, 1917, 1932, 1943, 1947, 1954, 1959, - 1961, 1953, 1935, 1911, 1883, 1851, 1812, 1763, - 1708, 1651, 1605, 1568, 1536, 1512, 1488, 1474, - 1470, 1482, 1502, 1527, 1554, 1580, 1608, 1649, - 1698, 1750, 1808, 1878, 1960, 2048, 2149, 2257, - 2358, 2448, 2534, 2620, 2711, 2796, 2863, 2917, - 2964, 3004, 3034, 3064, 3108, 3140, 3164, 3205, - 3250, 3293, 3327, 3355, 3386, 3423, 3462, 3484, - 3508, 3534, 3552, 3569, 3604, 3639, 3672, 3707, - 3737, 3772, 3803, 3829, 3844, 3850, 3840, 3814, - 3772, 3714, 3647, 3559, 3425, 3233, 3027, 2851, - 2657, 2445, 2257, 2089, 1918, 1770, 1645, 1522, - 1414, 1300, 1158, 1036, 939, 826, 725, 680, - 664, 668, 707, 755, 830, 935, 1031, 1122, - 1213, 1296, 1373, 1440, 1486, 1558, 1641, 1689, - 1732, 1791, 1842, 1889, 1940, 1977, 2013, 2045, - 2051, 2040, 2045, 2053, 2046, 2029, 2016, 2016, - 2020, 2012, 2010, 2013, 2013, 2034, 2069, 2111, - 2173, 2244, 2312, 2387, 2472, 2545, 2598, 2627, - 2643, 2655, 2658, 2667, 2675, 2678, 2686, 2699, - 2704, 2707, 2705, 2682, 2629, 2562, 2483, 2394, - 2306, 2212, 2115, 2022, 1933, 1845, 1755, 1661, - 1569, 1481, 1391, 1305, 1234, 1166, 1093, 1024, - 968, 922, 897, 866, 837, 821, 809, 795, - 792, 812, 829, 848, 872, 913, 966, 1020, - 1062, 1098, 1135, 1167, 1191, 1217, 1244, 1277, - 1316, 1357, 1410, 1472, 1532, 1583, 1633, 1677, - 1716, 1747, 1761, 1770, 1783, 1802, 1821, 1844, - 1872, 1897, 1918, 1929, 1934, 1937, 1934, 1922, - 1908, 1891, 1875, 1863, 1849, 1833, 1815, 1797, - 1774, 1753, 1730, 1706, 1679, 1652, 1636, 1622, - 1616, 1617, 1624, 1633, 1648, 1671, 1695, 1721, - 1752, 1794, 1843, 1894, 1958, 2022, 2084, 2144, - 2203, 2264, 2320, 2372, 2412, 2457, 2501, 2538, - 2577, 2616, 2651, 2683, 2711, 2736, 2764, 2789, - 2798, 2808, 2817, 2824, 2838, 2858, 2873, 2897, - 2921, 2939, 2971, 3004, 3030, 3054, 3079, 3104, - 3131, 3168, 3202, 3242, 3282, 3308, 3342, 3376, - 3408, 3432, 3444, 3445, 3442, 3428, 3404, 3378, - 3344, 3295, 3219, 3110, 2992, 2886, 2763, 2622, - 2498, 2377, 2254, 2155, 2056, 1960, 1891, 1803, - 1704, 1622, 1549, 1471, 1411, 1370, 1342, 1334, - 1331, 1342, 1378, 1427, 1475, 1521, 1557, 1594, - 1638, 1671, 1699, 1738, 1774, 1794, 1821, 1855, - 1876, 1905, 1924, 1930, 1937, 1943, 1935, 1919, - 1905, 1898, 1885, 1871, 1865, 1867, 1867, 1863, - 1862, 1859, 1865, 1878, 1891, 1909, 1942, 1989, - 2040, 2100, 2166, 2229, 2279, 2325, 2362, 2394, - 2427, 2458, 2478, 2496, 2523, 2549, 2567, 2590, - 2601, 2602, 2588, 2564, 2529, 2490, 2444, 2390, - 2334, 2279, 2227, 2174, 2121, 2068, 2014, 1954, - 1887, 1820, 1760, 1701, 1638, 1580, 1524, 1479, - 1444, 1415, 1391, 1372, 1355, 1338, 1322, 1314, - 1304, 1293, 1293, 1302, 1311, 1328, 1351, 1377, - 1413, 1450, 1478, 1506, 1535, 1567, 1604, 1641, - 1678, 1714, 1746, 1777, 1808, 1834, 1856, 1867, - 1870, 1869, 1870, 1866, 1856, 1852, 1852, 1853, - 1858, 1861, 1865, 1868, 1872, 1880, 1883, 1885, - 1885, 1886, 1887, 1888, 1891, 1895, 1895, 1888, - 1885, 1881, 1872, 1860, 1841, 1834, 1823, 1813, - 1809, 1804, 1803, 1804, 1810, 1817, 1825, 1836, - 1847, 1857, 1870, 1888, 1904, 1919, 1937, 1960, - 1983, 2004, 2026, 2045, 2066, 2084, 2098, 2115, - 2132, 2150, 2169, 2185, 2206, 2227, 2243, 2257, - 2271, 2285, 2295, 2302, 2309, 2316, 2323, 2333, - 2347, 2361, 2379, 2395, 2410, 2421, 2436, 2449, - 2465, 2480, 2491, 2500, 2513, 2525, 2538, 2557, - 2577, 2595, 2613, 2632, 2651, 2674, 2691, 2710, - 2727, 2745, 2758, 2769, 2785, 2800, 2810, 2816, - 2826, 2832, 2828, 2823, 2817, 2805, 2797, 2779, - 2750, 2716, 2684, 2650, 2609, 2569, 2528, 2485, - 2447, 2408, 2377, 2351, 2323, 2301, 2281, 2267, - 2257, 2247, 2241, 2243, 2247, 2247, 2253, 2259, - 2270, 2289, 2301, 2308, 2320, 2331, 2341, 2346, - 2348, 2350, 2347, 2338, 2330, 2321, 2311, 2302, - 2290, 2271, 2256, 2239, 2211, 2183, 2161, 2140, - 2115, 2087, 2064, 2047, 2029, 2015, 2001, 1988, - 1980, 1971, 1959, 1954, 1955, 1956, 1962, 1970, - 1978, 1987, 1995, 1998, 2001, 2003, 2000, 1997, - 1989, 1984, 1980, 1973, 1967, 1963, 1958, 1947, - 1939, 1929, 1917, 1905, 1893, 1880, 1869, 1860, - 1850, 1841, 1833, 1827, 1820, 1820, 1821, 1822, - 1824, 1824, 1822, 1824, 1830, 1831, 1837, 1849, - 1857, 1864, 1874, 1880, 1884, 1894, 1902, 1901, - 1900, 1900, 1903, 1909, 1910, 1909, 1901, 1895, - 1891, 1884, 1875, 1867, 1854, 1839, 1829, 1821, - 1811, 1803, 1791, 1779, 1774, 1764, 1751, 1735, - 1724, 1714, 1703, 1693, 1684, 1676, 1669, 1663, - 1659, 1656, 1655, 1653, 1650, 1650, 1651, 1652, - 1652, 1652, 1654, 1656, 1661, 1670, 1677, 1681, - 1690, 1700, 1711, 1719, 1729, 1742, 1750, 1761, - 1771, 1782, 1793, 1803, 1815, 1826, 1836, 1849, - 1861, 1874, 1884, 1894, 1910, 1921, 1934, 1947, - 1960, 1969, 1980, 1995, 2005, 2014, 2022, 2029, - 2035, 2040, 2048, 2054, 2059, 2066, 2074, 2082, - 2088, 2091, 2096, 2102, 2100, 2101, 2104, 2107, - 2113, 2121, 2131, 2136, 2140, 2145, 2148, 2151, - 2156, 2162, 2165, 2170, 2175, 2179, 2184, 2191, - 2198, 2206, 2219, 2229, 2240, 2252, 2268, 2282, - 2295, 2310, 2328, 2346, 2364, 2383, 2402, 2420, - 2439, 2456, 2472, 2489, 2503, 2516, 2530, 2545, - 2561, 2575, 2587, 2595, 2602, 2610, 2615, 2620, - 2620, 2619, 2615, 2612, 2609, 2600, 2594, 2583, - 2571, 2559, 2545, 2531, 2513, 2496, 2477, 2465, - 2451, 2438, 2426, 2409, 2395, 2385, 2369, 2354, - 2344, 2332, 2321, 2310, 2299, 2293, 2289, 2284, - 2277, 2265, 2256, 2249, 2234, 2223, 2215, 2201, - 2189, 2180, 2169, 2158, 2148, 2136, 2120, 2105, - 2091, 2073, 2053, 2034, 2016, 1998, 1982, 1968, - 1959, 1946, 1936, 1929, 1919, 1914, 1909, 1902, - 1899, 1894, 1892, 1890, 1891, 1894, 1895, 1897, - 1895, 1895, 1892, 1892, 1888, 1882, 1877, 1872, - 1869, 1862, 1859, 1858, 1854, 1849, 1843, 1837, - 1828, 1821, 1813, 1801, 1788, 1781, 1772, 1763, - 1752, 1745, 1735, 1724, 1713, 1704, 1693, 1685, - 1677, 1671, 1667, 1667, 1668, 1668, 1670, 1674, - 1678, 1680, 1681, 1683, 1686, 1688, 1689, 1694, - 1696, 1694, 1694, 1700, 1704, 1707, 1711, 1717, - 1721, 1730, 1736, 1741, 1746, 1753, 1760, 1765, - 1775, 1782, 1786, 1793, 1798, 1803, 1811, 1815, - 1822, 1830, 1836, 1844, 1852, 1857, 1864, 1870, - 1873, 1878, 1883, 1885, 1888, 1893, 1894, 1900, - 1905, 1908, 1912, 1916, 1921, 1925, 1927, 1931, - 1936, 1935, 1940, 1945, 1945, 1946, 1952, 1955, - 1958, 1963, 1965, 1967, 1970, 1969, 1969, 1974, - 1974, 1973, 1974, 1975, 1977, 1979, 1983, 1984, - 1989, 1996, 2002, 2002, 2007, 2016, 2021, 2022, - 2029, 2038, 2039, 2041, 2049, 2051, 2054, 2058, - 2063, 2065, 2072, 2079, 2084, 2091, 2100, 2109, - 2114, 2122, 2128, 2135, 2142, 2153, 2162, 2167, - 2179, 2191, 2195, 2204, 2215, 2222, 2233, 2244, - 2253, 2259, 2267, 2275, 2281, 2289, 2297, 2302, - 2301, 2308, 2316, 2316, 2321, 2324, 2324, 2329, - 2334, 2335, 2337, 2339, 2339, 2341, 2342, 2344, - 2344, 2345, 2346, 2349, 2348, 2349, 2350, 2351, - 2350, 2351, 2352, 2350, 2350, 2351, 2347, 2346, - 2346, 2346, 2340, 2339, 2340, 2341, 2337, 2335, - 2335, 2329, 2327, 2324, 2322, 2318, 2318, 2315, - 2311, 2309, 2305, 2303, 2300, 2303, 2301, 2295, - 2292, 2290, 2286, 2282, 2277, 2272, 2267, 2256, - 2248, 2242, 2231, 2220, 2207, 2196, 2185, 2176, - 2166, 2153, 2144, 2132, 2121, 2111, 2100, 2087, - 2074, 2060, 2051, 2042, 2030, 2025, 2015, 2005, - 1998, 1993, 1985, 1978, 1969, 1960, 1954, 1947, - 1940, 1932, 1928, 1921, 1915, 1912, 1904, 1899, - 1892, 1889, 1887, 1879, 1873, 1866, 1860, 1852, - 1848, 1842, 1837, 1835, 1833, 1832, 1828, 1827, - 1826, 1825, 1825, 1824, 1823, 1827, 1829, 1830, - 1833, 1835, 1839, 1841, 1843, 1842, 1846, 1848, - 1851, 1853, 1857, 1863, 1866, 1870, 1871, 1875, - 1877, 1879, 1880, 1881, 1882, 1882, 1883, 1882, - 1884, 1885, 1886, 1886, 1889, 1890, 1890, 1893, - 1893, 1891, 1891, 1893, 1892, 1894, 1896, 1897, - 1900, 1904, 1908, 1913, 1913, 1914, 1919, 1919, - 1923, 1929, 1932, 1937, 1940, 1945, 1949, 1953, - 1955, 1958, 1962, 1967, 1973, 1976, 1977, 1982, - 1986, 1989, 1993, 1999, 2001, 2007, 2009, 2012, - 2018, 2022, 2025, 2033, 2040, 2045, 2051, 2059, - 2064, 2073, 2081, 2082, 2092, 2098, 2105, 2111, - 2116, 2121, 2128, 2133, 2136, 2139, 2142, 2146, - 2152, 2156, 2158, 2161, 2167, 2165, 2169, 2173, - 2174, 2179, 2175, 2176, 2179, 2181, 2184, 2185, - 2186, 2188, 2191, 2189, 2190, 2190, 2191, 2193, - 2197, 2197, 2196, 2199, 2199, 2199, 2201, 2203, - 2205, 2208, 2210, 2212, 2214, 2216, 2219, 2222, - 2222, 2227, 2229, 2229, 2233, 2234, 2236, 2238, - 2240, 2242, 2244, 2248, 2249, 2251, 2250, 2250, - 2251, 2248, 2248, 2247, 2248, 2250, 2250, 2248, - 2247, 2247, 2247, 2247, 2248, 2250, 2252, 2253, - 2253, 2254, 2256, 2258, 2257, 2257, 2256, 2259, - 2258, 2257, 2257, 2256, 2253, 2256, 2258, 2254, - 2251, 2247, 2245, 2243, 2240, 2236, 2231, 2227, - 2224, 2221, 2217, 2215, 2214, 2210, 2206, 2202, - 2200, 2199, 2193, 2190, 2186, 2182, 2180, 2175, - 2171, 2168, 2162, 2157, 2152, 2148, 2144, 2139, - 2131, 2125, 2118, 2113, 2109, 2104, 2099, 2095, - 2090, 2087, 2082, 2076, 2070, 2068, 2065, 2056, - 2052, 2051, 2048, 2048, 2043, 2041, 2037, 2034, - 2030, 2026, 2023, 2021, 2020, 2017, 2014, 2011, - 2009, 2005, 2004, 2003, 2002, 2001, 2000, 1995, - 1993, 1992, 1987, 1984, 1984, 1979, 1976, 1972, - 1967, 1966, 1962, 1960, 1957, 1956, 1956, 1955, - 1953, 1951, 1949, 1946, 1944, 1942, 1938, 1936, - 1937, 1934, 1932, 1932, 1930, 1928, 1929, 1926, - 1925, 1925, 1923, 1923, 1922, 1919, 1922, 1920, - 1920, 1921, 1919, 1924, 1926, 1928, 1929, 1929, - 1934, 1936, 1936, 1937, 1937, 1939, 1939, 1943, - 1944, 1947, 1948, 1950, 1952, 1955, 1959, 1959, - 1963, 1964, 1967, 1970, 1972, 1975, 1978, 1981, - 1985, 1985, 1991, 1994, 1997, 2002, 2007, 2013, - 2016, 2022, 2025, 2028, 2031, 2032, 2033, 2035, - 2040, 2043, 2046, 2049, 2053, 2052, 2052, 2051, - 2050, 2052, 2054, 2053, 2053, 2058, 2062, 2063, - 2064, 2066, 2068, 2066, 2069, 2070, 2071, 2073, - 2074, 2074, 2076, 2076, 2076, 2078, 2077, 2079, - 2078, 2079, 2079, 2078, 2078, 2077, 2074, 2074, - 2073, 2074, 2070, 2068, 2070, 2069, 2067, 2067, - 2064, 2064, 2066, 2065, 2065, 2064, 2063, 2066, - 2066, 2066, 2064, 2065, 2067, 2065, 2067, 2068, - 2067, 2067, 2068, 2068, 2068, 2068, 2069, 2069, - 2071, 2071, 2072, 2075, 2076, 2076, 2076, 2076, - 2076, 2077, 2078, 2080, 2082, 2084, 2087, 2089, - 2090, 2091, 2091, 2093, 2091, 2093, 2097, 2097, - 2098, 2100, 2102, 2102, 2105, 2104, 2103, 2103, - 2105, 2105, 2111, 2112, 2109, 2111, 2111, 2110, - 2108, 2108, 2109, 2110, 2112, 2110, 2106, 2106, - 2106, 2106, 2101, 2102, 2103, 2101, 2098, 2098, - 2098, 2096, 2092, 2092, 2088, 2089, 2085, 2082, - 2081, 2077, 2074, 2069, 2068, 2062, 2058, 2057, - 2054, 2051, 2048, 2046, 2042, 2041, 2037, 2037, - 2031, 2026, 2026, 2021, 2018, 2015, 2011, 2006, - 2000, 1999, 1994, 1991, 1986, 1983, 1984, 1982, - 1980, 1978, 1978, 1977, 1976, 1975, 1973, 1974, - 1974, 1974, 1974, 1974, 1977, 1978, 1977, 1976, - 1976, 1977, 1976, 1978, 1981, 1982, 1980, 1983, - 1984, 1985, 1986, 1985, 1982, 1983, 1983, 1984, - 1984, 1987, 1984, 1983, 1984, 1980, 1979, 1984, - 1981, 1980, 1983, 1985, 1984, 1984, 1982, 1982, - 1987, 1987, 1986, 1992, 1989, 1989, 1998, 2001, - 2000, 2002, 2003, 2003, 2004, 2005, 2007, 2009, - 2010, 2010, 2013, 2013, 2014, 2014, 2016, 2021, - 2018, 2019, 2022, 2026, 2029, 2028, 2029, 2029, - 2033, 2034, 2032, 2035, 2035, 2035, 2038, 2039, - 2041, 2044, 2047, 2046, 2047, 2052, 2054, 2058, - 2059, 2058, 2060, 2063, 2065, 2068, 2067, 2069, - 2068, 2067, 2071, 2073, 2073, 2073, 2075, 2073, - 2071, 2069, 2072, 2072, 2072, 2073, 2072, 2067, - 2063, 2068, 2069, 2068, 2067, 2066, 2066, 2064, - 2065, 2064, 2063, 2061, 2061, 2059, 2061, 2061, - 2059, 2058, 2059, 2056, 2051, 2052, 2051, 2047, - 2045, 2042, 2039, 2041, 2041, 2036, 2035, 2032, - 2031, 2032, 2031, 2028, 2028, 2026, 2026, 2023, - 2022, 2021, 2022, 2022, 2020, 2019, 2016, 2018, - 2017, 2016, 2015, 2013, 2016, 2019, 2019, 2021, - 2023, 2024, 2025, 2027, 2029, 2030, 2033, 2032, - 2035, 2041, 2042, 2043, 2046, 2050, 2051, 2053, - 2057, 2056, 2058, 2055, 2056, 2056, 2054, 2051, - 2051, 2051, 2046, 2045, 2047, 2046, 2046, 2047, - 2046, 2043, 2044, 2041, 2041, 2040, 2040, 2041, - 2040, 2041, 2038, 2036, 2035, 2036, 2037, 2037, - 2034, 2035, 2033, 2030, 2030, 2029, 2029, 2028, - 2027, 2028, 2028, 2026, 2025, 2025, 2028, 2028, - 2030, 2031, 2031, 2033, 2038, 2039, 2040, 2042, - 2044, 2048, 2050, 2050, 2055, 2059, 2064, 2065, - 2068, 2071, 2074, 2076, 2076, 2080, 2086, 2085, - 2086, 2091, 2090, 2092, 2096, 2096, 2097, 2100, - 2103, 2105, 2103, 2104, 2104, 2106, 2107, 2106, - 2107, 2108, 2107, 2108, 2109, 2107, 2107, 2109, - 2107, 2108, 2105, 2103, 2102, 2101, 2101, 2101, - 2101, 2100, 2102, 2099, 2100, 2103, 2100, 2098, - 2095, 2096, 2091, 2088, 2087, 2087, 2086, 2084, - 2084, 2081, 2082, 2081, 2077, 2075, 2073, 2071, - 2069, 2067, 2067, 2067, 2066, 2065, 2068, 2068, - 2066, 2066, 2064, 2063, 2063, 2060, 2058, 2058, - 2057, 2057, 2057, 2055, 2051, 2048, 2049, 2047, - 2046, 2045, 2042, 2042, 2042, 2040, 2040, 2039, - 2038, 2034, 2032, 2032, 2032, 2031, 2029, 2029, - 2028, 2028, 2028, 2026, 2024, 2025, 2026, 2023, - 2024, 2024, 2023, 2023, 2020, 2021, 2020, 2021, - 2023, 2024, 2024, 2026, 2026, 2026, 2026, 2030, - 2028, 2030, 2032, 2034, 2032, 2032, 2032, 2034, - 2038, 2039, 2039, 2037, 2036, 2041, 2043, 2043, - 2044, 2046, 2050, 2052, 2046, 2045, 2048, 2051, - 2049, 2049, 2047, 2047, 2046, 2042, 2041, 2043, - 2040, 2040, 2045, 2045, 2043, 2043, 2038, 2040, - 2037, 2030, 2027, 2031, 2038, 2034, 2038, 2039, - 2033, 2032, 2032, 2028, 2029, 2035, 2037, 2038, - 2038, 2038, 2044, 2047, 2042, 2039, 2043, 2042, - 2044, 2048, 2048, 2051, 2051, 2056, 2058, 2058, - 2055, 2055, 2055, 2060, 2066, 2067, 2070, 2072, - 2074, 2069, 2069, 2070, 2070, 2074, 2076, 2074, - 2074, 2077, 2079, 2080, 2080, 2081, 2078, 2082, - 2084, 2084, 2086, 2086, 2087, 2081, 2087, 2090, - 2088, 2089, 2090, 2087, 2087, 2087, 2086, 2090, - 2094, 2090, 2088, 2093, 2093, 2091, 2090, 2089, - 2087, 2088, 2089, 2092, 2095, 2092, 2086, 2085, - 2085, 2085, 2088, 2087, 2084, 2078, 2075, 2078, - 2079, 2073, 2065, 2063, 2066, 2066, 2065, 2067, - 2063, 2056, 2060, 2062, 2060, 2059, 2062, 2057, - 2056, 2055, 2056, 2059, 2058, 2059, 2052, 2052, - 2054, 2054, 2057, 2055, 2053, 2055, 2056, 2054, - 2048, 2044, 2043, 2041, 2037, 2033, 2031, 2033, - 2035, 2035, 2030, 2025, 2024, 2025, 2028, 2024, - 2021, 2023, 2020, 2016, 2020, 2020, 2012, 2009, - 2015, 2019, 2021, 2019, 2015, 2018, 2017, 2012, - 2011, 2017, 2015, 2012, 2011, 2010, 2011, 2017, - 2018, 2014, 2013, 2015, 2011, 2006, 2006, 2005, - 2005, 2006, 2001, 2002, 2009, 2009, 2010, 2013, - 2017, 2021, 2019, 2020, 2024, 2025, 2028, 2029, - 2028, 2032, 2034, 2037, 2040, 2038, 2036, 2036, - 2040, 2039, 2034, 2034, 2033, 2027, 2030, 2033, - 2030, 2030, 2032, 2030, 2028, 2029, 2027, 2023, - 2022, 2022, 2017, 2018, 2021, 2020, 2017, 2014, - 2017, 2017, 2015, 2020, 2021, 2018, 2019, 2020, - 2021, 2019, 2017, 2017, 2018, 2021, 2021, 2021, - 2024, 2029, 2031, 2035, 2035, 2035, 2036, 2035, - 2038, 2043, 2047, 2048, 2046, 2043, 2045, 2047, - 2046, 2047, 2047, 2048, 2051, 2052, 2052, 2052, - 2052, 2051, 2052, 2050, 2045, 2047, 2050, 2048, - 2049, 2048, 2046, 2050, 2051, 2051, 2052, 2052, - 2055, 2056, 2056, 2055, 2060, 2061, 2057, 2061, - 2064, 2064, 2061, 2061, 2060, 2064, 2064, 2065, - 2068, 2067, 2066, 2066, 2067, 2069, 2070, 2068, - 2069, 2069, 2069, 2073, 2074, 2074, 2075, 2078, - 2082, 2081, 2079, 2084, 2088, 2086, 2085, 2088, - 2091, 2092, 2096, 2100, 2107, 2109, 2110, 2110, - 2113, 2112, 2110, 2114, 2116, 2116, 2116, 2115, - 2114, 2112, 2109, 2110, 2111, 2112, 2112, 2109, - 2108, 2108, 2111, 2113, 2113, 2111, 2109, 2107, - 2107, 2106, 2106, 2106, 2106, 2104, 2100, 2105, - 2105, 2101, 2104, 2104, 2104, 2103, 2098, 2096, - 2100, 2102, 2098, 2098, 2097, 2094, 2094, 2091, - 2089, 2090, 2091, 2091, 2087, 2086, 2086, 2086, - 2087, 2088, 2085, 2082, 2079, 2078, 2079, 2077, - 2079, 2077, 2078, 2078, 2077, 2078, 2083, 2083, - 2082, 2082, 2085, 2086, 2092, 2095, 2092, 2092, - 2096, 2096, 2100, 2102, 2103, 2106, 2108, 2106, - 2104, 2106, 2108, 2109, 2108, 2108, 2106, 2106, - 2103, 2103, 2105, 2103, 2102, 2099, 2098, 2101, - 2101, 2103, 2104, 2107, 2106, 2105, 2106, 2108, - 2108, 2107, 2107, 2106, 2109, 2111, 2108, 2107, - 2107, 2108, 2104, 2105, 2104, 2102, 2101, 2103, - 2107, 2103, 2101, 2099, 2096, 2097, 2098, 2098, - 2098, 2098, 2098, 2100, 2099, 2098, 2099, 2098, - 2098, 2100, 2102, 2099, 2098, 2096, 2095, 2097, - 2094, 2095, 2092, 2086, 2081, 2079, 2070, 2063, - 2053, 2046, 1902, 1613, 1570, 1719, 1812, 1882, - 1946, 1964, 1959, 1931, 1918, 1942, 1980, 2003, - 2025, 2040, 2049, 2063, 2059, 2053, 2062, 2086, - 2102, 2119, 2114, 2081, 2034, 2009, 2013, 2033, - 2068, 2109, 2134, 2126, 2096, 2053, 2007, 1980, - 1980, 2016, 2063, 2086, 2092, 2088, 2082, 2065, - 2051, 2037, 2030, 2040, 2056, 2065, 2048, 2026, - 2014, 2015, 2032, 2054, 2075, 2080, 2069, 2054, - 2031, 2011, 1994, 1982, 1987, 2005, 2030, 2055, - 2064, 2037, 1997, 1967, 1965, 1984, 2004, 2011, - 2007, 2002, 1993, 1985, 1985, 1984, 1985, 1988, - 1994, 1991, 1979, 1960, 1946, 1938, 1931, 1937, - 1952, 1972, 1984, 1979, 1953, 1927, 1909, 1894, - 1897, 1914, 1932, 1939, 1932, 1920, 1914, 1907, - 1913, 1933, 1944, 1937, 1933, 1935, 1925, 1916, - 1909, 1909, 1918, 1936, 1954, 1958, 1953, 1941, - 1927, 1914, 1908, 1925, 1941, 1949, 1955, 1954, - 1950, 1946, 1940, 1929, 1926, 1929, 1937, 1945, - 1950, 1942, 1932, 1925, 1928, 1940, 1947, 1950, - 1951, 1947, 1937, 1924, 1922, 1928, 1931, 1939, - 1947, 1950, 1948, 1941, 1938, 1932, 1927, 1924, - 1926, 1929, 1929, 1931, 1928, 1915, 1909, 1906, - 1909, 1914, 1919, 1921, 1919, 1912, 1903, 1897, - 1899, 1901, 1906, 1909, 1901, 1896, 1897, 1896, - 1893, 1887, 1880, 1884, 1884, 1878, 1878, 1881, - 1875, 1866, 1863, 1854, 1852, 1860, 1865, 1861, - 1853, 1859, 1865, 1865, 1858, 1859, 1858, 1853, - 1852, 1849, 1848, 1846, 1845, 1841, 1830, 1820, - 1827, 1834, 1827, 1828, 1826, 1806, 1804, 1805, - 1806, 1818, 1818, 1813, 1814, 1808, 1804, 1806, - 1813, 1816, 1820, 1821, 1816, 1815, 1813, 1814, - 1818, 1823, 1831, 1841, 1844, 1831, 1825, 1825, - 1821, 1826, 1827, 1827, 1831, 1836, 1841, 1840, - 1830, 1834, 1843, 1845, 1851, 1855, 1849, 1842, - 1839, 1838, 1837, 1841, 1841, 1842, 1842, 1836, - 1830, 1826, 1830, 1842, 1846, 1855, 1864, 1860, - 1859, 1857, 1850, 1853, 1859, 1858, 1862, 1867, - 1868, 1862, 1850, 1842, 1842, 1839, 1847, 1864, - 1870, 1869, 1870, 1862, 1850, 1842, 1846, 1856, - 1859, 1866, 1870, 1866, 1857, 1847, 1844, 1848, - 1858, 1863, 1863, 1861, 1856, 1853, 1858, 1867, - 1873, 1883, 1889, 1892, 1891, 1885, 1884, 1886, - 1891, 1904, 1919, 1925, 1924, 1919, 1911, 1904, - 1894, 1894, 1904, 1915, 1927, 1936, 1937, 1936, - 1926, 1918, 1920, 1926, 1931, 1938, 1937, 1935, - 1936, 1946, 1958, 1962, 1965, 1963, 1953, 1950, - 1947, 1935, 1923, 1914, 1911, 1914, 1925, 1931, - 1933, 1934, 1927, 1923, 1921, 1926, 1926, 1924, - 1929, 1938, 1952, 1956, 1956, 1959, 1957, 1960, - 1964, 1958, 1946, 1947, 1953, 1960, 1969, 1977, - 1983, 1981, 1975, 1965, 1955, 1948, 1937, 1921, - 1916, 1922, 1931, 1945, 1954, 1960, 1957, 1944, - 1927, 1922, 1923, 1925, 1929, 1932, 1943, 1952, - 1960, 1958, 1953, 1953, 1939, 1914, 1901, 1887, - 1880, 1878, 1878, 1883, 1881, 1882, 1888, 1896, - 1895, 1879, 1864, 1846, 1829, 1831, 1842, 1846, - 1851, 1867, 1873, 1866, 1852, 1838, 1834, 1833, - 1831, 1828, 1823, 1820, 1829, 1836, 1838, 1838, - 1837, 1827, 1814, 1801, 1801, 1802, 1797, 1797, - 1814, 1830, 1837, 1844, 1847, 1840, 1830, 1818, - 1803, 1797, 1801, 1811, 1823, 1838, 1837, 1823, - 1810, 1798, 1783, 1765, 1744, 1723, 1708, 1701, - 1701, 1715, 1728, 1737, 1731, 1725, 1723, 1719, - 1700, 1679, 1672, 1671, 1668, 1672, 1678, 1683, - 1692, 1698, 1695, 1684, 1671, 1662, 1660, 1653, - 1641, 1639, 1644, 1657, 1672, 1668, 1647, 1632, - 1626, 1617, 1598, 1584, 1588, 1597, 1603, 1613, - 1622, 1621, 1614, 1606, 1600, 1592, 1575, 1551, - 1537, 1531, 1525, 1531, 1557, 1573, 1574, 1571, - 1571, 1568, 1558, 1561, 1554, 1538, 1531, 1539, - 1553, 1560, 1558, 1547, 1531, 1511, 1498, 1493, - 1491, 1500, 1509, 1508, 1505, 1502, 1505, 1519, - 1531, 1527, 1524, 1529, 1524, 1513, 1517, 1521, - 1527, 1547, 1569, 1592, 1598, 1587, 1569, 1553, - 1538, 1528, 1531, 1538, 1540, 1540, 1544, 1552, - 1552, 1552, 1551, 1557, 1560, 1557, 1557, 1550, - 1535, 1513, 1493, 1501, 1524, 1536, 1543, 1542, - 1534, 1531, 1533, 1544, 1568, 1596, 1616, 1636, - 1653, 1658, 1654, 1647, 1641, 1634, 1637, 1632, - 1630, 1634, 1634, 1637, 1639, 1639, 1650, 1674, - 1689, 1687, 1672, 1663, 1647, 1635, 1646, 1661, - 1680, 1707, 1728, 1731, 1732, 1727, 1710, 1702, - 1711, 1730, 1758, 1770, 1772, 1779, 1778, 1776, - 1793, 1811, 1815, 1822, 1828, 1821, 1811, 1809, - 1812, 1828, 1852, 1871, 1891, 1899, 1881, 1856, - 1837, 1828, 1834, 1853, 1882, 1912, 1930, 1936, - 1931, 1924, 1934, 1962, 1991, 2007, 2007, 2003, - 2001, 1999, 2015, 2038, 2066, 2093, 2112, 2120, - 2119, 2112, 2104, 2106, 2123, 2136, 2155, 2178, - 2195, 2188, 2162, 2145, 2144, 2148, 2160, 2180, - 2194, 2201, 2196, 2189, 2186, 2197, 2213, 2233, - 2243, 2238, 2230, 2217, 2201, 2203, 2216, 2232, - 2251, 2267, 2278, 2283, 2276, 2258, 2252, 2264, - 2279, 2294, 2304, 2302, 2293, 2283, 2277, 2285, - 2302, 2315, 2320, 2313, 2309, 2311, 2316, 2322, - 2334, 2349, 2359, 2368, 2381, 2390, 2384, 2377, - 2381, 2404, 2430, 2449, 2464, 2479, 2481, 2471, - 2475, 2491, 2510, 2524, 2528, 2524, 2520, 2516, - 2523, 2539, 2550, 2559, 2572, 2582, 2583, 2579, - 2573, 2570, 2572, 2574, 2581, 2589, 2600, 2610, - 2602, 2594, 2596, 2610, 2629, 2641, 2642, 2638, - 2643, 2648, 2652, 2660, 2672, 2683, 2682, 2682, - 2692, 2700, 2699, 2703, 2715, 2721, 2724, 2734, - 2740, 2740, 2732, 2726, 2729, 2733, 2731, 2725, - 2721, 2722, 2718, 2708, 2703, 2707, 2714, 2720, - 2722, 2722, 2719, 2708, 2701, 2698, 2693, 2686, - 2679, 2678, 2676, 2676, 2672, 2671, 2663, 2648, - 2632, 2620, 2614, 2615, 2617, 2616, 2611, 2609, - 2603, 2592, 2586, 2587, 2590, 2594, 2590, 2584, - 2574, 2561, 2548, 2534, 2522, 2511, 2503, 2503, - 2501, 2496, 2488, 2488, 2486, 2484, 2492, 2504, - 2499, 2484, 2478, 2474, 2467, 2461, 2458, 2456, - 2449, 2438, 2429, 2426, 2422, 2413, 2404, 2394, - 2387, 2390, 2392, 2392, 2389, 2382, 2375, 2372, - 2367, 2355, 2347, 2346, 2344, 2340, 2333, 2325, - 2317, 2313, 2307, 2303, 2307, 2305, 2297, 2292, - 2288, 2282, 2280, 2282, 2289, 2295, 2298, 2289, - 2276, 2262, 2254, 2253, 2254, 2252, 2249, 2246, - 2234, 2221, 2213, 2214, 2208, 2198, 2192, 2194, - 2190, 2179, 2169, 2167, 2166, 2167, 2167, 2163, - 2155, 2144, 2133, 2130, 2130, 2127, 2123, 2124, - 2124, 2120, 2120, 2116, 2112, 2114, 2116, 2103, - 2083, 2074, 2068, 2068, 2069, 2079, 2093, 2098, - 2089, 2085, 2088, 2090, 2084, 2075, 2074, 2075, - 2079, 2081, 2079, 2075, 2076, 2086, 2096, 2099, - 2104, 2107, 2109, 2112, 2112, 2111, 2113, 2119, - 2123, 2128, 2131, 2130, 2123, 2117, 2118, 2120, - 2125, 2128, 2134, 2135, 2139, 2137, 2131, 2126, - 2123, 2127, 2127, 2126, 2121, 2119, 2114, 2115, - 2118, 2121, 2123, 2123, 2123, 2119, 2113, 2110, - 2107, 2102, 2102, 2105, 2109, 2109, 2099, 2085, - 2077, 2076, 2081, 2087, 2097, 2101, 2102, 2103, - 2104, 2103, 2104, 2108, 2111, 2112, 2111, 2109, - 2106, 2100, 2097, 2095, 2089, 2094, 2094, 2085, - 2074, 2067, 2058, 2053, 2056, 2058, 2056, 2052, - 2044, 2038, 2030, 2023, 2024, 2027, 2028, 2026, - 2019, 2015, 2020, 2022, 2020, 2013, 2013, 2010, - 2005, 2005, 2007, 2009, 2017, 2019, 2020, 2020, - 2021, 2021, 2019, 2015, 2019, 2023, 2031, 2039, - 2044, 2046, 2042, 2041, 2039, 2042, 2039, 2034, - 2030, 2025, 2019, 2020, 2022, 2026, 2028, 2026, - 2017, 2007, 1996, 1983, 1981, 1984, 1984, 1976, - 1973, 1974, 1966, 1953, 1947, 1948, 1947, 1943, - 1933, 1922, 1911, 1905, 1911, 1918, 1924, 1934, - 1942, 1938, 1933, 1927, 1928, 1932, 1937, 1950, - 1960, 1963, 1961, 1960, 1964, 1962, 1959, 1963, - 1964, 1956, 1946, 1936, 1935, 1931, 1925, 1926, - 1935, 1935, 1927, 1914, 1905, 1899, 1901, 1907, - 1910, 1912, 1910, 1908, 1908, 1909, 1914, 1918, - 1917, 1912, 1909, 1911, 1909, 1905, 1909, 1921, - 1931, 1936, 1938, 1940, 1942, 1937, 1934, 1926, - 1929, 1948, 1961, 1960, 1960, 1963, 1963, 1957, - 1954, 1955, 1955, 1953, 1950, 1948, 1953, 1959, - 1956, 1945, 1945, 1952, 1951, 1941, 1929, 1923, - 1926, 1931, 1933, 1940, 1959, 1969, 1961, 1949, - 1948, 1956, 1955, 1955, 1952, 1952, 1957, 1961, - 1968, 1977, 1986, 1991, 1985, 1987, 1991, 1988, - 1989, 1996, 2004, 2010, 2019, 2036, 2048, 2048, - 2044, 2041, 2040, 2048, 2062, 2075, 2078, 2074, - 2080, 2092, 2105, 2118, 2129, 2129, 2123, 2130, - 2141, 2144, 2148, 2163, 2173, 2168, 2169, 2179, - 2187, 2187, 2182, 2179, 2178, 2183, 2181, 2182, - 2190, 2202, 2204, 2195, 2194, 2196, 2198, 2197, - 2193, 2187, 2186, 2189, 2192, 2196, 2199, 2201, - 2198, 2196, 2201, 2201, 2196, 2191, 2193, 2202, - 2216, 2225, 2226, 2224, 2223, 2229, 2231, 2231, - 2236, 2241, 2242, 2240, 2251, 2260, 2265, 2267, - 2277, 2277, 2271, 2278, 2290, 2294, 2292, 2293, - 2301, 2308, 2320, 2332, 2339, 2336, 2327, 2320, - 2330, 2349, 2359, 2361, 2361, 2364, 2361, 2366, - 2371, 2378, 2380, 2379, 2374, 2367, 2367, 2370, - 2375, 2376, 2373, 2374, 2376, 2366, 2361, 2363, - 2362, 2358, 2354, 2351, 2355, 2360, 2359, 2361, - 2364, 2368, 2372, 2374, 2376, 2378, 2382, 2385, - 2393, 2400, 2400, 2393, 2394, 2399, 2399, 2397, - 2397, 2398, 2399, 2399, 2406, 2415, 2414, 2408, - 2402, 2405, 2408, 2405, 2404, 2404, 2404, 2410, - 2414, 2417, 2423, 2419, 2419, 2420, 2418, 2420, - 2423, 2423, 2420, 2424, 2421, 2420, 2426, 2431, - 2429, 2423, 2417, 2413, 2413, 2413, 2420, 2425, - 2424, 2424, 2419, 2416, 2417, 2422, 2418, 2420, - 2423, 2423, 2422, 2426, 2436, 2441, 2442, 2444, - 2446, 2446, 2442, 2443, 2446, 2449, 2446, 2445, - 2449, 2454, 2459, 2457, 2453, 2451, 2448, 2443, - 2441, 2445, 2447, 2449, 2450, 2452, 2455, 2459, - 2457, 2451, 2444, 2439, 2439, 2441, 2448, 2453, - 2455, 2462, 2468, 2471, 2476, 2482, 2486, 2490, - 2486, 2488, 2493, 2500, 2511, 2517, 2520, 2518, - 2521, 2526, 2525, 2521, 2528, 2539, 2545, 2547, - 2554, 2562, 2568, 2573, 2578, 2581, 2586, 2592, - 2596, 2600, 2607, 2612, 2619, 2631, 2639, 2641, - 2639, 2635, 2634, 2639, 2647, 2647, 2645, 2651, - 2650, 2649, 2646, 2635, 2628, 2628, 2627, 2621, - 2614, 2604, 2593, 2591, 2596, 2601, 2595, 2588, - 2590, 2587, 2578, 2579, 2585, 2590, 2589, 2587, - 2589, 2587, 2581, 2582, 2583, 2578, 2572, 2576, - 2576, 2578, 2577, 2576, 2577, 2580, 2584, 2586, - 2588, 2583, 2581, 2587, 2588, 2585, 2591, 2602, - 2605, 2607, 2607, 2609, 2611, 2612, 2614, 2615, - 2615, 2610, 2610, 2610, 2608, 2608, 2609, 2611, - 2600, 2591, 2593, 2592, 2589, 2582, 2575, 2572, - 2572, 2567, 2562, 2557, 2553, 2541, 2532, 2534, - 2534, 2530, 2529, 2526, 2522, 2518, 2512, 2504, - 2507, 2514, 2506, 2494, 2493, 2495, 2490, 2485, - 2487, 2489, 2483, 2470, 2468, 2471, 2471, 2468, - 2465, 2458, 2454, 2449, 2444, 2438, 2429, 2418, - 2416, 2412, 2408, 2404, 2394, 2395, 2395, 2384, - 2376, 2369, 2365, 2359, 2350, 2343, 2343, 2339, - 2331, 2330, 2324, 2320, 2315, 2303, 2295, 2292, - 2289, 2281, 2279, 2276, 2273, 2268, 2266, 2264, - 2259, 2251, 2248, 2244, 2242, 2238, 2234, 2231, - 2231, 2223, 2218, 2218, 2221, 2217, 2209, 2205, - 2201, 2200, 2199, 2202, 2205, 2207, 2203, 2202, - 2201, 2198, 2195, 2195, 2194, 2192, 2191, 2194, - 2196, 2200, 2199, 2202, 2200, 2199, 2196, 2197, - 2203, 2201, 2202, 2204, 2207, 2208, 2211, 2216, - 2215, 2214, 2212, 2213, 2217, 2223, 2227, 2230, - 2236, 2239, 2248, 2254, 2258, 2263, 2269, 2277, - 2286, 2300, 2315, 2331, 2342, 2355, 2371, 2385, - 2398, 2413, 2430, 2443, 2458, 2473, 2486, 2497, - 2512, 2523, 2529, 2533, 2538, 2542, 2546, 2549, - 2553, 2559, 2564, 2564, 2560, 2563, 2559, 2552, - 2548, 2546, 2545, 2540, 2540, 2541, 2537, 2539, - 2544, 2542, 2536, 2531, 2532, 2528, 2522, 2519, - 2516, 2524, 2527, 2527, 2531, 2536, 2536, 2532, - 2531, 2539, 2544, 2544, 2545, 2553, 2564, 2570, - 2571, 2571, 2573, 2574, 2578, 2587, 2595, 2598, - 2603, 2610, 2618, 2628, 2632, 2640, 2652, 2653, - 2650, 2652, 2655, 2660, 2671, 2676, 2681, 2691, - 2688, 2681, 2687, 2690, 2696, 2699, 2698, 2704, - 2709, 2706, 2708, 2717, 2717, 2711, 2710, 2709, - 2710, 2704, 2696, 2691, 2681, 2675, 2668, 2654, - 2634, 2608, 2581, 2560, 2539, 2511, 2479, 2446, - 2408, 2367, 2330, 2289, 2248, 2195, 2139, 2091, - 2037, 1980, 1927, 1871, 1817, 1766, 1716, 1665, - 1613, 1558, 1507, 1465, 1427, 1394, 1363, 1339, - 1315, 1291, 1276, 1266, 1257, 1252, 1253, 1260, - 1271, 1279, 1294, 1316, 1338, 1365, 1393, 1420, - 1443, 1471, 1502, 1534, 1568, 1599, 1629, 1655, - 1681, 1709, 1734, 1755, 1774, 1789, 1803, 1818, - 1828, 1841, 1851, 1855, 1859, 1862, 1864, 1869, - 1868, 1860, 1856, 1850, 1845, 1842, 1837, 1832, - 1824, 1818, 1807, 1802, 1794, 1792, 1786, 1778, - 1773, 1767, 1767, 1769, 1772, 1773, 1772, 1773, - 1777, 1782, 1788, 1799, 1816, 1836, 1857, 1880, - 1905, 1928, 1951, 1974, 2000, 2027, 2055, 2085, - 2120, 2149, 2179, 2208, 2240, 2272, 2298, 2323, - 2347, 2371, 2397, 2422, 2446, 2467, 2487, 2501, - 2516, 2532, 2544, 2550, 2557, 2561, 2567, 2575, - 2578, 2578, 2579, 2580, 2583, 2585, 2585, 2586, - 2587, 2585, 2582, 2590, 2595, 2599, 2601, 2602, - 2608, 2619, 2631, 2635, 2642, 2649, 2660, 2669, - 2683, 2704, 2721, 2739, 2755, 2769, 2791, 2811, - 2829, 2849, 2870, 2888, 2909, 2931, 2948, 2968, - 2989, 3004, 3031, 3052, 3063, 3069, 3081, 3095, - 3102, 3097, 3073, 3042, 3007, 2964, 2919, 2869, - 2814, 2755, 2694, 2634, 2584, 2535, 2473, 2404, - 2319, 2222, 2138, 2079, 2021, 1957, 1890, 1819, - 1758, 1713, 1675, 1641, 1610, 1569, 1526, 1500, - 1493, 1504, 1519, 1531, 1548, 1567, 1587, 1608, - 1634, 1661, 1680, 1704, 1738, 1782, 1844, 1901, - 1949, 1987, 2025, 2062, 2095, 2129, 2158, 2179, - 2192, 2209, 2225, 2246, 2277, 2294, 2301, 2296, - 2281, 2267, 2259, 2260, 2268, 2267, 2258, 2245, - 2229, 2214, 2201, 2187, 2168, 2145, 2119, 2090, - 2065, 2040, 2013, 1981, 1950, 1932, 1907, 1860, - 1805, 1751, 1700, 1661, 1626, 1591, 1554, 1504, - 1442, 1388, 1340, 1296, 1263, 1237, 1213, 1194, - 1173, 1159, 1154, 1154, 1160, 1173, 1190, 1202, - 1210, 1213, 1242, 1277, 1318, 1370, 1421, 1473, - 1517, 1558, 1603, 1657, 1711, 1762, 1812, 1857, - 1895, 1926, 1956, 1985, 2009, 2027, 2039, 2044, - 2042, 2038, 2037, 2039, 2047, 2055, 2057, 2049, - 2030, 2008, 1990, 1981, 1974, 1971, 1966, 1957, - 1949, 1943, 1944, 1953, 1964, 1979, 1986, 1991, - 2002, 2018, 2040, 2069, 2099, 2130, 2163, 2189, - 2212, 2233, 2261, 2297, 2338, 2381, 2416, 2454, - 2493, 2537, 2578, 2621, 2664, 2701, 2730, 2753, - 2776, 2805, 2841, 2877, 2914, 2940, 2961, 2975, - 2984, 2993, 3008, 3028, 3044, 3054, 3055, 3054, - 3058, 3063, 3072, 3080, 3086, 3082, 3074, 3069, - 3070, 3078, 3094, 3116, 3134, 3147, 3155, 3161, - 3171, 3185, 3203, 3222, 3235, 3235, 3229, 3218, - 3210, 3205, 3190, 3171, 3144, 3109, 3055, 3002, - 2953, 2902, 2840, 2760, 2669, 2559, 2445, 2337, - 2236, 2132, 2031, 1930, 1828, 1731, 1635, 1546, - 1473, 1410, 1352, 1298, 1258, 1226, 1205, 1195, - 1206, 1238, 1269, 1305, 1354, 1404, 1461, 1534, - 1624, 1727, 1839, 1952, 2056, 2159, 2258, 2362, - 2465, 2569, 2668, 2751, 2819, 2882, 2944, 3005, - 3063, 3111, 3143, 3152, 3148, 3135, 3115, 3092, - 3068, 3039, 2996, 2942, 2881, 2812, 2744, 2679, - 2611, 2549, 2481, 2412, 2346, 2283, 2230, 2185, - 2142, 2090, 2025, 1945, 1869, 1809, 1762, 1720, - 1681, 1633, 1574, 1519, 1480, 1451, 1427, 1397, - 1363, 1325, 1286, 1258, 1241, 1236, 1234, 1229, - 1226, 1224, 1222, 1220, 1230, 1252, 1284, 1329, - 1379, 1436, 1490, 1540, 1591, 1652, 1720, 1787, - 1850, 1907, 1961, 2016, 2078, 2145, 2213, 2274, - 2319, 2349, 2369, 2380, 2387, 2400, 2411, 2407, - 2392, 2366, 2329, 2292, 2255, 2225, 2192, 2149, - 2101, 2046, 1995, 1956, 1932, 1913, 1897, 1880, - 1851, 1825, 1806, 1799, 1808, 1830, 1854, 1880, - 1905, 1935, 1978, 2031, 2093, 2154, 2209, 2259, - 2315, 2369, 2428, 2497, 2564, 2630, 2685, 2733, - 2777, 2822, 2862, 2904, 2943, 2976, 3003, 3026, - 3043, 3062, 3076, 3079, 3077, 3076, 3075, 3063, - 3048, 3035, 3029, 3022, 3021, 3021, 3020, 3012, - 3004, 3001, 2998, 3004, 3013, 3022, 3031, 3035, - 3038, 3044, 3054, 3058, 3057, 3050, 3036, 3019, - 2998, 2976, 2955, 2925, 2883, 2829, 2770, 2691, - 2600, 2506, 2403, 2296, 2176, 2054, 1938, 1819, - 1703, 1592, 1488, 1383, 1281, 1183, 1096, 1024, - 961, 917, 890, 874, 873, 880, 901, 937, - 983, 1040, 1112, 1195, 1283, 1390, 1504, 1623, - 1753, 1883, 2011, 2131, 2245, 2356, 2464, 2566, - 2664, 2752, 2833, 2906, 2968, 3010, 3039, 3068, - 3070, 3054, 3033, 3002, 2960, 2908, 2853, 2792, - 2724, 2645, 2564, 2476, 2380, 2289, 2199, 2116, - 2039, 1969, 1899, 1839, 1780, 1722, 1670, 1626, - 1585, 1544, 1503, 1462, 1412, 1370, 1340, 1320, - 1299, 1272, 1252, 1224, 1193, 1168, 1156, 1155, - 1152, 1147, 1140, 1129, 1116, 1113, 1115, 1130, - 1143, 1146, 1152, 1169, 1187, 1215, 1258, 1301, - 1345, 1385, 1428, 1469, 1511, 1555, 1611, 1669, - 1716, 1761, 1802, 1841, 1880, 1920, 1959, 1995, - 2024, 2045, 2060, 2069, 2073, 2071, 2067, 2057, - 2039, 2006, 1965, 1921, 1879, 1835, 1799, 1764, - 1727, 1688, 1654, 1621, 1596, 1575, 1562, 1556, - 1549, 1545, 1545, 1557, 1578, 1610, 1654, 1700, - 1752, 1808, 1869, 1935, 2007, 2089, 2173, 2253, - 2327, 2396, 2458, 2518, 2580, 2640, 2694, 2739, - 2772, 2798, 2824, 2852, 2878, 2901, 2925, 2935, - 2940, 2938, 2935, 2931, 2927, 2927, 2921, 2911, - 2897, 2881, 2866, 2861, 2861, 2860, 2860, 2859, - 2858, 2855, 2858, 2860, 2863, 2864, 2863, 2856, - 2841, 2817, 2798, 2777, 2750, 2716, 2676, 2629, - 2570, 2498, 2413, 2325, 2232, 2122, 2010, 1907, - 1791, 1673, 1558, 1448, 1348, 1253, 1159, 1073, - 993, 920, 863, 823, 799, 791, 793, 806, - 836, 870, 913, 973, 1048, 1135, 1229, 1332, - 1440, 1556, 1679, 1806, 1939, 2067, 2184, 2295, - 2398, 2490, 2579, 2663, 2733, 2800, 2849, 2882, - 2903, 2910, 2900, 2880, 2851, 2810, 2755, 2692, - 2623, 2550, 2473, 2393, 2308, 2220, 2127, 2035, - 1944, 1859, 1783, 1713, 1649, 1596, 1549, 1509, - 1478, 1445, 1415, 1385, 1360, 1340, 1317, 1291, - 1271, 1259, 1243, 1229, 1219, 1212, 1199, 1181, - 1170, 1164, 1165, 1161, 1158, 1156, 1153, 1149, - 1150, 1159, 1173, 1185, 1196, 1212, 1236, 1264, - 1297, 1339, 1383, 1424, 1464, 1507, 1547, 1584, - 1627, 1668, 1711, 1747, 1781, 1813, 1845, 1872, - 1901, 1928, 1947, 1958, 1964, 1965, 1962, 1954, - 1943, 1927, 1906, 1875, 1838, 1802, 1770, 1737, - 1702, 1671, 1644, 1620, 1597, 1577, 1565, 1556, - 1550, 1547, 1549, 1557, 1572, 1587, 1610, 1645, - 1686, 1734, 1786, 1845, 1906, 1973, 2045, 2126, - 2209, 2289, 2365, 2435, 2502, 2571, 2632, 2690, - 2745, 2789, 2826, 2859, 2890, 2916, 2935, 2955, - 2975, 2991, 2997, 2994, 2989, 2977, 2966, 2959, - 2952, 2949, 2937, 2913, 2888, 2865, 2848, 2834, - 2820, 2794, 2762, 2729, 2699, 2671, 2644, 2619, - 2584, 2538, 2488, 2428, 2368, 2301, 2224, 2142, - 2053, 1956, 1853, 1754, 1662, 1572, 1481, 1390, - 1308, 1226, 1147, 1074, 1012, 962, 921, 893, - 877, 865, 870, 889, 924, 970, 1024, 1086, - 1153, 1230, 1315, 1407, 1510, 1618, 1729, 1841, - 1944, 2043, 2141, 2233, 2319, 2402, 2475, 2538, - 2598, 2649, 2685, 2714, 2732, 2734, 2725, 2703, - 2663, 2611, 2549, 2481, 2415, 2348, 2276, 2196, - 2114, 2031, 1949, 1867, 1792, 1723, 1661, 1605, - 1552, 1505, 1468, 1436, 1411, 1383, 1352, 1314, - 1281, 1252, 1236, 1221, 1201, 1186, 1171, 1157, - 1149, 1149, 1146, 1136, 1132, 1127, 1123, 1124, - 1135, 1145, 1155, 1163, 1160, 1169, 1187, 1210, - 1238, 1273, 1311, 1355, 1404, 1452, 1503, 1550, - 1598, 1647, 1691, 1729, 1764, 1798, 1828, 1857, - 1885, 1910, 1928, 1939, 1953, 1964, 1968, 1963, - 1955, 1941, 1919, 1892, 1865, 1834, 1804, 1772, - 1731, 1695, 1659, 1627, 1603, 1584, 1566, 1557, - 1554, 1551, 1552, 1560, 1580, 1595, 1617, 1646, - 1679, 1724, 1772, 1825, 1882, 1938, 1994, 2063, - 2135, 2205, 2276, 2347, 2419, 2491, 2564, 2640, - 2709, 2770, 2815, 2857, 2897, 2932, 2966, 2993, - 3017, 3035, 3045, 3052, 3059, 3067, 3068, 3072, - 3071, 3054, 3030, 3006, 2988, 2967, 2945, 2926, - 2897, 2854, 2807, 2758, 2711, 2665, 2621, 2573, - 2512, 2443, 2366, 2289, 2212, 2128, 2034, 1924, - 1801, 1677, 1567, 1465, 1369, 1283, 1202, 1126, - 1051, 982, 931, 896, 866, 842, 835, 845, - 865, 900, 951, 1014, 1086, 1160, 1242, 1332, - 1430, 1535, 1650, 1772, 1896, 2020, 2142, 2253, - 2352, 2438, 2514, 2578, 2632, 2675, 2708, 2731, - 2748, 2755, 2752, 2738, 2707, 2660, 2601, 2531, - 2453, 2371, 2289, 2206, 2121, 2038, 1951, 1867, - 1784, 1701, 1624, 1556, 1497, 1452, 1413, 1382, - 1366, 1357, 1345, 1330, 1316, 1299, 1272, 1237, - 1203, 1181, 1167, 1153, 1142, 1134, 1123, 1102, - 1086, 1080, 1077, 1072, 1067, 1071, 1079, 1087, - 1099, 1120, 1149, 1174, 1197, 1227, 1260, 1301, - 1348, 1402, 1464, 1528, 1587, 1642, 1694, 1739, - 1779, 1814, 1845, 1873, 1894, 1913, 1928, 1946, - 1962, 1974, 1982, 1978, 1964, 1939, 1912, 1883, - 1856, 1827, 1793, 1758, 1719, 1677, 1640, 1610, - 1583, 1561, 1542, 1537, 1538, 1546, 1567, 1592, - 1623, 1659, 1689, 1718, 1751, 1791, 1831, 1877, - 1930, 1990, 2051, 2110, 2172, 2236, 2297, 2353, - 2402, 2449, 2495, 2541, 2584, 2619, 2648, 2671, - 2693, 2711, 2727, 2742, 2753, 2769, 2782, 2803, - 2829, 2851, 2878, 2904, 2927, 2941, 2950, 2951, - 2942, 2928, 2917, 2901, 2876, 2843, 2803, 2766, - 2714, 2660, 2605, 2539, 2459, 2361, 2250, 2134, - 2021, 1900, 1768, 1634, 1507, 1377, 1254, 1147, - 1050, 960, 877, 803, 754, 726, 703, 690, - 699, 722, 757, 805, 874, 956, 1044, 1134, - 1238, 1357, 1481, 1608, 1737, 1864, 1991, 2113, - 2225, 2328, 2418, 2488, 2545, 2587, 2618, 2635, - 2642, 2639, 2620, 2592, 2552, 2505, 2447, 2375, - 2296, 2214, 2126, 2035, 1947, 1857, 1771, 1686, - 1604, 1532, 1471, 1415, 1371, 1338, 1316, 1304, - 1307, 1318, 1330, 1339, 1343, 1344, 1338, 1328, - 1319, 1297, 1262, 1225, 1196, 1172, 1148, 1120, - 1093, 1068, 1037, 1005, 987, 976, 965, 949, - 943, 942, 943, 953, 976, 1006, 1038, 1073, - 1118, 1173, 1236, 1308, 1381, 1456, 1531, 1599, - 1659, 1718, 1767, 1807, 1843, 1878, 1908, 1926, - 1936, 1943, 1945, 1941, 1934, 1917, 1890, 1851, - 1806, 1761, 1719, 1673, 1624, 1579, 1538, 1496, - 1460, 1442, 1435, 1437, 1447, 1467, 1499, 1536, - 1581, 1632, 1683, 1737, 1795, 1853, 1914, 1979, - 2042, 2105, 2168, 2238, 2308, 2369, 2428, 2482, - 2533, 2582, 2623, 2661, 2688, 2700, 2712, 2724, - 2733, 2739, 2735, 2729, 2724, 2719, 2718, 2734, - 2756, 2772, 2784, 2800, 2822, 2836, 2839, 2823, - 2803, 2780, 2749, 2714, 2676, 2636, 2582, 2508, - 2439, 2379, 2307, 2207, 2097, 1977, 1841, 1695, - 1563, 1455, 1351, 1237, 1117, 1015, 923, 843, - 781, 739, 709, 686, 675, 696, 742, 803, - 874, 961, 1055, 1146, 1237, 1334, 1440, 1562, - 1693, 1830, 1968, 2097, 2218, 2322, 2415, 2498, - 2564, 2606, 2631, 2638, 2623, 2603, 2579, 2547, - 2506, 2451, 2371, 2276, 2176, 2077, 1988, 1900, - 1818, 1734, 1648, 1571, 1500, 1429, 1366, 1308, - 1252, 1206, 1176, 1163, 1164, 1186, 1215, 1244, - 1267, 1279, 1285, 1271, 1246, 1230, 1216, 1196, - 1172, 1147, 1109, 1061, 1018, 988, 970, 944, - 908, 878, 858, 847, 850, 874, 915, 942, - 958, 979, 1013, 1060, 1118, 1193, 1280, 1361, - 1435, 1512, 1598, 1679, 1755, 1819, 1866, 1903, - 1928, 1939, 1954, 1973, 1977, 1973, 1961, 1934, - 1892, 1842, 1790, 1744, 1700, 1654, 1600, 1540, - 1483, 1428, 1385, 1354, 1329, 1309, 1296, 1298, - 1318, 1358, 1414, 1485, 1560, 1628, 1696, 1767, - 1842, 1913, 1991, 2071, 2150, 2229, 2292, 2350, - 2414, 2479, 2535, 2582, 2628, 2658, 2673, 2682, - 2700, 2721, 2728, 2725, 2719, 2707, 2679, 2653, - 2642, 2645, 2649, 2649, 2658, 2676, 2697, 2726, - 2755, 2770, 2767, 2755, 2739, 2722, 2696, 2663, - 2621, 2565, 2499, 2432, 2359, 2262, 2157, 2046, - 1915, 1769, 1624, 1487, 1368, 1254, 1134, 1031, - 931, 833, 759, 706, 669, 645, 635, 651, - 689, 745, 819, 914, 1021, 1131, 1240, 1348, - 1460, 1580, 1706, 1839, 1977, 2111, 2231, 2338, - 2431, 2513, 2577, 2616, 2638, 2643, 2627, 2592, - 2550, 2503, 2451, 2386, 2304, 2208, 2103, 1997, - 1897, 1801, 1719, 1645, 1576, 1513, 1455, 1402, - 1358, 1322, 1296, 1270, 1253, 1244, 1252, 1269, - 1290, 1315, 1335, 1346, 1342, 1325, 1299, 1269, - 1236, 1190, 1140, 1090, 1038, 986, 931, 880, - 837, 794, 755, 723, 711, 714, 726, 754, - 795, 844, 896, 954, 1020, 1100, 1186, 1273, - 1369, 1472, 1574, 1672, 1766, 1855, 1932, 1995, - 2040, 2069, 2094, 2106, 2103, 2096, 2079, 2048, - 2006, 1953, 1897, 1834, 1774, 1708, 1641, 1579, - 1520, 1465, 1414, 1377, 1348, 1328, 1321, 1319, - 1329, 1361, 1410, 1471, 1540, 1618, 1698, 1779, - 1866, 1952, 2034, 2117, 2192, 2258, 2320, 2377, - 2431, 2479, 2521, 2558, 2581, 2596, 2610, 2617, - 2616, 2618, 2625, 2624, 2610, 2601, 2597, 2589, - 2584, 2589, 2594, 2612, 2633, 2651, 2692, 2745, - 2787, 2813, 2835, 2854, 2852, 2837, 2821, 2803, - 2774, 2715, 2641, 2566, 2481, 2384, 2272, 2143, - 2003, 1843, 1666, 1507, 1374, 1251, 1128, 1015, - 915, 821, 744, 691, 659, 650, 654, 671, - 713, 783, 872, 979, 1108, 1238, 1364, 1477, - 1592, 1713, 1838, 1966, 2090, 2207, 2314, 2405, - 2475, 2525, 2559, 2571, 2561, 2537, 2497, 2435, - 2363, 2295, 2229, 2157, 2073, 1981, 1880, 1778, - 1689, 1613, 1551, 1506, 1470, 1436, 1418, 1406, - 1398, 1399, 1408, 1421, 1435, 1449, 1461, 1480, - 1502, 1516, 1514, 1500, 1473, 1432, 1372, 1303, - 1236, 1162, 1081, 995, 917, 848, 785, 718, - 669, 632, 595, 575, 574, 601, 646, 693, - 755, 835, 929, 1024, 1124, 1236, 1354, 1468, - 1576, 1688, 1800, 1903, 1985, 2051, 2106, 2150, - 2168, 2162, 2149, 2130, 2093, 2045, 1989, 1929, - 1862, 1792, 1715, 1639, 1573, 1511, 1451, 1398, - 1359, 1335, 1321, 1323, 1331, 1356, 1402, 1453, - 1507, 1576, 1665, 1755, 1838, 1929, 2023, 2110, - 2190, 2261, 2323, 2373, 2415, 2449, 2473, 2497, - 2513, 2504, 2491, 2485, 2468, 2443, 2430, 2413, - 2380, 2358, 2355, 2354, 2349, 2368, 2388, 2403, - 2436, 2478, 2526, 2594, 2673, 2745, 2809, 2877, - 2926, 2942, 2962, 2981, 2972, 2937, 2882, 2829, - 2752, 2666, 2568, 2448, 2320, 2183, 2012, 1813, - 1625, 1455, 1286, 1138, 1015, 902, 802, 715, - 646, 613, 614, 626, 649, 694, 772, 872, - 983, 1118, 1271, 1428, 1569, 1695, 1806, 1920, - 2040, 2151, 2251, 2344, 2415, 2460, 2491, 2500, - 2491, 2458, 2398, 2319, 2231, 2136, 2038, 1941, - 1856, 1782, 1709, 1633, 1556, 1487, 1428, 1387, - 1366, 1364, 1378, 1396, 1416, 1443, 1479, 1520, - 1565, 1604, 1637, 1658, 1671, 1679, 1685, 1674, - 1649, 1602, 1528, 1432, 1320, 1199, 1073, 955, - 842, 731, 635, 553, 482, 426, 391, 382, - 389, 409, 450, 515, 603, 706, 824, 959, - 1108, 1257, 1397, 1531, 1672, 1808, 1928, 2040, - 2137, 2213, 2259, 2286, 2291, 2285, 2256, 2196, - 2120, 2038, 1952, 1861, 1764, 1679, 1604, 1528, - 1451, 1384, 1332, 1293, 1267, 1256, 1265, 1294, - 1334, 1386, 1453, 1535, 1634, 1741, 1845, 1948, - 2053, 2151, 2234, 2305, 2380, 2451, 2504, 2523, - 2527, 2531, 2528, 2509, 2474, 2446, 2422, 2382, - 2322, 2274, 2253, 2240, 2215, 2184, 2172, 2186, - 2199, 2212, 2257, 2327, 2392, 2450, 2522, 2612, - 2714, 2823, 2921, 3008, 3092, 3154, 3180, 3186, - 3189, 3174, 3128, 3049, 2951, 2839, 2711, 2572, - 2418, 2254, 2092, 1912, 1708, 1505, 1315, 1151, - 1010, 895, 805, 739, 696, 670, 667, 710, - 786, 872, 967, 1070, 1196, 1336, 1482, 1634, - 1793, 1945, 2069, 2157, 2225, 2301, 2370, 2412, - 2438, 2451, 2442, 2407, 2349, 2283, 2213, 2133, - 2031, 1925, 1823, 1731, 1643, 1573, 1531, 1507, - 1497, 1485, 1485, 1492, 1520, 1560, 1611, 1676, - 1738, 1796, 1848, 1893, 1934, 1964, 1978, 1976, - 1957, 1904, 1815, 1726, 1631, 1513, 1380, 1243, - 1097, 940, 788, 649, 532, 436, 351, 290, - 258, 256, 276, 316, 391, 494, 613, 739, - 878, 1029, 1181, 1343, 1509, 1669, 1819, 1947, - 2052, 2145, 2220, 2263, 2282, 2284, 2264, 2223, - 2158, 2081, 1997, 1914, 1827, 1736, 1646, 1560, - 1483, 1424, 1377, 1346, 1339, 1346, 1359, 1391, - 1444, 1512, 1579, 1658, 1751, 1849, 1944, 2040, - 2133, 2221, 2300, 2372, 2426, 2464, 2490, 2496, - 2484, 2467, 2437, 2400, 2360, 2309, 2255, 2205, - 2169, 2130, 2080, 2051, 2049, 2068, 2081, 2113, - 2173, 2239, 2309, 2396, 2499, 2606, 2715, 2815, - 2917, 3026, 3140, 3237, 3323, 3408, 3472, 3491, - 3454, 3398, 3342, 3252, 3136, 3009, 2868, 2715, - 2552, 2390, 2240, 2090, 1934, 1769, 1609, 1465, - 1338, 1221, 1116, 1058, 1049, 1040, 1032, 1052, - 1100, 1169, 1245, 1330, 1438, 1550, 1650, 1740, - 1838, 1933, 2015, 2072, 2112, 2149, 2167, 2156, - 2133, 2126, 2121, 2105, 2072, 2027, 1981, 1930, - 1881, 1839, 1802, 1768, 1740, 1723, 1721, 1739, - 1773, 1812, 1866, 1924, 1988, 2047, 2102, 2159, - 2210, 2251, 2274, 2286, 2278, 2254, 2212, 2157, - 2084, 1999, 1909, 1802, 1678, 1548, 1416, 1278, - 1139, 997, 841, 704, 599, 505, 421, 370, - 363, 374, 395, 448, 538, 646, 759, 880, - 1015, 1157, 1299, 1422, 1541, 1671, 1790, 1879, - 1949, 2008, 2060, 2084, 2077, 2065, 2043, 2003, - 1939, 1867, 1803, 1735, 1659, 1589, 1536, 1507, - 1486, 1466, 1462, 1485, 1534, 1587, 1638, 1703, - 1781, 1853, 1917, 1987, 2058, 2121, 2172, 2215, - 2258, 2301, 2331, 2335, 2341, 2355, 2355, 2327, - 2291, 2261, 2221, 2172, 2122, 2080, 2050, 2030, - 2012, 2015, 2042, 2060, 2081, 2126, 2184, 2241, - 2296, 2369, 2449, 2526, 2596, 2663, 2741, 2830, - 2900, 2954, 3003, 3058, 3092, 3101, 3128, 3167, - 3178, 3160, 3129, 3100, 3050, 2972, 2880, 2785, - 2696, 2597, 2481, 2383, 2299, 2221, 2146, 2075, - 2018, 1959, 1883, 1804, 1739, 1681, 1619, 1568, - 1548, 1541, 1536, 1536, 1548, 1577, 1613, 1648, - 1678, 1710, 1737, 1750, 1758, 1779, 1804, 1822, - 1826, 1831, 1845, 1852, 1858, 1872, 1904, 1943, - 1970, 1991, 2015, 2044, 2070, 2084, 2097, 2110, - 2117, 2118, 2120, 2135, 2155, 2171, 2188, 2210, - 2226, 2223, 2208, 2194, 2173, 2142, 2097, 2046, - 1988, 1918, 1836, 1761, 1699, 1622, 1528, 1438, - 1355, 1269, 1186, 1109, 1036, 968, 906, 845, - 798, 773, 757, 749, 762, 803, 857, 915, - 984, 1067, 1151, 1229, 1305, 1380, 1451, 1518, - 1568, 1613, 1657, 1693, 1716, 1736, 1756, 1768, - 1769, 1759, 1750, 1750, 1744, 1728, 1709, 1700, - 1702, 1700, 1700, 1712, 1735, 1766, 1799, 1839, - 1887, 1935, 1969, 1999, 2036, 2069, 2092, 2106, - 2117, 2130, 2136, 2136, 2145, 2153, 2148, 2145, - 2142, 2141, 2136, 2131, 2134, 2147, 2154, 2157, - 2164, 2171, 2176, 2200, 2244, 2290, 2326, 2368, - 2436, 2502, 2560, 2631, 2712, 2769, 2814, 2855, - 2894, 2939, 2991, 3028, 3042, 3069, 3115, 3144, - 3139, 3149, 3177, 3146, 3045, 2956, 2888, 2804, - 2708, 2608, 2497, 2401, 2333, 2263, 2194, 2157, - 2126, 2058, 1970, 1902, 1862, 1818, 1760, 1719, - 1681, 1625, 1582, 1558, 1531, 1528, 1528, 1526, - 1534, 1553, 1588, 1610, 1631, 1655, 1670, 1654, - 1639, 1651, 1670, 1683, 1721, 1789, 1857, 1919, - 1977, 2027, 2076, 2120, 2145, 2162, 2177, 2191, - 2200, 2201, 2211, 2226, 2230, 2219, 2210, 2200, - 2188, 2183, 2180, 2179, 2162, 2132, 2093, 2045, - 1983, 1911, 1840, 1773, 1711, 1638, 1572, 1539, - 1512, 1456, 1381, 1314, 1248, 1178, 1112, 1042, - 980, 936, 887, 833, 809, 817, 825, 832, - 859, 909, 961, 1014, 1085, 1169, 1246, 1316, - 1375, 1420, 1468, 1524, 1575, 1623, 1672, 1715, - 1746, 1773, 1802, 1822, 1833, 1823, 1807, 1794, - 1778, 1761, 1754, 1754, 1768, 1792, 1804, 1818, - 1845, 1882, 1918, 1951, 1984, 2014, 2036, 2047, - 2062, 2071, 2068, 2066, 2068, 2068, 2064, 2063, - 2077, 2103, 2118, 2120, 2135, 2152, 2149, 2139, - 2148, 2171, 2185, 2192, 2211, 2254, 2303, 2353, - 2404, 2436, 2463, 2510, 2546, 2562, 2586, 2620, - 2648, 2674, 2701, 2718, 2744, 2786, 2828, 2847, - 2860, 2897, 2940, 2944, 2953, 2989, 3012, 3010, - 3010, 3007, 2977, 2931, 2881, 2830, 2764, 2696, - 2632, 2553, 2463, 2383, 2308, 2227, 2147, 2068, - 1981, 1885, 1804, 1738, 1656, 1584, 1538, 1514, - 1501, 1484, 1482, 1504, 1534, 1573, 1613, 1649, - 1691, 1734, 1762, 1782, 1814, 1847, 1865, 1877, - 1896, 1922, 1940, 1954, 1973, 1997, 2022, 2036, - 2039, 2043, 2052, 2057, 2055, 2059, 2061, 2064, - 2065, 2076, 2094, 2119, 2139, 2155, 2175, 2187, - 2186, 2175, 2156, 2131, 2096, 2051, 1997, 1944, - 1877, 1783, 1686, 1620, 1554, 1449, 1335, 1249, - 1153, 1045, 978, 932, 869, 820, 804, 793, - 790, 821, 881, 942, 1009, 1099, 1189, 1267, - 1349, 1437, 1508, 1563, 1617, 1660, 1676, 1686, - 1705, 1723, 1722, 1712, 1703, 1688, 1666, 1651, - 1646, 1636, 1634, 1650, 1663, 1682, 1726, 1772, - 1822, 1888, 1957, 2014, 2065, 2121, 2172, 2209, - 2237, 2255, 2252, 2240, 2225, 2204, 2169, 2139, - 2119, 2081, 2047, 2036, 2029, 2002, 1986, 2001, - 2023, 2039, 2065, 2114, 2155, 2197, 2257, 2326, - 2387, 2446, 2502, 2539, 2590, 2671, 2725, 2742, - 2786, 2852, 2893, 2909, 2931, 2955, 2967, 2974, - 2990, 3006, 3012, 3030, 3055, 3078, 3110, 3146, - 3172, 3187, 3175, 3122, 3050, 2998, 2952, 2876, - 2779, 2702, 2649, 2594, 2518, 2453, 2423, 2375, - 2289, 2205, 2122, 2041, 1980, 1915, 1848, 1793, - 1727, 1661, 1602, 1558, 1544, 1537, 1531, 1556, - 1597, 1638, 1679, 1727, 1763, 1782, 1783, 1771, - 1775, 1793, 1826, 1875, 1938, 2019, 2096, 2144, - 2174, 2207, 2230, 2232, 2226, 2229, 2232, 2235, - 2238, 2249, 2267, 2275, 2267, 2261, 2266, 2270, - 2278, 2291, 2310, 2326, 2314, 2272, 2217, 2158, - 2089, 2015, 1952, 1906, 1868, 1820, 1771, 1747, - 1731, 1670, 1566, 1474, 1385, 1287, 1202, 1122, - 1035, 976, 956, 932, 901, 904, 930, 952, - 991, 1055, 1130, 1195, 1253, 1314, 1372, 1419, - 1463, 1505, 1539, 1569, 1616, 1675, 1730, 1765, - 1786, 1802, 1815, 1814, 1802, 1780, 1758, 1764, - 1780, 1789, 1814, 1862, 1914, 1967, 2019, 2068, - 2111, 2153, 2194, 2211, 2219, 2230, 2220, 2196, - 2171, 2142, 2109, 2083, 2068, 2048, 2031, 2030, - 2039, 2044, 2040, 2048, 2071, 2099, 2123, 2159, - 2208, 2266, 2333, 2404, 2458, 2498, 2553, 2617, - 2651, 2660, 2681, 2704, 2706, 2691, 2674, 2667, - 2662, 2652, 2653, 2663, 2680, 2704, 2738, 2777, - 2833, 2895, 2936, 2970, 3020, 3065, 3101, 3148, - 3207, 3260, 3300, 3332, 3338, 3311, 3244, 3157, - 3055, 2947, 2826, 2691, 2553, 2429, 2328, 2240, - 2156, 2069, 1987, 1916, 1854, 1798, 1759, 1717, - 1672, 1653, 1667, 1676, 1669, 1679, 1708, 1740, - 1781, 1833, 1874, 1906, 1930, 1941, 1929, 1913, - 1895, 1866, 1836, 1814, 1812, 1829, 1856, 1895, - 1946, 1994, 2042, 2084, 2128, 2170, 2203, 2235, - 2266, 2292, 2311, 2320, 2325, 2338, 2348, 2342, - 2331, 2325, 2320, 2301, 2262, 2216, 2163, 2097, - 2025, 1953, 1890, 1838, 1796, 1768, 1755, 1738, - 1678, 1583, 1524, 1524, 1492, 1387, 1313, 1302, - 1264, 1200, 1181, 1187, 1175, 1151, 1115, 1105, - 1128, 1150, 1177, 1219, 1268, 1316, 1358, 1394, - 1436, 1476, 1523, 1577, 1629, 1681, 1720, 1745, - 1779, 1820, 1839, 1841, 1836, 1835, 1843, 1849, - 1852, 1870, 1909, 1941, 1944, 1944, 1968, 1999, - 2008, 2017, 2038, 2055, 2055, 2050, 2057, 2070, - 2073, 2060, 2049, 2050, 2058, 2059, 2054, 2064, - 2087, 2092, 2088, 2084, 2103, 2136, 2159, 2183, - 2222, 2267, 2310, 2349, 2391, 2434, 2465, 2475, - 2489, 2517, 2542, 2564, 2576, 2602, 2640, 2683, - 2727, 2763, 2792, 2822, 2893, 2982, 3023, 3033, - 3073, 3122, 3156, 3207, 3257, 3268, 3288, 3328, - 3359, 3391, 3399, 3342, 3235, 3125, 3034, 2927, - 2795, 2671, 2547, 2464, 2432, 2398, 2365, 2327, - 2260, 2199, 2151, 2078, 2010, 1966, 1924, 1892, - 1861, 1812, 1760, 1710, 1682, 1660, 1624, 1618, - 1643, 1664, 1687, 1723, 1746, 1744, 1728, 1693, - 1662, 1659, 1673, 1709, 1777, 1874, 1986, 2078, - 2131, 2162, 2187, 2193, 2185, 2180, 2179, 2174, - 2171, 2187, 2212, 2224, 2217, 2197, 2177, 2170, - 2173, 2182, 2197, 2213, 2218, 2200, 2168, 2126, - 2074, 2021, 1980, 1956, 1951, 1960, 1976, 1994, - 1990, 1953, 1870, 1770, 1693, 1623, 1514, 1393, - 1338, 1331, 1292, 1241, 1226, 1199, 1124, 1047, - 1013, 1026, 1043, 1046, 1072, 1135, 1198, 1244, - 1300, 1372, 1438, 1487, 1540, 1604, 1674, 1726, - 1742, 1749, 1765, 1768, 1732, 1679, 1657, 1657, - 1664, 1678, 1705, 1744, 1778, 1791, 1795, 1820, - 1856, 1881, 1907, 1952, 1996, 2032, 2074, 2104, - 2119, 2124, 2110, 2079, 2046, 2023, 2009, 1982, - 1947, 1923, 1905, 1880, 1860, 1867, 1885, 1908, - 1937, 1991, 2068, 2132, 2179, 2234, 2293, 2334, - 2370, 2401, 2419, 2438, 2479, 2513, 2518, 2531, - 2549, 2544, 2525, 2524, 2537, 2549, 2556, 2573, - 2607, 2654, 2705, 2766, 2848, 2924, 2965, 3009, - 3095, 3191, 3244, 3263, 3285, 3322, 3360, 3369, - 3358, 3366, 3377, 3362, 3309, 3223, 3100, 2971, - 2853, 2705, 2544, 2429, 2334, 2258, 2244, 2247, - 2249, 2259, 2246, 2209, 2162, 2093, 2036, 1997, - 1927, 1841, 1792, 1772, 1753, 1701, 1644, 1621, - 1614, 1607, 1606, 1603, 1600, 1609, 1609, 1587, - 1573, 1569, 1570, 1597, 1651, 1730, 1838, 1959, - 2065, 2153, 2212, 2247, 2253, 2234, 2202, 2168, - 2139, 2119, 2113, 2118, 2127, 2127, 2128, 2135, - 2136, 2143, 2153, 2172, 2190, 2190, 2179, 2166, - 2147, 2123, 2095, 2068, 2062, 2066, 2078, 2096, - 2113, 2110, 2076, 2028, 1963, 1880, 1789, 1692, - 1585, 1439, 1286, 1214, 1227, 1225, 1179, 1161, - 1195, 1237, 1278, 1329, 1359, 1366, 1356, 1329, - 1322, 1337, 1354, 1373, 1427, 1494, 1557, 1610, - 1653, 1676, 1670, 1652, 1633, 1618, 1592, 1550, - 1524, 1539, 1592, 1648, 1708, 1783, 1849, 1916, - 1987, 2036, 2066, 2101, 2110, 2080, 2044, 2026, - 2007, 1983, 1963, 1957, 1956, 1956, 1944, 1929, - 1928, 1926, 1899, 1866, 1847, 1847, 1861, 1889, - 1921, 1962, 2034, 2115, 2179, 2234, 2301, 2358, - 2384, 2393, 2392, 2381, 2362, 2343, 2330, 2339, - 2362, 2383, 2408, 2442, 2475, 2524, 2594, 2642, - 2654, 2663, 2705, 2764, 2806, 2840, 2899, 2984, - 3073, 3150, 3210, 3274, 3351, 3398, 3413, 3414, - 3426, 3448, 3427, 3394, 3394, 3422, 3435, 3389, - 3293, 3187, 3082, 2982, 2890, 2789, 2677, 2584, - 2551, 2552, 2545, 2534, 2520, 2465, 2386, 2306, - 2218, 2135, 2067, 1985, 1891, 1796, 1711, 1655, - 1602, 1532, 1459, 1434, 1451, 1476, 1514, 1567, - 1615, 1641, 1652, 1656, 1658, 1666, 1684, 1714, - 1771, 1860, 1952, 2039, 2107, 2133, 2122, 2096, - 2060, 2029, 2009, 1992, 1984, 2002, 2044, 2093, - 2131, 2166, 2195, 2222, 2254, 2291, 2333, 2381, - 2411, 2416, 2396, 2362, 2316, 2259, 2200, 2145, - 2107, 2091, 2088, 2089, 2084, 2057, 2020, 1972, - 1921, 1875, 1833, 1805, 1787, 1760, 1725, 1711, - 1724, 1723, 1665, 1582, 1539, 1528, 1519, 1470, - 1395, 1321, 1257, 1221, 1211, 1204, 1206, 1241, - 1307, 1386, 1481, 1564, 1612, 1640, 1645, 1639, - 1637, 1644, 1652, 1669, 1688, 1710, 1743, 1777, - 1792, 1785, 1773, 1763, 1752, 1748, 1750, 1751, - 1761, 1784, 1804, 1820, 1848, 1890, 1937, 1973, - 1999, 2027, 2053, 2064, 2054, 2025, 1990, 1950, - 1912, 1883, 1867, 1856, 1844, 1858, 1887, 1904, - 1929, 1966, 1997, 2011, 2021, 2044, 2090, 2135, - 2170, 2194, 2221, 2265, 2308, 2339, 2360, 2365, - 2374, 2383, 2393, 2411, 2432, 2433, 2417, 2442, - 2509, 2565, 2589, 2630, 2706, 2777, 2825, 2879, - 2951, 3017, 3067, 3106, 3145, 3206, 3269, 3305, - 3331, 3370, 3399, 3399, 3409, 3429, 3426, 3423, - 3438, 3448, 3428, 3388, 3318, 3224, 3143, 3055, - 2938, 2822, 2753, 2717, 2689, 2666, 2655, 2661, - 2657, 2613, 2524, 2431, 2341, 2221, 2102, 2012, - 1921, 1819, 1714, 1615, 1549, 1530, 1516, 1486, - 1483, 1518, 1560, 1594, 1627, 1650, 1647, 1627, - 1606, 1601, 1617, 1644, 1689, 1759, 1844, 1919, - 1969, 1991, 1983, 1960, 1934, 1899, 1879, 1887, - 1909, 1937, 1996, 2073, 2145, 2204, 2262, 2319, - 2371, 2416, 2452, 2479, 2500, 2503, 2474, 2425, - 2365, 2308, 2251, 2209, 2191, 2197, 2208, 2216, - 2229, 2240, 2232, 2203, 2160, 2115, 2081, 2062, - 2057, 2063, 2082, 2102, 2109, 2102, 2086, 2055, - 2006, 1946, 1855, 1713, 1552, 1432, 1352, 1247, - 1135, 1105, 1156, 1213, 1273, 1373, 1474, 1529, - 1555, 1553, 1526, 1488, 1435, 1396, 1396, 1421, - 1447, 1484, 1523, 1547, 1561, 1565, 1553, 1534, - 1524, 1516, 1511, 1525, 1554, 1587, 1630, 1687, - 1742, 1811, 1896, 1976, 2036, 2089, 2132, 2128, - 2082, 2033, 1984, 1932, 1874, 1837, 1834, 1856, - 1881, 1912, 1958, 2005, 2033, 2043, 2056, 2062, - 2060, 2052, 2051, 2059, 2071, 2088, 2103, 2109, - 2114, 2124, 2127, 2114, 2101, 2088, 2075, 2049, - 2015, 1989, 1971, 1978, 2007, 2040, 2083, 2137, - 2211, 2308, 2398, 2456, 2487, 2520, 2553, 2590, - 2637, 2610, 2541, 2576, 2666, 2721, 2798, 2921, - 3018, 3073, 3113, 3155, 3193, 3195, 3196, 3234, - 3295, 3344, 3386, 3442, 3477, 3483, 3516, 3567, - 3562, 3505, 3425, 3332, 3226, 3113, 3003, 2915, - 2846, 2762, 2686, 2652, 2632, 2626, 2646, 2648, - 2600, 2514, 2408, 2265, 2114, 1969, 1837, 1697, - 1544, 1430, 1392, 1388, 1372, 1366, 1399, 1443, - 1472, 1489, 1481, 1450, 1434, 1427, 1410, 1403, - 1418, 1449, 1494, 1555, 1620, 1690, 1760, 1808, - 1831, 1839, 1830, 1823, 1830, 1841, 1857, 1901, - 1974, 2050, 2131, 2226, 2331, 2429, 2521, 2589, - 2625, 2644, 2641, 2605, 2553, 2498, 2446, 2401, - 2368, 2349, 2345, 2357, 2375, 2392, 2406, 2406, - 2386, 2341, 2282, 2228, 2182, 2144, 2109, 2078, - 2060, 2044, 2018, 1989, 1961, 1934, 1897, 1845, - 1788, 1732, 1671, 1601, 1516, 1439, 1390, 1356, - 1315, 1272, 1251, 1253, 1265, 1276, 1291, 1306, - 1319, 1320, 1325, 1343, 1362, 1369, 1373, 1381, - 1393, 1409, 1439, 1474, 1514, 1554, 1591, 1634, - 1669, 1688, 1684, 1682, 1694, 1712, 1736, 1770, - 1812, 1866, 1925, 1980, 2018, 2044, 2056, 2048, - 2034, 2023, 2012, 1992, 1969, 1961, 1960, 1964, - 1961, 1956, 1950, 1952, 1952, 1947, 1946, 1939, - 1924, 1908, 1891, 1874, 1865, 1863, 1854, 1854, - 1864, 1870, 1863, 1855, 1852, 1846, 1824, 1794, - 1780, 1781, 1785, 1791, 1802, 1816, 1839, 1868, - 1903, 1943, 1974, 1996, 2020, 2039, 2066, 2101, - 2126, 2145, 2173, 2219, 2276, 2326, 2383, 2457, - 2529, 2596, 2678, 2775, 2858, 2928, 3002, 3073, - 3156, 3217, 3222, 3232, 3276, 3292, 3278, 3276, - 3286, 3298, 3326, 3372, 3409, 3426, 3448, 3477, - 3507, 3517, 3507, 3499, 3475, 3430, 3384, 3331, - 3252, 3169, 3102, 3032, 2937, 2838, 2773, 2714, - 2632, 2546, 2452, 2363, 2276, 2179, 2062, 1935, - 1831, 1751, 1652, 1538, 1472, 1461, 1462, 1453, - 1460, 1505, 1543, 1560, 1562, 1537, 1486, 1430, - 1380, 1344, 1329, 1335, 1370, 1432, 1511, 1599, - 1677, 1734, 1790, 1847, 1884, 1926, 1987, 2058, - 2126, 2195, 2258, 2320, 2373, 2411, 2448, 2487, - 2526, 2572, 2614, 2641, 2658, 2661, 2637, 2591, - 2545, 2506, 2478, 2464, 2477, 2514, 2556, 2588, - 2604, 2602, 2572, 2518, 2446, 2365, 2292, 2233, - 2181, 2132, 2089, 2049, 2002, 1947, 1891, 1842, - 1802, 1771, 1752, 1737, 1724, 1714, 1703, 1677, - 1641, 1606, 1585, 1577, 1578, 1594, 1610, 1607, - 1584, 1557, 1530, 1489, 1431, 1367, 1306, 1285, - 1323, 1372, 1373, 1384, 1451, 1526, 1581, 1625, - 1663, 1702, 1742, 1767, 1791, 1811, 1811, 1794, - 1771, 1771, 1786, 1799, 1812, 1831, 1854, 1872, - 1884, 1894, 1914, 1926, 1917, 1921, 1956, 1998, - 2021, 2032, 2043, 2061, 2074, 2051, 2014, 1986, - 1959, 1926, 1888, 1848, 1817, 1794, 1764, 1740, - 1734, 1741, 1755, 1765, 1781, 1802, 1810, 1809, - 1808, 1798, 1776, 1754, 1729, 1708, 1694, 1692, - 1680, 1667, 1657, 1655, 1647, 1641, 1651, 1658, - 1673, 1705, 1741, 1766, 1792, 1835, 1890, 1935, - 1957, 1977, 2017, 2055, 2080, 2109, 2140, 2164, - 2188, 2224, 2263, 2305, 2344, 2396, 2466, 2534, - 2617, 2713, 2807, 2896, 2988, 3086, 3178, 3240, - 3270, 3278, 3263, 3229, 3190, 3154, 3122, 3091, - 3079, 3114, 3189, 3260, 3320, 3390, 3475, 3555, - 3606, 3610, 3599, 3605, 3578, 3521, 3455, 3383, - 3306, 3208, 3112, 3042, 2970, 2890, 2812, 2744, - 2699, 2661, 2598, 2528, 2484, 2433, 2374, 2329, - 2285, 2244, 2187, 2104, 2015, 1908, 1774, 1629, - 1506, 1424, 1369, 1336, 1349, 1409, 1490, 1561, - 1624, 1652, 1664, 1676, 1661, 1644, 1666, 1708, - 1753, 1807, 1861, 1918, 1961, 1974, 1972, 1982, - 2004, 2041, 2097, 2170, 2258, 2338, 2399, 2453, - 2491, 2511, 2525, 2541, 2584, 2645, 2696, 2737, - 2767, 2767, 2730, 2658, 2561, 2472, 2398, 2340, - 2309, 2314, 2344, 2376, 2398, 2402, 2387, 2353, - 2298, 2240, 2195, 2154, 2115, 2075, 2035, 1984, - 1919, 1833, 1744, 1672, 1617, 1581, 1569, 1581, - 1606, 1630, 1642, 1640, 1628, 1607, 1581, 1567, - 1578, 1602, 1643, 1691, 1733, 1760, 1766, 1759, - 1733, 1704, 1681, 1673, 1688, 1724, 1778, 1837, - 1898, 1950, 1994, 2018, 2006, 1947, 1860, 1802, - 1808, 1852, 1877, 1871, 1876, 1905, 1928, 1927, - 1913, 1887, 1844, 1813, 1817, 1858, 1912, 1934, - 1926, 1913, 1900, 1874, 1832, 1788, 1751, 1724, - 1708, 1705, 1715, 1720, 1702, 1674, 1656, 1661, - 1676, 1684, 1686, 1701, 1723, 1732, 1718, 1693, - 1667, 1641, 1611, 1590, 1586, 1595, 1614, 1630, - 1644, 1658, 1660, 1638, 1616, 1619, 1628, 1629, - 1638, 1662, 1703, 1733, 1745, 1760, 1780, 1787, - 1779, 1769, 1774, 1787, 1798, 1794, 1791, 1788, - 1786, 1790, 1795, 1810, 1831, 1853, 1884, 1930, - 1974, 2000, 2014, 2016, 2009, 1999, 1991, 1991, - 1995, 2005, 2030, 2059, 2084, 2107, 2125, 2147, - 2175, 2207, 2246, 2290, 2337, 2392, 2451, 2507, - 2555, 2598, 2638, 2667, 2690, 2719, 2744, 2751, - 2748, 2745, 2745, 2760, 2783, 2827, 2871, 2902, - 2943, 3006, 3067, 3102, 3129, 3176, 3221, 3233, - 3258, 3285, 3304, 3307, 3285, 3257, 3210, 3162, - 3135, 3116, 3096, 3072, 3061, 3066, 3069, 3044, - 3013, 2994, 2960, 2933, 2904, 2868, 2849, 2832, - 2808, 2778, 2711, 2622, 2529, 2419, 2281, 2128, - 1981, 1840, 1737, 1683, 1663, 1682, 1732, 1810, - 1909, 2005, 2075, 2105, 2088, 2029, 1944, 1831, - 1726, 1639, 1568, 1521, 1501, 1511, 1545, 1591, - 1631, 1669, 1715, 1770, 1836, 1901, 1958, 2015, - 2062, 2089, 2103, 2105, 2089, 2074, 2069, 2074, - 2094, 2116, 2134, 2150, 2150, 2128, 2089, 2045, - 2016, 2010, 2029, 2077, 2155, 2245, 2333, 2399, - 2435, 2435, 2393, 2327, 2242, 2154, 2072, 1999, - 1945, 1904, 1870, 1845, 1828, 1820, 1829, 1846, - 1880, 1921, 1966, 2007, 2030, 2033, 2009, 1959, - 1893, 1818, 1749, 1706, 1681, 1674, 1689, 1707, - 1726, 1736, 1732, 1724, 1711, 1701, 1702, 1719, - 1750, 1792, 1844, 1893, 1928, 1950, 1957, 1952, - 1938, 1923, 1907, 1889, 1877, 1865, 1862, 1864, - 1867, 1866, 1850, 1822, 1803, 1810, 1830, 1855, - 1887, 1930, 1989, 2050, 2084, 2070, 2027, 1966, - 1895, 1822, 1755, 1707, 1691, 1694, 1722, 1770, - 1814, 1842, 1859, 1856, 1841, 1830, 1820, 1814, - 1803, 1791, 1782, 1769, 1750, 1730, 1705, 1676, - 1653, 1648, 1652, 1649, 1649, 1652, 1651, 1647, - 1635, 1625, 1628, 1632, 1641, 1667, 1695, 1713, - 1724, 1715, 1695, 1674, 1649, 1621, 1594, 1576, - 1580, 1597, 1617, 1645, 1685, 1719, 1738, 1755, - 1776, 1797, 1812, 1810, 1801, 1798, 1806, 1810, - 1805, 1790, 1780, 1790, 1806, 1817, 1832, 1843, - 1868, 1901, 1919, 1932, 1942, 1950, 1961, 1968, - 1973, 1983, 1991, 1993, 1994, 1993, 1983, 1976, - 1976, 1979, 1987, 2000, 2010, 2033, 2072, 2108, - 2148, 2196, 2244, 2299, 2353, 2397, 2440, 2468, - 2478, 2473, 2451, 2426, 2426, 2449, 2477, 2503, - 2537, 2609, 2715, 2815, 2883, 2932, 2965, 2970, - 2953, 2930, 2929, 2967, 3017, 3056, 3089, 3121, - 3185, 3277, 3343, 3378, 3378, 3376, 3385, 3349, - 3291, 3264, 3246, 3209, 3174, 3163, 3193, 3258, - 3315, 3361, 3385, 3377, 3372, 3372, 3338, 3251, - 3163, 3068, 2932, 2807, 2675, 2534, 2433, 2362, - 2322, 2314, 2331, 2364, 2376, 2350, 2292, 2214, - 2120, 2012, 1907, 1840, 1802, 1771, 1764, 1746, - 1706, 1661, 1587, 1504, 1444, 1419, 1420, 1455, - 1516, 1579, 1640, 1699, 1727, 1725, 1703, 1664, - 1628, 1624, 1655, 1699, 1741, 1783, 1822, 1836, - 1818, 1792, 1780, 1799, 1857, 1940, 2039, 2144, - 2251, 2331, 2360, 2349, 2315, 2264, 2199, 2150, - 2137, 2145, 2177, 2222, 2254, 2275, 2288, 2285, - 2271, 2257, 2249, 2257, 2272, 2281, 2286, 2269, - 2227, 2166, 2100, 2037, 1978, 1938, 1924, 1930, - 1954, 1988, 2010, 2017, 2007, 1985, 1947, 1910, - 1885, 1872, 1877, 1884, 1894, 1899, 1897, 1885, - 1866, 1840, 1814, 1807, 1810, 1823, 1842, 1870, - 1901, 1926, 1941, 1952, 1960, 1968, 1977, 1987, - 2003, 2022, 2040, 2058, 2069, 2068, 2065, 2062, - 2061, 2068, 2082, 2107, 2141, 2176, 2213, 2243, - 2261, 2262, 2234, 2179, 2126, 2097, 2086, 2073, - 2058, 2058, 2082, 2107, 2107, 2088, 2059, 2022, - 1981, 1951, 1924, 1896, 1875, 1861, 1863, 1873, - 1875, 1868, 1861, 1852, 1834, 1817, 1803, 1788, - 1766, 1729, 1687, 1655, 1637, 1615, 1587, 1579, - 1605, 1641, 1678, 1710, 1739, 1767, 1773, 1767, - 1752, 1738, 1706, 1677, 1654, 1649, 1664, 1682, - 1694, 1707, 1738, 1773, 1797, 1815, 1836, 1858, - 1880, 1882, 1877, 1879, 1877, 1869, 1852, 1843, - 1840, 1840, 1844, 1852, 1862, 1872, 1883, 1890, - 1894, 1892, 1896, 1906, 1916, 1923, 1931, 1937, - 1941, 1948, 1950, 1941, 1932, 1931, 1928, 1921, - 1916, 1910, 1905, 1913, 1931, 1961, 1990, 2008, - 2024, 2042, 2056, 2063, 2043, 2011, 1982, 1956, - 1936, 1927, 1932, 1950, 1979, 2012, 2046, 2082, - 2113, 2128, 2137, 2142, 2148, 2161, 2180, 2196, - 2213, 2248, 2299, 2350, 2405, 2460, 2499, 2530, - 2546, 2550, 2556, 2556, 2547, 2548, 2577, 2640, - 2720, 2786, 2846, 2921, 3004, 3063, 3069, 3056, - 3055, 3065, 3067, 3060, 3049, 3054, 3077, 3103, - 3126, 3137, 3145, 3161, 3187, 3206, 3211, 3231, - 3246, 3242, 3228, 3203, 3182, 3176, 3157, 3118, - 3075, 3031, 3006, 2990, 2952, 2903, 2849, 2812, - 2790, 2763, 2745, 2712, 2653, 2579, 2502, 2404, - 2267, 2098, 1929, 1827, 1771, 1732, 1734, 1804, - 1919, 2028, 2098, 2107, 2069, 1992, 1851, 1667, - 1499, 1371, 1291, 1254, 1250, 1289, 1363, 1435, - 1495, 1544, 1583, 1627, 1676, 1733, 1789, 1827, - 1845, 1849, 1833, 1798, 1746, 1692, 1667, 1686, - 1750, 1843, 1955, 2066, 2162, 2232, 2266, 2261, - 2230, 2198, 2180, 2188, 2219, 2271, 2335, 2398, - 2437, 2442, 2422, 2386, 2341, 2290, 2242, 2209, - 2207, 2215, 2226, 2232, 2230, 2232, 2228, 2219, - 2214, 2219, 2226, 2229, 2216, 2188, 2141, 2071, - 1991, 1905, 1834, 1782, 1761, 1775, 1819, 1878, - 1938, 1990, 2025, 2038, 2028, 2001, 1958, 1917, - 1876, 1841, 1811, 1792, 1783, 1781, 1782, 1793, - 1813, 1841, 1874, 1912, 1946, 1977, 1996, 2002, - 2000, 1987, 1971, 1955, 1947, 1952, 1966, 1985, - 2007, 2032, 2052, 2065, 2076, 2081, 2080, 2083, - 2090, 2103, 2120, 2139, 2159, 2181, 2201, 2211, - 2215, 2214, 2204, 2192, 2175, 2156, 2135, 2117, - 2102, 2086, 2077, 2075, 2081, 2084, 2078, 2081, - 2093, 2099, 2076, 2020, 1937, 1824, 1714, 1648, - 1607, 1576, 1560, 1579, 1647, 1740, 1800, 1814, - 1801, 1770, 1725, 1675, 1627, 1576, 1531, 1481, - 1439, 1424, 1430, 1437, 1449, 1470, 1511, 1561, - 1622, 1687, 1744, 1780, 1781, 1758, 1726, 1704, - 1679, 1638, 1611, 1619, 1643, 1675, 1713, 1751, - 1786, 1810, 1824, 1833, 1846, 1858, 1865, 1864, - 1862, 1858, 1856, 1856, 1859, 1858, 1851, 1842, - 1840, 1843, 1843, 1842, 1842, 1845, 1838, 1830, - 1827, 1836, 1849, 1863, 1877, 1888, 1902, 1916, - 1915, 1893, 1865, 1837, 1810, 1797, 1799, 1806, - 1817, 1834, 1864, 1897, 1929, 1960, 1981, 2007, - 2031, 2035, 2034, 2028, 2019, 2006, 1982, 1964, - 1965, 1983, 2006, 2033, 2067, 2104, 2144, 2179, - 2199, 2203, 2195, 2192, 2185, 2176, 2171, 2173, - 2194, 2222, 2244, 2259, 2284, 2315, 2342, 2376, - 2405, 2415, 2426, 2436, 2443, 2460, 2474, 2481, - 2488, 2505, 2544, 2598, 2652, 2706, 2760, 2798, - 2814, 2836, 2865, 2865, 2833, 2807, 2795, 2803, - 2827, 2847, 2877, 2928, 2958, 2979, 3006, 3042, - 3081, 3090, 3065, 3050, 3061, 3071, 3063, 3036, - 3006, 2987, 2962, 2932, 2920, 2919, 2895, 2866, - 2855, 2855, 2853, 2828, 2756, 2623, 2409, 2184, - 2063, 1996, 1882, 1807, 1871, 2060, 2301, 2485, - 2555, 2552, 2477, 2278, 1995, 1698, 1429, 1241, - 1139, 1114, 1204, 1368, 1522, 1640, 1719, 1756, - 1761, 1742, 1745, 1784, 1820, 1830, 1820, 1789, - 1722, 1606, 1446, 1308, 1235, 1253, 1354, 1533, - 1763, 1996, 2199, 2322, 2338, 2264, 2138, 2010, - 1902, 1827, 1805, 1859, 1970, 2091, 2185, 2220, - 2213, 2189, 2150, 2102, 2083, 2113, 2184, 2253, - 2304, 2335, 2342, 2316, 2258, 2188, 2128, 2099, - 2117, 2163, 2209, 2240, 2237, 2199, 2137, 2062, - 1982, 1911, 1879, 1900, 1971, 2061, 2149, 2224, - 2266, 2259, 2213, 2139, 2046, 1958, 1890, 1844, - 1823, 1821, 1826, 1839, 1859, 1879, 1897, 1923, - 1966, 2014, 2061, 2091, 2106, 2103, 2069, 2004, - 1927, 1856, 1808, 1787, 1785, 1809, 1867, 1943, - 2022, 2090, 2145, 2185, 2208, 2215, 2211, 2201, - 2186, 2172, 2156, 2140, 2126, 2120, 2121, 2132, - 2154, 2184, 2218, 2253, 2282, 2309, 2320, 2319, - 2308, 2289, 2271, 2258, 2243, 2230, 2231, 2233, - 2225, 2217, 2211, 2196, 2178, 2162, 2141, 2114, - 2090, 2078, 2077, 2063, 2049, 2059, 2070, 2077, - 2073, 2050, 2013, 1985, 1942, 1879, 1823, 1787, - 1762, 1756, 1764, 1774, 1792, 1795, 1793, 1805, - 1809, 1801, 1789, 1770, 1752, 1739, 1712, 1678, - 1656, 1643, 1633, 1629, 1646, 1681, 1722, 1753, - 1776, 1804, 1824, 1830, 1822, 1805, 1784, 1763, - 1740, 1727, 1731, 1745, 1762, 1776, 1805, 1843, - 1870, 1883, 1901, 1915, 1917, 1915, 1908, 1901, - 1899, 1893, 1873, 1862, 1859, 1864, 1870, 1877, - 1892, 1910, 1927, 1939, 1945, 1944, 1940, 1938, - 1932, 1922, 1911, 1904, 1908, 1915, 1919, 1923, - 1931, 1939, 1944, 1947, 1953, 1964, 1973, 1977, - 1986, 2006, 2027, 2033, 2031, 2040, 2061, 2078, - 2085, 2087, 2099, 2114, 2124, 2130, 2140, 2153, - 2165, 2178, 2196, 2223, 2250, 2268, 2279, 2292, - 2310, 2333, 2344, 2344, 2344, 2346, 2347, 2352, - 2350, 2345, 2346, 2361, 2383, 2408, 2426, 2436, - 2455, 2474, 2476, 2473, 2484, 2485, 2479, 2479, - 2477, 2470, 2467, 2461, 2456, 2464, 2470, 2482, - 2504, 2522, 2537, 2556, 2561, 2556, 2547, 2534, - 2522, 2509, 2485, 2473, 2487, 2502, 2512, 2513, - 2527, 2553, 2558, 2535, 2528, 2544, 2556, 2542, - 2518, 2513, 2521, 2527, 2520, 2500, 2497, 2511, - 2517, 2501, 2467, 2427, 2396, 2367, 2310, 2253, - 2226, 2226, 2250, 2280, 2302, 2331, 2358, 2366, - 2357, 2320, 2263, 2197, 2131, 2069, 2016, 1979, - 1949, 1933, 1934, 1943, 1951, 1964, 1982, 2007, - 2036, 2056, 2066, 2068, 2057, 2030, 1980, 1911, - 1844, 1795, 1766, 1751, 1754, 1781, 1832, 1887, - 1936, 1974, 2007, 2027, 2032, 2025, 2006, 1989, - 1976, 1963, 1948, 1934, 1918, 1915, 1914, 1919, - 1931, 1953, 1990, 2033, 2069, 2096, 2117, 2127, - 2125, 2111, 2084, 2056, 2040, 2029, 2023, 2025, - 2032, 2038, 2046, 2057, 2067, 2073, 2077, 2083, - 2095, 2107, 2113, 2121, 2123, 2122, 2121, 2117, - 2109, 2102, 2101, 2100, 2102, 2104, 2103, 2104, - 2104, 2101, 2096, 2093, 2091, 2093, 2100, 2108, - 2121, 2134, 2141, 2137, 2130, 2118, 2103, 2085, - 2068, 2055, 2047, 2042, 2046, 2052, 2059, 2069, - 2080, 2094, 2103, 2113, 2120, 2120, 2119, 2110, - 2098, 2084, 2072, 2058, 2047, 2040, 2039, 2044, - 2064, 2075, 2086, 2092, 2089, 2095, 2104, 2112, - 2113, 2104, 2082, 2056, 2033, 2026, 2027, 2025, - 2025, 2023, 2018, 2018, 2010, 1989, 1975, 1966, - 1946, 1919, 1910, 1920, 1932, 1939, 1939, 1939, - 1943, 1925, 1878, 1815, 1771, 1740, 1694, 1656, - 1659, 1689, 1722, 1751, 1766, 1779, 1792, 1791, - 1778, 1756, 1730, 1697, 1667, 1642, 1629, 1615, - 1589, 1580, 1583, 1593, 1621, 1656, 1696, 1743, - 1775, 1796, 1810, 1810, 1797, 1762, 1719, 1681, - 1649, 1632, 1627, 1640, 1670, 1702, 1741, 1785, - 1821, 1848, 1865, 1875, 1882, 1877, 1856, 1835, - 1815, 1796, 1775, 1749, 1738, 1742, 1756, 1774, - 1799, 1834, 1869, 1896, 1916, 1931, 1929, 1918, - 1905, 1888, 1869, 1852, 1842, 1849, 1860, 1872, - 1889, 1910, 1933, 1954, 1974, 1990, 2007, 2021, - 2029, 2028, 2034, 2041, 2042, 2045, 2058, 2072, - 2082, 2092, 2113, 2137, 2156, 2171, 2183, 2201, - 2225, 2242, 2248, 2260, 2279, 2300, 2322, 2337, - 2350, 2369, 2385, 2396, 2395, 2397, 2412, 2430, - 2446, 2459, 2471, 2493, 2516, 2539, 2555, 2570, - 2589, 2606, 2626, 2650, 2658, 2659, 2672, 2697, - 2709, 2714, 2721, 2737, 2762, 2772, 2768, 2775, - 2799, 2820, 2818, 2803, 2790, 2789, 2780, 2753, - 2717, 2681, 2647, 2577, 2477, 2416, 2401, 2371, - 2325, 2324, 2389, 2484, 2552, 2565, 2540, 2494, - 2418, 2288, 2121, 1974, 1863, 1782, 1728, 1721, - 1757, 1808, 1862, 1900, 1913, 1916, 1922, 1923, - 1922, 1918, 1907, 1895, 1866, 1812, 1734, 1642, - 1550, 1471, 1429, 1439, 1501, 1606, 1729, 1852, - 1956, 2028, 2050, 2026, 1979, 1920, 1854, 1789, - 1754, 1754, 1777, 1803, 1819, 1830, 1846, 1863, - 1880, 1905, 1951, 2014, 2077, 2127, 2174, 2199, - 2191, 2146, 2082, 2012, 1948, 1913, 1908, 1928, - 1967, 2013, 2062, 2107, 2139, 2153, 2149, 2143, - 2144, 2152, 2162, 2179, 2203, 2220, 2218, 2197, - 2166, 2128, 2089, 2058, 2039, 2040, 2058, 2085, - 2114, 2144, 2169, 2176, 2163, 2141, 2124, 2113, - 2099, 2085, 2077, 2071, 2061, 2044, 2021, 1995, - 1970, 1945, 1927, 1926, 1942, 1970, 2004, 2038, - 2065, 2087, 2093, 2090, 2081, 2063, 2039, 2018, - 2001, 1994, 1993, 1996, 2001, 2009, 2017, 2026, - 2039, 2057, 2080, 2107, 2130, 2151, 2170, 2180, - 2182, 2172, 2152, 2128, 2104, 2084, 2072, 2073, - 2079, 2094, 2116, 2139, 2159, 2174, 2187, 2194, - 2195, 2190, 2186, 2185, 2182, 2172, 2161, 2153, - 2139, 2125, 2116, 2109, 2103, 2101, 2104, 2118, - 2141, 2162, 2177, 2188, 2189, 2185, 2173, 2158, - 2145, 2129, 2114, 2099, 2091, 2085, 2077, 2070, - 2065, 2058, 2056, 2052, 2051, 2062, 2071, 2077, - 2080, 2079, 2072, 2059, 2042, 2019, 1997, 1981, - 1970, 1959, 1958, 1961, 1970, 1976, 1976, 1977, - 1979, 1976, 1974, 1969, 1960, 1954, 1952, 1951, - 1949, 1948, 1941, 1937, 1933, 1927, 1923, 1923, - 1927, 1930, 1931, 1932, 1920, 1892, 1884, 1894, - 1895, 1884, 1871, 1875, 1890, 1907, 1909, 1885, - 1865, 1864, 1874, 1884, 1883, 1878, 1870, 1865, - 1858, 1846, 1829, 1823, 1829, 1832, 1834, 1849, - 1874, 1902, 1917, 1920, 1920, 1929, 1941, 1948, - 1947, 1938, 1939, 1946, 1950, 1954, 1960, 1971, - 1979, 1989, 1998, 2011, 2026, 2046, 2066, 2079, - 2083, 2080, 2083, 2086, 2086, 2076, 2060, 2049, - 2052, 2060, 2067, 2076, 2081, 2089, 2101, 2114, - 2124, 2128, 2128, 2129, 2126, 2125, 2127, 2126, - 2121, 2117, 2109, 2098, 2093, 2096, 2109, 2119, - 2123, 2130, 2141, 2159, 2170, 2172, 2169, 2168, - 2175, 2172, 2163, 2165, 2168, 2170, 2170, 2169, - 2169, 2177, 2185, 2189, 2182, 2186, 2193, 2199, - 2206, 2218, 2224, 2217, 2215, 2212, 2209, 2205, - 2202, 2198, 2193, 2193, 2200, 2207, 2208, 2205, - 2208, 2208, 2205, 2207, 2209, 2208, 2208, 2212, - 2215, 2224, 2234, 2239, 2242, 2240, 2240, 2243, - 2239, 2233, 2238, 2245, 2241, 2242, 2243, 2243, - 2244, 2242, 2241, 2242, 2247, 2253, 2257, 2260, - 2268, 2274, 2271, 2262, 2258, 2256, 2252, 2244, - 2231, 2226, 2225, 2224, 2222, 2218, 2214, 2211, - 2208, 2209, 2212, 2213, 2215, 2218, 2220, 2220, - 2216, 2208, 2199, 2191, 2178, 2165, 2151, 2144, - 2140, 2137, 2131, 2127, 2128, 2127, 2123, 2118, - 2111, 2108, 2101, 2093, 2086, 2080, 2071, 2063, - 2052, 2039, 2028, 2016, 2007, 1998, 1990, 1987, - 1985, 1987, 1990, 1992, 1995, 1995, 1992, 1986, - 1979, 1973, 1966, 1955, 1945, 1938, 1929, 1926, - 1922, 1919, 1918, 1923, 1925, 1929, 1936, 1942, - 1944, 1946, 1947, 1945, 1942, 1937, 1934, 1930, - 1925, 1923, 1924, 1928, 1932, 1938, 1944, 1950, - 1959, 1969, 1974, 1979, 1984, 1985, 1983, 1983, - 1983, 1981, 1980, 1975, 1975, 1972, 1976, 1981, - 1983, 1986, 1987, 1989, 1990, 1990, 1992, 1993, - 1992, 1996, 1998, 1998, 1995, 1994, 1993, 1991, - 1988, 1982, 1977, 1973, 1970, 1968, 1965, 1963, - 1966, 1968, 1969, 1971, 1974, 1979, 1984, 1985, - 1987, 1988, 1985, 1979, 1973, 1965, 1957, 1954, - 1950, 1947, 1948, 1948, 1952, 1959, 1966, 1974, - 1980, 1986, 1990, 1992, 1993, 1994, 1992, 1987, - 1979, 1975, 1976, 1977, 1973, 1973, 1977, 1986, - 1995, 2004, 2008, 2018, 2026, 2025, 2026, 2024, - 2021, 2019, 2013, 2009, 2006, 2005, 2007, 2007, - 2011, 2018, 2028, 2038, 2047, 2056, 2063, 2074, - 2083, 2087, 2087, 2089, 2090, 2087, 2086, 2085, - 2090, 2094, 2094, 2105, 2118, 2127, 2131, 2136, - 2145, 2153, 2156, 2155, 2150, 2152, 2156, 2158, - 2155, 2154, 2158, 2165, 2167, 2165, 2166, 2170, - 2177, 2184, 2185, 2190, 2195, 2199, 2202, 2200, - 2198, 2197, 2199, 2199, 2196, 2193, 2197, 2202, - 2203, 2203, 2206, 2208, 2208, 2209, 2210, 2210, - 2210, 2212, 2213, 2214, 2214, 2215, 2215, 2214, - 2216, 2217, 2212, 2208, 2212, 2214, 2213, 2215, - 2216, 2222, 2226, 2226, 2229, 2225, 2221, 2224, - 2222, 2215, 2208, 2203, 2196, 2192, 2184, 2175, - 2170, 2165, 2163, 2159, 2154, 2150, 2146, 2142, - 2138, 2137, 2133, 2130, 2126, 2124, 2121, 2113, - 2104, 2094, 2087, 2081, 2075, 2064, 2058, 2054, - 2052, 2049, 2045, 2044, 2042, 2039, 2038, 2032, - 2028, 2025, 2022, 2020, 2015, 2008, 1999, 1993, - 1988, 1982, 1974, 1970, 1972, 1972, 1975, 1977, - 1977, 1980, 1980, 1976, 1973, 1973, 1970, 1966, - 1962, 1961, 1957, 1955, 1954, 1955, 1956, 1956, - 1958, 1961, 1969, 1975, 1978, 1981, 1983, 1984, - 1988, 1985, 1982, 1981, 1980, 1980, 1982, 1985, - 1990, 1997, 2003, 2010, 2015, 2021, 2027, 2030, - 2033, 2035, 2036, 2039, 2042, 2044, 2045, 2049, - 2050, 2050, 2052, 2055, 2056, 2058, 2061, 2066, - 2070, 2069, 2073, 2074, 2076, 2079, 2081, 2079, - 2077, 2076, 2074, 2075, 2074, 2072, 2070, 2070, - 2070, 2069, 2066, 2064, 2062, 2063, 2060, 2059, - 2060, 2061, 2061, 2057, 2055, 2053, 2049, 2043, - 2036, 2027, 2021, 2012, 2010, 1999, 1994, 1992, - 1987, 1980, 1972, 1973, 1972, 1968, 1965, 1965, - 1966, 1967, 1963, 1958, 1954, 1947, 1945, 1940, - 1935, 1933, 1930, 1929, 1931, 1933, 1933, 1933, - 1933, 1934, 1935, 1936, 1934, 1932, 1934, 1934, - 1933, 1935, 1933, 1932, 1934, 1933, 1930, 1928, - 1931, 1930, 1931, 1932, 1931, 1934, 1932, 1932, - 1932, 1934, 1937, 1936, 1937, 1940, 1943, 1942, - 1946, 1945, 1944, 1944, 1942, 1944, 1946, 1948, - 1947, 1949, 1953, 1956, 1958, 1961, 1964, 1968, - 1970, 1971, 1975, 1976, 1979, 1981, 1982, 1985, - 1988, 1990, 1992, 1997, 2002, 2009, 2013, 2018, - 2027, 2033, 2039, 2042, 2049, 2054, 2061, 2062, - 2062, 2066, 2069, 2076, 2080, 2084, 2089, 2094, - 2099, 2105, 2110, 2114, 2120, 2125, 2130, 2137, - 2141, 2146, 2152, 2159, 2164, 2168, 2172, 2177, - 2182, 2186, 2187, 2192, 2197, 2201, 2205, 2210, - 2218, 2220, 2224, 2228, 2232, 2238, 2243, 2246, - 2249, 2252, 2250, 2248, 2248, 2246, 2249, 2250, - 2252, 2252, 2252, 2258, 2262, 2264, 2268, 2271, - 2272, 2274, 2271, 2269, 2268, 2268, 2264, 2262, - 2261, 2261, 2255, 2251, 2249, 2248, 2248, 2243, - 2241, 2244, 2246, 2249, 2248, 2247, 2246, 2246, - 2245, 2240, 2238, 2237, 2241, 2240, 2240, 2239, - 2240, 2240, 2238, 2236, 2234, 2233, 2230, 2226, - 2222, 2222, 2219, 2215, 2213, 2209, 2204, 2201, - 2193, 2185, 2182, 2175, 2169, 2164, 2161, 2154, - 2150, 2143, 2134, 2132, 2127, 2122, 2114, 2109, - 2104, 2097, 2092, 2085, 2077, 2068, 2060, 2054, - 2049, 2045, 2039, 2035, 2033, 2033, 2031, 2029, - 2027, 2023, 2023, 2018, 2015, 2013, 2010, 2008, - 2008, 2005, 2001, 2002, 1997, 1996, 1993, 1991, - 1991, 1995, 1996, 1996, 1997, 1998, 1999, 1999, - 1995, 1994, 1998, 1996, 1996, 1997, 1999, 2001, - 2002, 2006, 2009, 2011, 2012, 2015, 2017, 2020, - 2023, 2031, 2035, 2039, 2041, 2042, 2047, 2049, - 2048, 2049, 2052, 2056, 2058, 2060, 2064, 2068, - 2071, 2073, 2071, 2073, 2077, 2079, 2077, 2078, - 2077, 2077, 2076, 2073, 2073, 2071, 2069, 2068, - 2069, 2066, 2068, 2070, 2069, 2070, 2068, 2070, - 2067, 2067, 2064, 2062, 2059, 2056, 2050, 2048, - 2047, 2044, 2041, 2040, 2038, 2038, 2036, 2036, - 2035, 2035, 2035, 2033, 2035, 2032, 2030, 2027, - 2024, 2019, 2015, 2014, 2013, 2011, 2011, 2011, - 2011, 2010, 2012, 2012, 2009, 2009, 2005, 2004, - 2002, 1997, 1995, 1991, 1990, 1989, 1985, 1983, - 1982, 1982, 1980, 1978, 1978, 1980, 1980, 1980, - 1984, 1986, 1984, 1984, 1986, 1987, 1987, 1986, - 1987, 1986, 1987, 1988, 1989, 1989, 1987, 1990, - 1992, 1996, 1998, 2002, 2007, 2011, 2015, 2018, - 2021, 2026, 2028, 2028, 2028, 2026, 2026, 2025, - 2024, 2024, 2024, 2025, 2027, 2033, 2033, 2034, - 2038, 2040, 2043, 2041, 2044, 2043, 2042, 2040, - 2036, 2036, 2038, 2040, 2043, 2044, 2045, 2048, - 2049, 2055, 2058, 2059, 2061, 2064, 2064, 2064, - 2064, 2064, 2063, 2064, 2064, 2064, 2065, 2066, - 2067, 2070, 2074, 2076, 2078, 2077, 2079, 2074, - 2075, 2074, 2071, 2073, 2073, 2074, 2075, 2077, - 2079, 2079, 2080, 2080, 2079, 2083, 2087, 2091, - 2093, 2093, 2097, 2098, 2100, 2105, 2108, 2107, - 2109, 2111, 2112, 2116, 2119, 2121, 2123, 2126, - 2131, 2134, 2138, 2140, 2143, 2144, 2148, 2149, - 2151, 2152, 2152, 2154, 2152, 2155, 2156, 2157, - 2158, 2162, 2165, 2165, 2167, 2169, 2171, 2170, - 2173, 2171, 2172, 2174, 2174, 2171, 2168, 2169, - 2168, 2163, 2162, 2164, 2166, 2167, 2169, 2165, - 2167, 2166, 2165, 2165, 2165, 2162, 2160, 2160, - 2159, 2156, 2153, 2152, 2152, 2146, 2143, 2141, - 2139, 2136, 2133, 2129, 2125, 2120, 2114, 2111, - 2108, 2103, 2100, 2092, 2091, 2091, 2087, 2080, - 2076, 2076, 2073, 2068, 2065, 2061, 2056, 2053, - 2050, 2044, 2039, 2036, 2032, 2028, 2024, 2024, - 2021, 2018, 2017, 2017, 2013, 2007, 2006, 2001, - 1996, 1997, 1992, 1990, 1988, 1982, 1979, 1977, - 1973, 1970, 1967, 1965, 1963, 1961, 1960, 1958, - 1954, 1955, 1951, 1949, 1947, 1941, 1937, 1935, - 1935, 1934, 1934, 1931, 1933, 1935, 1936, 1936, - 1936, 1937, 1939, 1939, 1942, 1943, 1946, 1945, - 1944, 1945, 1946, 1948, 1949, 1950, 1952, 1949, - 1948, 1948, 1947, 1946, 1946, 1949, 1949, 1949, - 1952, 1954, 1956, 1955, 1953, 1954, 1954, 1955, - 1957, 1953, 1952, 1950, 1948, 1948, 1948, 1948, - 1947, 1949, 1949, 1947, 1946, 1948, 1951, 1950, - 1951, 1953, 1953, 1952, 1955, 1955, 1953, 1951, - 1952, 1953, 1951, 1950, 1950, 1953, 1954, 1953, - 1954, 1951, 1952, 1953, 1953, 1952, 1953, 1954, - 1956, 1955, 1954, 1955, 1953, 1953, 1953, 1951, - 1951, 1951, 1950, 1954, 1955, 1956, 1956, 1957, - 1956, 1961, 1964, 1965, 1969, 1970, 1974, 1978, - 1980, 1981, 1981, 1983, 1983, 1986, 1987, 1992, - 1997, 2000, 2002, 2006, 2011, 2016, 2020, 2027, - 2031, 2033, 2039, 2044, 2046, 2049, 2053, 2058, - 2059, 2060, 2061, 2064, 2067, 2072, 2077, 2081, - 2086, 2090, 2096, 2100, 2102, 2104, 2108, 2111, - 2115, 2115, 2116, 2118, 2120, 2119, 2119, 2119, - 2118, 2119, 2119, 2120, 2120, 2120, 2124, 2128, - 2127, 2127, 2127, 2127, 2129, 2127, 2125, 2124, - 2124, 2125, 2124, 2125, 2123, 2122, 2123, 2122, - 2121, 2122, 2125, 2128, 2129, 2132, 2134, 2133, - 2134, 2136, 2135, 2137, 2136, 2134, 2137, 2137, - 2138, 2139, 2137, 2134, 2139, 2139, 2141, 2142, - 2145, 2150, 2152, 2154, 2156, 2159, 2159, 2160, - 2160, 2159, 2160, 2160, 2159, 2160, 2163, 2166, - 2166, 2166, 2165, 2166, 2168, 2169, 2171, 2174, - 2178, 2176, 2176, 2176, 2177, 2177, 2176, 2174, - 2174, 2177, 2181, 2181, 2182, 2183, 2186, 2188, - 2189, 2191, 2190, 2191, 2188, 2186, 2186, 2185, - 2183, 2185, 2186, 2184, 2183, 2183, 2182, 2183, - 2180, 2180, 2177, 2175, 2175, 2172, 2168, 2165, - 2165, 2165, 2163, 2162, 2162, 2158, 2158, 2154, - 2150, 2146, 2143, 2138, 2139, 2134, 2130, 2124, - 2122, 2117, 2116, 2109, 2104, 2099, 2097, 2089, - 2084, 2079, 2072, 2068, 2064, 2061, 2055, 2048, - 2043, 2041, 2034, 2032, 2028, 2022, 2019, 2012, - 2008, 2005, 2001, 1996, 1991, 1989, 1988, 1985, - 1982, 1978, 1974, 1972, 1970, 1967, 1964, 1960, - 1961, 1959, 1955, 1952, 1951, 1949, 1949, 1947, - 1944, 1945, 1944, 1944, 1942, 1941, 1940, 1937, - 1934, 1931, 1932, 1931, 1931, 1932, 1932, 1930, - 1929, 1927, 1926, 1926, 1928, 1931, 1933, 1935, - 1935, 1935, 1937, 1938, 1940, 1941, 1937, 1938, - 1940, 1940, 1942, 1942, 1943, 1945, 1947, 1948, - 1950, 1954, 1953, 1955, 1957, 1959, 1961, 1965, - 1965, 1965, 1966, 1968, 1971, 1971, 1972, 1972, - 1974, 1975, 1975, 1978, 1980, 1980, 1982, 1983, - 1983, 1984, 1986, 1988, 1992, 1993, 1994, 1997, - 1996, 1994, 1994, 1998, 1999, 2002, 2004, 2007, - 2009, 2010, 2012, 2013, 2017, 2020, 2022, 2024, - 2027, 2027, 2030, 2034, 2037, 2039, 2041, 2045, - 2049, 2050, 2052, 2055, 2055, 2057, 2060, 2062, - 2067, 2072, 2075, 2077, 2078, 2082, 2085, 2089, - 2090, 2094, 2095, 2098, 2099, 2103, 2107, 2108, - 2111, 2113, 2115, 2115, 2117, 2116, 2117, 2118, - 2120, 2121, 2124, 2125, 2126, 2126, 2127, 2129, - 2129, 2129, 2129, 2131, 2129, 2129, 2129, 2128, - 2128, 2126, 2127, 2127, 2128, 2128, 2126, 2126, - 2125, 2126, 2125, 2124, 2121, 2120, 2119, 2118, - 2118, 2118, 2116, 2114, 2114, 2116, 2115, 2115, - 2111, 2110, 2110, 2110, 2107, 2108, 2108, 2106, - 2109, 2109, 2110, 2110, 2109, 2108, 2107, 2103, - 2102, 2102, 2102, 2101, 2099, 2101, 2098, 2096, - 2093, 2093, 2094, 2093, 2094, 2095, 2095, 2097, - 2094, 2090, 2091, 2088, 2084, 2083, 2083, 2082, - 2079, 2076, 2076, 2076, 2076, 2073, 2073, 2071, - 2068, 2069, 2068, 2066, 2063, 2063, 2063, 2065, - 2064, 2063, 2062, 2063, 2065, 2065, 2068, 2068, - 2066, 2068, 2066, 2062, 2064, 2067, 2063, 2063, - 2063, 2063, 2064, 2061, 2060, 2062, 2061, 2061, - 2059, 2061, 2060, 2057, 2059, 2059, 2058, 2058, - 2055, 2053, 2054, 2052, 2047, 2044, 2041, 2042, - 2040, 2041, 2041, 2042, 2039, 2039, 2040, 2042, - 2042, 2040, 2040, 2036, 2036, 2037, 2035, 2034, - 2034, 2032, 2031, 2028, 2027, 2026, 2023, 2025, - 2026, 2028, 2027, 2027, 2028, 2026, 2026, 2027, - 2025, 2022, 2019, 2016, 2011, 2010, 2008, 2008, - 2004, 2001, 1999, 1998, 1996, 1997, 1994, 1992, - 1993, 1990, 1989, 1985, 1984, 1983, 1980, 1979, - 1975, 1970, 1969, 1971, 1970, 1969, 1969, 1969, - 1970, 1971, 1973, 1975, 1974, 1974, 1974, 1975, - 1972, 1974, 1974, 1974, 1976, 1972, 1973, 1973, - 1973, 1973, 1969, 1972, 1972, 1977, 1981, 1984, - 1987, 1989, 1989, 1990, 1991, 1991, 1990, 1991, - 1989, 1987, 1985, 1988, 1987, 1986, 1987, 1988, - 1989, 1988, 1992, 1993, 1992, 1994, 1995, 1995, - 1994, 1993, 1991, 1994, 1992, 1990, 1992, 1990, - 1994, 1994, 1997, 1997, 1999, 2001, 2002, 2003, - 2003, 2003, 2005, 2003, 2000, 2000, 2001, 2003, - 2004, 2004, 2002, 2002, 2003, 2002, 2002, 2002, - 2003, 2002, 2001, 2005, 2003, 2001, 2001, 2003, - 2002, 2001, 2001, 2000, 2002, 2000, 2002, 2002, - 2002, 2003, 2002, 2005, 2004, 2004, 2008, 2007, - 2008, 2010, 2013, 2018, 2019, 2020, 2021, 2022, - 2023, 2023, 2024, 2024, 2022, 2022, 2023, 2025, - 2026, 2026, 2029, 2030, 2030, 2032, 2032, 2034, - 2032, 2033, 2031, 2033, 2035, 2036, 2037, 2037, - 2036, 2035, 2038, 2040, 2040, 2040, 2039, 2039, - 2040, 2041, 2040, 2040, 2039, 2041, 2040, 2039, - 2041, 2039, 2038, 2038, 2041, 2042, 2042, 2044, - 2042, 2042, 2040, 2042, 2044, 2043, 2043, 2045, - 2045, 2044, 2047, 2048, 2048, 2049, 2050, 2049, - 2051, 2052, 2053, 2056, 2055, 2055, 2056, 2056, - 2059, 2056, 2058, 2056, 2055, 2056, 2054, 2058, - 2059, 2059, 2059, 2058, 2057, 2058, 2056, 2056, - 2059, 2060, 2060, 2062, 2064, 2064, 2063, 2065, - 2065, 2066, 2064, 2065, 2067, 2064, 2064, 2064, - 2066, 2064, 2066, 2064, 2064, 2066, 2065, 2065, - 2064, 2064, 2063, 2064, 2063, 2063, 2064, 2063, - 2064, 2066, 2066, 2068, 2068, 2063, 2062, 2062, - 2063, 2065, 2065, 2063, 2062, 2064, 2064, 2067, - 2064, 2065, 2066, 2062, 2063, 2064, 2064, 2065, - 2066, 2064, 2066, 2069, 2069, 2070, 2070, 2070, - 2068, 2069, 2071, 2073, 2074, 2077, 2076, 2079, - 2080, 2082, 2082, 2083, 2083, 2082, 2082, 2081, - 2083, 2083, 2080, 2081, 2081, 2083, 2083, 2083, - 2083, 2080, 2081, 2084, 2085, 2084, 2085, 2085, - 2083, 2082, 2080, 2081, 2080, 2080, 2078, 2079, - 2077, 2076, 2076, 2076, 2078, 2076, 2077, 2078, - 2080, 2080, 2082, 2084, 2082, 2082, 2082, 2081, - 2082, 2082, 2083, 2083, 2084, 2085, 2086, 2086, - 2084, 2085, 2086, 2087, 2087, 2089, 2088, 2085, - 2086, 2089, 2088, 2087, 2086, 2086, 2086, 2090, - 2089, 2089, 2090, 2092, 2094, 2095, 2095, 2097, - 2098, 2099, 2100, 2099, 2101, 2104, 2102, 2101, - 2101, 2101, 2103, 2102, 2099, 2096, 2097, 2098, - 2097, 2097, 2099, 2099, 2100, 2100, 2102, 2105, - 2104, 2100, 2099, 2096, 2097, 2095, 2092, 2094, - 2092, 2089, 2089, 2088, 2088, 2085, 2085, 2083, - 2082, 2081, 2080, 2081, 2082, 2082, 2080, 2080, - 2080, 2079, 2080, 2078, 2076, 2074, 2073, 2073, - 2073, 2072, 2071, 2067, 2067, 2069, 2070, 2072, - 2074, 2077, 2078, 2078, 2080, 2078, 2076, 2076, - 2073, 2073, 2071, 2070, 2071, 2069, 2069, 2069, - 2069, 2068, 2069, 2069, 2068, 2068, 2068, 2069, - 2068, 2066, 2064, 2064, 2063, 2062, 2061, 2055, - 2058, 2059, 2057, 2056, 2055, 2058, 2057, 2055, - 2054, 2055, 2056, 2055, 2055, 2055, 2052, 2053, - 2055, 2054, 2055, 2052, 2051, 2051, 2050, 2049, - 2049, 2050, 2048, 2049, 2049, 2049, 2050, 2052, - 2052, 2052, 2052, 2053, 2054, 2057, 2057, 2058, - 2058, 2058, 2061, 2061, 2062, 2064, 2065, 2066, - 2068, 2067, 2070, 2071, 2073, 2075, 2075, 2076, - 2078, 2078, 2077, 2076, 2080, 2077, 2079, 2080, - 2081, 2079, 2076, 2075, 2074, 2077, 2075, 2071, - 2071, 2070, 2070, 2073, 2073, 2076, 2074, 2071, - 2072, 2072, 2071, 2072, 2069, 2066, 2064, 2062, - 2061, 2062, 2063, 2062, 2064, 2062, 2060, 2062, - 2062, 2061, 2061, 2060, 2056, 2057, 2057, 2055, - 2056, 2056, 2055, 2056, 2057, 2057, 2058, 2059, - 2060, 2059, 2062, 2065, 2067, 2068, 2067, 2067, - 2067, 2066, 2066, 2065, 2063, 2060, 2064, 2067, - 2067, 2065, 2063, 2062, 2063, 2063, 2061, 2061, - 2060, 2060, 2059, 2059, 2061, 2060, 2064, 2064, - 2063, 2062, 2061, 2061, 2060, 2060, 2059, 2057, - 2056, 2055, 2056, 2058, 2058, 2060, 2058, 2060, - 2060, 2057, 2056, 2055, 2055, 2054, 2052, 2051, - 2052, 2048, 2048, 2050, 2051, 2046, 2044, 2043, - 2045, 2045, 2042, 2044, 2044, 2045, 2046, 2048, - 2047, 2049, 2045, 2043, 2042, 2042, 2040, 2039, - 2040, 2039, 2042, 2041, 2042, 2044, 2043, 2041, - 2040, 2039, 2036, 2038, 2039, 2040, 2042, 2043, - 2042, 2042, 2043, 2043, 2042, 2042, 2041, 2042, - 2041, 2044, 2044, 2041, 2042, 2043, 2040, 2041, - 2040, 2038, 2038, 2036, 2034, 2034, 2035, 2032, - 2032, 2031, 2032, 2031, 2029, 2030, 2029, 2029, - 2027, 2025, 2024, 2025, 2022, 2021, 2016, 2012, - 2012, 2014, 2014, 2014, 2013, 2011, 2010, 2008, - 2010, 2009, 2008, 2007, 2006, 2008, 2009, 2010, - 2011, 2008, 2009, 2011, 2010, 2012, 2012, 2011, - 2011, 2008, 2010, 2012, 2012, 2014, 2014, 2013, - 2007, 2012, 2017, 2018, 2016, 2013, 2011, 2015, - 2016, 2018, 2020, 2019, 2018, 2020, 2021, 2023, - 2024, 2023, 2026, 2024, 2025, 2027, 2027, 2026, - 2025, 2026, 2026, 2024, 2025, 2024, 2019, 2017, - 2015, 2012, 2010, 2009, 2010, 2010, 2008, 2005, - 2007, 2008, 2004, 2002, 1999, 1995, 1994, 1997, - 1997, 1997, 1996, 1995, 2000, 2001, 1998, 1998, - 1994, 1994, 1993, 1993, 1990, 1991, 1991, 1991, - 1996, 1993, 1995, 1995, 1997, 1994, 1994, 1994, - 1993, 1993, 1990, 1990, 1992, 1994, 1996, 1998, - 1998, 1998, 2000, 2002, 2001, 2001, 2000, 1998, - 2003, 2004, 2002, 2003, 2006, 2006, 2007, 2004, - 2002, 2001, 2000, 2000, 2002, 2001, 2002, 2003, - 2003, 2005, 2002, 2003, 2004, 2004, 2003, 1999, - 1996, 1998, 2000, 2001, 2001, 2000, 2001, 2003, - 2007, 2006, 2006, 2006, 2007, 2005, 2009, 2008, - 2008, 2011, 2011, 2017, 2016, 2016, 2019, 2021, - 2022, 2023, 2020, 2019, 2021, 2022, 2022, 2019, - 2020, 2021, 2022, 2021, 2025, 2027, 2025, 2025, - 2026, 2028, 2029, 2031, 2029, 2030, 2033, 2034, - 2034, 2031, 2030, 2032, 2033, 2032, 2033, 2032, - 2032, 2033, 2033, 2033, 2034, 2033, 2033, 2035, - 2034, 2032, 2033, 2034, 2030, 2028, 2026, 2026, - 2029, 2028, 2028, 2027, 2029, 2031, 2033, 2034, - 2034, 2033, 2032, 2034, 2034, 2032, 2031, 2034, - 2032, 2034, 2030, 2032, 2033, 2031, 2032, 2031, - 2030, 2031, 2031, 2030, 2029, 2028, 2027, 2028, - 2029, 2029, 2027, 2027, 2027, 2028, 2029, 2025, - 2024, 2022, 2022, 2025, 2026, 2027, 2026, 2027, - 2030, 2032, 2030, 2030, 2028, 2029, 2028, 2027, - 2028, 2030, 2032, 2030, 2032, 2033, 2032, 2031, - 2030, 2033, 2031, 2031, 2034, 2033, 2039, 2039, - 2039, 2041, 2043, 2043, 2041, 2039, 2038, 2038, - 2039, 2040, 2041, 2040, 2044, 2044, 2043, 2044, - 2044, 2047, 2049, 2045, 2046, 2046, 2044, 2046, - 2046, 2046, 2047, 2043, 2040, 2041, 2040, 2041, - 2045, 2044, 2044, 2046, 2043, 2042, 2042, 2041, - 2041, 2041, 2042, 2043, 2043, 2044, 2044, 2042, - 2042, 2044, 2044, 2044, 2046, 2045, 2046, 2046, - 2044, 2043, 2044, 2041, 2040, 2042, 2043, 2042, - 2043, 2047, 2046, 2048, 2045, 2045, 2046, 2046, - 2045, 2046, 2046, 2044, 2042, 2042, 2043, 2045, - 2047, 2046, 2046, 2048, 2048, 2049, 2050, 2049, - 2047, 2047, 2048, 2050, 2050, 2049, 2050, 2050, - 2051, 2050, 2048, 2048, 2047, 2044, 2044, 2043, - 2042, 2043, 2041, 2040, 2041, 2039, 2038, 2038, - 2038, 2038, 2039, 2036, 2034, 2034, 2031, 2031, - 2031, 2029, 2028, 2027, 2028, 2028, 2026, 2025, - 2027, 2030, 2028, 2027, 2025, 2024, 2023, 2020, - 2021, 2020, 2018, 2021, 2021, 2020, 2018, 2020, - 2019, 2021, 2026, 2027, 2027, 2027, 2028, 2027, - 2028, 2026, 2029, 2026, 2025, 2028, 2029, 2030, - 2033, 2034, 2034, 2034, 2036, 2036, 2039, 2041, - 2041, 2040, 2039, 2036, 2033, 2030, 2032, 2031, - 2029, 2034, 2039, 2044, 2048, 2051, 2054, 2055, - 2054, 2057, 2059, 2056, 2053, 2050, 2048, 2044, - 2037, 2033, 2030, 2026, 2027, 2028, 2031, 2037, - 2042, 2046, 2051, 2051, 2056, 2056, 2052, 2048, - 2044, 2037, 2029, 2023, 2014, 2007, 2003, 2002, - 2001, 1999, 1952, 1835, 1745, 1700, 1674, 1683, - 1730, 1806, 1892, 1979, 2053, 2095, 2102, 2106, - 2121, 2130, 2119, 2100, 2071, 2028, 1984, 1947, - 1918, 1900, 1904, 1935, 1979, 2022, 2068, 2117, - 2154, 2185, 2200, 2203, 2195, 2171, 2138, 2103, - 2079, 2045, 2012, 2001, 2006, 2014, 2025, 2046, - 2071, 2087, 2104, 2123, 2137, 2145, 2147, 2156, - 2150, 2130, 2105, 2082, 2044, 2005, 1982, 1967, - 1967, 1976, 1996, 1991, 1900, 1837, 1827, 1801, - 1808, 1817, 1847, 1897, 1932, 1965, 1973, 1967, - 1969, 2007, 2030, 2021, 2003, 1972, 1936, 1895, - 1870, 1845, 1822, 1827, 1856, 1892, 1915, 1937, - 1964, 1985, 2006, 2025, 2041, 2046, 2029, 2015, - 2001, 1988, 1969, 1936, 1912, 1908, 1909, 1918, - 1931, 1948, 1974, 2003, 2029, 2050, 2066, 2074, - 2075, 2065, 2045, 2027, 2012, 1990, 1967, 1957, - 1960, 1970, 1981, 1996, 2015, 2026, 2040, 2054, - 2058, 2051, 2049, 2056, 2058, 2049, 2029, 2008, - 1991, 1985, 1983, 1975, 1951, 1915, 1878, 1859, - 1850, 1841, 1846, 1863, 1891, 1923, 1957, 1977, - 1975, 1960, 1953, 1956, 1965, 1970, 1964, 1957, - 1943, 1933, 1923, 1910, 1898, 1892, 1897, 1914, - 1945, 1973, 2000, 2018, 2031, 2040, 2038, 2026, - 2002, 1975, 1954, 1945, 1942, 1938, 1941, 1951, - 1964, 1971, 1972, 1970, 1979, 1989, 1996, 2004, - 2013, 2012, 2009, 2022, 2016, 1991, 1975, 1980, - 1974, 1947, 1934, 1950, 1976, 2002, 2023, 2035, - 2041, 2047, 2053, 2046, 2030, 2021, 2017, 2011, - 2015, 2021, 2010, 1991, 1984, 1996, 2011, 2016, - 2013, 2008, 2006, 2017, 2024, 2023, 2026, 2032, - 2031, 2030, 2029, 2025, 2004, 1987, 1996, 2021, - 2041, 2042, 2035, 2033, 2031, 2026, 2011, 1998, - 1989, 1977, 1963, 1956, 1957, 1951, 1941, 1935, - 1939, 1951, 1956, 1956, 1952, 1948, 1950, 1950, - 1945, 1938, 1908, 1840, 1792, 1779, 1765, 1742, - 1726, 1745, 1771, 1801, 1839, 1877, 1904, 1924, - 1950, 1965, 1975, 1976, 1957, 1929, 1906, 1900, - 1888, 1864, 1847, 1846, 1861, 1881, 1909, 1945, - 1986, 2019, 2043, 2056, 2062, 2055, 2026, 2000, - 1988, 1976, 1954, 1935, 1934, 1950, 1972, 1984, - 1998, 2022, 2047, 2060, 2063, 2064, 2062, 2057, - 2046, 2040, 2033, 2016, 2000, 1991, 1978, 1969, - 1972, 1995, 2016, 2028, 2051, 2070, 2071, 2066, - 2059, 2044, 2023, 2007, 2003, 1999, 1984, 1970, - 1965, 1963, 1962, 1970, 1982, 1988, 1993, 1996, - 2001, 2005, 2000, 2001, 1999, 1991, 1984, 1972, - 1960, 1944, 1929, 1920, 1919, 1935, 1958, 1974, - 1980, 1991, 2005, 2018, 2015, 1997, 1984, 1971, - 1956, 1948, 1945, 1940, 1945, 1963, 1973, 1972, - 1975, 1981, 1986, 1988, 1995, 2009, 2020, 2032, - 2035, 2026, 2008, 1991, 1973, 1962, 1964, 1971, - 1981, 1999, 2025, 2050, 2063, 2068, 2062, 2052, - 2044, 2038, 2033, 2028, 2027, 2028, 2031, 2031, - 2033, 2029, 2021, 2019, 2017, 2021, 2031, 2044, - 2058, 2068, 2075, 2074, 2067, 2056, 2044, 2031, - 2015, 2002, 2000, 1997, 2001, 2010, 2012, 2025, - 2035, 2041, 2044, 2046, 2048, 2043, 2039, 2035, - 2036, 2032, 2025, 2016, 2004, 1989, 1982, 1983, - 1989, 1998, 2008, 2021, 2032, 2036, 2037, 2035, - 2031, 2021, 2012, 2011, 2008, 2002, 1999, 2000, - 2001, 2003, 2011, 2021, 2025, 2024, 2027, 2033, - 2036, 2036, 2038, 2039, 2042, 2040, 2037, 2034, - 2027, 2019, 2013, 2012, 2013, 2018, 2030, 2043, - 2057, 2067, 2074, 2075, 2069, 2060, 2051, 2044, - 2036, 2030, 2031, 2033, 2037, 2040, 2043, 2043, - 2048, 2053, 2054, 2054, 2061, 2069, 2066, 2060, - 2059, 2056, 2052, 2050, 2054, 2057, 2053, 2055, - 2055, 2059, 2060, 2063, 2067, 2069, 2068, 2070, - 2067, 2058, 2047, 2043, 2042, 2039, 2040, 2047, - 2051, 2050, 2052, 2055, 2058, 2056, 2055, 2053, - 2053, 2049, 2047, 2045, 2040, 2036, 2031, 2028, - 2026, 2026, 2032, 2039, 2047, 2053, 2058, 2061, - 2060, 2062, 2056, 2046, 2043, 2040, 2040, 2037, - 2036, 2037, 2041, 2042, 2044, 2048, 2048, 2050, - 2056, 2062, 2066, 2068, 2071, 2072, 2070, 2069, - 2066, 2057, 2048, 2044, 2044, 2047, 2050, 2055, - 2061, 2067, 2072, 2078, 2083, 2085, 2088, 2087, - 2084, 2083, 2076, 2071, 2067, 2062, 2060, 2060, - 2058, 2056, 2059, 2065, 2073, 2079, 2088, 2089, - 2093, 2097, 2097, 2092, 2084, 2078, 2074, 2067, - 2060, 2058, 2056, 2058, 2058, 2065, 2067, 2073, - 2077, 2081, 2080, 2074, 2072, 2069, 2067, 2063, - 2062, 2059, 2061, 2060, 2057, 2055, 2054, 2057, - 2061, 2065, 2067, 2065, 2063, 2063, 2061, 2058, - 2053, 2052, 2050, 2051, 2053, 2057, 2059, 2061, - 2060, 2058, 2060, 2058, 2061, 2068, 2071, 2070, - 2066, 2069, 2067, 2061, 2055, 2052, 2054, 2054, - 2055, 2056, 2061, 2063, 2065, 2066, 2071, 2076, - 2080, 2082, 2081, 2080, 2075, 2068, 2058, 2048, - 2040, 2036, 2035, 2040, 2050, 2059, 2070, 2083, - 2092, 2097, 2094, 2091, 2087, 2077, 2070, 2062, - 2054, 2049, 2048, 2048, 2046, 2044, 2051, 2058, - 2067, 2075, 2088, 2091, 2085, 2077, 2068, 2063, - 2056, 2056, 2062, 2064, 2061, 2056, 2051, 2046, - 2044, 2047, 2050, 2057, 2063, 2064, 2061, 2056, - 2057, 2059, 2063, 2068, 2068, 2068, 2063, 2054, - 2043, 2036, 2033, 2035, 2039, 2045, 2048, 2051, - 2049, 2047, 2048, 2046, 2052, 2057, 2058, 2058, - 2054, 2046, 2040, 2039, 2036, 2037, 2041, 2045, - 2049, 2052, 2049, 2042, 2030, 2022, 2020, 2022, - 2029, 2039, 2048, 2058, 2064, 2062, 2056, 2045, - 2040, 2036, 2032, 2029, 2024, 2020, 2014, 2012, - 2016, 2023, 2034, 2043, 2051, 2053, 2052, 2048, - 2041, 2034, 2030, 2028, 2027, 2024, 2016, 2008, - 2003, 2001, 2003, 2009, 2019, 2026, 2032, 2033, - 2033, 2032, 2033, 2036, 2038, 2038, 2034, 2035, - 2031, 2029, 2024, 2023, 2024, 2027, 2027, 2026, - 2020, 2017, 2018, 2022, 2026, 2031, 2038, 2039, - 2038, 2039, 2038, 2036, 2030, 2024, 2022, 2020, - 2016, 2012, 2011, 2011, 2013, 2018, 2025, 2028, - 2026, 2024, 2018, 2014, 2008, 2003, 2001, 2007, - 2014, 2025, 2029, 2026, 2019, 2008, 1999, 1990, - 1985, 1984, 1989, 1995, 2007, 2015, 2015, 2015, - 2014, 2013, 2012, 2016, 2016, 2015, 2014, 2008, - 2001, 1991, 1987, 1984, 1986, 1989, 1995, 2004, - 2009, 2011, 2010, 2006, 2000, 1996, 1997, 1996, - 2000, 2000, 1999, 2002, 2001, 2000, 1997, 1994, - 1989, 1988, 1986, 1981, 1977, 1979, 1982, 1986, - 1990, 1998, 2000, 2002, 2001, 2000, 1993, 1983, - 1977, 1970, 1963, 1960, 1963, 1962, 1965, 1966, - 1967, 1969, 1968, 1972, 1976, 1979, 1983, 1984, - 1985, 1986, 1982, 1975, 1969, 1963, 1960, 1958, - 1961, 1965, 1969, 1972, 1976, 1980, 1983, 1988, - 1989, 1990, 1991, 1990, 1986, 1984, 1983, 1980, - 1974, 1972, 1973, 1977, 1984, 1992, 1997, 2000, - 2005, 2009, 2009, 2003, 1998, 1992, 1986, 1983, - 1977, 1973, 1969, 1968, 1974, 1977, 1984, 1992, - 1998, 2004, 2001, 1996, 1990, 1986, 1984, 1982, - 1982, 1986, 1988, 1990, 1988, 1986, 1984, 1984, - 1983, 1984, 1988, 1993, 1998, 2003, 2005, 2001, - 1996, 1991, 1986, 1983, 1979, 1982, 1983, 1986, - 1991, 1992, 1990, 1986, 1984, 1980, 1982, 1982, - 1984, 1986, 1984, 1987, 1987, 1982, 1984, 1986, - 1983, 1984, 1985, 1987, 1986, 1985, 1982, 1982, - 1984, 1985, 1988, 1986, 1988, 1990, 1991, 1992, - 1993, 1992, 1991, 1991, 1988, 1987, 1990, 1991, - 1994, 1997, 2001, 2001, 1999, 1995, 1988, 1984, - 1980, 1976, 1976, 1982, 1985, 1987, 1989, 1991, - 1993, 1993, 1996, 1999, 2003, 2005, 2004, 2004, - 2002, 1998, 1994, 1989, 1986, 1984, 1983, 1984, - 1983, 1981, 1985, 1986, 1986, 1986, 1988, 1992, - 1997, 2000, 1999, 1996, 1991, 1991, 1988, 1982, - 1983, 1980, 1981, 1984, 1984, 1985, 1985, 1989, - 1991, 1994, 1999, 1996, 1994, 1989, 1988, 1988, - 1979, 1980, 1979, 1980, 1979, 1980, 1982, 1984, - 1985, 1986, 1988, 1988, 1992, 1991, 1989, 1987, - 1988, 1987, 1987, 1991, 1994, 1999, 2003, 2001, - 2000, 1999, 1996, 1991, 1990, 1990, 1991, 1990, - 1992, 1994, 1993, 1997, 1997, 2002, 2009, 2016, - 2022, 2025, 2028, 2027, 2024, 2024, 2024, 2022, - 2025, 2024, 2022, 2021, 2019, 2017, 2014, 2017, - 2020, 2023, 2026, 2030, 2034, 2036, 2033, 2032, - 2030, 2029, 2027, 2021, 2019, 2017, 2016, 2019, - 2027, 2031, 2033, 2035, 2032, 2030, 2024, 2022, - 2016, 2015, 2017, 2014, 2013, 2013, 2012, 2012, - 2014, 2017, 2023, 2029, 2033, 2036, 2037, 2034, - 2032, 2029, 2029, 2029, 2030, 2030, 2032, 2030, - 2026, 2021, 2019, 2021, 2027, 2033, 2038, 2040, - 2044, 2047, 2043, 2038, 2035, 2033, 2031, 2030, - 2030, 2030, 2031, 2033, 2038, 2039, 2038, 2037, - 2039, 2038, 2037, 2035, 2036, 2039, 2042, 2043, - 2041, 2042, 2042, 2040, 2036, 2037, 2040, 2040, - 2042, 2046, 2049, 2046, 2044, 2044, 2043, 2040, - 2036, 2039, 2042, 2045, 2048, 2043, 2040, 2037, - 2036, 2034, 2033, 2032, 2032, 2032, 2036, 2037, - 2040, 2041, 2042, 2043, 2047, 2051, 2051, 2049, - 2047, 2043, 2035, 2031, 2027, 2025, 2026, 2024, - 2030, 2034, 2036, 2038, 2039, 2045, 2052, 2054, - 2055, 2054, 2053, 2052, 2051, 2048, 2046, 2044, - 2048, 2048, 2046, 2046, 2047, 2046, 2047, 2048, - 2049, 2051, 2051, 2052, 2051, 2052, 2052, 2055, - 2062, 2064, 2067, 2068, 2066, 2068, 2067, 2066, - 2069, 2069, 2070, 2072, 2071, 2071, 2067, 2062, - 2061, 2063, 2064, 2067, 2067, 2067, 2071, 2071, - 2074, 2079, 2080, 2081, 2080, 2078, 2074, 2072, - 2068, 2062, 2060, 2061, 2064, 2065, 2069, 2073, - 2076, 2081, 2084, 2089, 2091, 2094, 2093, 2093, - 2090, 2086, 2085, 2081, 2081, 2081, 2082, 2082, - 2081, 2081, 2080, 2078, 2080, 2084, 2086, 2090, - 2096, 2095, 2095, 2093, 2091, 2085, 2086, 2088, - 2088, 2090, 2091, 2091, 2089, 2088, 2089, 2088, - 2087, 2089, 2089, 2092, 2096, 2099, 2102, 2101, - 2100, 2102, 2102, 2098, 2096, 2092, 2089, 2086, - 2084, 2086, 2093, 2097, 2105, 2111, 2115, 2116, - 2114, 2112, 2111, 2112, 2113, 2116, 2114, 2119, - 2124, 2127, 2122, 2115, 2114, 2111, 2111, 2112, - 2114, 2115, 2118, 2123, 2127, 2131, 2133, 2135, - 2136, 2135, 2131, 2130, 2130, 2131, 2130, 2129, - 2131, 2135, 2136, 2139, 2139, 2137, 2133, 2130, - 2126, 2124, 2129, 2129, 2129, 2126, 2126, 2128, - 2128, 2126, 2127, 2127, 2132, 2134, 2131, 2129, - 2126, 2124, 2122, 2119, 2115, 2112, 2110, 2111, - 2112, 2114, 2114, 2116, 2115, 2118, 2121, 2125, - 2126, 2124, 2124, 2120, 2118, 2115, 2113, 2110, - 2111, 2111, 2109, 2108, 2110, 2112, 2115, 2119, - 2121, 2123, 2123, 2121, 2121, 2120, 2123, 2124, - 2125, 2127, 2128, 2129, 2127, 2124, 2119, 2114, - 2112, 2110, 2111, 2114, 2114, 2118, 2123, 2126, - 2127, 2125, 2126, 2130, 2131, 2133, 2130, 2128, - 2125, 2120, 2118, 2117, 2116, 2119, 2129, 2132, - 2133, 2134, 2131, 2132, 2131, 2134, 2137, 2139, - 2140, 2139, 2138, 2133, 2130, 2126, 2123, 2123, - 2127, 2128, 2130, 2134, 2133, 2134, 2137, 2140, - 2142, 2144, 2144, 2141, 2136, 2133, 2128, 2121, - 2118, 2120, 2127, 2129, 2134, 2138, 2138, 2138, - 2134, 2133, 2131, 2133, 2134, 2131, 2126, 2121, - 2115, 2108, 2109, 2114, 2120, 2128, 2136, 2141, - 2142, 2142, 2143, 2139, 2139, 2139, 2137, 2135, - 2128, 2123, 2116, 2110, 2108, 2108, 2110, 2116, - 2119, 2122, 2128, 2129, 2126, 2123, 2125, 2127, - 2130, 2128, 2124, 2119, 2113, 2106, 2104, 2105, - 2107, 2110, 2115, 2118, 2118, 2118, 2118, 2115, - 2114, 2115, 2115, 2115, 2114, 2112, 2111, 2111, - 2110, 2112, 2115, 2116, 2117, 2119, 2116, 2115, - 2112, 2111, 2110, 2108, 2107, 2105, 2106, 2106, - 2106, 2106, 2106, 2106, 2107, 2108, 2108, 2107, - 2110, 2113, 2115, 2113, 2108, 2103, 2094, 2086, - 2084, 2086, 2087, 2084, 2085, 2089, 2090, 2091, - 2096, 2100, 2103, 2105, 2110, 2108, 2105, 2098, - 2093, 2091, 2087, 2089, 2094, 2099, 2101, 2101, - 2097, 2094, 2093, 2090, 2096, 2104, 2109, 2110, - 2108, 2104, 2102, 2102, 2104, 2108, 2113, 2117, - 2120, 2119, 2118, 2118, 2113, 2115, 2119, 2120, - 2125, 2126, 2121, 2117, 2111, 2108, 2110, 2112, - 2116, 2121, 2127, 2129, 2130, 2127, 2128, 2128, - 2130, 2134, 2137, 2136, 2133, 2129, 2124, 2119, - 2115, 2115, 2117, 2121, 2127, 2131, 2132, 2132, - 2131, 2131, 2135, 2138, 2140, 2138, 2136, 2130, - 2124, 2122, 2123, 2125, 2132, 2138, 2144, 2147, - 2147, 2146, 2144, 2144, 2143, 2143, 2144, 2143, - 2138, 2133, 2127, 2121, 2118, 2121, 2128, 2135, - 2143, 2151, 2154, 2152, 2151, 2147, 2143, 2142, - 2142, 2139, 2135, 2134, 2133, 2133, 2134, 2135, - 2136, 2140, 2144, 2143, 2143, 2144, 2144, 2144, - 2144, 2145, 2148, 2146, 2145, 2144, 2143, 2139, - 2139, 2138, 2139, 2140, 2141, 2144, 2149, 2152, - 2155, 2157, 2158, 2160, 2160, 2160, 2157, 2156, - 2153, 2151, 2152, 2152, 2149, 2148, 2148, 2147, - 2149, 2152, 2158, 2161, 2165, 2164, 2165, 2166, - 2166, 2164, 2161, 2163, 2163, 2163, 2160, 2157, - 2157, 2156, 2153, 2155, 2159, 2162, 2163, 2166, - 2171, 2171, 2170, 2166, 2161, 2157, 2153, 2153, - 2155, 2155, 2152, 2153, 2155, 2157, 2159, 2160, - 2165, 2168, 2167, 2167, 2161, 2156, 2154, 2152, - 2152, 2154, 2155, 2157, 2156, 2159, 2156, 2157, - 2157, 2158, 2159, 2163, 2169, 2166, 2162, 2158, - 2154, 2153, 2151, 2148, 2152, 2158, 2156, 2155, - 2157, 2159, 2156, 2154, 2154, 2157, 2156, 2158, - 2160, 2158, 2156, 2153, 2151, 2149, 2146, 2150, - 2155, 2156, 2159, 2160, 2161, 2163, 2166, 2168, - 2168, 2169, 2170, 2169, 2164, 2157, 2152, 2150, - 2150, 2148, 2150, 2155, 2162, 2165, 2170, 2172, - 2177, 2181, 2184, 2184, 2182, 2180, 2175, 2171, - 2164, 2160, 2156, 2157, 2161, 2162, 2164, 2167, - 2165, 2163, 2165, 2165, 2167, 2169, 2171, 2172, - 2172, 2171, 2170, 2170, 2173, 2176, 2172, 2171, - 2171, 2171, 2165, 2160, 2153, 2154, 2159, 2167, - 2170, 2170, 2171, 2173, 2172, 2170, 2169, 2171, - 2174, 2176, 2180, 2179, 2174, 2170, 2168, 2168, - 2167, 2167, 2168, 2169, 2171, 2169, 2169, 2171, - 2173, 2177, 2179, 2185, 2189, 2191, 2188, 2181, - 2179, 2178, 2176, 2179, 2182, 2183, 2178, 2177, - 2172, 2165, 2159, 2158, 2164, 2168, 2169, 2173, - 2173, 2170, 2173, 2175, 2177, 2179, 2185, 2189, - 2193, 2190, 2186, 2183, 2180, 2182, 2182, 2184, - 2188, 2188, 2185, 2180, 2174, 2172, 2171, 2170, - 2173, 2178, 2178, 2178, 2176, 2177, 2177, 2179, - 2184, 2188, 2194, 2199, 2200, 2198, 2193, 2188, - 2182, 2177, 2175, 2172, 2172, 2172, 2174, 2173, - 2175, 2173, 2179, 2186, 2190, 2197, 2200, 2201, - 2196, 2190, 2185, 2180, 2176, 2174, 2169, 2167, - 2164, 2162, 2158, 2157, 2158, 2162, 2169, 2177, - 2185, 2190, 2192, 2192, 2186, 2180, 2175, 2173, - 2169, 2166, 2165, 2162, 2158, 2153, 2152, 2155, - 2161, 2168, 2176, 2185, 2185, 2184, 2181, 2180, - 2176, 2174, 2175, 2177, 2181, 2185, 2185, 2179, - 2177, 2172, 2169, 2170, 2172, 2174, 2175, 2176, - 2172, 2170, 2171, 2174, 2179, 2185, 2191, 2198, - 2203, 2202, 2197, 2190, 2190, 2190, 2188, 2190, - 2188, 2183, 2178, 2173, 2168, 2167, 2166, 2173, - 2180, 2188, 2199, 2202, 2205, 2202, 2201, 2195, - 2192, 2191, 2190, 2189, 2186, 2182, 2179, 2177, - 2175, 2176, 2178, 2185, 2189, 2193, 2196, 2195, - 2197, 2195, 2192, 2193, 2194, 2196, 2196, 2189, - 2183, 2181, 2180, 2182, 2185, 2190, 2198, 2201, - 2206, 2203, 2198, 2192, 2186, 2185, 2182, 2179, - 2178, 2179, 2175, 2175, 2180, 2186, 2191, 2195, - 2199, 2201, 2199, 2196, 2190, 2190, 2185, 2184, - 2182, 2179, 2177, 2170, 2164, 2162, 2162, 2165, - 2169, 2173, 2180, 2186, 2191, 2193, 2194, 2193, - 2193, 2192, 2190, 2186, 2185, 2182, 2175, 2172, - 2171, 2171, 2172, 2174, 2179, 2180, 2182, 2188, - 2190, 2191, 2192, 2192, 2192, 2190, 2188, 2190, - 2188, 2185, 2183, 2182, 2181, 2179, 2178, 2178, - 2175, 2175, 2175, 2176, 2179, 2180, 2183, 2182, - 2179, 2179, 2178, 2177, 2179, 2180, 2187, 2188, - 2192, 2194, 2194, 2193, 2191, 2192, 2192, 2188, - 2185, 2183, 2183, 2182, 2180, 2184, 2186, 2191, - 2195, 2199, 2200, 2203, 2201, 2201, 2203, 2206, - 2208, 2207, 2209, 2205, 2198, 2193, 2186, 2185, - 2183, 2188, 2190, 2194, 2198, 2199, 2200, 2199, - 2200, 2202, 2203, 2204, 2202, 2202, 2200, 2192, - 2186, 2183, 2177, 2174, 2172, 2166, 2164, 2161, - 2160, 2158, 2158, 2160, 2161, 2167, 2169, 2169, - 2165, 2162, 2160, 2161, 2161, 2162, 2164, 2167, - 2167, 2165, 2161, 2156, 2155, 2150, 2146, 2147, - 2150, 2152, 2156, 2158, 2161, 2164, 2166, 2166, - 2165, 2165, 2163, 2163, 2161, 2159, 2158, 2157, - 2160, 2157, 2158, 2156, 2153, 2148, 2147, 2150, - 2154, 2155, 2159, 2162, 2166, 2165, 2165, 2166, - 2164, 2163, 2158, 2154, 2152, 2151, 2151, 2151, - 2148, 2147, 2147, 2147, 2148, 2149, 2154, 2158, - 2162, 2165, 2166, 2170, 2172, 2172, 2172, 2169, - 2169, 2166, 2164, 2162, 2160, 2159, 2159, 2162, - 2166, 2167, 2168, 2170, 2172, 2172, 2174, 2175, - 2177, 2178, 2183, 2185, 2181, 2179, 2176, 2174, - 2169, 2164, 2162, 2163, 2161, 2165, 2165, 2165, - 2169, 2171, 2173, 2175, 2177, 2178, 2177, 2177, - 2176, 2174, 2174, 2176, 2177, 2177, 2177, 2174, - 2173, 2170, 2167, 2167, 2170, 2173, 2179, 2182, - 2182, 2183, 2183, 2185, 2188, 2190, 2192, 2194, - 2193, 2193, 2192, 2191, 2190, 2191, 2194, 2194, - 2196, 2201, 2203, 2202, 2198, 2198, 2199, 2205, - 2208, 2214, 2218, 2220, 2218, 2220, 2218, 2219, - 2220, 2219, 2218, 2216, 2213, 2212, 2214, 2210, - 2210, 2212, 2213, 2215, 2217, 2216, 2217, 2218, - 2220, 2223, 2223, 2226, 2228, 2228, 2224, 2223, - 2220, 2219, 2218, 2219, 2218, 2216, 2216, 2218, - 2221, 2221, 2225, 2230, 2238, 2245, 2250, 2250, - 2250, 2249, 2241, 2237, 2235, 2232, 2230, 2227, - 2227, 2230, 2230, 2231, 2235, 2238, 2238, 2240, - 2244, 2246, 2244, 2243, 2244, 2246, 2247, 2246, - 2243, 2239, 2237, 2233, 2231, 2230, 2231, 2231, - 2234, 2237, 2240, 2243, 2242, 2239, 2238, 2240, - 2243, 2242, 2243, 2246, 2250, 2253, 2251, 2249, - 2251, 2250, 2249, 2249, 2249, 2247, 2247, 2247, - 2247, 2246, 2246, 2248, 2249, 2251, 2253, 2254, - 2256, 2258, 2258, 2261, 2261, 2260, 2261, 2258, - 2257, 2252, 2251, 2252, 2247, 2245, 2244, 2243, - 2245, 2241, 2239, 2239, 2241, 2241, 2242, 2243, - 2246, 2244, 2241, 2237, 2235, 2235, 2232, 2231, - 2231, 2232, 2230, 2230, 2229, 2230, 2233, 2233, - 2233, 2237, 2239, 2239, 2238, 2237, 2239, 2242, - 2244, 2244, 2245, 2243, 2236, 2232, 2227, 2223, - 2225, 2226, 2230, 2232, 2235, 2234, 2234, 2234, - 2235, 2240, 2240, 2245, 2248, 2249, 2245, 2239, - 2235, 2231, 2226, 2224, 2223, 2219, 2218, 2217, - 2217, 2217, 2221, 2223, 2227, 2230, 2232, 2233, - 2231, 2231, 2228, 2226, 2226, 2224, 2219, 2218, - 2216, 2211, 2211, 2213, 2217, 2218, 2221, 2223, - 2226, 2231, 2235, 2242, 2248, 2251, 2251, 2253, - 2254, 2259, 2259, 2254, 2255, 2254, 2250, 2246, - 2241, 2238, 2232, 2231, 2234, 2239, 2241, 2243, - 2248, 2250, 2254, 2256, 2259, 2262, 2264, 2263, - 2261, 2255, 2251, 2246, 2240, 2233, 2230, 2233, - 2232, 2228, 2224, 2223, 2222, 2221, 2223, 2227, - 2230, 2235, 2234, 2232, 2230, 2231, 2230, 2232, - 2232, 2232, 2229, 2227, 2228, 2225, 2224, 2224, - 2227, 2229, 2227, 2228, 2227, 2228, 2230, 2230, - 2229, 2231, 2233, 2233, 2231, 2226, 2226, 2223, - 2223, 2223, 2225, 2228, 2227, 2228, 2226, 2226, - 2224, 2221, 2223, 2224, 2225, 2227, 2229, 2227, - 2228, 2225, 2224, 2223, 2226, 2224, 2224, 2226, - 2225, 2226, 2226, 2226, 2225, 2224, 2225, 2227, - 2225, 2223, 2223, 2227, 2227, 2226, 2227, 2226, - 2226, 2225, 2226, 2228, 2227, 2229, 2229, 2232, - 2231, 2232, 2230, 2233, 2232, 2232, 2231, 2230, - 2231, 2230, 2230, 2231, 2231, 2233, 2234, 2235, - 2235, 2231, 2228, 2227, 2226, 2224, 2222, 2222, - 2222, 2224, 2221, 2220, 2217, 2215, 2213, 2214, - 2215, 2216, 2215, 2212, 2211, 2209, 2211, 2212, - 2209, 2211, 2212, 2210, 2206, 2203, 2199, 2197, - 2198, 2199, 2203, 2207, 2210, 2212, 2214, 2216, - 2219, 2220, 2222, 2224, 2226, 2227, 2223, 2217, - 2212, 2206, 2203, 2197, 2193, 2193, 2195, 2199, - 2203, 2209, 2213, 2216, 2218, 2223, 2225, 2227, - 2228, 2222, 2219, 2214, 2213, 2213, 2213, 2210, - 2210, 2207, 2207, 2206, 2204, 2201, 2204, 2207, - 2209, 2212, 2214, 2216, 2215, 2211, 2206, 2204, - 2203, 2199, 2200, 2198, 2199, 2202, 2200, 2199, - 2198, 2198, 2198, 2200, 2201, 2199, 2201, 2199, - 2198, 2193, 2192, 2191, 2190, 2190, 2192, 2192, - 2192, 2191, 2191, 2191, 2193, 2193, 2194, 2193, - 2192, 2192, 2188, 2185, 2182, 2181, 2177, 2177, - 2178, 2175, 2176, 2174, 2175, 2172, 2173, 2172, - 2172, 2172, 2170, 2169, 2164, 2158, 2153, 2149, - 2144, 2143, 2138, 2134, 2132, 2135, 2138, 2137, - 2138, 2140, 2144, 2147, 2148, 2149, 2150, 2147, - 2144, 2143, 2141, 2139, 2136, 2134, 2132, 2132, - 2133, 2132, 2131, 2136, 2138, 2142, 2146, 2146, - 2147, 2146, 2148, 2147, 2142, 2140, 2139, 2138, - 2138, 2133, 2130, 2126, 2122, 2121, 2123, 2124, - 2123, 2125, 2127, 2128, 2126, 2125, 2123, 2120, - 2117, 2112, 2110, 2107, 2104, 2102, 2096, 2092, - 2091, 2091, 2087, 2086, 2087, 2089, 2090, 2089, - 2087, 2086, 2088, 2090, 2094, 2095, 2095, 2093, - 2089, 2085, 2081, 2078, 2077, 2075, 2075, 2074, - 2073, 2073, 2069, 2066, 2065, 2064, 2064, 2062, - 2064, 2064, 2065, 2067, 2067, 2067, 2066, 2067, - 2065, 2064, 2064, 2062, 2059, 2055, 2053, 2053, - 2055, 2054, 2055, 2054, 2054, 2050, 2050, 2051, - 2051, 2051, 2052, 2055, 2059, 2060, 2058, 2058, - 2052, 2049, 2047, 2044, 2044, 2046, 2045, 2050, - 2051, 2052, 2051, 2052, 2055, 2053, 2055, 2056, - 2052, 2051, 2052, 2049, 2046, 2045, 2046, 2044, - 2043, 2043, 2043, 2041, 2042, 2043, 2045, 2047, - 2049, 2050, 2049, 2049, 2047, 2046, 2045, 2041, - 2042, 2041, 2041, 2038, 2039, 2038, 2036, 2036, - 2033, 2029, 2030, 2028, 2029, 2033, 2030, 2032, - 2031, 2030, 2030, 2030, 2029, 2028, 2031, 2030, - 2031, 2028, 2028, 2029, 2025, 2022, 2019, 2017, - 2013, 2011, 2010, 2009, 2011, 2012, 2013, 2016, - 2017, 2019, 2020, 2019, 2018, 2012, 2011, 2012, - 2012, 2013, 2009, 2008, 2007, 2008, 2008, 2011, - 2012, 2009, 2008, 2007, 2006, 2004, 2003, 2002, - 2003, 2001, 2001, 2001, 2002, 2002, 2005, 2004, - 2005, 2003, 2000, 2000, 1998, 1997, 1996, 1994, - 1990, 1987, 1983, 1985, 1985, 1988, 1991, 1994, - 1999, 2000, 1999, 1997, 1998, 1997, 1994, 1994, - 1993, 1990, 1988, 1985, 1979, 1977, 1977, 1977, - 1979, 1981, 1978, 1980, 1979, 1982, 1981, 1981, - 1983, 1983, 1983, 1984, 1983, 1985, 1983, 1977, - 1976, 1976, 1977, 1976, 1977, 1979, 1977, 1976, - 1971, 1966, 1965, 1963, 1962, 1965, 1968, 1967, - 1968, 1967, 1967, 1963, 1965, 1964, 1965, 1967, - 1969, 1968, 1964, 1962, 1960, 1957, 1955, 1953, - 1949, 1949, 1948, 1949, 1950, 1951, 1953, 1957, - 1963, 1964, 1963, 1965, 1960, 1959, 1957, 1951, - 1948, 1946, 1943, 1941, 1941, 1940, 1937, 1936, - 1939, 1939, 1941, 1944, 1944, 1945, 1945, 1946, - 1944, 1945, 1941, 1940, 1940, 1940, 1941, 1939, - 1935, 1936, 1936, 1934, 1933, 1934, 1935, 1937, - 1936, 1934, 1938, 1938, 1938, 1938, 1939, 1938, - 1938, 1939, 1939, 1940, 1937, 1936, 1932, 1933, - 1933, 1934, 1932, 1933, 1933, 1936, 1937, 1936, - 1941, 1944, 1946, 1948, 1952, 1954, 1953, 1950, - 1949, 1947, 1946, 1943, 1942, 1939, 1940, 1940, - 1940, 1938, 1939, 1940, 1940, 1940, 1942, 1945, - 1949, 1949, 1947, 1946, 1947, 1944, 1939, 1937, - 1938, 1936, 1936, 1939, 1937, 1938, 1937, 1935, - 1934, 1935, 1933, 1932, 1930, 1932, 1932, 1932, - 1933, 1933, 1936, 1938, 1942, 1945, 1947, 1948, - 1948, 1952, 1951, 1949, 1947, 1947, 1948, 1946, - 1945, 1945, 1945, 1946, 1944, 1945, 1948, 1952, - 1958, 1959, 1962, 1964, 1965, 1963, 1964, 1960, - 1957, 1956, 1951, 1947, 1943, 1942, 1938, 1939, - 1935, 1937, 1939, 1940, 1943, 1946, 1949, 1950, - 1948, 1947, 1948, 1948, 1947, 1943, 1938, 1939, - 1938, 1937, 1934, 1935, 1933, 1934, 1936, 1940, - 1941, 1942, 1943, 1943, 1946, 1944, 1944, 1944, - 1945, 1946, 1946, 1945, 1946, 1945, 1944, 1942, - 1939, 1936, 1937, 1935, 1935, 1936, 1935, 1937, - 1938, 1939, 1938, 1939, 1938, 1940, 1938, 1937, - 1936, 1935, 1932, 1929, 1926, 1925, 1921, 1921, - 1918, 1915, 1912, 1915, 1916, 1915, 1917, 1918, - 1921, 1925, 1927, 1924, 1921, 1918, 1920, 1918, - 1917, 1920, 1924, 1923, 1925, 1925, 1923, 1922, - 1923, 1926, 1929, 1929, 1932, 1936, 1937, 1936, - 1934, 1934, 1932, 1934, 1933, 1932, 1932, 1927, - 1926, 1926, 1926, 1927, 1925, 1924, 1923, 1923, - 1922, 1923, 1921, 1921, 1921, 1922, 1922, 1923, - 1922, 1923, 1925, 1926, 1927, 1927, 1927, 1928, - 1926, 1925, 1922, 1921, 1922, 1922, 1922, 1922, - 1920, 1921, 1921, 1918, 1919, 1919, 1923, 1924, - 1929, 1931, 1934, 1932, 1931, 1932, 1931, 1932, - 1933, 1931, 1931, 1930, 1931, 1932, 1930, 1930, - 1931, 1930, 1932, 1932, 1931, 1932, 1932, 1928, - 1928, 1930, 1931, 1932, 1932, 1933, 1932, 1930, - 1929, 1927, 1925, 1924, 1924, 1924, 1925, 1924, - 1925, 1927, 1927, 1927, 1924, 1925, 1928, 1927, - 1926, 1925, 1923, 1925, 1926, 1927, 1924, 1922, - 1921, 1919, 1921, 1918, 1917, 1918, 1921, 1922, - 1926, 1928, 1928, 1928, 1927, 1928, 1929, 1931, - 1931, 1930, 1932, 1932, 1928, 1930, 1928, 1927, - 1929, 1931, 1934, 1937, 1937, 1937, 1936, 1938, - 1938, 1939, 1937, 1938, 1937, 1937, 1936, 1933, - 1932, 1932, 1931, 1930, 1931, 1930, 1930, 1930, - 1932, 1932, 1932, 1934, 1936, 1937, 1937, 1936, - 1935, 1936, 1938, 1938, 1938, 1937, 1934, 1937, - 1934, 1928, 1930, 1928, 1930, 1930, 1932, 1934, - 1939, 1940, 1939, 1944, 1943, 1945, 1945, 1943, - 1940, 1940, 1942, 1939, 1942, 1938, 1936, 1935, - 1933, 1930, 1934, 1932, 1929, 1930, 1929, 1931, - 1929, 1927, 1928, 1926, 1925, 1923, 1920, 1920, - 1916, 1915, 1915, 1913, 1912, 1913, 1914, 1914, - 1911, 1911, 1909, 1907, 1909, 1909, 1907, 1909, - 1908, 1907, 1908, 1908, 1910, 1912, 1912, 1910, - 1910, 1913, 1912, 1915, 1916, 1913, 1914, 1911, - 1912, 1911, 1911, 1912, 1913, 1913, 1913, 1914, - 1916, 1916, 1914, 1912, 1911, 1909, 1909, 1907, - 1903, 1903, 1904, 1906, 1907, 1909, 1911, 1912, - 1913, 1912, 1913, 1913, 1912, 1914, 1913, 1913, - 1911, 1909, 1907, 1907, 1907, 1911, 1914, 1917, - 1920, 1922, 1925, 1927, 1928, 1929, 1927, 1927, - 1926, 1927, 1928, 1926, 1927, 1928, 1929, 1934, - 1937, 1938, 1939, 1940, 1941, 1940, 1938, 1937, - 1934, 1933, 1933, 1932, 1930, 1928, 1927, 1928, - 1928, 1928, 1930, 1934, 1936, 1934, 1936, 1938, - 1940, 1937, 1938, 1936, 1934, 1930, 1928, 1927, - 1929, 1928, 1925, 1928, 1930, 1932, 1936, 1940, - 1942, 1944, 1944, 1940, 1944, 1943, 1944, 1942, - 1941, 1941, 1942, 1941, 1943, 1944, 1946, 1950, - 1950, 1953, 1950, 1949, 1947, 1945, 1946, 1946, - 1946, 1948, 1950, 1948, 1946, 1946, 1947, 1946, - 1946, 1948, 1948, 1950, 1951, 1949, 1949, 1949, - 1948, 1944, 1942, 1946, 1945, 1946, 1944, 1949, - 1950, 1952, 1954, 1956, 1957, 1955, 1954, 1953, - 1952, 1949, 1948, 1949, 1950, 1951, 1955, 1956, - 1960, 1962, 1963, 1962, 1963, 1965, 1966, 1970, - 1970, 1969, 1967, 1964, 1962, 1959, 1958, 1957, - 1956, 1956, 1956, 1960, 1960, 1963, 1964, 1965, - 1965, 1966, 1964, 1963, 1962, 1960, 1959, 1958, - 1958, 1957, 1957, 1958, 1955, 1954, 1956, 1956, - 1956, 1957, 1957, 1958, 1959, 1959, 1957, 1958, - 1961, 1960, 1957, 1956, 1954, 1957, 1958, 1959, - 1958, 1957, 1961, 1961, 1963, 1959, 1960, 1963, - 1963, 1963, 1964, 1965, 1965, 1966, 1965, 1967, - 1965, 1967, 1968, 1966, 1971, 1971, 1970, 1969, - 1970, 1971, 1971, 1972, 1971, 1972, 1970, 1970, - 1969, 1967, 1967, 1966, 1967, 1971, 1972, 1974, - 1977, 1976, 1976, 1975, 1974, 1974, 1974, 1973, - 1971, 1972, 1973, 1973, 1973, 1974, 1974, 1975, - 1977, 1979, 1979, 1977, 1979, 1980, 1978, 1978, - 1976, 1976, 1975, 1975, 1974, 1973, 1971, 1974, - 1976, 1977, 1978, 1977, 1977, 1976, 1980, 1981, - 1977, 1977, 1977, 1976, 1975, 1977, 1975, 1974, - 1969, 1970, 1969, 1969, 1965, 1965, 1965, 1966, - 1968, 1967, 1970, 1971, 1972, 1973, 1974, 1973, - 1972, 1975, 1978, 1977, 1976, 1976, 1978, 1978, - 1979, 1981, 1980, 1980, 1981, 1980, 1981, 1980, - 1980, 1981, 1979, 1979, 1977, 1979, 1980, 1982, - 1983, 1984, 1985, 1987, 1992, 1994, 1996, 1997, - 1993, 1992, 1990, 1990, 1989, 1989, 1987, 1987, - 1988, 1986, 1988, 1992, 1993, 1993, 1993, 1994, - 1994, 1997, 1999, 2001, 2003, 2000, 1999, 1996, - 1997, 1996, 1996, 1995, 1996, 1996, 1994, 1994, - 1995, 1998, 1999, 2000, 2001, 2001, 2001, 2001, - 1999, 2001, 2004, 2003, 2006, 2008, 2005, 2007, - 2008, 2007, 2005, 2005, 2001, 2001, 2002, 2000, - 2001, 2002, 2000, 2001, 2003, 2001, 1997, 1994, - 1995, 1999, 2001, 2003, 2008, 2005, 2003, 2002, - 2001, 2001, 2000, 1999, 2000, 2001, 1998, 1997, - 1997, 1996, 1996, 1994, 1994, 1995, 1995, 1997, - 1996, 1996, 1999, 2001, 2001, 2003, 2006, 2004, - 2005, 2003, 2004, 2000, 1999, 1997, 1997, 1997, - 1994, 1994, 1993, 1993, 1994, 1996, 1995, 1994, - 1992, 1993, 1991, 1991, 1990, 1992, 1991, 1987, - 1986, 1986, 1985, 1984, 1986, 1982, 1980, 1979, - 1976, 1978, 1973, 1977, 1978, 1978, 1979, 1980, - 1981, 1981, 1983, 1982, 1983, 1985, 1982, 1985, - 1985, 1983, 1982, 1980, 1980, 1982, 1981, 1984, - 1986, 1986, 1986, 1986, 1984, 1982, 1984, 1987, - 1988, 1990, 1990, 1988, 1986, 1985, 1985, 1984, - 1983, 1983, 1984, 1986, 1986, 1986, 1986, 1986, - 1985, 1985, 1984, 1987, 1987, 1988, 1985, 1983, - 1981, 1979, 1980, 1976, 1974, 1977, 1978, 1979, - 1981, 1981, 1980, 1981, 1980, 1983, 1985, 1987, - 1986, 1984, 1983, 1981, 1980, 1978, 1980, 1978, - 1979, 1979, 1975, 1975, 1975, 1973, 1972, 1971, - 1971, 1969, 1971, 1970, 1970, 1969, 1966, 1964, - 1964, 1964, 1965, 1966, 1968, 1968, 1966, 1968, - 1967, 1967, 1968, 1964, 1962, 1964, 1962, 1963, - 1960, 1960, 1959, 1961, 1964, 1963, 1966, 1966, - 1968, 1969, 1971, 1968, 1967, 1969, 1969, 1969, - 1970, 1968, 1966, 1964, 1966, 1964, 1962, 1964, - 1964, 1962, 1961, 1961, 1958, 1957, 1958, 1958, - 1959, 1957, 1956, 1958, 1958, 1959, 1960, 1960, - 1961, 1960, 1961, 1958, 1958, 1956, 1955, 1954, - 1951, 1949, 1948, 1950, 1951, 1952, 1953, 1954, - 1955, 1955, 1956, 1957, 1958, 1956, 1954, 1954, - 1954, 1951, 1948, 1946, 1946, 1946, 1945, 1946, - 1946, 1946, 1946, 1946, 1946, 1946, 1945, 1943, - 1945, 1944, 1941, 1940, 1939, 1941, 1941, 1938, - 1939, 1941, 1944, 1941, 1941, 1939, 1938, 1939, - 1936, 1931, 1931, 1933, 1932, 1932, 1931, 1932, - 1933, 1933, 1934, 1934, 1936, 1937, 1934, 1935, - 1933, 1932, 1931, 1930, 1928, 1927, 1927, 1927, - 1928, 1930, 1928, 1928, 1930, 1930, 1930, 1930, - 1930, 1929, 1927, 1925, 1924, 1922, 1922, 1923, - 1918, 1917, 1915, 1916, 1917, 1916, 1916, 1915, - 1914, 1915, 1917, 1918, 1920, 1918, 1916, 1917, - 1916, 1914, 1912, 1913, 1914, 1913, 1914, 1914, - 1912, 1909, 1908, 1910, 1912, 1912, 1913, 1914, - 1914, 1913, 1912, 1914, 1914, 1915, 1914, 1913, - 1912, 1910, 1910, 1909, 1905, 1906, 1910, 1910, - 1910, 1906, 1908, 1905, 1903, 1906, 1908, 1908, - 1909, 1910, 1906, 1905, 1905, 1905, 1905, 1905, - 1907, 1907, 1908, 1910, 1911, 1911, 1909, 1910, - 1910, 1909, 1907, 1905, 1903, 1903, 1904, 1905, - 1907, 1905, 1905, 1906, 1906, 1907, 1909, 1909, - 1911, 1911, 1911, 1910, 1910, 1907, 1907, 1907, - 1906, 1905, 1903, 1902, 1905, 1903, 1906, 1907, - 1907, 1909, 1907, 1908, 1910, 1907, 1907, 1908, - 1908, 1905, 1904, 1903, 1903, 1903, 1904, 1905, - 1907, 1908, 1907, 1907, 1906, 1904, 1907, 1905, - 1905, 1906, 1903, 1902, 1901, 1901, 1901, 1898, - 1896, 1895, 1895, 1895, 1894, 1896, 1897, 1900, - 1896, 1896, 1898, 1897, 1898, 1901, 1900, 1899, - 1901, 1901, 1901, 1899, 1899, 1899, 1898, 1901, - 1903, 1904, 1904, 1905, 1906, 1905, 1903, 1903, - 1907, 1906, 1907, 1908, 1908, 1911, 1909, 1908, - 1911, 1911, 1913, 1916, 1917, 1915, 1915, 1913, - 1913, 1912, 1913, 1915, 1915, 1914, 1916, 1915, - 1917, 1918, 1916, 1918, 1920, 1920, 1922, 1921, - 1922, 1920, 1919, 1916, 1916, 1917, 1917, 1917, - 1918, 1921, 1920, 1921, 1919, 1920, 1922, 1921, - 1920, 1922, 1922, 1922, 1921, 1918, 1918, 1918, - 1919, 1919, 1919, 1919, 1919, 1920, 1920, 1925, - 1925, 1923, 1922, 1922, 1922, 1923, 1922, 1923, - 1922, 1919, 1919, 1919, 1919, 1920, 1919, 1921, - 1921, 1921, 1920, 1921, 1920, 1921, 1921, 1920, - 1921, 1924, 1924, 1923, 1922, 1923, 1921, 1923, - 1923, 1922, 1923, 1922, 1923, 1920, 1917, 1918, - 1916, 1917, 1921, 1922, 1922, 1923, 1925, 1925, - 1926, 1925, 1928, 1926, 1925, 1928, 1927, 1926, - 1926, 1925, 1925, 1925, 1922, 1923, 1923, 1925, - 1927, 1925, 1924, 1925, 1926, 1926, 1924, 1926, - 1924, 1922, 1925, 1925, 1925, 1925, 1925, 1926, - 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1926, - 1927, 1926, 1926, 1926, 1926, 1926, 1927, 1926, - 1924, 1927, 1927, 1929, 1928, 1926, 1926, 1926, - 1925, 1926, 1926, 1927, 1931, 1932, 1932, 1932, - 1933, 1931, 1931, 1931, 1929, 1928, 1928, 1930, - 1931, 1931, 1931, 1931, 1931, 1929, 1932, 1932, - 1932, 1933, 1930, 1932, 1933, 1936, 1936, 1935, - 1933, 1932, 1930, 1931, 1931, 1932, 1932, 1932, - 1935, 1934, 1934, 1937, 1937, 1937, 1938, 1935, - 1935, 1935, 1935, 1936, 1937, 1937, 1939, 1941, - 1942, 1942, 1942, 1942, 1944, 1943, 1944, 1944, - 1943, 1943, 1944, 1946, 1949, 1949, 1947, 1947, - 1945, 1945, 1946, 1943, 1942, 1947, 1944, 1943, - 1942, 1942, 1943, 1944, 1945, 1946, 1949, 1949, - 1948, 1951, 1949, 1950, 1950, 1948, 1949, 1944, - 1945, 1946, 1946, 1946, 1944, 1945, 1949, 1950, - 1953, 1953, 1954, 1954, 1954, 1953, 1954, 1957, - 1955, 1957, 1958, 1956, 1955, 1953, 1953, 1952, - 1951, 1953, 1954, 1955, 1955, 1955, 1952, 1953, - 1954, 1951, 1953, 1952, 1953, 1956, 1957, 1957, - 1955, 1954, 1957, 1950, 1948, 1950, 1949, 1951, - 1950, 1947, 1946, 1943, 1943, 1942, 1942, 1944, - 1944, 1947, 1948, 1947, 1947, 1949, 1949, 1949, - 1951, 1950, 1946, 1945, 1945, 1945, 1942, 1939, - 1943, 1943, 1943, 1943, 1944, 1947, 1945, 1943, - 1944, 1946, 1947, 1949, 1949, 1948, 1949, 1951, - 1947, 1946, 1944, 1943, 1945, 1944, 1943, 1942, - 1940, 1940, 1939, 1940, 1941, 1939, 1939, 1939, - 1942, 1943, 1943, 1942, 1943, 1944, 1947, 1946, - 1946, 1948, 1946, 1944, 1943, 1941, 1941, 1940, - 1941, 1942, 1944, 1944, 1945, 1944, 1945, 1946, - 1943, 1945, 1945, 1946, 1944, 1945, 1945, 1947, - 1947, 1946, 1942, 1942, 1940, 1938, 1937, 1936, - 1936, 1936, 1936, 1936, 1936, 1937, 1937, 1939, - 1940, 1942, 1941, 1940, 1938, 1938, 1938, 1939, - 1938, 1935, 1936, 1935, 1934, 1934, 1933, 1934, - 1934, 1934, 1933, 1932, 1933, 1933, 1933, 1929, - 1928, 1929, 1929, 1928, 1928, 1929, 1927, 1928, - 1929, 1929, 1928, 1930, 1931, 1929, 1927, 1927, - 1925, 1926, 1926, 1928, 1928, 1927, 1925, 1923, - 1923, 1924, 1925, 1924, 1927, 1929, 1930, 1928, - 1927, 1929, 1928, 1927, 1927, 1927, 1926, 1927, - 1928, 1927, 1930, 1930, 1929, 1930, 1926, 1927, - 1929, 1932, 1933, 1933, 1931, 1929, 1927, 1927, - 1925, 1926, 1928, 1928, 1928, 1925, 1926, 1927, - 1929, 1929, 1932, 1931, 1930, 1929, 1928, 1928, - 1926, 1926, 1925, 1927, 1927, 1927, 1924, 1924, - 1923, 1923, 1922, 1923, 1925, 1921, 1921, 1920, - 1922, 1923, 1921, 1921, 1921, 1918, 1918, 1916, - 1916, 1915, 1914, 1913, 1913, 1913, 1911, 1910, - 1910, 1909, 1908, 1908, 1908, 1909, 1912, 1911, - 1909, 1909, 1907, 1908, 1910, 1907, 1907, 1906, - 1907, 1906, 1905, 1902, 1902, 1900, 1899, 1900, - 1900, 1901, 1901, 1901, 1902, 1902, 1901, 1901, - 1898, 1898, 1899, 1900, 1899, 1899, 1898, 1896, - 1895, 1895, 1893, 1892, 1893, 1890, 1890, 1889, - 1889, 1891, 1891, 1893, 1894, 1897, 1898, 1898, - 1897, 1899, 1898, 1897, 1897, 1896, 1896, 1895, - 1892, 1891, 1891, 1888, 1889, 1893, 1893, 1895, - 1895, 1896, 1899, 1902, 1900, 1899, 1899, 1900, - 1901, 1901, 1901, 1900, 1901, 1901, 1903, 1900, - 1902, 1903, 1904, 1902, 1902, 1903, 1902, 1901, - 1902, 1903, 1902, 1900, 1900, 1896, 1892, 1891, - 1897, 1899, 1902, 1908, 1907, 1914, 1916, 1917, - 1918, 1918, 1917, 1912, 1904, 1898, 1891, 1886, - 1885, 1884, 1886, 1885, 1888, 1894, 1900, 1911, - 1917, 1923, 1927, 1931, 1930, 1927, 1920, 1915, - 1911, 1902, 1894, 1887, 1883, 1883, 1887, 1891, - 1894, 1900, 1906, 1915, 1922, 1925, 1930, 1931, - 1931, 1925, 1921, 1915, 1907, 1901, 1898, 1895, - 1891, 1893, 1897, 1901, 1905, 1912, 1921, 1923, - 1929, 1934, 1936, 1937, 1934, 1932, 1928, 1924, - 1918, 1915, 1910, 1908, 1908, 1910, 1910, 1910, - 1914, 1918, 1922, 1925, 1928, 1927, 1929, 1927, - 1930, 1929, 1928, 1927, 1924, 1922, 1921, 1921, - 1921, 1921, 1918, 1918, 1920, 1920, 1920, 1920, - 1922, 1927, 1931, 1930, 1932, 1933, 1933, 1937, - 1935, 1935, 1935, 1932, 1930, 1929, 1928, 1926, - 1926, 1926, 1927, 1928, 1930, 1933, 1936, 1939, - 1941, 1945, 1945, 1947, 1946, 1942, 1939, 1935, - 1932, 1929, 1928, 1928, 1927, 1929, 1931, 1935, - 1936, 1938, 1939, 1942, 1945, 1946, 1949, 1949, - 1946, 1946, 1943, 1939, 1937, 1934, 1935, 1934, - 1934, 1934, 1933, 1935, 1938, 1940, 1942, 1942, - 1944, 1943, 1944, 1943, 1944, 1944, 1943, 1943, - 1942, 1941, 1941, 1941, 1941, 1941, 1942, 1943, - 1942, 1943, 1945, 1946, 1947, 1947, 1948, 1950, - 1949, 1948, 1947, 1945, 1947, 1949, 1949, 1948, - 1950, 1952, 1948, 1950, 1954, 1952, 1952, 1955, - 1955, 1956, 1956, 1955, 1957, 1956, 1956, 1957, - 1960, 1958, 1959, 1960, 1959, 1960, 1963, 1964, - 1963, 1963, 1962, 1964, 1964, 1964, 1964, 1965, - 1967, 1967, 1966, 1964, 1965, 1962, 1961, 1961, - 1962, 1960, 1962, 1961, 1961, 1962, 1963, 1966, - 1968, 1969, 1967, 1968, 1967, 1967, 1966, 1967, - 1969, 1967, 1968, 1966, 1967, 1967, 1968, 1966, - 1966, 1969, 1970, 1973, 1972, 1974, 1978, 1976, - 1976, 1977, 1979, 1978, 1975, 1974, 1972, 1972, - 1971, 1969, 1969, 1970, 1971, 1972, 1974, 1976, - 1979, 1980, 1979, 1980, 1981, 1982, 1982, 1982, - 1980, 1978, 1980, 1980, 1978, 1976, 1977, 1979, - 1979, 1977, 1978, 1979, 1981, 1982, 1986, 1987, - 1988, 1989, 1989, 1994, 1993, 1995, 1994, 1993, - 1993, 1994, 1997, 1997, 1995, 1993, 1993, 1993, - 1995, 1995, 1997, 1996, 2000, 2002, 2001, 2001, - 2000, 2002, 2002, 2001, 2000, 2001, 2001, 2000, - 2001, 1998, 1998, 1998, 1998, 1997, 1997, 1998, - 1996, 1996, 1997, 1998, 2000, 1999, 2000, 2000, - 2000, 2003, 2002, 2001, 2001, 2002, 2004, 2005, - 2002, 2001, 2001, 2001, 2001, 1998, 2000, 1999, - 2000, 2000, 1998, 1999, 2001, 2000, 2002, 2004, - 2005, 2007, 2006, 2006, 2004, 2004, 2004, 2003, - 2003, 2001, 2001, 2000, 2000, 1999, 1999, 1998, - 1996, 1998, 1998, 1998, 1996, 1997, 1996, 1994, - 1995, 1995, 1994, 1997, 1997, 1997, 2002, 2002, - 2000, 2000, 1999, 2000, 1998, 2000, 2001, 2001, - 2001, 1999, 1998, 1998, 1999, 1999, 1999, 2000, - 2003, 2006, 2006, 2008, 2006, 2004, 2006, 2007, - 2008, 2007, 2007, 2006, 2005, 2007, 2006, 2010, - 2009, 2007, 2008, 2010, 2011, 2011, 2012, 2013, - 2012, 2014, 2011, 2012, 2014, 2013, 2015, 2013, - 2015, 2013, 2012, 2014, 2014, 2012, 2013, 2010, - 2010, 2012, 2013, 2014, 2014, 2011, 2013, 2014, - 2013, 2011, 2010, 2011, 2009, 2009, 2008, 2008, - 2007, 2006, 2005, 2005, 2004, 2005, 2005, 2004, - 2004, 2003, 2003, 2004, 2006, 2007, 2008, 2007, - 2008, 2010, 2011, 2009, 2008, 2006, 2007, 2007, - 2007, 2005, 2005, 2006, 2005, 2007, 2009, 2008, - 2008, 2008, 2008, 2007, 2006, 2004, 2004, 2005, - 2004, 2004, 2003, 2003, 2002, 2002, 2001, 2000, - 2000, 1999, 2000, 1997, 2000, 2000, 1999, 1999, - 2000, 2002, 2002, 2004, 2003, 2003, 2003, 2003, - 2002, 2003, 2006, 2007, 2007, 2009, 2007, 2006, - 2005, 2005, 2004, 2002, 2001, 2001, 2002, 2000, - 1999, 1996, 1999, 2000, 1999, 2001, 2001, 2000, - 1998, 2000, 2001, 2001, 2001, 2001, 2000, 1999, - 1998, 1998, 2000, 2000, 2000, 1999, 1998, 1996, - 1994, 1992, 1992, 1993, 1994, 1993, 1995, 1994, - 1993, 1998, 1999, 1996, 1994, 1995, 1995, 1996, - 1994, 1994, 1995, 1995, 1994, 1994, 1992, 1992, - 1993, 1992, 1992, 1993, 1994, 1994, 1994, 1996, - 1996, 1996, 1996, 1996, 1995, 1997, 1997, 1998, - 2001, 2000, 2000, 1998, 1999, 2000, 1999, 2000, - 1999, 1998, 1998, 1997, 1999, 2001, 2000, 2000, - 2001, 1998, 1998, 1997, 1998, 1998, 1998, 1998, - 1998, 1997, 1994, 1995, 1997, 1997, 1995, 1996, - 1995, 1993, 1995, 1994, 1997, 1995, 1995, 1994, - 1997, 1997, 1996, 1998, 1999, 1998, 1997, 1999, - 1999, 1999, 1999, 1998, 1997, 1995, 1998, 1999, - 1999, 1997, 1998, 1999, 1998, 1999, 2000, 2000, - 1998, 1998, 1997, 1992, 1994, 1996, 1993, 1994, - 1993, 1995, 1995, 1997, 1994, 1995, 1995, 1995, - 1994, 1993, 1993, 1992, 1991, 1993, 1992, 1993, - 1992, 1991, 1993, 1991, 1992, 1992, 1991, 1992, - 1989, 1990, 1990, 1992, 1990, 1991, 1991, 1991, - 1989, 1991, 1989, 1990, 1989, 1990, 1991, 1990, - 1990, 1990, 1990, 1990, 1991, 1993, 1991, 1991, - 1991, 1992, 1993, 1994, 1993, 1994, 1994, 1994, - 1995, 1995, 2000, 2000, 1999, 2001, 2000, 1997, - 1999, 1998, 1996, 1997, 1996, 1996, 1996, 1995, - 1997, 1997, 1997, 1996, 1995, 1997, 1997, 1999, - 1999, 2000, 1999, 1999, 2000, 2001, 2000, 2002, - 2005, 2004, 2007, 2006, 2006, 2005, 2005, 2006, - 2006, 2008, 2007, 2008, 2009, 2009, 2011, 2013, - 2013, 2013, 2017, 2017, 2019, 2020, 2019, 2021, - 2021, 2021, 2022, 2022, 2023, 2022, 2024, 2023, - 2027, 2025, 2027, 2027, 2026, 2029, 2029, 2027, - 2029, 2030, 2029, 2029, 2031, 2029, 2028, 2030, - 2029, 2033, 2032, 2035, 2032, 2031, 2032, 2027, - 2031, 2030, 2029, 2030, 2030, 2029, 2030, 2034, - 2033, 2033, 2036, 2038, 2038, 2039, 2038, 2040, - 2040, 2041, 2040, 2040, 2039, 2040, 2040, 2043, - 2044, 2044, 2044, 2044, 2045, 2047, 2045, 2047, - 2048, 2047, 2048, 2048, 2049, 2051, 2051, 2051, - 2051, 2054, 2052, 2049, 2051, 2051, 2049, 2050, - 2050, 2050, 2052, 2050, 2052, 2052, 2051, 2051, - 2051, 2050, 2051, 2050, 2052, 2053, 2053, 2052, - 2054, 2053, 2052, 2053, 2054, 2052, 2056, 2057, - 2057, 2056, 2057, 2056, 2056, 2057, 2057, 2056, - 2056, 2056, 2059, 2058, 2058, 2059, 2059, 2059, - 2059, 2061, 2059, 2059, 2059, 2062, 2062, 2061, - 2062, 2061, 2062, 2063, 2063, 2064, 2064, 2064, - 2064, 2062, 2061, 2061, 2061, 2061, 2059, 2058, - 2059, 2061, 2062, 2059, 2059, 2061, 2060, 2059, - 2060, 2060, 2062, 2062, 2064, 2067, 2064, 2066, - 2067, 2066, 2066, 2066, 2067, 2067, 2066, 2066, - 2066, 2066, 2069, 2068, 2066, 2069, 2067, 2067, - 2069, 2069, 2070, 2069, 2071, 2072, 2074, 2072, - 2071, 2073, 2073, 2073, 2071, 2073, 2076, 2073, - 2071, 2072, 2074, 2072, 2075, 2073, 2074, 2077, - 2079, 2080, 2081, 2084, 2083, 2083, 2082, 2086, - 2087, 2086, 2086, 2086, 2088, 2089, 2088, 2088, - 2088, 2088, 2090, 2090, 2090, 2090, 2093, 2093, - 2093, 2094, 2093, 2097, 2098, 2096, 2096, 2094, - 2095, 2096, 2096, 2092, 2095, 2097, 2094, 2096, - 2095, 2097, 2097, 2095, 2095, 2097, 2097, 2097, - 2095, 2094, 2097, 2097, 2098, 2097, 2096, 2096, - 2096, 2099, 2100, 2100, 2098, 2099, 2099, 2099, - 2102, 2104, 2103, 2103, 2105, 2104, 2105, 2104, - 2106, 2107, 2107, 2106, 2107, 2109, 2110, 2110, - 2111, 2113, 2115, 2113, 2114, 2116, 2114, 2116, - 2113, 2114, 2112, 2112, 2112, 2111, 2114, 2114, - 2112, 2112, 2112, 2115, 2116, 2115, 2114, 2112, - 2113, 2114, 2114, 2114, 2114, 2114, 2114, 2112, - 2113, 2115, 2113, 2115, 2114, 2115, 2117, 2115, - 2116, 2116, 2117, 2118, 2116, 2116, 2117, 2117, - 2117, 2118, 2118, 2120, 2121, 2120, 2117, 2116, - 2118, 2120, 2121, 2120, 2120, 2122, 2121, 2124, - 2122, 2120, 2123, 2121, 2121, 2123, 2121, 2121, - 2121, 2119, 2119, 2118, 2115, 2117, 2119, 2117, - 2116, 2115, 2115, 2115, 2114, 2113, 2112, 2113, - 2111, 2111, 2111, 2112, 2110, 2111, 2111, 2111, - 2111, 2111, 2112, 2111, 2111, 2112, 2111, 2110, - 2111, 2113, 2113, 2111, 2111, 2109, 2110, 2109, - 2107, 2109, 2110, 2112, 2111, 2112, 2109, 2109, - 2110, 2110, 2109, 2112, 2112, 2110, 2108, 2108, - 2108, 2109, 2107, 2108, 2112, 2111, 2109, 2108, - 2109, 2111, 2112, 2108, 2106, 2107, 2108, 2107, - 2107, 2106, 2106, 2107, 2107, 2107, 2107, 2109, - 2109, 2112, 2111, 2108, 2106, 2108, 2108, 2105, - 2106, 2107, 2106, 2107, 2105, 2104, 2105, 2105, - 2104, 2104, 2103, 2102, 2101, 2100, 2098, 2099, - 2098, 2098, 2098, 2097, 2099, 2099, 2097, 2094, - 2095, 2097, 2094, 2094, 2090, 2092, 2093, 2093, - 2094, 2094, 2094, 2093, 2094, 2094, 2094, 2093, - 2090, 2093, 2092, 2089, 2092, 2091, 2092, 2088, - 2088, 2090, 2088, 2087, 2087, 2088, 2087, 2088, - 2086, 2087, 2087, 2088, 2089, 2085, 2085, 2086, - 2088, 2087, 2086, 2088, 2087, 2085, 2085, 2086, - 2087, 2086, 2085, 2084, 2085, 2085, 2087, 2089, - 2091, 2091, 2086, 2086, 2085, 2083, 2083, 2082, - 2081, 2084, 2085, 2085, 2082, 2081, 2082, 2080, - 2082, 2084, 2082, 2082, 2082, 2079, 2080, 2080, - 2079, 2078, 2077, 2076, 2076, 2075, 2076, 2076, - 2077, 2074, 2077, 2077, 2075, 2075, 2075, 2074, - 2074, 2074, 2075, 2075, 2072, 2073, 2071, 2072, - 2072, 2070, 2070, 2068, 2070, 2068, 2069, 2068, - 2067, 2068, 2069, 2066, 2063, 2065, 2067, 2065, - 2065, 2065, 2064, 2064, 2062, 2063, 2062, 2061, - 2061, 2060, 2063, 2060, 2059, 2058, 2055, 2058, - 2059, 2059, 2061, 2058, 2057, 2057, 2058, 2058, - 2058, 2057, 2056, 2054, 2054, 2055, 2056, 2058, - 2058, 2058, 2054, 2058, 2060, 2059, 2056, 2056, - 2055, 2056, 2058, 2057, 2057, 2057, 2056, 2056, - 2057, 2058, 2058, 2058, 2058, 2058, 2058, 2058, - 2059, 2059, 2059, 2060, 2061, 2060, 2059, 2059, - 2060, 2061, 2062, 2063, 2065, 2063, 2062, 2061, - 2062, 2063, 2064, 2064, 2061, 2061, 2062, 2065, - 2067, 2065, 2068, 2065, 2066, 2066, 2066, 2067, - 2068, 2069, 2070, 2068, 2068, 2068, 2066, 2066, - 2066, 2068, 2070, 2068, 2071, 2070, 2068, 2067, - 2066, 2068, 2069, 2068, 2067, 2069, 2067, 2067, - 2070, 2069, 2068, 2067, 2066, 2066, 2068, 2069, - 2069, 2069, 2069, 2071, 2071, 2069, 2070, 2070, - 2067, 2070, 2072, 2073, 2074, 2073, 2068, 2069, - 2071, 2073, 2075, 2077, 2080, 2078, 2079, 2078, - 2078, 2078, 2078, 2077, 2076, 2078, 2076, 2079, - 2079, 2079, 2078, 2079, 2080, 2079, 2081, 2080, - 2082, 2084, 2084, 2085, 2085, 2086, 2088, 2089, - 2087, 2087, 2088, 2090, 2090, 2090, 2091, 2092, - 2093, 2093, 2092, 2094, 2093, 2095, 2093, 2093, - 2093, 2094, 2093, 2095, 2096, 2097, 2095, 2092, - 2097, 2093, 2093, 2094, 2096, 2095, 2092, 2092, - 2093, 2093, 2093, 2095, 2093, 2092, 2092, 2090, - 2090, 2091, 2091, 2092, 2094, 2095, 2096, 2094, - 2096, 2097, 2094, 2097, 2096, 2094, 2096, 2096, - 2096, 2097, 2097, 2097, 2094, 2095, 2097, 2098, - 2100, 2099, 2099, 2099, 2098, 2100, 2100, 2097, - 2099, 2100, 2101, 2100, 2100, 2102, 2102, 2100, - 2100, 2100, 2102, 2103, 2106, 2104, 2102, 2101, - 2101, 2101, 2099, 2100, 2102, 2103, 2103, 2103, - 2102, 2101, 2103, 2105, 2104, 2106, 2104, 2105, - 2105, 2105, 2105, 2102, 2101, 2102, 2103, 2103, - 2103, 2102, 2101, 2102, 2103, 2101, 2105, 2102, - 2103, 2104, 2104, 2103, 2104, 2104, 2103, 2105, - 2103, 2102, 2103, 2103, 2105, 2104, 2101, 2100, - 2099, 2099, 2100, 2101, 2101, 2099, 2100, 2100, - 2101, 2103, 2104, 2104, 2105, 2103, 2103, 2104, - 2103, 2103, 2102, 2100, 2100, 2101, 2101, 2100, - 2101, 2099, 2098, 2099, 2099, 2102, 2101, 2099, - 2099, 2098, 2100, 2103, 2103, 2104, 2107, 2106, - 2108, 2107, 2105, 2107, 2104, 2104, 2105, 2105, - 2104, 2104, 2107, 2107, 2107, 2108, 2107, 2108, - 2108, 2109, 2110, 2111, 2112, 2111, 2110, 2110, - 2111, 2110, 2111, 2112, 2113, 2114, 2114, 2112, - 2112, 2112, 2116, 2116, 2115, 2116, 2116, 2118, - 2119, 2120, 2119, 2121, 2122, 2120, 2122, 2125, - 2125, 2124, 2124, 2125, 2124, 2123, 2123, 2123, - 2121, 2122, 2122, 2125, 2124, 2123, 2124, 2126, - 2123, 2125, 2126, 2126, 2125, 2125, 2124, 2125, - 2125, 2124, 2126, 2126, 2127, 2127, 2125, 2127, - 2126, 2128, 2128, 2126, 2127, 2129, 2129, 2131, - 2131, 2131, 2131, 2132, 2130, 2130, 2132, 2132, - 2132, 2130, 2132, 2132, 2134, 2136, 2136, 2137, - 2139, 2138, 2138, 2136, 2136, 2136, 2135, 2132, - 2133, 2132, 2133, 2133, 2132, 2134, 2132, 2133, - 2136, 2131, 2132, 2133, 2133, 2135, 2134, 2134, - 2133, 2132, 2132, 2133, 2135, 2133, 2133, 2132, - 2133, 2133, 2133, 2134, 2135, 2136, 2135, 2133, - 2135, 2137, 2136, 2136, 2137, 2136, 2139, 2138, - 2137, 2138, 2137, 2139, 2138, 2138, 2139, 2139, - 2137, 2137, 2139, 2136, 2132, 2134, 2134, 2132, - 2130, 2132, 2132, 2129, 2128, 2126, 2126, 2128, - 2129, 2128, 2127, 2128, 2128, 2127, 2129, 2130, - 2130, 2128, 2128, 2128, 2129, 2129, 2131, 2132, - 2130, 2128, 2129, 2130, 2128, 2127, 2128, 2128, - 2128, 2128, 2129, 2131, 2131, 2132, 2132, 2132, - 2131, 2132, 2131, 2130, 2130, 2132, 2131, 2127, - 2130, 2127, 2127, 2127, 2128, 2124, 2123, 2124, - 2124, 2124, 2124, 2125, 2124, 2122, 2121, 2121, - 2119, 2120, 2119, 2118, 2117, 2118, 2118, 2114, - 2114, 2113, 2113, 2115, 2112, 2114, 2114, 2111, - 2111, 2111, 2111, 2109, 2110, 2110, 2109, 2108, - 2111, 2113, 2110, 2110, 2107, 2109, 2108, 2106, - 2108, 2106, 2107, 2106, 2108, 2109, 2109, 2108, - 2108, 2109, 2108, 2107, 2110, 2108, 2104, 2103, - 2105, 2106, 2104, 2104, 2103, 2103, 2102, 2102, - 2102, 2103, 2103, 2101, 2102, 2101, 2103, 2106, - 2105, 2102, 2104, 2103, 2102, 2100, 2101, 2102, - 2099, 2101, 2102, 2104, 2102, 2101, 2101, 2101, + 2041, 2039, 2039, 2037, 2035, 2037, 2037, 2037, + 2038, 2037, 2037, 2040, 2039, 2038, 2036, 2035, + 2036, 2036, 2036, 2034, 2034, 2034, 2032, 2032, + 2033, 2034, 2032, 2030, 2029, 2031, 2030, 2029, + 2029, 2030, 2029, 2030, 2030, 2031, 2028, 2028, + 2028, 2027, 2025, 2026, 2027, 2026, 2025, 2026, + 2026, 2025, 2023, 2022, 2023, 2021, 2021, 2023, + 2020, 2023, 2023, 2022, 2022, 2021, 2021, 2020, + 2022, 2020, 2017, 2016, 2015, 2018, 2017, 2015, + 2013, 2012, 2015, 2013, 2011, 2012, 2011, 2011, + 2010, 2008, 2008, 2010, 2010, 2006, 2006, 2006, + 2004, 2005, 2006, 2006, 2005, 2002, 2005, 2003, + 2003, 2004, 2002, 2001, 2003, 2003, 2002, 2003, + 2003, 2000, 2000, 2000, 1998, 1997, 1998, 1999, + 1997, 1995, 1995, 1996, 1996, 1992, 1995, 1995, + 1994, 1994, 1995, 1997, 1996, 1996, 1997, 1997, + 1997, 1996, 1996, 1995, 1997, 1997, 1996, 1998, + 1995, 1996, 1996, 1996, 1996, 1994, 1990, 1991, + 1992, 1991, 1994, 1992, 1993, 1995, 1994, 1995, + 1992, 1991, 1991, 1992, 1993, 1992, 1992, 1993, + 1993, 1992, 1990, 1989, 1991, 1992, 1991, 1991, + 1990, 1990, 1992, 1992, 1991, 1992, 1992, 1994, + 1992, 1992, 1992, 1993, 1993, 1994, 1995, 1993, + 1991, 1992, 1990, 1989, 1990, 1988, 1988, 1987, + 1989, 1989, 1985, 1986, 1987, 1985, 1986, 1986, + 1987, 1988, 1988, 1989, 1989, 1988, 1988, 1990, + 1991, 1991, 1990, 1991, 1992, 1994, 1994, 1995, + 1994, 1995, 1997, 1995, 1995, 1995, 1997, 1997, + 1997, 1996, 1999, 2000, 1997, 1998, 1999, 2002, + 2001, 2001, 2001, 2002, 2000, 1998, 2000, 2004, + 2002, 2001, 2003, 2005, 2004, 2004, 2002, 2004, + 2004, 2001, 2000, 2001, 2003, 2005, 2005, 2005, + 2005, 2006, 2010, 2010, 2009, 2007, 2006, 2008, + 2006, 2007, 2007, 2005, 2005, 2005, 2007, 2005, + 2006, 2007, 2009, 2010, 2008, 2007, 2006, 2006, + 2005, 2005, 2005, 2004, 2005, 2004, 2004, 2003, + 2007, 2006, 2006, 2004, 2005, 2006, 2007, 2007, + 2006, 2010, 2007, 2008, 2009, 2012, 2012, 2010, + 2011, 2010, 2014, 2012, 2013, 2013, 2014, 2014, + 2013, 2012, 2012, 2012, 2010, 2013, 2012, 2010, + 2011, 2011, 2012, 2012, 2013, 2013, 2015, 2016, + 2015, 2015, 2015, 2015, 2015, 2014, 2012, 2014, + 2016, 2017, 2016, 2015, 2018, 2019, 2017, 2017, + 2017, 2017, 2016, 2016, 2017, 2017, 2018, 2021, + 2020, 2019, 2019, 2022, 2022, 2024, 2024, 2023, + 2023, 2023, 2024, 2025, 2026, 2025, 2024, 2025, + 2025, 2026, 2026, 2023, 2023, 2023, 2023, 2023, + 2023, 2024, 2024, 2025, 2024, 2022, 2022, 2021, + 2021, 2022, 2022, 2024, 2023, 2023, 2023, 2021, + 2023, 2023, 2024, 2024, 2025, 2024, 2026, 2027, + 2025, 2026, 2028, 2026, 2027, 2027, 2025, 2024, + 2027, 2028, 2027, 2028, 2027, 2027, 2028, 2028, + 2030, 2029, 2032, 2031, 2030, 2029, 2028, 2030, + 2027, 2028, 2028, 2028, 2026, 2027, 2028, 2027, + 2029, 2032, 2030, 2030, 2032, 2033, 2030, 2030, + 2032, 2030, 2030, 2030, 2032, 2032, 2033, 2031, + 2034, 2032, 2029, 2028, 2028, 2030, 2028, 2029, + 2030, 2028, 2029, 2029, 2029, 2030, 2032, 2033, + 2031, 2036, 2034, 2032, 2032, 2031, 2032, 2031, + 2032, 2033, 2035, 2033, 2032, 2034, 2035, 2036, + 2037, 2038, 2039, 2038, 2038, 2038, 2040, 2040, + 2041, 2041, 2041, 2043, 2041, 2041, 2043, 2043, + 2041, 2040, 2042, 2042, 2042, 2044, 2044, 2041, + 2042, 2043, 2042, 2044, 2043, 2044, 2044, 2045, + 2045, 2044, 2045, 2044, 2045, 2043, 2042, 2043, + 2043, 2043, 2043, 2044, 2044, 2044, 2045, 2044, + 2044, 2043, 2042, 2045, 2046, 2045, 2046, 2048, + 2048, 2046, 2046, 2046, 2049, 2048, 2050, 2049, + 2049, 2050, 2053, 2051, 2049, 2050, 2047, 2050, + 2048, 2052, 2050, 2051, 2053, 2051, 2051, 2048, + 2051, 2050, 2049, 2051, 2052, 2051, 2050, 2051, + 2050, 2050, 2051, 2050, 2048, 2049, 2049, 2048, + 2050, 2050, 2050, 2049, 2048, 2048, 2048, 2048, + 2049, 2049, 2049, 2050, 2051, 2050, 2053, 2051, + 2051, 2053, 2052, 2052, 2052, 2051, 2053, 2055, + 2056, 2056, 2055, 2056, 2056, 2056, 2059, 2058, + 2055, 2057, 2059, 2057, 2056, 2056, 2056, 2057, + 2059, 2060, 2060, 2059, 2059, 2059, 2059, 2061, + 2059, 2059, 2060, 2061, 2059, 2057, 2058, 2060, + 2060, 2061, 2060, 2061, 2062, 2063, 2062, 2060, + 2062, 2060, 2061, 2061, 2060, 2060, 2061, 2062, + 2062, 2062, 2061, 2059, 2062, 2063, 2062, 2063, + 2063, 2063, 2063, 2063, 2063, 2063, 2065, 2063, + 2063, 2065, 2065, 2066, 2065, 2067, 2067, 2066, + 2065, 2065, 2065, 2066, 2066, 2063, 2064, 2062, + 2063, 2062, 2062, 2061, 2062, 2063, 2062, 2061, + 2061, 2062, 2058, 2059, 2061, 2062, 2062, 2062, + 2062, 2064, 2063, 2063, 2062, 2061, 2061, 2063, + 2060, 2059, 2059, 2058, 2059, 2059, 2059, 2062, + 2063, 2063, 2062, 2061, 2061, 2061, 2061, 2062, + 2060, 2058, 2059, 2060, 2060, 2059, 2059, 2057, + 2059, 2059, 2056, 2057, 2056, 2057, 2056, 2056, + 2056, 2057, 2057, 2057, 2055, 2055, 2055, 2053, + 2054, 2054, 2054, 2054, 2052, 2051, 2054, 2055, + 2055, 2053, 2055, 2054, 2055, 2055, 2053, 2053, + 2054, 2052, 2051, 2053, 2051, 2052, 2052, 2054, + 2054, 2053, 2051, 2051, 2053, 2052, 2051, 2050, + 2049, 2049, 2048, 2049, 2049, 2047, 2046, 2047, + 2047, 2047, 2046, 2048, 2046, 2046, 2046, 2044, + 2043, 2044, 2045, 2046, 2043, 2044, 2043, 2046, + 2044, 2044, 2043, 2043, 2042, 2039, 2037, 2039, + 2038, 2039, 2039, 2038, 2038, 2038, 2039, 2036, + 2034, 2034, 2033, 2035, 2034, 2032, 2031, 2034, + 2035, 2033, 2034, 2032, 2032, 2033, 2031, 2031, + 2031, 2032, 2032, 2032, 2030, 2030, 2029, 2029, + 2029, 2025, 2024, 2024, 2024, 2025, 2025, 2028, + 2028, 2025, 2024, 2026, 2025, 2022, 2023, 2021, + 2018, 2019, 2020, 2020, 2020, 2021, 2021, 2018, + 2017, 2019, 2017, 2016, 2018, 2019, 2018, 2016, + 2017, 2016, 2014, 2017, 2017, 2017, 2016, 2014, + 2012, 2011, 2011, 2011, 2011, 2012, 2011, 2009, + 2011, 2011, 2011, 2012, 2009, 2009, 2010, 2011, + 2011, 2011, 2008, 2008, 2010, 2009, 2009, 2008, + 2007, 2010, 2009, 2011, 2012, 2011, 2012, 2012, + 2010, 2010, 2011, 2009, 2010, 2010, 2010, 2012, + 2011, 2011, 2011, 2010, 2010, 2009, 2012, 2008, + 2009, 2010, 2010, 2008, 2008, 2009, 2007, 2007, + 2007, 2007, 2009, 2008, 2006, 2006, 2010, 2011, + 2011, 2009, 2010, 2007, 2008, 2007, 2009, 2011, + 2009, 2009, 2008, 2009, 2009, 2009, 2007, 2010, + 2008, 2009, 2013, 2011, 2011, 2009, 2010, 2009, + 2007, 2007, 2008, 2008, 2009, 2010, 2008, 2009, + 2009, 2010, 2010, 2010, 2009, 2007, 2008, 2007, + 2011, 2012, 2010, 2009, 2009, 2010, 2008, 2010, + 2011, 2010, 2010, 2012, 2011, 2010, 2013, 2014, + 2013, 2014, 2016, 2015, 2016, 2017, 2016, 2020, + 2022, 2022, 2020, 2022, 2023, 2024, 2023, 2022, + 2021, 2020, 2023, 2022, 2023, 2022, 2023, 2024, + 2022, 2021, 2021, 2021, 2021, 2021, 2021, 2023, + 2024, 2024, 2022, 2022, 2023, 2026, 2027, 2024, + 2025, 2029, 2027, 2029, 2030, 2029, 2029, 2028, + 2029, 2029, 2028, 2031, 2031, 2029, 2027, 2026, + 2026, 2028, 2025, 2025, 2021, 2022, 2025, 2025, + 2028, 2026, 2025, 2025, 2023, 2024, 2024, 2027, + 2027, 2029, 2028, 2025, 2027, 2029, 2031, 2028, + 2026, 2028, 2028, 2028, 2028, 2030, 2026, 2028, + 2029, 2029, 2030, 2030, 2030, 2032, 2032, 2032, + 2031, 2030, 2031, 2031, 2033, 2035, 2033, 2032, + 2031, 2032, 2032, 2032, 2032, 2031, 2030, 2030, + 2028, 2030, 2029, 2027, 2029, 2028, 2027, 2029, + 2032, 2031, 2031, 2032, 2030, 2029, 2032, 2033, + 2032, 2027, 2026, 2029, 2030, 2031, 2033, 2033, + 2033, 2035, 2035, 2034, 2035, 2034, 2035, 2036, + 2037, 2035, 2035, 2034, 2034, 2034, 2037, 2036, + 2035, 2033, 2033, 2034, 2033, 2035, 2035, 2036, + 2038, 2037, 2035, 2038, 2038, 2033, 2033, 2035, + 2036, 2036, 2038, 2037, 2037, 2038, 2038, 2039, + 2039, 2038, 2038, 2040, 2041, 2040, 2042, 2042, + 2042, 2043, 2042, 2040, 2041, 2040, 2041, 2043, + 2040, 2042, 2042, 2041, 2044, 2045, 2043, 2043, + 2045, 2045, 2047, 2045, 2044, 2046, 2045, 2048, + 2049, 2050, 2050, 2050, 2050, 2048, 2050, 2051, + 2050, 2050, 2052, 2053, 2053, 2055, 2054, 2053, + 2055, 2053, 2053, 2052, 2050, 2052, 2052, 2053, + 2053, 2054, 2053, 2055, 2056, 2055, 2053, 2053, + 2054, 2054, 2056, 2054, 2054, 2056, 2054, 2053, + 2054, 2057, 2055, 2054, 2056, 2057, 2056, 2058, + 2057, 2058, 2059, 2057, 2058, 2057, 2057, 2055, + 2056, 2056, 2055, 2059, 2057, 2055, 2052, 2050, + 2053, 2054, 2052, 2053, 2055, 2056, 2055, 2054, + 2055, 2055, 2053, 2053, 2053, 2054, 2055, 2055, + 2055, 2052, 2054, 2056, 2057, 2059, 2058, 2055, + 2056, 2057, 2056, 2056, 2056, 2057, 2057, 2056, + 2057, 2056, 2057, 2055, 2056, 2057, 2057, 2058, + 2057, 2055, 2055, 2056, 2057, 2056, 2056, 2056, + 2057, 2057, 2058, 2058, 2058, 2059, 2057, 2056, + 2057, 2055, 2053, 2055, 2056, 2056, 2056, 2057, + 2059, 2058, 2058, 2058, 2057, 2060, 2058, 2058, + 2058, 2059, 2059, 2060, 2061, 2060, 2058, 2059, + 2060, 2060, 2058, 2058, 2059, 2058, 2056, 2058, + 2059, 2059, 2058, 2058, 2057, 2059, 2060, 2058, + 2058, 2058, 2057, 2059, 2058, 2056, 2061, 2061, + 2060, 2059, 2061, 2062, 2062, 2062, 2059, 2061, + 2059, 2058, 2060, 2061, 2058, 2058, 2058, 2059, + 2059, 2057, 2060, 2058, 2058, 2057, 2055, 2054, + 2056, 2056, 2059, 2056, 2056, 2059, 2059, 2057, + 2055, 2052, 2051, 2052, 2052, 2052, 2053, 2051, + 2052, 2052, 2051, 2050, 2048, 2049, 2050, 2052, + 2050, 2052, 2051, 2052, 2053, 2052, 2050, 2050, + 2052, 2051, 2051, 2053, 2052, 2051, 2053, 2055, + 2055, 2054, 2053, 2054, 2051, 2052, 2052, 2053, + 2053, 2052, 2052, 2053, 2053, 2049, 2048, 2051, + 2048, 2048, 2049, 2050, 2051, 2049, 2047, 2047, + 2049, 2050, 2051, 2049, 2048, 2045, 2045, 2046, + 2046, 2046, 2045, 2046, 2045, 2043, 2044, 2043, + 2043, 2043, 2044, 2042, 2042, 2042, 2044, 2046, + 2044, 2039, 2040, 2039, 2038, 2040, 2040, 2040, + 2040, 2039, 2039, 2039, 2037, 2036, 2036, 2037, + 2037, 2034, 2036, 2035, 2034, 2033, 2033, 2031, + 2029, 2027, 2029, 2028, 2028, 2029, 2030, 2029, + 2027, 2027, 2026, 2028, 2028, 2026, 2026, 2024, + 2025, 2028, 2027, 2025, 2026, 2027, 2023, 2018, + 2017, 2021, 2020, 2019, 2018, 2016, 2014, 2013, + 2011, 2010, 2007, 2010, 2009, 2006, 2008, 2008, + 2004, 2005, 2006, 2009, 2009, 2010, 2009, 2007, + 2007, 2008, 2007, 2006, 2008, 2009, 2008, 2008, + 2006, 2007, 2009, 2008, 2007, 2007, 2008, 2007, + 2007, 2009, 2008, 2007, 2008, 2009, 2007, 2006, + 2005, 2004, 2007, 2006, 2006, 2004, 2004, 2003, + 2001, 2001, 2002, 2004, 2003, 2003, 2001, 2001, + 2002, 1998, 2000, 1999, 2000, 2001, 2001, 1999, + 2000, 1999, 1998, 1998, 2001, 2000, 1998, 1997, + 1996, 1995, 1994, 1994, 1995, 1995, 1993, 1996, + 1996, 1994, 1992, 1992, 1993, 1991, 1990, 1989, + 1991, 1987, 1988, 1989, 1989, 1989, 1992, 1990, + 1992, 1993, 1992, 1993, 1992, 1990, 1989, 1991, + 1990, 1990, 1988, 1989, 1991, 1991, 1992, 1991, + 1994, 1993, 1991, 1991, 1991, 1991, 1989, 1990, + 1990, 1991, 1989, 1991, 1990, 1991, 1989, 1988, + 1988, 1987, 1987, 1990, 1990, 1988, 1988, 1988, + 1988, 1987, 1987, 1984, 1986, 1985, 1986, 1988, + 1988, 1987, 1987, 1988, 1987, 1988, 1989, 1988, + 1989, 1991, 1990, 1988, 1990, 1989, 1987, 1987, + 1987, 1985, 1986, 1987, 1988, 1985, 1987, 1985, + 1986, 1988, 1988, 1988, 1988, 1987, 1988, 1988, + 1988, 1988, 1989, 1987, 1988, 1989, 1989, 1991, + 1990, 1992, 1990, 1990, 1991, 1991, 1993, 1994, + 1994, 1996, 1993, 1995, 1995, 1998, 1997, 1996, + 1997, 1997, 1998, 1998, 1997, 1999, 1999, 2000, + 2001, 2003, 2004, 2004, 2006, 2005, 2003, 2008, + 2006, 2005, 2005, 2005, 2008, 2009, 2011, 2011, + 2009, 2008, 2010, 2010, 2012, 2013, 2014, 2015, + 2015, 2014, 2015, 2015, 2013, 2013, 2013, 2013, + 2014, 2015, 2018, 2018, 2016, 2016, 2018, 2019, + 2017, 2015, 2017, 2016, 2016, 2016, 2015, 2017, + 2018, 2018, 2017, 2016, 2018, 2017, 2019, 2018, + 2016, 2015, 2014, 2014, 2016, 2018, 2018, 2015, + 2016, 2016, 2017, 2017, 2016, 2015, 2015, 2015, + 2015, 2018, 2016, 2017, 2016, 2014, 2016, 2017, + 2020, 2019, 2018, 2018, 2016, 2017, 2019, 2017, + 2017, 2013, 2015, 2016, 2015, 2015, 2016, 2016, + 2017, 2015, 2013, 2016, 2016, 2017, 2018, 2017, + 2016, 2017, 2016, 2016, 2017, 2019, 2019, 2021, + 2020, 2018, 2019, 2019, 2019, 2018, 2018, 2018, + 2020, 2021, 2022, 2023, 2019, 2018, 2022, 2022, + 2022, 2022, 2023, 2024, 2021, 2022, 2023, 2024, + 2024, 2024, 2025, 2027, 2028, 2029, 2030, 2028, + 2029, 2027, 2028, 2026, 2029, 2028, 2029, 2030, + 2029, 2031, 2029, 2030, 2029, 2028, 2028, 2030, + 2029, 2029, 2031, 2029, 2029, 2030, 2029, 2030, + 2030, 2029, 2027, 2026, 2025, 2024, 2024, 2023, + 2024, 2024, 2024, 2023, 2024, 2024, 2025, 2029, + 2027, 2025, 2027, 2029, 2029, 2033, 2034, 2035, + 2034, 2036, 2038, 2035, 2035, 2036, 2037, 2038, + 2036, 2038, 2038, 2037, 2038, 2039, 2039, 2033, + 2031, 2031, 2030, 2030, 2029, 2031, 2031, 2031, + 2031, 2032, 2034, 2034, 2037, 2038, 2038, 2039, + 2038, 2037, 2040, 2039, 2041, 2040, 2039, 2039, + 2038, 2041, 2038, 2035, 2037, 2037, 2037, 2035, + 2033, 2036, 2037, 2037, 2037, 2036, 2036, 2037, + 2035, 2036, 2038, 2039, 2040, 2039, 2039, 2038, + 2039, 2041, 2042, 2042, 2044, 2042, 2042, 2041, + 2041, 2040, 2041, 2041, 2040, 2041, 2041, 2042, + 2042, 2039, 2041, 2040, 2040, 2038, 2030, 2025, + 2024, 2015, 1982, 1933, 1910, 1911, 1896, 1878, + 1888, 1889, 1882, 1894, 1915, 1938, 1950, 1959, + 1977, 1987, 1989, 2008, 2032, 2054, 2074, 2093, + 2112, 2129, 2145, 2158, 2166, 2164, 2146, 2135, + 2129, 2105, 2079, 2064, 2040, 2017, 1999, 1987, + 1980, 1972, 1963, 1962, 1963, 1965, 1968, 1974, + 1982, 1991, 2001, 2014, 2031, 2043, 2058, 2074, + 2089, 2102, 2120, 2136, 2134, 2127, 2123, 2121, + 2116, 2102, 2092, 2087, 2073, 2048, 2032, 2017, + 1998, 1986, 1973, 1960, 1956, 1949, 1945, 1951, + 1957, 1960, 1964, 1976, 1985, 1994, 2014, 2031, + 2039, 2059, 2079, 2089, 2104, 2113, 2117, 2118, + 2114, 2115, 2117, 2112, 2108, 2106, 2085, 2057, + 2049, 2039, 2026, 2019, 2006, 1988, 1975, 1961, + 1958, 1961, 1957, 1956, 1962, 1965, 1966, 1975, + 1988, 1997, 2008, 2012, 2018, 2029, 2036, 2047, + 2059, 2063, 2061, 2057, 2059, 2065, 2062, 2053, + 2048, 2042, 2029, 2024, 2023, 2023, 2023, 2020, + 2015, 2015, 2020, 2021, 2028, 2040, 2042, 2043, + 2049, 2053, 2053, 2058, 2066, 2068, 2061, 2071, + 2089, 2081, 2072, 2088, 2089, 2074, 2061, 2052, + 2049, 2041, 2027, 2014, 2011, 2007, 2010, 2025, + 2026, 2000, 1982, 1984, 1991, 1993, 1992, 1998, + 1997, 2001, 2015, 2038, 2052, 2052, 2057, 2068, + 2070, 2067, 2071, 2084, 2092, 2087, 2079, 2086, + 2089, 2076, 2091, 2106, 2076, 2063, 2079, 2070, + 2058, 2064, 2060, 2040, 2022, 2035, 2043, 2023, + 2024, 2042, 2037, 2022, 2026, 2044, 2030, 2014, + 2025, 2029, 2023, 2034, 2043, 2048, 2051, 2031, + 2030, 2043, 2037, 2039, 2046, 2041, 2033, 2026, + 2038, 2050, 2044, 2050, 2056, 2047, 2041, 2035, + 2036, 2044, 2035, 2028, 2033, 2028, 2029, 2031, + 2038, 2048, 2027, 2017, 2036, 2036, 2033, 2036, + 2039, 2039, 2031, 2034, 2049, 2050, 2045, 2033, + 2032, 2037, 2022, 2021, 2036, 2032, 2031, 2028, + 2032, 2038, 2028, 2028, 2036, 2025, 2017, 2013, + 2017, 2021, 2014, 2018, 2027, 2020, 2021, 2038, + 2042, 2032, 2021, 2026, 2036, 2026, 2014, 2021, + 2023, 2009, 2001, 2003, 2002, 1998, 1986, 1985, + 1992, 1981, 1979, 2006, 2013, 2003, 2013, 2026, + 2027, 2029, 2047, 2064, 2055, 2040, 2052, 2069, + 2069, 2063, 2053, 2052, 2046, 2028, 2007, 1999, + 1993, 1985, 1981, 1977, 1976, 1971, 1976, 1986, + 1977, 1973, 1984, 1996, 2006, 2018, 2029, 2038, + 2045, 2052, 2073, 2092, 2105, 2115, 2106, 2063, + 2025, 2028, 2033, 1998, 1963, 1962, 1957, 1928, + 1932, 1964, 1977, 1980, 1979, 1996, 2011, 2003, + 2001, 2012, 2028, 2039, 2041, 2060, 2086, 2091, + 2093, 2112, 2108, 2078, 2072, 2073, 2047, 2018, + 1989, 1972, 1968, 1939, 1916, 1928, 1925, 1906, + 1904, 1923, 1950, 1953, 1945, 1974, 2006, 2012, + 2042, 2095, 2105, 2098, 2110, 2108, 2097, 2111, + 2111, 2067, 2035, 2022, 1989, 1970, 1956, 1929, + 1915, 1889, 1861, 1867, 1873, 1875, 1893, 1898, + 1916, 1937, 1945, 1985, 2034, 2062, 2080, 2101, + 2113, 2117, 2142, 2178, 2174, 2152, 2142, 2126, + 2110, 2077, 2040, 2046, 2017, 1943, 1932, 1944, + 1911, 1882, 1892, 1928, 1922, 1899, 1949, 1987, + 1968, 1974, 2010, 2042, 2041, 2024, 2063, 2094, + 2082, 2105, 2114, 2114, 2123, 2111, 2131, 2121, + 2064, 2060, 2046, 2015, 2001, 1965, 1958, 1953, + 1938, 1957, 1955, 1979, 2008, 1983, 2027, 2079, + 2038, 2052, 2115, 2120, 2093, 2092, 2122, 2126, + 2103, 2103, 2109, 2106, 2073, 2025, 2035, 2018, + 1956, 1950, 1939, 1887, 1861, 1850, 1851, 1873, + 1863, 1870, 1912, 1936, 1960, 1994, 2022, 2060, + 2082, 2081, 2114, 2142, 2132, 2146, 2165, 2166, + 2156, 2137, 2143, 2144, 2100, 2076, 2083, 2051, + 2018, 2004, 1984, 1971, 1946, 1935, 1955, 1962, + 1973, 1991, 1990, 2012, 2041, 2054, 2094, 2122, + 2104, 2120, 2135, 2114, 2136, 2152, 2137, 2137, + 2123, 2128, 2127, 2082, 2083, 2077, 2017, 1986, + 1969, 1938, 1910, 1894, 1901, 1896, 1905, 1928, + 1921, 1958, 2016, 2007, 2012, 2046, 2031, 2038, + 2079, 2074, 2074, 2093, 2091, 2102, 2131, 2117, + 2102, 2109, 2101, 2084, 2076, 2073, 2058, 2032, + 2016, 2006, 2004, 2009, 1990, 1981, 2006, 1996, + 1982, 2010, 2035, 2023, 2021, 2040, 2045, 2035, + 2033, 2065, 2079, 2050, 2047, 2074, 2093, 2116, + 2124, 2123, 2129, 2117, 2126, 2145, 2157, 2161, + 2115, 2056, 2011, 1943, 1899, 1882, 1861, 1837, + 1795, 1781, 1812, 1825, 1842, 1895, 1920, 1929, + 1948, 1966, 1998, 2039, 2072, 2100, 2139, 2179, + 2230, 2299, 2359, 2371, 2355, 2347, 2345, 2314, + 2274, 2244, 2183, 2096, 2018, 1968, 1954, 1911, + 1860, 1868, 1870, 1850, 1854, 1874, 1916, 1951, + 1948, 1976, 2058, 2103, 2106, 2166, 2246, 2250, + 2237, 2292, 2361, 2357, 2314, 2333, 2334, 2254, + 2225, 2223, 2161, 2099, 2047, 2009, 2004, 1971, + 1936, 1926, 1887, 1852, 1883, 1911, 1896, 1942, + 1999, 1955, 1965, 2055, 2063, 2096, 2166, 2165, + 2156, 2152, 2153, 2179, 2174, 2160, 2142, 2090, + 2086, 2085, 2045, 2052, 2047, 2003, 1985, 1996, + 2024, 2019, 2009, 2035, 2003, 1957, 1988, 2028, + 2047, 2039, 2015, 2029, 2040, 2024, 2046, 2086, + 2086, 2049, 2036, 2066, 2056, 2031, 2046, 2058, + 2024, 2008, 2029, 2032, 2023, 2038, 2043, 2026, + 2034, 2052, 2059, 2071, 2082, 2069, 2042, 2059, + 2091, 2079, 2065, 2085, 2086, 2066, 2100, 2140, + 2106, 2090, 2131, 2120, 2080, 2087, 2088, 2031, + 1987, 1986, 1965, 1930, 1928, 1957, 1972, 1962, + 1969, 2023, 2075, 2066, 2085, 2149, 2139, 2113, + 2166, 2204, 2159, 2145, 2185, 2183, 2164, 2192, + 2207, 2198, 2220, 2226, 2194, 2186, 2185, 2160, + 2127, 2116, 2092, 2018, 1990, 2024, 2011, 1975, + 2015, 2069, 2056, 2051, 2112, 2149, 2131, 2136, + 2165, 2167, 2147, 2143, 2161, 2183, 2178, 2173, + 2217, 2237, 2217, 2227, 2217, 2182, 2153, 2107, + 2080, 2073, 2026, 1969, 1939, 1909, 1879, 1869, + 1888, 1899, 1891, 1904, 1935, 1966, 1995, 2030, + 2069, 2105, 2107, 2085, 2107, 2134, 2109, 2104, + 2149, 2159, 2133, 2156, 2196, 2187, 2184, 2200, + 2191, 2162, 2140, 2110, 2059, 1991, 1940, 1916, + 1882, 1870, 1864, 1831, 1829, 1866, 1889, 1900, + 1928, 1948, 1934, 1917, 1941, 1954, 1934, 1942, + 1953, 1937, 1957, 1998, 2036, 2076, 2104, 2124, + 2126, 2111, 2113, 2116, 2079, 2029, 1992, 1945, + 1883, 1881, 1918, 1894, 1878, 1928, 1936, 1936, + 1997, 2025, 2012, 2037, 2053, 2045, 2058, 2068, + 2078, 2105, 2120, 2110, 2107, 2116, 2123, 2133, + 2150, 2145, 2135, 2139, 2111, 2106, 2141, 2125, + 2099, 2107, 2100, 2097, 2109, 2113, 2126, 2133, + 2135, 2158, 2179, 2177, 2167, 2177, 2189, 2156, + 2127, 2146, 2115, 2068, 2098, 2095, 2055, 2055, + 2064, 2077, 2086, 2096, 2135, 2152, 2148, 2171, + 2176, 2162, 2172, 2168, 2159, 2144, 2126, 2121, + 2095, 2097, 2110, 2083, 2090, 2108, 2094, 2086, + 2083, 2064, 2042, 2027, 2022, 2000, 1986, 1994, + 1989, 1997, 2002, 2004, 2048, 2075, 2066, 2096, + 2114, 2096, 2102, 2113, 2081, 2049, 2051, 2061, + 2039, 2025, 2034, 2017, 2016, 2032, 2055, 2065, + 2063, 2080, 2084, 2063, 2042, 2053, 2030, 1987, + 2002, 1986, 1928, 1937, 1953, 1924, 1937, 1982, + 1985, 1973, 1983, 1989, 1971, 1963, 1975, 1953, + 1915, 1900, 1906, 1928, 1934, 1936, 1935, 1944, + 1964, 1966, 1954, 1945, 1926, 1895, 1876, 1856, + 1826, 1814, 1808, 1791, 1785, 1797, 1802, 1819, + 1840, 1849, 1875, 1900, 1890, 1886, 1908, 1923, + 1913, 1891, 1897, 1915, 1902, 1902, 1923, 1935, + 1960, 1988, 2021, 2066, 2093, 2121, 2153, 2175, + 2204, 2227, 2229, 2241, 2257, 2266, 2270, 2291, + 2314, 2318, 2338, 2362, 2337, 2306, 2310, 2309, + 2272, 2231, 2194, 2176, 2193, 2173, 2148, 2166, + 2180, 2188, 2212, 2244, 2271, 2300, 2316, 2313, + 2346, 2371, 2353, 2356, 2371, 2361, 2340, 2332, + 2340, 2330, 2322, 2329, 2336, 2339, 2331, 2337, + 2354, 2328, 2297, 2297, 2276, 2254, 2251, 2251, + 2267, 2287, 2299, 2312, 2353, 2396, 2393, 2380, + 2388, 2374, 2323, 2274, 2243, 2211, 2164, 2120, + 2103, 2099, 2073, 2055, 2068, 2065, 2049, 2043, + 2037, 2025, 2017, 2011, 2000, 1995, 1992, 1977, + 1967, 1979, 1977, 1955, 1948, 1951, 1946, 1923, + 1905, 1895, 1864, 1815, 1765, 1733, 1683, 1627, + 1593, 1563, 1542, 1544, 1551, 1563, 1590, 1613, + 1631, 1654, 1676, 1692, 1698, 1703, 1716, 1731, + 1743, 1767, 1789, 1802, 1817, 1839, 1859, 1863, + 1856, 1843, 1827, 1801, 1774, 1754, 1727, 1695, + 1677, 1654, 1635, 1635, 1625, 1610, 1618, 1634, + 1634, 1643, 1665, 1681, 1689, 1711, 1726, 1742, + 1774, 1815, 1880, 1951, 2022, 2119, 2197, 2263, + 2363, 2462, 2534, 2609, 2666, 2684, 2710, 2746, + 2766, 2776, 2767, 2757, 2763, 2765, 2770, 2760, + 2731, 2718, 2701, 2673, 2666, 2653, 2622, 2604, + 2616, 2632, 2630, 2655, 2718, 2777, 2832, 2873, + 2915, 2982, 3039, 3059, 3076, 3083, 3031, 2947, + 2886, 2790, 2659, 2541, 2422, 2298, 2187, 2089, + 2012, 1960, 1912, 1862, 1820, 1812, 1835, 1854, + 1884, 1926, 1963, 1992, 2034, 2093, 2133, 2162, + 2205, 2232, 2233, 2245, 2258, 2252, 2247, 2228, + 2184, 2136, 2088, 2040, 1994, 1963, 1932, 1898, + 1889, 1908, 1931, 1964, 2010, 2050, 2083, 2116, + 2151, 2177, 2197, 2209, 2200, 2178, 2150, 2115, + 2066, 2015, 1957, 1883, 1804, 1730, 1654, 1568, + 1487, 1408, 1326, 1253, 1202, 1167, 1145, 1151, + 1180, 1227, 1295, 1377, 1462, 1555, 1648, 1727, + 1796, 1855, 1892, 1913, 1929, 1931, 1916, 1892, + 1856, 1820, 1784, 1738, 1689, 1637, 1584, 1541, + 1504, 1470, 1443, 1431, 1421, 1422, 1454, 1496, + 1546, 1619, 1694, 1765, 1857, 1957, 2043, 2126, + 2187, 2228, 2280, 2307, 2307, 2322, 2309, 2280, + 2262, 2240, 2227, 2237, 2241, 2254, 2279, 2311, + 2352, 2392, 2436, 2473, 2505, 2567, 2638, 2668, + 2697, 2757, 2812, 2856, 2902, 2928, 2945, 2967, + 2985, 2986, 2985, 2982, 2970, 2957, 2932, 2917, + 2937, 2958, 2961, 2977, 3007, 3023, 3065, 3135, + 3154, 3137, 3091, 2996, 2881, 2762, 2607, 2430, + 2270, 2102, 1967, 1888, 1827, 1784, 1774, 1771, + 1771, 1779, 1790, 1792, 1788, 1781, 1776, 1780, + 1798, 1843, 1889, 1941, 2014, 2092, 2170, 2242, + 2299, 2344, 2381, 2408, 2411, 2392, 2350, 2297, + 2244, 2188, 2151, 2119, 2096, 2080, 2086, 2108, + 2139, 2178, 2208, 2221, 2219, 2211, 2187, 2143, + 2087, 2017, 1940, 1863, 1792, 1733, 1681, 1631, + 1583, 1530, 1478, 1435, 1393, 1353, 1316, 1282, + 1257, 1246, 1248, 1269, 1308, 1345, 1390, 1452, + 1515, 1573, 1631, 1676, 1708, 1738, 1755, 1752, + 1740, 1718, 1678, 1636, 1597, 1560, 1527, 1500, + 1476, 1460, 1463, 1478, 1487, 1506, 1540, 1576, + 1612, 1668, 1726, 1786, 1863, 1927, 1999, 2116, + 2199, 2257, 2356, 2424, 2455, 2493, 2514, 2529, + 2536, 2529, 2516, 2496, 2487, 2480, 2468, 2461, + 2452, 2449, 2466, 2501, 2527, 2557, 2594, 2636, + 2682, 2733, 2769, 2807, 2872, 2910, 2921, 2966, + 3030, 3088, 3147, 3185, 3218, 3259, 3314, 3374, + 3388, 3375, 3362, 3368, 3375, 3366, 3338, 3227, + 3059, 2936, 2802, 2623, 2447, 2265, 2083, 1951, + 1873, 1837, 1819, 1812, 1806, 1806, 1824, 1841, + 1851, 1853, 1825, 1786, 1762, 1759, 1778, 1799, + 1811, 1841, 1898, 1971, 2050, 2110, 2151, 2179, + 2195, 2203, 2203, 2192, 2176, 2146, 2138, 2149, + 2172, 2204, 2235, 2273, 2315, 2363, 2418, 2466, + 2496, 2505, 2495, 2469, 2439, 2397, 2321, 2217, + 2109, 2007, 1915, 1837, 1772, 1708, 1649, 1602, + 1566, 1526, 1470, 1398, 1324, 1250, 1186, 1129, + 1086, 1072, 1075, 1104, 1155, 1226, 1311, 1390, + 1462, 1520, 1560, 1586, 1597, 1584, 1562, 1537, + 1500, 1471, 1448, 1423, 1402, 1392, 1403, 1417, + 1436, 1462, 1497, 1531, 1571, 1613, 1654, 1693, + 1722, 1758, 1814, 1873, 1932, 1999, 2068, 2129, + 2200, 2288, 2360, 2394, 2415, 2415, 2392, 2377, + 2356, 2314, 2263, 2220, 2206, 2218, 2251, 2294, + 2337, 2363, 2393, 2438, 2495, 2547, 2566, 2559, + 2562, 2588, 2624, 2666, 2709, 2732, 2741, 2785, + 2857, 2907, 2948, 2987, 3028, 3078, 3140, 3206, + 3255, 3286, 3297, 3318, 3359, 3381, 3376, 3373, + 3353, 3261, 3141, 3049, 2919, 2735, 2553, 2360, + 2188, 2078, 2000, 1936, 1890, 1861, 1845, 1848, + 1861, 1863, 1847, 1832, 1817, 1805, 1799, 1786, + 1774, 1775, 1787, 1792, 1805, 1849, 1912, 1961, + 1996, 2042, 2087, 2111, 2118, 2115, 2101, 2083, + 2073, 2081, 2105, 2128, 2151, 2186, 2238, 2297, + 2350, 2399, 2441, 2474, 2487, 2480, 2458, 2418, + 2344, 2245, 2137, 2031, 1931, 1843, 1758, 1680, + 1623, 1574, 1514, 1466, 1423, 1358, 1288, 1243, + 1198, 1146, 1111, 1103, 1113, 1150, 1195, 1244, + 1311, 1383, 1443, 1495, 1540, 1567, 1569, 1559, + 1540, 1517, 1485, 1447, 1408, 1367, 1337, 1320, + 1311, 1321, 1340, 1356, 1389, 1459, 1526, 1582, + 1659, 1739, 1799, 1864, 1928, 1978, 2035, 2088, + 2126, 2179, 2241, 2284, 2325, 2368, 2389, 2399, + 2414, 2406, 2385, 2367, 2333, 2295, 2294, 2309, + 2314, 2334, 2371, 2399, 2441, 2502, 2553, 2596, + 2635, 2651, 2679, 2731, 2789, 2823, 2844, 2861, + 2884, 2921, 2960, 3004, 3027, 3029, 3057, 3111, + 3181, 3251, 3291, 3320, 3363, 3407, 3433, 3458, + 3475, 3419, 3287, 3161, 3060, 2925, 2788, 2641, + 2459, 2316, 2249, 2211, 2185, 2170, 2134, 2079, + 2044, 2037, 2017, 1964, 1880, 1795, 1725, 1681, + 1658, 1653, 1655, 1661, 1694, 1754, 1843, 1947, + 2015, 2054, 2081, 2102, 2127, 2137, 2118, 2081, + 2049, 2039, 2058, 2094, 2124, 2144, 2165, 2204, + 2265, 2332, 2388, 2414, 2420, 2416, 2411, 2405, + 2381, 2315, 2216, 2133, 2069, 2004, 1955, 1909, + 1847, 1795, 1757, 1709, 1660, 1607, 1516, 1410, + 1330, 1252, 1168, 1113, 1080, 1063, 1082, 1126, + 1180, 1255, 1338, 1398, 1449, 1496, 1523, 1519, + 1495, 1465, 1438, 1404, 1357, 1317, 1292, 1272, + 1262, 1270, 1293, 1314, 1343, 1394, 1447, 1498, + 1554, 1607, 1645, 1702, 1762, 1800, 1846, 1912, + 1975, 2039, 2110, 2189, 2264, 2336, 2396, 2435, + 2467, 2473, 2457, 2433, 2402, 2364, 2333, 2317, + 2315, 2329, 2356, 2391, 2441, 2503, 2557, 2593, + 2632, 2678, 2718, 2738, 2745, 2762, 2784, 2803, + 2835, 2876, 2895, 2927, 2997, 3046, 3098, 3186, + 3242, 3273, 3344, 3410, 3434, 3453, 3465, 3456, + 3444, 3411, 3316, 3201, 3100, 2979, 2842, 2716, + 2594, 2480, 2382, 2314, 2287, 2267, 2228, 2179, + 2143, 2119, 2086, 2047, 2013, 1979, 1939, 1893, + 1847, 1832, 1837, 1824, 1802, 1801, 1828, 1864, + 1900, 1931, 1955, 1974, 1982, 1989, 1997, 2002, + 1990, 1983, 2001, 2040, 2081, 2108, 2145, 2201, + 2261, 2317, 2368, 2413, 2445, 2458, 2460, 2458, + 2449, 2422, 2357, 2270, 2201, 2148, 2088, 2020, + 1948, 1869, 1802, 1737, 1670, 1617, 1554, 1464, + 1386, 1338, 1296, 1250, 1212, 1189, 1191, 1213, + 1236, 1271, 1320, 1364, 1392, 1423, 1454, 1468, + 1455, 1429, 1400, 1373, 1340, 1305, 1263, 1234, + 1211, 1192, 1197, 1219, 1242, 1268, 1303, 1353, + 1421, 1491, 1555, 1618, 1679, 1757, 1830, 1879, + 1944, 2019, 2070, 2119, 2181, 2235, 2279, 2319, + 2346, 2361, 2380, 2383, 2365, 2357, 2355, 2347, + 2335, 2344, 2368, 2396, 2431, 2472, 2520, 2574, + 2619, 2666, 2725, 2772, 2805, 2838, 2875, 2914, + 2949, 2979, 3001, 3024, 3055, 3082, 3106, 3134, + 3177, 3221, 3258, 3312, 3367, 3408, 3456, 3495, + 3502, 3481, 3419, 3321, 3218, 3105, 2971, 2827, + 2692, 2583, 2498, 2440, 2404, 2379, 2350, 2316, + 2286, 2255, 2220, 2176, 2115, 2057, 1997, 1929, + 1867, 1819, 1781, 1752, 1726, 1714, 1726, 1754, + 1793, 1837, 1879, 1922, 1953, 1968, 1976, 1982, + 1979, 1967, 1966, 1976, 1985, 1999, 2030, 2074, + 2130, 2188, 2247, 2309, 2355, 2385, 2403, 2412, + 2403, 2378, 2338, 2284, 2218, 2152, 2109, 2076, + 2025, 1959, 1898, 1840, 1775, 1715, 1658, 1580, + 1500, 1425, 1356, 1307, 1269, 1221, 1177, 1165, + 1162, 1160, 1184, 1220, 1250, 1276, 1309, 1337, + 1359, 1372, 1375, 1364, 1345, 1319, 1288, 1252, + 1217, 1188, 1163, 1152, 1157, 1178, 1204, 1244, + 1288, 1344, 1407, 1466, 1524, 1589, 1649, 1710, + 1771, 1834, 1901, 1960, 2014, 2073, 2125, 2176, + 2223, 2261, 2295, 2329, 2348, 2362, 2376, 2384, + 2391, 2403, 2417, 2418, 2421, 2439, 2465, 2501, + 2540, 2581, 2624, 2676, 2722, 2765, 2824, 2870, + 2891, 2916, 2943, 2961, 2993, 3028, 3063, 3097, + 3136, 3183, 3238, 3300, 3345, 3372, 3400, 3428, + 3440, 3420, 3379, 3313, 3222, 3138, 3059, 2955, + 2843, 2738, 2634, 2561, 2514, 2465, 2418, 2379, + 2338, 2299, 2283, 2268, 2230, 2181, 2127, 2056, + 1974, 1906, 1857, 1802, 1741, 1704, 1690, 1699, + 1727, 1761, 1793, 1825, 1850, 1868, 1881, 1891, + 1887, 1875, 1873, 1881, 1885, 1895, 1920, 1950, + 1988, 2035, 2085, 2133, 2175, 2214, 2248, 2264, + 2275, 2286, 2280, 2258, 2233, 2198, 2148, 2109, + 2083, 2027, 1964, 1908, 1840, 1773, 1732, 1686, + 1620, 1566, 1512, 1443, 1392, 1359, 1301, 1247, + 1218, 1187, 1163, 1171, 1189, 1205, 1224, 1252, + 1279, 1300, 1323, 1338, 1335, 1319, 1303, 1288, + 1265, 1238, 1213, 1189, 1181, 1186, 1187, 1195, + 1223, 1250, 1283, 1334, 1388, 1436, 1500, 1563, + 1619, 1679, 1740, 1802, 1859, 1914, 1962, 2008, + 2057, 2107, 2156, 2209, 2258, 2293, 2321, 2359, + 2388, 2407, 2427, 2442, 2446, 2445, 2452, 2471, + 2494, 2516, 2543, 2579, 2620, 2666, 2717, 2769, + 2816, 2854, 2889, 2933, 2971, 3001, 3042, 3079, + 3106, 3147, 3185, 3217, 3254, 3285, 3299, 3323, + 3344, 3334, 3313, 3300, 3253, 3184, 3133, 3067, + 2976, 2893, 2808, 2725, 2666, 2615, 2555, 2509, + 2470, 2425, 2393, 2374, 2345, 2315, 2282, 2231, + 2180, 2124, 2060, 2004, 1955, 1900, 1851, 1821, + 1799, 1792, 1804, 1815, 1827, 1841, 1848, 1860, + 1876, 1881, 1882, 1888, 1893, 1893, 1898, 1914, + 1932, 1951, 1980, 2011, 2047, 2082, 2116, 2147, + 2170, 2184, 2199, 2208, 2201, 2187, 2157, 2122, + 2101, 2066, 2014, 1960, 1903, 1839, 1794, 1760, + 1711, 1669, 1632, 1587, 1555, 1537, 1503, 1467, + 1444, 1412, 1372, 1358, 1353, 1341, 1344, 1350, + 1354, 1363, 1384, 1393, 1401, 1402, 1397, 1393, + 1383, 1358, 1334, 1310, 1288, 1273, 1266, 1266, + 1268, 1275, 1299, 1334, 1370, 1415, 1467, 1515, + 1564, 1620, 1676, 1722, 1775, 1825, 1861, 1903, + 1945, 1981, 2024, 2073, 2109, 2143, 2190, 2241, + 2276, 2320, 2372, 2402, 2426, 2457, 2481, 2498, + 2521, 2544, 2563, 2584, 2603, 2629, 2662, 2696, + 2729, 2758, 2785, 2808, 2839, 2876, 2907, 2936, + 2972, 3010, 3045, 3083, 3121, 3150, 3175, 3200, + 3217, 3234, 3245, 3238, 3220, 3201, 3178, 3145, + 3107, 3061, 3001, 2936, 2877, 2827, 2774, 2718, + 2665, 2610, 2561, 2522, 2484, 2447, 2410, 2366, + 2317, 2266, 2210, 2155, 2110, 2059, 2010, 1968, + 1935, 1910, 1905, 1903, 1896, 1898, 1906, 1903, + 1903, 1912, 1912, 1910, 1919, 1926, 1926, 1927, + 1937, 1948, 1952, 1965, 1980, 1986, 2000, 2015, + 2021, 2031, 2046, 2058, 2061, 2059, 2048, 2036, + 2025, 2005, 1976, 1943, 1905, 1860, 1823, 1798, + 1772, 1745, 1719, 1685, 1659, 1644, 1621, 1597, + 1580, 1550, 1511, 1484, 1466, 1451, 1450, 1453, + 1443, 1434, 1441, 1454, 1460, 1458, 1453, 1445, + 1434, 1423, 1406, 1386, 1371, 1360, 1343, 1334, + 1335, 1333, 1336, 1350, 1370, 1394, 1429, 1471, + 1509, 1546, 1585, 1641, 1696, 1740, 1781, 1824, + 1865, 1905, 1950, 1988, 2018, 2056, 2093, 2130, + 2176, 2220, 2252, 2289, 2337, 2370, 2389, 2427, + 2464, 2479, 2504, 2542, 2566, 2591, 2627, 2654, + 2677, 2712, 2753, 2788, 2812, 2841, 2886, 2932, + 2976, 3012, 3042, 3078, 3118, 3143, 3160, 3180, + 3197, 3204, 3206, 3206, 3202, 3195, 3183, 3166, + 3140, 3105, 3074, 3045, 3003, 2952, 2903, 2859, + 2823, 2780, 2725, 2682, 2646, 2608, 2573, 2532, + 2486, 2443, 2399, 2342, 2287, 2244, 2199, 2152, + 2109, 2065, 2033, 2022, 2002, 1975, 1960, 1952, + 1938, 1935, 1934, 1928, 1921, 1922, 1924, 1924, + 1933, 1944, 1947, 1958, 1973, 1981, 1985, 1992, + 2002, 2004, 2004, 2013, 2020, 2019, 2009, 1999, + 1993, 1984, 1969, 1945, 1904, 1864, 1831, 1797, + 1768, 1741, 1709, 1678, 1655, 1641, 1628, 1613, + 1605, 1595, 1572, 1557, 1554, 1547, 1537, 1535, + 1531, 1522, 1520, 1525, 1520, 1512, 1509, 1497, + 1480, 1465, 1446, 1427, 1406, 1392, 1378, 1364, + 1360, 1354, 1347, 1355, 1374, 1390, 1413, 1439, + 1471, 1510, 1558, 1606, 1657, 1707, 1748, 1791, + 1834, 1869, 1906, 1940, 1965, 1998, 2029, 2063, + 2099, 2138, 2175, 2211, 2250, 2283, 2310, 2340, + 2370, 2396, 2422, 2455, 2477, 2504, 2533, 2565, + 2596, 2632, 2667, 2695, 2730, 2768, 2806, 2845, + 2889, 2920, 2951, 2991, 3035, 3069, 3094, 3113, + 3129, 3141, 3149, 3150, 3145, 3139, 3127, 3111, + 3102, 3091, 3065, 3039, 3017, 2982, 2948, 2918, + 2886, 2846, 2807, 2770, 2729, 2696, 2669, 2632, + 2587, 2544, 2495, 2441, 2389, 2344, 2289, 2232, + 2189, 2143, 2101, 2072, 2048, 2023, 2002, 1987, + 1970, 1954, 1949, 1935, 1922, 1923, 1914, 1906, + 1911, 1919, 1927, 1936, 1946, 1950, 1955, 1959, + 1959, 1950, 1942, 1930, 1922, 1916, 1905, 1889, + 1879, 1871, 1854, 1836, 1807, 1772, 1738, 1707, + 1679, 1653, 1632, 1608, 1582, 1569, 1559, 1542, + 1534, 1531, 1515, 1497, 1492, 1487, 1482, 1485, + 1487, 1481, 1478, 1482, 1484, 1479, 1473, 1458, + 1437, 1416, 1395, 1372, 1348, 1332, 1317, 1303, + 1295, 1293, 1294, 1301, 1313, 1328, 1347, 1367, + 1390, 1421, 1458, 1496, 1534, 1576, 1621, 1660, + 1696, 1734, 1765, 1797, 1829, 1853, 1877, 1910, + 1939, 1970, 2010, 2049, 2077, 2111, 2144, 2166, + 2196, 2231, 2253, 2281, 2309, 2331, 2361, 2403, + 2436, 2469, 2507, 2536, 2567, 2600, 2636, 2673, + 2707, 2743, 2776, 2812, 2856, 2893, 2921, 2950, + 2976, 2994, 3003, 3010, 3014, 3014, 3015, 3013, + 3005, 2999, 2989, 2978, 2966, 2953, 2939, 2915, + 2891, 2861, 2835, 2809, 2781, 2758, 2734, 2705, + 2666, 2628, 2588, 2532, 2478, 2426, 2371, 2312, + 2257, 2206, 2159, 2124, 2094, 2064, 2034, 2016, + 1990, 1973, 1967, 1947, 1929, 1921, 1907, 1890, + 1888, 1892, 1893, 1897, 1902, 1908, 1907, 1908, + 1906, 1893, 1879, 1864, 1849, 1830, 1814, 1803, + 1789, 1775, 1765, 1748, 1722, 1693, 1662, 1629, + 1597, 1568, 1539, 1512, 1496, 1481, 1467, 1458, + 1452, 1437, 1425, 1412, 1399, 1390, 1389, 1391, + 1394, 1392, 1394, 1404, 1406, 1410, 1411, 1403, + 1383, 1364, 1345, 1318, 1294, 1276, 1257, 1238, + 1231, 1226, 1222, 1227, 1234, 1240, 1255, 1274, + 1291, 1314, 1346, 1384, 1420, 1460, 1504, 1544, + 1583, 1622, 1651, 1679, 1707, 1733, 1750, 1773, + 1802, 1829, 1857, 1892, 1927, 1955, 1985, 2014, + 2040, 2061, 2090, 2114, 2132, 2160, 2194, 2226, + 2265, 2306, 2346, 2383, 2419, 2459, 2497, 2534, + 2571, 2603, 2633, 2671, 2709, 2742, 2778, 2811, + 2836, 2864, 2886, 2902, 2915, 2925, 2924, 2932, + 2938, 2943, 2943, 2944, 2945, 2942, 2941, 2935, + 2923, 2914, 2897, 2878, 2861, 2840, 2818, 2800, + 2779, 2755, 2726, 2693, 2651, 2602, 2556, 2504, + 2453, 2399, 2341, 2291, 2243, 2208, 2172, 2138, + 2111, 2082, 2053, 2035, 2022, 2002, 1987, 1977, + 1958, 1944, 1939, 1934, 1931, 1932, 1934, 1930, + 1928, 1925, 1916, 1898, 1883, 1861, 1839, 1824, + 1810, 1800, 1787, 1775, 1762, 1741, 1714, 1682, + 1650, 1616, 1578, 1545, 1514, 1482, 1464, 1449, + 1430, 1420, 1414, 1396, 1380, 1373, 1367, 1355, + 1352, 1349, 1345, 1346, 1352, 1360, 1362, 1365, + 1366, 1355, 1341, 1332, 1317, 1294, 1277, 1255, + 1233, 1221, 1215, 1209, 1208, 1212, 1212, 1219, + 1233, 1250, 1270, 1293, 1319, 1353, 1388, 1425, + 1469, 1515, 1552, 1580, 1612, 1636, 1655, 1678, + 1698, 1712, 1734, 1769, 1789, 1813, 1848, 1878, + 1901, 1929, 1952, 1969, 1991, 2013, 2035, 2059, + 2092, 2123, 2156, 2192, 2233, 2275, 2314, 2360, + 2404, 2440, 2479, 2518, 2555, 2595, 2632, 2669, + 2705, 2739, 2766, 2794, 2818, 2836, 2861, 2881, + 2889, 2901, 2915, 2929, 2946, 2966, 2973, 2975, + 2988, 2990, 2982, 2985, 2976, 2953, 2937, 2926, + 2910, 2889, 2876, 2858, 2831, 2800, 2767, 2722, + 2670, 2624, 2575, 2517, 2462, 2414, 2361, 2314, + 2276, 2243, 2208, 2180, 2156, 2125, 2099, 2085, + 2068, 2051, 2041, 2029, 2015, 2008, 2007, 2011, + 2013, 2010, 2007, 1996, 1985, 1972, 1958, 1933, + 1908, 1892, 1873, 1855, 1845, 1836, 1821, 1807, + 1790, 1762, 1733, 1706, 1674, 1638, 1604, 1576, + 1547, 1521, 1503, 1483, 1462, 1449, 1431, 1410, + 1396, 1383, 1366, 1360, 1355, 1346, 1343, 1343, + 1343, 1343, 1342, 1340, 1334, 1323, 1311, 1297, + 1283, 1268, 1251, 1236, 1220, 1209, 1204, 1200, + 1201, 1202, 1208, 1215, 1227, 1244, 1262, 1287, + 1318, 1352, 1385, 1424, 1459, 1490, 1522, 1554, + 1578, 1598, 1620, 1637, 1656, 1680, 1711, 1740, + 1764, 1797, 1826, 1854, 1884, 1916, 1945, 1967, + 1994, 2019, 2044, 2074, 2108, 2145, 2178, 2217, + 2253, 2294, 2334, 2374, 2419, 2463, 2506, 2552, + 2594, 2640, 2681, 2717, 2756, 2793, 2820, 2849, + 2878, 2903, 2924, 2948, 2968, 2982, 3009, 3030, + 3045, 3064, 3082, 3095, 3100, 3105, 3103, 3093, + 3089, 3073, 3057, 3045, 3028, 3009, 2985, 2956, + 2922, 2881, 2833, 2776, 2716, 2661, 2599, 2537, + 2483, 2428, 2378, 2336, 2295, 2260, 2229, 2206, + 2178, 2153, 2136, 2116, 2102, 2092, 2084, 2069, + 2061, 2058, 2057, 2055, 2056, 2054, 2046, 2036, + 2025, 2008, 1990, 1969, 1946, 1923, 1903, 1888, + 1873, 1860, 1852, 1833, 1811, 1788, 1760, 1735, + 1711, 1686, 1662, 1634, 1608, 1593, 1569, 1541, + 1518, 1491, 1454, 1426, 1406, 1382, 1369, 1364, + 1347, 1326, 1324, 1318, 1307, 1298, 1290, 1277, + 1261, 1252, 1242, 1229, 1219, 1211, 1195, 1178, + 1171, 1163, 1149, 1145, 1145, 1137, 1139, 1149, + 1159, 1173, 1191, 1215, 1239, 1265, 1293, 1321, + 1353, 1382, 1414, 1446, 1469, 1497, 1524, 1551, + 1583, 1614, 1642, 1665, 1697, 1727, 1753, 1787, + 1818, 1840, 1868, 1896, 1921, 1948, 1980, 2009, + 2040, 2077, 2113, 2149, 2187, 2226, 2267, 2309, + 2357, 2405, 2452, 2501, 2549, 2596, 2644, 2685, + 2722, 2759, 2797, 2831, 2863, 2900, 2934, 2958, + 2993, 3021, 3042, 3068, 3094, 3116, 3134, 3152, + 3165, 3173, 3181, 3180, 3173, 3164, 3154, 3139, + 3123, 3103, 3075, 3049, 3014, 2979, 2933, 2869, + 2798, 2732, 2669, 2597, 2532, 2466, 2396, 2341, + 2299, 2259, 2228, 2201, 2176, 2148, 2125, 2107, + 2094, 2082, 2076, 2066, 2044, 2034, 2033, 2031, + 2033, 2038, 2032, 2023, 2020, 2010, 1995, 1976, + 1956, 1932, 1907, 1887, 1870, 1854, 1843, 1834, + 1811, 1788, 1770, 1748, 1728, 1712, 1700, 1684, + 1667, 1652, 1636, 1615, 1592, 1569, 1534, 1489, + 1447, 1408, 1380, 1354, 1328, 1301, 1280, 1260, + 1242, 1231, 1219, 1201, 1179, 1159, 1137, 1121, + 1108, 1095, 1087, 1077, 1069, 1064, 1058, 1055, + 1057, 1054, 1051, 1059, 1064, 1070, 1081, 1096, + 1113, 1134, 1158, 1179, 1200, 1218, 1240, 1267, + 1293, 1322, 1349, 1373, 1409, 1452, 1491, 1529, + 1570, 1605, 1632, 1663, 1693, 1718, 1749, 1780, + 1799, 1822, 1858, 1896, 1928, 1963, 2001, 2033, + 2066, 2107, 2141, 2177, 2223, 2264, 2301, 2351, + 2400, 2449, 2498, 2546, 2593, 2636, 2683, 2730, + 2769, 2810, 2858, 2901, 2939, 2986, 3032, 3065, + 3101, 3137, 3164, 3193, 3219, 3236, 3257, 3273, + 3275, 3276, 3281, 3273, 3258, 3247, 3225, 3201, + 3173, 3143, 3108, 3061, 3009, 2947, 2872, 2788, + 2704, 2627, 2545, 2457, 2380, 2310, 2243, 2191, + 2156, 2123, 2094, 2072, 2046, 2025, 2014, 2002, + 1984, 1972, 1967, 1955, 1950, 1958, 1961, 1965, + 1970, 1975, 1972, 1964, 1960, 1943, 1920, 1898, + 1872, 1844, 1816, 1799, 1781, 1767, 1757, 1748, + 1733, 1716, 1706, 1700, 1701, 1704, 1706, 1710, + 1710, 1702, 1692, 1675, 1648, 1616, 1578, 1536, + 1492, 1453, 1411, 1382, 1356, 1321, 1289, 1266, + 1241, 1208, 1179, 1152, 1115, 1085, 1062, 1038, + 1020, 1006, 997, 994, 988, 987, 986, 993, + 998, 1002, 1012, 1021, 1036, 1049, 1060, 1076, + 1091, 1109, 1128, 1149, 1166, 1179, 1193, 1215, + 1245, 1276, 1307, 1339, 1374, 1413, 1456, 1500, + 1540, 1574, 1602, 1635, 1670, 1709, 1747, 1783, + 1820, 1860, 1899, 1941, 1988, 2035, 2076, 2112, + 2146, 2181, 2215, 2252, 2287, 2320, 2360, 2401, + 2450, 2498, 2546, 2597, 2649, 2697, 2747, 2800, + 2851, 2901, 2953, 3010, 3057, 3100, 3144, 3182, + 3221, 3265, 3301, 3327, 3359, 3385, 3406, 3427, + 3442, 3454, 3457, 3447, 3431, 3412, 3385, 3351, + 3320, 3284, 3234, 3187, 3136, 3076, 3012, 2935, + 2845, 2749, 2654, 2562, 2465, 2374, 2289, 2216, + 2153, 2100, 2059, 2020, 1990, 1968, 1946, 1926, + 1911, 1899, 1891, 1889, 1887, 1887, 1894, 1902, + 1915, 1926, 1932, 1937, 1932, 1922, 1911, 1893, + 1876, 1861, 1845, 1827, 1808, 1794, 1784, 1779, + 1776, 1762, 1745, 1734, 1725, 1730, 1743, 1757, + 1771, 1783, 1787, 1790, 1792, 1781, 1756, 1720, + 1674, 1624, 1580, 1541, 1498, 1459, 1422, 1384, + 1352, 1326, 1281, 1230, 1189, 1144, 1086, 1040, + 1005, 966, 939, 923, 915, 908, 911, 917, + 919, 922, 931, 944, 948, 952, 961, 972, + 981, 1004, 1031, 1046, 1060, 1074, 1088, 1104, + 1126, 1151, 1174, 1203, 1239, 1279, 1322, 1376, + 1421, 1457, 1494, 1528, 1559, 1586, 1625, 1665, + 1702, 1747, 1794, 1851, 1909, 1968, 2021, 2064, + 2103, 2136, 2169, 2198, 2223, 2252, 2281, 2316, + 2356, 2398, 2446, 2496, 2543, 2593, 2645, 2697, + 2748, 2803, 2862, 2919, 2979, 3036, 3090, 3140, + 3185, 3221, 3251, 3278, 3300, 3323, 3348, 3375, + 3398, 3422, 3441, 3464, 3489, 3504, 3505, 3499, + 3489, 3467, 3440, 3414, 3375, 3335, 3309, 3270, + 3221, 3180, 3122, 3038, 2947, 2844, 2737, 2623, + 2503, 2388, 2277, 2176, 2098, 2039, 1989, 1943, + 1901, 1864, 1828, 1809, 1791, 1762, 1748, 1749, + 1745, 1753, 1780, 1804, 1828, 1854, 1876, 1889, + 1902, 1911, 1910, 1896, 1888, 1889, 1886, 1879, + 1876, 1875, 1866, 1859, 1857, 1841, 1817, 1795, + 1771, 1753, 1754, 1763, 1769, 1785, 1813, 1843, + 1868, 1885, 1883, 1853, 1819, 1786, 1750, 1709, + 1667, 1624, 1580, 1548, 1525, 1496, 1462, 1419, + 1361, 1298, 1228, 1154, 1083, 1016, 951, 889, + 843, 808, 789, 778, 772, 776, 785, 797, + 812, 830, 841, 858, 880, 893, 912, 938, + 960, 985, 1021, 1052, 1081, 1115, 1145, 1182, + 1227, 1268, 1313, 1356, 1390, 1424, 1460, 1487, + 1507, 1530, 1547, 1561, 1586, 1620, 1659, 1709, + 1764, 1823, 1885, 1945, 1994, 2039, 2079, 2113, + 2138, 2162, 2190, 2211, 2237, 2270, 2316, 2368, + 2419, 2473, 2530, 2584, 2638, 2705, 2766, 2821, + 2877, 2941, 2995, 3046, 3103, 3157, 3202, 3240, + 3280, 3322, 3364, 3401, 3433, 3476, 3516, 3548, + 3588, 3630, 3656, 3656, 3652, 3650, 3629, 3599, + 3563, 3524, 3479, 3434, 3398, 3367, 3334, 3294, + 3252, 3205, 3128, 3029, 2911, 2771, 2633, 2492, + 2352, 2209, 2076, 1972, 1887, 1824, 1787, 1752, + 1719, 1689, 1660, 1634, 1620, 1605, 1591, 1586, + 1588, 1592, 1610, 1642, 1675, 1703, 1733, 1762, + 1787, 1819, 1843, 1856, 1865, 1872, 1877, 1878, + 1867, 1854, 1840, 1821, 1804, 1786, 1765, 1743, + 1726, 1723, 1741, 1769, 1793, 1828, 1861, 1902, + 1944, 1976, 1994, 2000, 1988, 1959, 1929, 1908, + 1883, 1843, 1800, 1754, 1711, 1658, 1596, 1535, + 1455, 1354, 1259, 1171, 1075, 977, 877, 780, + 701, 638, 580, 545, 531, 516, 513, 548, + 590, 623, 669, 724, 767, 808, 859, 898, + 925, 951, 978, 1007, 1033, 1070, 1111, 1141, + 1169, 1209, 1251, 1287, 1318, 1342, 1356, 1376, + 1397, 1415, 1431, 1450, 1475, 1504, 1544, 1595, + 1645, 1687, 1739, 1799, 1853, 1903, 1953, 1994, + 2023, 2052, 2082, 2102, 2123, 2147, 2168, 2184, + 2213, 2256, 2294, 2331, 2382, 2434, 2480, 2536, + 2592, 2645, 2699, 2760, 2820, 2878, 2951, 3015, + 3072, 3132, 3193, 3263, 3327, 3380, 3423, 3474, + 3526, 3562, 3598, 3642, 3672, 3691, 3711, 3728, + 3735, 3723, 3700, 3678, 3657, 3608, 3548, 3499, + 3457, 3382, 3313, 3273, 3208, 3142, 3075, 2959, + 2817, 2667, 2519, 2370, 2221, 2069, 1919, 1806, + 1717, 1645, 1604, 1570, 1528, 1489, 1456, 1427, + 1402, 1369, 1344, 1348, 1363, 1373, 1404, 1457, + 1507, 1553, 1606, 1660, 1709, 1755, 1788, 1814, + 1831, 1842, 1851, 1841, 1823, 1812, 1799, 1787, + 1788, 1790, 1774, 1756, 1750, 1751, 1765, 1798, + 1819, 1836, 1865, 1907, 1947, 1986, 2017, 2027, + 2025, 2025, 2033, 2050, 2070, 2073, 2068, 2054, + 2022, 1971, 1907, 1814, 1695, 1575, 1452, 1322, + 1207, 1104, 999, 907, 833, 756, 684, 625, + 552, 482, 446, 421, 396, 394, 417, 445, + 486, 556, 636, 709, 784, 863, 927, 986, + 1044, 1096, 1138, 1182, 1228, 1277, 1328, 1379, + 1423, 1452, 1474, 1484, 1485, 1486, 1495, 1510, + 1525, 1544, 1574, 1609, 1638, 1671, 1709, 1738, + 1758, 1777, 1800, 1826, 1856, 1892, 1932, 1975, + 2014, 2050, 2083, 2116, 2140, 2148, 2151, 2157, + 2161, 2170, 2187, 2210, 2240, 2284, 2344, 2409, + 2477, 2550, 2624, 2702, 2778, 2854, 2938, 3026, + 3115, 3202, 3281, 3353, 3429, 3507, 3561, 3601, + 3650, 3683, 3706, 3747, 3797, 3830, 3873, 3924, + 3949, 3972, 3978, 3955, 3922, 3887, 3821, 3732, + 3655, 3579, 3479, 3401, 3352, 3285, 3209, 3141, + 3040, 2876, 2688, 2517, 2355, 2168, 1979, 1819, + 1679, 1564, 1495, 1459, 1424, 1386, 1344, 1301, + 1274, 1256, 1223, 1201, 1210, 1236, 1261, 1312, + 1384, 1449, 1511, 1577, 1641, 1695, 1750, 1801, + 1834, 1853, 1880, 1912, 1919, 1911, 1910, 1906, + 1897, 1903, 1903, 1884, 1856, 1834, 1824, 1842, + 1887, 1927, 1954, 1992, 2046, 2096, 2142, 2177, + 2194, 2185, 2167, 2166, 2186, 2213, 2246, 2277, + 2306, 2334, 2333, 2288, 2207, 2101, 1966, 1800, + 1634, 1475, 1312, 1164, 1042, 941, 857, 784, + 716, 654, 599, 541, 481, 435, 405, 384, + 379, 399, 446, 520, 616, 713, 806, 898, + 986, 1072, 1150, 1217, 1280, 1331, 1368, 1404, + 1442, 1478, 1507, 1520, 1518, 1506, 1489, 1474, + 1482, 1505, 1526, 1549, 1577, 1614, 1655, 1687, + 1707, 1719, 1719, 1711, 1715, 1727, 1744, 1767, + 1803, 1848, 1899, 1953, 1994, 2024, 2043, 2045, + 2035, 2020, 2002, 1986, 1975, 1971, 1987, 2018, + 2059, 2111, 2166, 2228, 2299, 2377, 2464, 2553, + 2637, 2724, 2814, 2914, 3028, 3140, 3240, 3332, + 3412, 3474, 3542, 3616, 3671, 3720, 3764, 3805, + 3855, 3908, 3953, 3986, 4025, 4042, 4044, 4048, + 4038, 3998, 3961, 3927, 3885, 3828, 3774, 3712, + 3639, 3573, 3491, 3406, 3320, 3221, 3102, 2943, + 2742, 2530, 2346, 2173, 1982, 1799, 1648, 1520, + 1422, 1366, 1330, 1297, 1248, 1199, 1170, 1160, + 1130, 1098, 1100, 1128, 1156, 1198, 1264, 1342, + 1427, 1518, 1601, 1680, 1763, 1838, 1889, 1930, + 1965, 1996, 2010, 2003, 1990, 1980, 1974, 1977, + 1988, 1997, 1998, 1992, 1984, 2002, 2047, 2085, + 2102, 2124, 2152, 2181, 2216, 2246, 2262, 2268, + 2263, 2275, 2302, 2335, 2376, 2413, 2447, 2483, + 2511, 2513, 2494, 2446, 2364, 2246, 2118, 1985, + 1833, 1679, 1530, 1383, 1250, 1135, 1038, 947, + 858, 776, 700, 640, 579, 518, 464, 420, + 396, 395, 421, 465, 520, 577, 648, 746, + 848, 938, 1029, 1115, 1188, 1256, 1322, 1372, + 1413, 1441, 1448, 1443, 1450, 1461, 1469, 1480, + 1500, 1528, 1562, 1606, 1649, 1675, 1692, 1699, + 1687, 1682, 1680, 1671, 1665, 1675, 1693, 1724, + 1764, 1809, 1853, 1888, 1915, 1933, 1945, 1947, + 1929, 1901, 1866, 1838, 1823, 1814, 1817, 1829, + 1846, 1875, 1915, 1969, 2030, 2093, 2161, 2232, + 2308, 2389, 2471, 2554, 2644, 2731, 2823, 2918, + 3032, 3147, 3228, 3317, 3411, 3490, 3582, 3674, + 3736, 3781, 3821, 3846, 3882, 3932, 3947, 3947, + 3976, 4000, 4013, 4047, 4080, 4083, 4083, 4079, + 4052, 4025, 3978, 3903, 3825, 3745, 3646, 3543, + 3457, 3355, 3229, 3081, 2872, 2637, 2440, 2233, + 2004, 1804, 1624, 1462, 1332, 1234, 1156, 1091, + 1036, 971, 913, 884, 848, 800, 797, 850, + 917, 990, 1081, 1192, 1306, 1426, 1536, 1625, + 1715, 1785, 1832, 1867, 1904, 1953, 1978, 1982, + 1993, 2014, 2031, 2047, 2067, 2072, 2064, 2041, + 2013, 2008, 2027, 2043, 2045, 2054, 2088, 2131, + 2168, 2198, 2230, 2248, 2259, 2287, 2329, 2375, + 2421, 2470, 2517, 2569, 2613, 2619, 2593, 2547, + 2484, 2404, 2326, 2256, 2172, 2065, 1941, 1812, + 1679, 1549, 1416, 1271, 1127, 994, 860, 747, + 663, 577, 491, 424, 376, 356, 342, 336, + 334, 347, 378, 429, 509, 594, 677, 766, + 867, 969, 1064, 1145, 1220, 1288, 1342, 1389, + 1428, 1461, 1481, 1503, 1528, 1554, 1589, 1622, + 1627, 1615, 1602, 1584, 1577, 1569, 1559, 1560, + 1566, 1571, 1585, 1614, 1640, 1660, 1670, 1685, + 1706, 1720, 1723, 1727, 1731, 1736, 1740, 1743, + 1747, 1745, 1731, 1709, 1690, 1678, 1671, 1667, + 1676, 1700, 1740, 1787, 1841, 1903, 1965, 2033, + 2109, 2189, 2267, 2352, 2441, 2527, 2626, 2743, + 2857, 2965, 3071, 3173, 3259, 3334, 3404, 3461, + 3530, 3603, 3653, 3704, 3752, 3795, 3834, 3883, + 3935, 3970, 4002, 4038, 4052, 4058, 4075, 4095, + 4094, 4084, 4076, 4046, 4017, 3989, 3933, 3855, + 3773, 3674, 3558, 3452, 3351, 3209, 3023, 2797, + 2555, 2342, 2122, 1878, 1665, 1482, 1308, 1166, + 1067, 979, 909, 855, 779, 731, 714, 658, + 615, 635, 679, 744, 832, 920, 1027, 1152, + 1272, 1387, 1507, 1618, 1709, 1767, 1810, 1867, + 1929, 1956, 1961, 1974, 1984, 1992, 2018, 2034, + 2038, 2044, 2024, 2000, 2018, 2051, 2063, 2059, + 2067, 2090, 2128, 2158, 2185, 2209, 2224, 2237, + 2277, 2334, 2395, 2452, 2504, 2562, 2627, 2677, + 2694, 2677, 2632, 2570, 2504, 2446, 2397, 2332, + 2259, 2182, 2109, 2034, 1951, 1852, 1732, 1593, + 1437, 1291, 1167, 1047, 926, 810, 706, 632, + 577, 522, 487, 465, 427, 397, 412, 435, + 454, 488, 532, 593, 675, 760, 828, 903, + 980, 1041, 1108, 1181, 1249, 1306, 1354, 1402, + 1465, 1533, 1578, 1605, 1614, 1611, 1609, 1603, + 1592, 1592, 1597, 1588, 1594, 1620, 1651, 1686, + 1702, 1700, 1696, 1700, 1695, 1694, 1695, 1690, + 1693, 1699, 1717, 1743, 1753, 1754, 1754, 1751, + 1742, 1731, 1719, 1702, 1688, 1687, 1693, 1706, + 1723, 1741, 1767, 1803, 1851, 1905, 1964, 2034, + 2106, 2183, 2272, 2373, 2471, 2564, 2660, 2756, + 2847, 2947, 3037, 3120, 3209, 3289, 3362, 3432, + 3508, 3576, 3621, 3668, 3712, 3749, 3784, 3803, + 3821, 3862, 3892, 3900, 3928, 3973, 3988, 4005, + 4037, 4047, 4036, 4022, 3988, 3946, 3912, 3858, + 3784, 3710, 3633, 3546, 3446, 3344, 3221, 3046, + 2803, 2566, 2353, 2113, 1878, 1678, 1481, 1308, + 1191, 1088, 989, 921, 837, 727, 653, 596, + 519, 479, 498, 538, 606, 699, 799, 919, + 1049, 1174, 1286, 1387, 1485, 1579, 1642, 1695, + 1788, 1878, 1921, 1960, 2014, 2042, 2065, 2100, + 2117, 2128, 2133, 2116, 2104, 2123, 2160, 2166, + 2160, 2179, 2208, 2224, 2237, 2255, 2260, 2261, + 2285, 2325, 2381, 2455, 2530, 2598, 2674, 2751, + 2806, 2823, 2811, 2779, 2726, 2681, 2652, 2618, + 2569, 2519, 2465, 2408, 2352, 2286, 2196, 2075, + 1944, 1798, 1652, 1527, 1395, 1256, 1133, 1024, + 935, 856, 784, 704, 619, 550, 509, 485, + 458, 435, 419, 429, 462, 503, 547, 591, + 633, 673, 727, 792, 851, 912, 984, 1059, + 1136, 1222, 1305, 1377, 1427, 1460, 1488, 1512, + 1532, 1549, 1570, 1601, 1635, 1683, 1734, 1790, + 1841, 1867, 1888, 1905, 1912, 1910, 1904, 1894, + 1890, 1904, 1926, 1936, 1943, 1950, 1957, 1959, + 1952, 1930, 1901, 1864, 1822, 1795, 1773, 1754, + 1730, 1700, 1677, 1663, 1646, 1629, 1627, 1634, + 1652, 1687, 1739, 1801, 1868, 1938, 2004, 2077, + 2152, 2223, 2290, 2356, 2436, 2523, 2615, 2721, + 2831, 2939, 3034, 3118, 3199, 3263, 3307, 3338, + 3360, 3385, 3412, 3443, 3484, 3532, 3590, 3636, + 3678, 3741, 3795, 3823, 3843, 3860, 3869, 3883, + 3905, 3922, 3931, 3949, 3961, 3967, 3971, 3950, + 3917, 3867, 3796, 3725, 3641, 3527, 3364, 3145, + 2925, 2727, 2501, 2257, 2038, 1833, 1624, 1458, + 1332, 1208, 1102, 997, 875, 772, 695, 608, + 539, 519, 519, 538, 589, 658, 758, 881, + 1002, 1121, 1249, 1370, 1484, 1576, 1646, 1729, + 1821, 1872, 1910, 1966, 2011, 2047, 2093, 2135, + 2168, 2194, 2196, 2185, 2192, 2210, 2209, 2187, + 2176, 2179, 2183, 2183, 2191, 2198, 2198, 2214, + 2249, 2296, 2358, 2432, 2503, 2580, 2662, 2731, + 2778, 2798, 2799, 2781, 2760, 2744, 2719, 2690, + 2660, 2627, 2593, 2566, 2531, 2471, 2388, 2293, + 2188, 2074, 1965, 1850, 1725, 1591, 1448, 1321, + 1214, 1114, 1024, 945, 875, 819, 781, 749, + 711, 677, 640, 606, 595, 587, 579, 581, + 595, 622, 669, 735, 803, 875, 950, 1028, + 1106, 1177, 1229, 1266, 1295, 1321, 1350, 1381, + 1407, 1440, 1481, 1528, 1587, 1654, 1716, 1771, + 1812, 1836, 1853, 1871, 1877, 1876, 1877, 1878, + 1887, 1903, 1917, 1932, 1943, 1947, 1954, 1959, + 1961, 1953, 1935, 1911, 1883, 1851, 1812, 1763, + 1708, 1651, 1605, 1568, 1536, 1512, 1488, 1474, + 1470, 1482, 1502, 1527, 1554, 1580, 1608, 1649, + 1698, 1750, 1808, 1878, 1960, 2048, 2149, 2257, + 2358, 2448, 2534, 2620, 2711, 2796, 2863, 2917, + 2964, 3004, 3034, 3064, 3108, 3140, 3164, 3205, + 3250, 3293, 3327, 3355, 3386, 3423, 3462, 3484, + 3508, 3534, 3552, 3569, 3604, 3639, 3672, 3707, + 3737, 3772, 3803, 3829, 3844, 3850, 3840, 3814, + 3772, 3714, 3647, 3559, 3425, 3233, 3027, 2851, + 2657, 2445, 2257, 2089, 1918, 1770, 1645, 1522, + 1414, 1300, 1158, 1036, 939, 826, 725, 680, + 664, 668, 707, 755, 830, 935, 1031, 1122, + 1213, 1296, 1373, 1440, 1486, 1558, 1641, 1689, + 1732, 1791, 1842, 1889, 1940, 1977, 2013, 2045, + 2051, 2040, 2045, 2053, 2046, 2029, 2016, 2016, + 2020, 2012, 2010, 2013, 2013, 2034, 2069, 2111, + 2173, 2244, 2312, 2387, 2472, 2545, 2598, 2627, + 2643, 2655, 2658, 2667, 2675, 2678, 2686, 2699, + 2704, 2707, 2705, 2682, 2629, 2562, 2483, 2394, + 2306, 2212, 2115, 2022, 1933, 1845, 1755, 1661, + 1569, 1481, 1391, 1305, 1234, 1166, 1093, 1024, + 968, 922, 897, 866, 837, 821, 809, 795, + 792, 812, 829, 848, 872, 913, 966, 1020, + 1062, 1098, 1135, 1167, 1191, 1217, 1244, 1277, + 1316, 1357, 1410, 1472, 1532, 1583, 1633, 1677, + 1716, 1747, 1761, 1770, 1783, 1802, 1821, 1844, + 1872, 1897, 1918, 1929, 1934, 1937, 1934, 1922, + 1908, 1891, 1875, 1863, 1849, 1833, 1815, 1797, + 1774, 1753, 1730, 1706, 1679, 1652, 1636, 1622, + 1616, 1617, 1624, 1633, 1648, 1671, 1695, 1721, + 1752, 1794, 1843, 1894, 1958, 2022, 2084, 2144, + 2203, 2264, 2320, 2372, 2412, 2457, 2501, 2538, + 2577, 2616, 2651, 2683, 2711, 2736, 2764, 2789, + 2798, 2808, 2817, 2824, 2838, 2858, 2873, 2897, + 2921, 2939, 2971, 3004, 3030, 3054, 3079, 3104, + 3131, 3168, 3202, 3242, 3282, 3308, 3342, 3376, + 3408, 3432, 3444, 3445, 3442, 3428, 3404, 3378, + 3344, 3295, 3219, 3110, 2992, 2886, 2763, 2622, + 2498, 2377, 2254, 2155, 2056, 1960, 1891, 1803, + 1704, 1622, 1549, 1471, 1411, 1370, 1342, 1334, + 1331, 1342, 1378, 1427, 1475, 1521, 1557, 1594, + 1638, 1671, 1699, 1738, 1774, 1794, 1821, 1855, + 1876, 1905, 1924, 1930, 1937, 1943, 1935, 1919, + 1905, 1898, 1885, 1871, 1865, 1867, 1867, 1863, + 1862, 1859, 1865, 1878, 1891, 1909, 1942, 1989, + 2040, 2100, 2166, 2229, 2279, 2325, 2362, 2394, + 2427, 2458, 2478, 2496, 2523, 2549, 2567, 2590, + 2601, 2602, 2588, 2564, 2529, 2490, 2444, 2390, + 2334, 2279, 2227, 2174, 2121, 2068, 2014, 1954, + 1887, 1820, 1760, 1701, 1638, 1580, 1524, 1479, + 1444, 1415, 1391, 1372, 1355, 1338, 1322, 1314, + 1304, 1293, 1293, 1302, 1311, 1328, 1351, 1377, + 1413, 1450, 1478, 1506, 1535, 1567, 1604, 1641, + 1678, 1714, 1746, 1777, 1808, 1834, 1856, 1867, + 1870, 1869, 1870, 1866, 1856, 1852, 1852, 1853, + 1858, 1861, 1865, 1868, 1872, 1880, 1883, 1885, + 1885, 1886, 1887, 1888, 1891, 1895, 1895, 1888, + 1885, 1881, 1872, 1860, 1841, 1834, 1823, 1813, + 1809, 1804, 1803, 1804, 1810, 1817, 1825, 1836, + 1847, 1857, 1870, 1888, 1904, 1919, 1937, 1960, + 1983, 2004, 2026, 2045, 2066, 2084, 2098, 2115, + 2132, 2150, 2169, 2185, 2206, 2227, 2243, 2257, + 2271, 2285, 2295, 2302, 2309, 2316, 2323, 2333, + 2347, 2361, 2379, 2395, 2410, 2421, 2436, 2449, + 2465, 2480, 2491, 2500, 2513, 2525, 2538, 2557, + 2577, 2595, 2613, 2632, 2651, 2674, 2691, 2710, + 2727, 2745, 2758, 2769, 2785, 2800, 2810, 2816, + 2826, 2832, 2828, 2823, 2817, 2805, 2797, 2779, + 2750, 2716, 2684, 2650, 2609, 2569, 2528, 2485, + 2447, 2408, 2377, 2351, 2323, 2301, 2281, 2267, + 2257, 2247, 2241, 2243, 2247, 2247, 2253, 2259, + 2270, 2289, 2301, 2308, 2320, 2331, 2341, 2346, + 2348, 2350, 2347, 2338, 2330, 2321, 2311, 2302, + 2290, 2271, 2256, 2239, 2211, 2183, 2161, 2140, + 2115, 2087, 2064, 2047, 2029, 2015, 2001, 1988, + 1980, 1971, 1959, 1954, 1955, 1956, 1962, 1970, + 1978, 1987, 1995, 1998, 2001, 2003, 2000, 1997, + 1989, 1984, 1980, 1973, 1967, 1963, 1958, 1947, + 1939, 1929, 1917, 1905, 1893, 1880, 1869, 1860, + 1850, 1841, 1833, 1827, 1820, 1820, 1821, 1822, + 1824, 1824, 1822, 1824, 1830, 1831, 1837, 1849, + 1857, 1864, 1874, 1880, 1884, 1894, 1902, 1901, + 1900, 1900, 1903, 1909, 1910, 1909, 1901, 1895, + 1891, 1884, 1875, 1867, 1854, 1839, 1829, 1821, + 1811, 1803, 1791, 1779, 1774, 1764, 1751, 1735, + 1724, 1714, 1703, 1693, 1684, 1676, 1669, 1663, + 1659, 1656, 1655, 1653, 1650, 1650, 1651, 1652, + 1652, 1652, 1654, 1656, 1661, 1670, 1677, 1681, + 1690, 1700, 1711, 1719, 1729, 1742, 1750, 1761, + 1771, 1782, 1793, 1803, 1815, 1826, 1836, 1849, + 1861, 1874, 1884, 1894, 1910, 1921, 1934, 1947, + 1960, 1969, 1980, 1995, 2005, 2014, 2022, 2029, + 2035, 2040, 2048, 2054, 2059, 2066, 2074, 2082, + 2088, 2091, 2096, 2102, 2100, 2101, 2104, 2107, + 2113, 2121, 2131, 2136, 2140, 2145, 2148, 2151, + 2156, 2162, 2165, 2170, 2175, 2179, 2184, 2191, + 2198, 2206, 2219, 2229, 2240, 2252, 2268, 2282, + 2295, 2310, 2328, 2346, 2364, 2383, 2402, 2420, + 2439, 2456, 2472, 2489, 2503, 2516, 2530, 2545, + 2561, 2575, 2587, 2595, 2602, 2610, 2615, 2620, + 2620, 2619, 2615, 2612, 2609, 2600, 2594, 2583, + 2571, 2559, 2545, 2531, 2513, 2496, 2477, 2465, + 2451, 2438, 2426, 2409, 2395, 2385, 2369, 2354, + 2344, 2332, 2321, 2310, 2299, 2293, 2289, 2284, + 2277, 2265, 2256, 2249, 2234, 2223, 2215, 2201, + 2189, 2180, 2169, 2158, 2148, 2136, 2120, 2105, + 2091, 2073, 2053, 2034, 2016, 1998, 1982, 1968, + 1959, 1946, 1936, 1929, 1919, 1914, 1909, 1902, + 1899, 1894, 1892, 1890, 1891, 1894, 1895, 1897, + 1895, 1895, 1892, 1892, 1888, 1882, 1877, 1872, + 1869, 1862, 1859, 1858, 1854, 1849, 1843, 1837, + 1828, 1821, 1813, 1801, 1788, 1781, 1772, 1763, + 1752, 1745, 1735, 1724, 1713, 1704, 1693, 1685, + 1677, 1671, 1667, 1667, 1668, 1668, 1670, 1674, + 1678, 1680, 1681, 1683, 1686, 1688, 1689, 1694, + 1696, 1694, 1694, 1700, 1704, 1707, 1711, 1717, + 1721, 1730, 1736, 1741, 1746, 1753, 1760, 1765, + 1775, 1782, 1786, 1793, 1798, 1803, 1811, 1815, + 1822, 1830, 1836, 1844, 1852, 1857, 1864, 1870, + 1873, 1878, 1883, 1885, 1888, 1893, 1894, 1900, + 1905, 1908, 1912, 1916, 1921, 1925, 1927, 1931, + 1936, 1935, 1940, 1945, 1945, 1946, 1952, 1955, + 1958, 1963, 1965, 1967, 1970, 1969, 1969, 1974, + 1974, 1973, 1974, 1975, 1977, 1979, 1983, 1984, + 1989, 1996, 2002, 2002, 2007, 2016, 2021, 2022, + 2029, 2038, 2039, 2041, 2049, 2051, 2054, 2058, + 2063, 2065, 2072, 2079, 2084, 2091, 2100, 2109, + 2114, 2122, 2128, 2135, 2142, 2153, 2162, 2167, + 2179, 2191, 2195, 2204, 2215, 2222, 2233, 2244, + 2253, 2259, 2267, 2275, 2281, 2289, 2297, 2302, + 2301, 2308, 2316, 2316, 2321, 2324, 2324, 2329, + 2334, 2335, 2337, 2339, 2339, 2341, 2342, 2344, + 2344, 2345, 2346, 2349, 2348, 2349, 2350, 2351, + 2350, 2351, 2352, 2350, 2350, 2351, 2347, 2346, + 2346, 2346, 2340, 2339, 2340, 2341, 2337, 2335, + 2335, 2329, 2327, 2324, 2322, 2318, 2318, 2315, + 2311, 2309, 2305, 2303, 2300, 2303, 2301, 2295, + 2292, 2290, 2286, 2282, 2277, 2272, 2267, 2256, + 2248, 2242, 2231, 2220, 2207, 2196, 2185, 2176, + 2166, 2153, 2144, 2132, 2121, 2111, 2100, 2087, + 2074, 2060, 2051, 2042, 2030, 2025, 2015, 2005, + 1998, 1993, 1985, 1978, 1969, 1960, 1954, 1947, + 1940, 1932, 1928, 1921, 1915, 1912, 1904, 1899, + 1892, 1889, 1887, 1879, 1873, 1866, 1860, 1852, + 1848, 1842, 1837, 1835, 1833, 1832, 1828, 1827, + 1826, 1825, 1825, 1824, 1823, 1827, 1829, 1830, + 1833, 1835, 1839, 1841, 1843, 1842, 1846, 1848, + 1851, 1853, 1857, 1863, 1866, 1870, 1871, 1875, + 1877, 1879, 1880, 1881, 1882, 1882, 1883, 1882, + 1884, 1885, 1886, 1886, 1889, 1890, 1890, 1893, + 1893, 1891, 1891, 1893, 1892, 1894, 1896, 1897, + 1900, 1904, 1908, 1913, 1913, 1914, 1919, 1919, + 1923, 1929, 1932, 1937, 1940, 1945, 1949, 1953, + 1955, 1958, 1962, 1967, 1973, 1976, 1977, 1982, + 1986, 1989, 1993, 1999, 2001, 2007, 2009, 2012, + 2018, 2022, 2025, 2033, 2040, 2045, 2051, 2059, + 2064, 2073, 2081, 2082, 2092, 2098, 2105, 2111, + 2116, 2121, 2128, 2133, 2136, 2139, 2142, 2146, + 2152, 2156, 2158, 2161, 2167, 2165, 2169, 2173, + 2174, 2179, 2175, 2176, 2179, 2181, 2184, 2185, + 2186, 2188, 2191, 2189, 2190, 2190, 2191, 2193, + 2197, 2197, 2196, 2199, 2199, 2199, 2201, 2203, + 2205, 2208, 2210, 2212, 2214, 2216, 2219, 2222, + 2222, 2227, 2229, 2229, 2233, 2234, 2236, 2238, + 2240, 2242, 2244, 2248, 2249, 2251, 2250, 2250, + 2251, 2248, 2248, 2247, 2248, 2250, 2250, 2248, + 2247, 2247, 2247, 2247, 2248, 2250, 2252, 2253, + 2253, 2254, 2256, 2258, 2257, 2257, 2256, 2259, + 2258, 2257, 2257, 2256, 2253, 2256, 2258, 2254, + 2251, 2247, 2245, 2243, 2240, 2236, 2231, 2227, + 2224, 2221, 2217, 2215, 2214, 2210, 2206, 2202, + 2200, 2199, 2193, 2190, 2186, 2182, 2180, 2175, + 2171, 2168, 2162, 2157, 2152, 2148, 2144, 2139, + 2131, 2125, 2118, 2113, 2109, 2104, 2099, 2095, + 2090, 2087, 2082, 2076, 2070, 2068, 2065, 2056, + 2052, 2051, 2048, 2048, 2043, 2041, 2037, 2034, + 2030, 2026, 2023, 2021, 2020, 2017, 2014, 2011, + 2009, 2005, 2004, 2003, 2002, 2001, 2000, 1995, + 1993, 1992, 1987, 1984, 1984, 1979, 1976, 1972, + 1967, 1966, 1962, 1960, 1957, 1956, 1956, 1955, + 1953, 1951, 1949, 1946, 1944, 1942, 1938, 1936, + 1937, 1934, 1932, 1932, 1930, 1928, 1929, 1926, + 1925, 1925, 1923, 1923, 1922, 1919, 1922, 1920, + 1920, 1921, 1919, 1924, 1926, 1928, 1929, 1929, + 1934, 1936, 1936, 1937, 1937, 1939, 1939, 1943, + 1944, 1947, 1948, 1950, 1952, 1955, 1959, 1959, + 1963, 1964, 1967, 1970, 1972, 1975, 1978, 1981, + 1985, 1985, 1991, 1994, 1997, 2002, 2007, 2013, + 2016, 2022, 2025, 2028, 2031, 2032, 2033, 2035, + 2040, 2043, 2046, 2049, 2053, 2052, 2052, 2051, + 2050, 2052, 2054, 2053, 2053, 2058, 2062, 2063, + 2064, 2066, 2068, 2066, 2069, 2070, 2071, 2073, + 2074, 2074, 2076, 2076, 2076, 2078, 2077, 2079, + 2078, 2079, 2079, 2078, 2078, 2077, 2074, 2074, + 2073, 2074, 2070, 2068, 2070, 2069, 2067, 2067, + 2064, 2064, 2066, 2065, 2065, 2064, 2063, 2066, + 2066, 2066, 2064, 2065, 2067, 2065, 2067, 2068, + 2067, 2067, 2068, 2068, 2068, 2068, 2069, 2069, + 2071, 2071, 2072, 2075, 2076, 2076, 2076, 2076, + 2076, 2077, 2078, 2080, 2082, 2084, 2087, 2089, + 2090, 2091, 2091, 2093, 2091, 2093, 2097, 2097, + 2098, 2100, 2102, 2102, 2105, 2104, 2103, 2103, + 2105, 2105, 2111, 2112, 2109, 2111, 2111, 2110, + 2108, 2108, 2109, 2110, 2112, 2110, 2106, 2106, + 2106, 2106, 2101, 2102, 2103, 2101, 2098, 2098, + 2098, 2096, 2092, 2092, 2088, 2089, 2085, 2082, + 2081, 2077, 2074, 2069, 2068, 2062, 2058, 2057, + 2054, 2051, 2048, 2046, 2042, 2041, 2037, 2037, + 2031, 2026, 2026, 2021, 2018, 2015, 2011, 2006, + 2000, 1999, 1994, 1991, 1986, 1983, 1984, 1982, + 1980, 1978, 1978, 1977, 1976, 1975, 1973, 1974, + 1974, 1974, 1974, 1974, 1977, 1978, 1977, 1976, + 1976, 1977, 1976, 1978, 1981, 1982, 1980, 1983, + 1984, 1985, 1986, 1985, 1982, 1983, 1983, 1984, + 1984, 1987, 1984, 1983, 1984, 1980, 1979, 1984, + 1981, 1980, 1983, 1985, 1984, 1984, 1982, 1982, + 1987, 1987, 1986, 1992, 1989, 1989, 1998, 2001, + 2000, 2002, 2003, 2003, 2004, 2005, 2007, 2009, + 2010, 2010, 2013, 2013, 2014, 2014, 2016, 2021, + 2018, 2019, 2022, 2026, 2029, 2028, 2029, 2029, + 2033, 2034, 2032, 2035, 2035, 2035, 2038, 2039, + 2041, 2044, 2047, 2046, 2047, 2052, 2054, 2058, + 2059, 2058, 2060, 2063, 2065, 2068, 2067, 2069, + 2068, 2067, 2071, 2073, 2073, 2073, 2075, 2073, + 2071, 2069, 2072, 2072, 2072, 2073, 2072, 2067, + 2063, 2068, 2069, 2068, 2067, 2066, 2066, 2064, + 2065, 2064, 2063, 2061, 2061, 2059, 2061, 2061, + 2059, 2058, 2059, 2056, 2051, 2052, 2051, 2047, + 2045, 2042, 2039, 2041, 2041, 2036, 2035, 2032, + 2031, 2032, 2031, 2028, 2028, 2026, 2026, 2023, + 2022, 2021, 2022, 2022, 2020, 2019, 2016, 2018, + 2017, 2016, 2015, 2013, 2016, 2019, 2019, 2021, + 2023, 2024, 2025, 2027, 2029, 2030, 2033, 2032, + 2035, 2041, 2042, 2043, 2046, 2050, 2051, 2053, + 2057, 2056, 2058, 2055, 2056, 2056, 2054, 2051, + 2051, 2051, 2046, 2045, 2047, 2046, 2046, 2047, + 2046, 2043, 2044, 2041, 2041, 2040, 2040, 2041, + 2040, 2041, 2038, 2036, 2035, 2036, 2037, 2037, + 2034, 2035, 2033, 2030, 2030, 2029, 2029, 2028, + 2027, 2028, 2028, 2026, 2025, 2025, 2028, 2028, + 2030, 2031, 2031, 2033, 2038, 2039, 2040, 2042, + 2044, 2048, 2050, 2050, 2055, 2059, 2064, 2065, + 2068, 2071, 2074, 2076, 2076, 2080, 2086, 2085, + 2086, 2091, 2090, 2092, 2096, 2096, 2097, 2100, + 2103, 2105, 2103, 2104, 2104, 2106, 2107, 2106, + 2107, 2108, 2107, 2108, 2109, 2107, 2107, 2109, + 2107, 2108, 2105, 2103, 2102, 2101, 2101, 2101, + 2101, 2100, 2102, 2099, 2100, 2103, 2100, 2098, + 2095, 2096, 2091, 2088, 2087, 2087, 2086, 2084, + 2084, 2081, 2082, 2081, 2077, 2075, 2073, 2071, + 2069, 2067, 2067, 2067, 2066, 2065, 2068, 2068, + 2066, 2066, 2064, 2063, 2063, 2060, 2058, 2058, + 2057, 2057, 2057, 2055, 2051, 2048, 2049, 2047, + 2046, 2045, 2042, 2042, 2042, 2040, 2040, 2039, + 2038, 2034, 2032, 2032, 2032, 2031, 2029, 2029, + 2028, 2028, 2028, 2026, 2024, 2025, 2026, 2023, + 2024, 2024, 2023, 2023, 2020, 2021, 2020, 2021, + 2023, 2024, 2024, 2026, 2026, 2026, 2026, 2030, + 2028, 2030, 2032, 2034, 2032, 2032, 2032, 2034, + 2038, 2039, 2039, 2037, 2036, 2041, 2043, 2043, + 2044, 2046, 2050, 2052, 2046, 2045, 2048, 2051, + 2049, 2049, 2047, 2047, 2046, 2042, 2041, 2043, + 2040, 2040, 2045, 2045, 2043, 2043, 2038, 2040, + 2037, 2030, 2027, 2031, 2038, 2034, 2038, 2039, + 2033, 2032, 2032, 2028, 2029, 2035, 2037, 2038, + 2038, 2038, 2044, 2047, 2042, 2039, 2043, 2042, + 2044, 2048, 2048, 2051, 2051, 2056, 2058, 2058, + 2055, 2055, 2055, 2060, 2066, 2067, 2070, 2072, + 2074, 2069, 2069, 2070, 2070, 2074, 2076, 2074, + 2074, 2077, 2079, 2080, 2080, 2081, 2078, 2082, + 2084, 2084, 2086, 2086, 2087, 2081, 2087, 2090, + 2088, 2089, 2090, 2087, 2087, 2087, 2086, 2090, + 2094, 2090, 2088, 2093, 2093, 2091, 2090, 2089, + 2087, 2088, 2089, 2092, 2095, 2092, 2086, 2085, + 2085, 2085, 2088, 2087, 2084, 2078, 2075, 2078, + 2079, 2073, 2065, 2063, 2066, 2066, 2065, 2067, + 2063, 2056, 2060, 2062, 2060, 2059, 2062, 2057, + 2056, 2055, 2056, 2059, 2058, 2059, 2052, 2052, + 2054, 2054, 2057, 2055, 2053, 2055, 2056, 2054, + 2048, 2044, 2043, 2041, 2037, 2033, 2031, 2033, + 2035, 2035, 2030, 2025, 2024, 2025, 2028, 2024, + 2021, 2023, 2020, 2016, 2020, 2020, 2012, 2009, + 2015, 2019, 2021, 2019, 2015, 2018, 2017, 2012, + 2011, 2017, 2015, 2012, 2011, 2010, 2011, 2017, + 2018, 2014, 2013, 2015, 2011, 2006, 2006, 2005, + 2005, 2006, 2001, 2002, 2009, 2009, 2010, 2013, + 2017, 2021, 2019, 2020, 2024, 2025, 2028, 2029, + 2028, 2032, 2034, 2037, 2040, 2038, 2036, 2036, + 2040, 2039, 2034, 2034, 2033, 2027, 2030, 2033, + 2030, 2030, 2032, 2030, 2028, 2029, 2027, 2023, + 2022, 2022, 2017, 2018, 2021, 2020, 2017, 2014, + 2017, 2017, 2015, 2020, 2021, 2018, 2019, 2020, + 2021, 2019, 2017, 2017, 2018, 2021, 2021, 2021, + 2024, 2029, 2031, 2035, 2035, 2035, 2036, 2035, + 2038, 2043, 2047, 2048, 2046, 2043, 2045, 2047, + 2046, 2047, 2047, 2048, 2051, 2052, 2052, 2052, + 2052, 2051, 2052, 2050, 2045, 2047, 2050, 2048, + 2049, 2048, 2046, 2050, 2051, 2051, 2052, 2052, + 2055, 2056, 2056, 2055, 2060, 2061, 2057, 2061, + 2064, 2064, 2061, 2061, 2060, 2064, 2064, 2065, + 2068, 2067, 2066, 2066, 2067, 2069, 2070, 2068, + 2069, 2069, 2069, 2073, 2074, 2074, 2075, 2078, + 2082, 2081, 2079, 2084, 2088, 2086, 2085, 2088, + 2091, 2092, 2096, 2100, 2107, 2109, 2110, 2110, + 2113, 2112, 2110, 2114, 2116, 2116, 2116, 2115, + 2114, 2112, 2109, 2110, 2111, 2112, 2112, 2109, + 2108, 2108, 2111, 2113, 2113, 2111, 2109, 2107, + 2107, 2106, 2106, 2106, 2106, 2104, 2100, 2105, + 2105, 2101, 2104, 2104, 2104, 2103, 2098, 2096, + 2100, 2102, 2098, 2098, 2097, 2094, 2094, 2091, + 2089, 2090, 2091, 2091, 2087, 2086, 2086, 2086, + 2087, 2088, 2085, 2082, 2079, 2078, 2079, 2077, + 2079, 2077, 2078, 2078, 2077, 2078, 2083, 2083, + 2082, 2082, 2085, 2086, 2092, 2095, 2092, 2092, + 2096, 2096, 2100, 2102, 2103, 2106, 2108, 2106, + 2104, 2106, 2108, 2109, 2108, 2108, 2106, 2106, + 2103, 2103, 2105, 2103, 2102, 2099, 2098, 2101, + 2101, 2103, 2104, 2107, 2106, 2105, 2106, 2108, + 2108, 2107, 2107, 2106, 2109, 2111, 2108, 2107, + 2107, 2108, 2104, 2105, 2104, 2102, 2101, 2103, + 2107, 2103, 2101, 2099, 2096, 2097, 2098, 2098, + 2098, 2098, 2098, 2100, 2099, 2098, 2099, 2098, + 2098, 2100, 2102, 2099, 2098, 2096, 2095, 2097, + 2094, 2095, 2092, 2086, 2081, 2079, 2070, 2063, + 2053, 2046, 1902, 1613, 1570, 1719, 1812, 1882, + 1946, 1964, 1959, 1931, 1918, 1942, 1980, 2003, + 2025, 2040, 2049, 2063, 2059, 2053, 2062, 2086, + 2102, 2119, 2114, 2081, 2034, 2009, 2013, 2033, + 2068, 2109, 2134, 2126, 2096, 2053, 2007, 1980, + 1980, 2016, 2063, 2086, 2092, 2088, 2082, 2065, + 2051, 2037, 2030, 2040, 2056, 2065, 2048, 2026, + 2014, 2015, 2032, 2054, 2075, 2080, 2069, 2054, + 2031, 2011, 1994, 1982, 1987, 2005, 2030, 2055, + 2064, 2037, 1997, 1967, 1965, 1984, 2004, 2011, + 2007, 2002, 1993, 1985, 1985, 1984, 1985, 1988, + 1994, 1991, 1979, 1960, 1946, 1938, 1931, 1937, + 1952, 1972, 1984, 1979, 1953, 1927, 1909, 1894, + 1897, 1914, 1932, 1939, 1932, 1920, 1914, 1907, + 1913, 1933, 1944, 1937, 1933, 1935, 1925, 1916, + 1909, 1909, 1918, 1936, 1954, 1958, 1953, 1941, + 1927, 1914, 1908, 1925, 1941, 1949, 1955, 1954, + 1950, 1946, 1940, 1929, 1926, 1929, 1937, 1945, + 1950, 1942, 1932, 1925, 1928, 1940, 1947, 1950, + 1951, 1947, 1937, 1924, 1922, 1928, 1931, 1939, + 1947, 1950, 1948, 1941, 1938, 1932, 1927, 1924, + 1926, 1929, 1929, 1931, 1928, 1915, 1909, 1906, + 1909, 1914, 1919, 1921, 1919, 1912, 1903, 1897, + 1899, 1901, 1906, 1909, 1901, 1896, 1897, 1896, + 1893, 1887, 1880, 1884, 1884, 1878, 1878, 1881, + 1875, 1866, 1863, 1854, 1852, 1860, 1865, 1861, + 1853, 1859, 1865, 1865, 1858, 1859, 1858, 1853, + 1852, 1849, 1848, 1846, 1845, 1841, 1830, 1820, + 1827, 1834, 1827, 1828, 1826, 1806, 1804, 1805, + 1806, 1818, 1818, 1813, 1814, 1808, 1804, 1806, + 1813, 1816, 1820, 1821, 1816, 1815, 1813, 1814, + 1818, 1823, 1831, 1841, 1844, 1831, 1825, 1825, + 1821, 1826, 1827, 1827, 1831, 1836, 1841, 1840, + 1830, 1834, 1843, 1845, 1851, 1855, 1849, 1842, + 1839, 1838, 1837, 1841, 1841, 1842, 1842, 1836, + 1830, 1826, 1830, 1842, 1846, 1855, 1864, 1860, + 1859, 1857, 1850, 1853, 1859, 1858, 1862, 1867, + 1868, 1862, 1850, 1842, 1842, 1839, 1847, 1864, + 1870, 1869, 1870, 1862, 1850, 1842, 1846, 1856, + 1859, 1866, 1870, 1866, 1857, 1847, 1844, 1848, + 1858, 1863, 1863, 1861, 1856, 1853, 1858, 1867, + 1873, 1883, 1889, 1892, 1891, 1885, 1884, 1886, + 1891, 1904, 1919, 1925, 1924, 1919, 1911, 1904, + 1894, 1894, 1904, 1915, 1927, 1936, 1937, 1936, + 1926, 1918, 1920, 1926, 1931, 1938, 1937, 1935, + 1936, 1946, 1958, 1962, 1965, 1963, 1953, 1950, + 1947, 1935, 1923, 1914, 1911, 1914, 1925, 1931, + 1933, 1934, 1927, 1923, 1921, 1926, 1926, 1924, + 1929, 1938, 1952, 1956, 1956, 1959, 1957, 1960, + 1964, 1958, 1946, 1947, 1953, 1960, 1969, 1977, + 1983, 1981, 1975, 1965, 1955, 1948, 1937, 1921, + 1916, 1922, 1931, 1945, 1954, 1960, 1957, 1944, + 1927, 1922, 1923, 1925, 1929, 1932, 1943, 1952, + 1960, 1958, 1953, 1953, 1939, 1914, 1901, 1887, + 1880, 1878, 1878, 1883, 1881, 1882, 1888, 1896, + 1895, 1879, 1864, 1846, 1829, 1831, 1842, 1846, + 1851, 1867, 1873, 1866, 1852, 1838, 1834, 1833, + 1831, 1828, 1823, 1820, 1829, 1836, 1838, 1838, + 1837, 1827, 1814, 1801, 1801, 1802, 1797, 1797, + 1814, 1830, 1837, 1844, 1847, 1840, 1830, 1818, + 1803, 1797, 1801, 1811, 1823, 1838, 1837, 1823, + 1810, 1798, 1783, 1765, 1744, 1723, 1708, 1701, + 1701, 1715, 1728, 1737, 1731, 1725, 1723, 1719, + 1700, 1679, 1672, 1671, 1668, 1672, 1678, 1683, + 1692, 1698, 1695, 1684, 1671, 1662, 1660, 1653, + 1641, 1639, 1644, 1657, 1672, 1668, 1647, 1632, + 1626, 1617, 1598, 1584, 1588, 1597, 1603, 1613, + 1622, 1621, 1614, 1606, 1600, 1592, 1575, 1551, + 1537, 1531, 1525, 1531, 1557, 1573, 1574, 1571, + 1571, 1568, 1558, 1561, 1554, 1538, 1531, 1539, + 1553, 1560, 1558, 1547, 1531, 1511, 1498, 1493, + 1491, 1500, 1509, 1508, 1505, 1502, 1505, 1519, + 1531, 1527, 1524, 1529, 1524, 1513, 1517, 1521, + 1527, 1547, 1569, 1592, 1598, 1587, 1569, 1553, + 1538, 1528, 1531, 1538, 1540, 1540, 1544, 1552, + 1552, 1552, 1551, 1557, 1560, 1557, 1557, 1550, + 1535, 1513, 1493, 1501, 1524, 1536, 1543, 1542, + 1534, 1531, 1533, 1544, 1568, 1596, 1616, 1636, + 1653, 1658, 1654, 1647, 1641, 1634, 1637, 1632, + 1630, 1634, 1634, 1637, 1639, 1639, 1650, 1674, + 1689, 1687, 1672, 1663, 1647, 1635, 1646, 1661, + 1680, 1707, 1728, 1731, 1732, 1727, 1710, 1702, + 1711, 1730, 1758, 1770, 1772, 1779, 1778, 1776, + 1793, 1811, 1815, 1822, 1828, 1821, 1811, 1809, + 1812, 1828, 1852, 1871, 1891, 1899, 1881, 1856, + 1837, 1828, 1834, 1853, 1882, 1912, 1930, 1936, + 1931, 1924, 1934, 1962, 1991, 2007, 2007, 2003, + 2001, 1999, 2015, 2038, 2066, 2093, 2112, 2120, + 2119, 2112, 2104, 2106, 2123, 2136, 2155, 2178, + 2195, 2188, 2162, 2145, 2144, 2148, 2160, 2180, + 2194, 2201, 2196, 2189, 2186, 2197, 2213, 2233, + 2243, 2238, 2230, 2217, 2201, 2203, 2216, 2232, + 2251, 2267, 2278, 2283, 2276, 2258, 2252, 2264, + 2279, 2294, 2304, 2302, 2293, 2283, 2277, 2285, + 2302, 2315, 2320, 2313, 2309, 2311, 2316, 2322, + 2334, 2349, 2359, 2368, 2381, 2390, 2384, 2377, + 2381, 2404, 2430, 2449, 2464, 2479, 2481, 2471, + 2475, 2491, 2510, 2524, 2528, 2524, 2520, 2516, + 2523, 2539, 2550, 2559, 2572, 2582, 2583, 2579, + 2573, 2570, 2572, 2574, 2581, 2589, 2600, 2610, + 2602, 2594, 2596, 2610, 2629, 2641, 2642, 2638, + 2643, 2648, 2652, 2660, 2672, 2683, 2682, 2682, + 2692, 2700, 2699, 2703, 2715, 2721, 2724, 2734, + 2740, 2740, 2732, 2726, 2729, 2733, 2731, 2725, + 2721, 2722, 2718, 2708, 2703, 2707, 2714, 2720, + 2722, 2722, 2719, 2708, 2701, 2698, 2693, 2686, + 2679, 2678, 2676, 2676, 2672, 2671, 2663, 2648, + 2632, 2620, 2614, 2615, 2617, 2616, 2611, 2609, + 2603, 2592, 2586, 2587, 2590, 2594, 2590, 2584, + 2574, 2561, 2548, 2534, 2522, 2511, 2503, 2503, + 2501, 2496, 2488, 2488, 2486, 2484, 2492, 2504, + 2499, 2484, 2478, 2474, 2467, 2461, 2458, 2456, + 2449, 2438, 2429, 2426, 2422, 2413, 2404, 2394, + 2387, 2390, 2392, 2392, 2389, 2382, 2375, 2372, + 2367, 2355, 2347, 2346, 2344, 2340, 2333, 2325, + 2317, 2313, 2307, 2303, 2307, 2305, 2297, 2292, + 2288, 2282, 2280, 2282, 2289, 2295, 2298, 2289, + 2276, 2262, 2254, 2253, 2254, 2252, 2249, 2246, + 2234, 2221, 2213, 2214, 2208, 2198, 2192, 2194, + 2190, 2179, 2169, 2167, 2166, 2167, 2167, 2163, + 2155, 2144, 2133, 2130, 2130, 2127, 2123, 2124, + 2124, 2120, 2120, 2116, 2112, 2114, 2116, 2103, + 2083, 2074, 2068, 2068, 2069, 2079, 2093, 2098, + 2089, 2085, 2088, 2090, 2084, 2075, 2074, 2075, + 2079, 2081, 2079, 2075, 2076, 2086, 2096, 2099, + 2104, 2107, 2109, 2112, 2112, 2111, 2113, 2119, + 2123, 2128, 2131, 2130, 2123, 2117, 2118, 2120, + 2125, 2128, 2134, 2135, 2139, 2137, 2131, 2126, + 2123, 2127, 2127, 2126, 2121, 2119, 2114, 2115, + 2118, 2121, 2123, 2123, 2123, 2119, 2113, 2110, + 2107, 2102, 2102, 2105, 2109, 2109, 2099, 2085, + 2077, 2076, 2081, 2087, 2097, 2101, 2102, 2103, + 2104, 2103, 2104, 2108, 2111, 2112, 2111, 2109, + 2106, 2100, 2097, 2095, 2089, 2094, 2094, 2085, + 2074, 2067, 2058, 2053, 2056, 2058, 2056, 2052, + 2044, 2038, 2030, 2023, 2024, 2027, 2028, 2026, + 2019, 2015, 2020, 2022, 2020, 2013, 2013, 2010, + 2005, 2005, 2007, 2009, 2017, 2019, 2020, 2020, + 2021, 2021, 2019, 2015, 2019, 2023, 2031, 2039, + 2044, 2046, 2042, 2041, 2039, 2042, 2039, 2034, + 2030, 2025, 2019, 2020, 2022, 2026, 2028, 2026, + 2017, 2007, 1996, 1983, 1981, 1984, 1984, 1976, + 1973, 1974, 1966, 1953, 1947, 1948, 1947, 1943, + 1933, 1922, 1911, 1905, 1911, 1918, 1924, 1934, + 1942, 1938, 1933, 1927, 1928, 1932, 1937, 1950, + 1960, 1963, 1961, 1960, 1964, 1962, 1959, 1963, + 1964, 1956, 1946, 1936, 1935, 1931, 1925, 1926, + 1935, 1935, 1927, 1914, 1905, 1899, 1901, 1907, + 1910, 1912, 1910, 1908, 1908, 1909, 1914, 1918, + 1917, 1912, 1909, 1911, 1909, 1905, 1909, 1921, + 1931, 1936, 1938, 1940, 1942, 1937, 1934, 1926, + 1929, 1948, 1961, 1960, 1960, 1963, 1963, 1957, + 1954, 1955, 1955, 1953, 1950, 1948, 1953, 1959, + 1956, 1945, 1945, 1952, 1951, 1941, 1929, 1923, + 1926, 1931, 1933, 1940, 1959, 1969, 1961, 1949, + 1948, 1956, 1955, 1955, 1952, 1952, 1957, 1961, + 1968, 1977, 1986, 1991, 1985, 1987, 1991, 1988, + 1989, 1996, 2004, 2010, 2019, 2036, 2048, 2048, + 2044, 2041, 2040, 2048, 2062, 2075, 2078, 2074, + 2080, 2092, 2105, 2118, 2129, 2129, 2123, 2130, + 2141, 2144, 2148, 2163, 2173, 2168, 2169, 2179, + 2187, 2187, 2182, 2179, 2178, 2183, 2181, 2182, + 2190, 2202, 2204, 2195, 2194, 2196, 2198, 2197, + 2193, 2187, 2186, 2189, 2192, 2196, 2199, 2201, + 2198, 2196, 2201, 2201, 2196, 2191, 2193, 2202, + 2216, 2225, 2226, 2224, 2223, 2229, 2231, 2231, + 2236, 2241, 2242, 2240, 2251, 2260, 2265, 2267, + 2277, 2277, 2271, 2278, 2290, 2294, 2292, 2293, + 2301, 2308, 2320, 2332, 2339, 2336, 2327, 2320, + 2330, 2349, 2359, 2361, 2361, 2364, 2361, 2366, + 2371, 2378, 2380, 2379, 2374, 2367, 2367, 2370, + 2375, 2376, 2373, 2374, 2376, 2366, 2361, 2363, + 2362, 2358, 2354, 2351, 2355, 2360, 2359, 2361, + 2364, 2368, 2372, 2374, 2376, 2378, 2382, 2385, + 2393, 2400, 2400, 2393, 2394, 2399, 2399, 2397, + 2397, 2398, 2399, 2399, 2406, 2415, 2414, 2408, + 2402, 2405, 2408, 2405, 2404, 2404, 2404, 2410, + 2414, 2417, 2423, 2419, 2419, 2420, 2418, 2420, + 2423, 2423, 2420, 2424, 2421, 2420, 2426, 2431, + 2429, 2423, 2417, 2413, 2413, 2413, 2420, 2425, + 2424, 2424, 2419, 2416, 2417, 2422, 2418, 2420, + 2423, 2423, 2422, 2426, 2436, 2441, 2442, 2444, + 2446, 2446, 2442, 2443, 2446, 2449, 2446, 2445, + 2449, 2454, 2459, 2457, 2453, 2451, 2448, 2443, + 2441, 2445, 2447, 2449, 2450, 2452, 2455, 2459, + 2457, 2451, 2444, 2439, 2439, 2441, 2448, 2453, + 2455, 2462, 2468, 2471, 2476, 2482, 2486, 2490, + 2486, 2488, 2493, 2500, 2511, 2517, 2520, 2518, + 2521, 2526, 2525, 2521, 2528, 2539, 2545, 2547, + 2554, 2562, 2568, 2573, 2578, 2581, 2586, 2592, + 2596, 2600, 2607, 2612, 2619, 2631, 2639, 2641, + 2639, 2635, 2634, 2639, 2647, 2647, 2645, 2651, + 2650, 2649, 2646, 2635, 2628, 2628, 2627, 2621, + 2614, 2604, 2593, 2591, 2596, 2601, 2595, 2588, + 2590, 2587, 2578, 2579, 2585, 2590, 2589, 2587, + 2589, 2587, 2581, 2582, 2583, 2578, 2572, 2576, + 2576, 2578, 2577, 2576, 2577, 2580, 2584, 2586, + 2588, 2583, 2581, 2587, 2588, 2585, 2591, 2602, + 2605, 2607, 2607, 2609, 2611, 2612, 2614, 2615, + 2615, 2610, 2610, 2610, 2608, 2608, 2609, 2611, + 2600, 2591, 2593, 2592, 2589, 2582, 2575, 2572, + 2572, 2567, 2562, 2557, 2553, 2541, 2532, 2534, + 2534, 2530, 2529, 2526, 2522, 2518, 2512, 2504, + 2507, 2514, 2506, 2494, 2493, 2495, 2490, 2485, + 2487, 2489, 2483, 2470, 2468, 2471, 2471, 2468, + 2465, 2458, 2454, 2449, 2444, 2438, 2429, 2418, + 2416, 2412, 2408, 2404, 2394, 2395, 2395, 2384, + 2376, 2369, 2365, 2359, 2350, 2343, 2343, 2339, + 2331, 2330, 2324, 2320, 2315, 2303, 2295, 2292, + 2289, 2281, 2279, 2276, 2273, 2268, 2266, 2264, + 2259, 2251, 2248, 2244, 2242, 2238, 2234, 2231, + 2231, 2223, 2218, 2218, 2221, 2217, 2209, 2205, + 2201, 2200, 2199, 2202, 2205, 2207, 2203, 2202, + 2201, 2198, 2195, 2195, 2194, 2192, 2191, 2194, + 2196, 2200, 2199, 2202, 2200, 2199, 2196, 2197, + 2203, 2201, 2202, 2204, 2207, 2208, 2211, 2216, + 2215, 2214, 2212, 2213, 2217, 2223, 2227, 2230, + 2236, 2239, 2248, 2254, 2258, 2263, 2269, 2277, + 2286, 2300, 2315, 2331, 2342, 2355, 2371, 2385, + 2398, 2413, 2430, 2443, 2458, 2473, 2486, 2497, + 2512, 2523, 2529, 2533, 2538, 2542, 2546, 2549, + 2553, 2559, 2564, 2564, 2560, 2563, 2559, 2552, + 2548, 2546, 2545, 2540, 2540, 2541, 2537, 2539, + 2544, 2542, 2536, 2531, 2532, 2528, 2522, 2519, + 2516, 2524, 2527, 2527, 2531, 2536, 2536, 2532, + 2531, 2539, 2544, 2544, 2545, 2553, 2564, 2570, + 2571, 2571, 2573, 2574, 2578, 2587, 2595, 2598, + 2603, 2610, 2618, 2628, 2632, 2640, 2652, 2653, + 2650, 2652, 2655, 2660, 2671, 2676, 2681, 2691, + 2688, 2681, 2687, 2690, 2696, 2699, 2698, 2704, + 2709, 2706, 2708, 2717, 2717, 2711, 2710, 2709, + 2710, 2704, 2696, 2691, 2681, 2675, 2668, 2654, + 2634, 2608, 2581, 2560, 2539, 2511, 2479, 2446, + 2408, 2367, 2330, 2289, 2248, 2195, 2139, 2091, + 2037, 1980, 1927, 1871, 1817, 1766, 1716, 1665, + 1613, 1558, 1507, 1465, 1427, 1394, 1363, 1339, + 1315, 1291, 1276, 1266, 1257, 1252, 1253, 1260, + 1271, 1279, 1294, 1316, 1338, 1365, 1393, 1420, + 1443, 1471, 1502, 1534, 1568, 1599, 1629, 1655, + 1681, 1709, 1734, 1755, 1774, 1789, 1803, 1818, + 1828, 1841, 1851, 1855, 1859, 1862, 1864, 1869, + 1868, 1860, 1856, 1850, 1845, 1842, 1837, 1832, + 1824, 1818, 1807, 1802, 1794, 1792, 1786, 1778, + 1773, 1767, 1767, 1769, 1772, 1773, 1772, 1773, + 1777, 1782, 1788, 1799, 1816, 1836, 1857, 1880, + 1905, 1928, 1951, 1974, 2000, 2027, 2055, 2085, + 2120, 2149, 2179, 2208, 2240, 2272, 2298, 2323, + 2347, 2371, 2397, 2422, 2446, 2467, 2487, 2501, + 2516, 2532, 2544, 2550, 2557, 2561, 2567, 2575, + 2578, 2578, 2579, 2580, 2583, 2585, 2585, 2586, + 2587, 2585, 2582, 2590, 2595, 2599, 2601, 2602, + 2608, 2619, 2631, 2635, 2642, 2649, 2660, 2669, + 2683, 2704, 2721, 2739, 2755, 2769, 2791, 2811, + 2829, 2849, 2870, 2888, 2909, 2931, 2948, 2968, + 2989, 3004, 3031, 3052, 3063, 3069, 3081, 3095, + 3102, 3097, 3073, 3042, 3007, 2964, 2919, 2869, + 2814, 2755, 2694, 2634, 2584, 2535, 2473, 2404, + 2319, 2222, 2138, 2079, 2021, 1957, 1890, 1819, + 1758, 1713, 1675, 1641, 1610, 1569, 1526, 1500, + 1493, 1504, 1519, 1531, 1548, 1567, 1587, 1608, + 1634, 1661, 1680, 1704, 1738, 1782, 1844, 1901, + 1949, 1987, 2025, 2062, 2095, 2129, 2158, 2179, + 2192, 2209, 2225, 2246, 2277, 2294, 2301, 2296, + 2281, 2267, 2259, 2260, 2268, 2267, 2258, 2245, + 2229, 2214, 2201, 2187, 2168, 2145, 2119, 2090, + 2065, 2040, 2013, 1981, 1950, 1932, 1907, 1860, + 1805, 1751, 1700, 1661, 1626, 1591, 1554, 1504, + 1442, 1388, 1340, 1296, 1263, 1237, 1213, 1194, + 1173, 1159, 1154, 1154, 1160, 1173, 1190, 1202, + 1210, 1213, 1242, 1277, 1318, 1370, 1421, 1473, + 1517, 1558, 1603, 1657, 1711, 1762, 1812, 1857, + 1895, 1926, 1956, 1985, 2009, 2027, 2039, 2044, + 2042, 2038, 2037, 2039, 2047, 2055, 2057, 2049, + 2030, 2008, 1990, 1981, 1974, 1971, 1966, 1957, + 1949, 1943, 1944, 1953, 1964, 1979, 1986, 1991, + 2002, 2018, 2040, 2069, 2099, 2130, 2163, 2189, + 2212, 2233, 2261, 2297, 2338, 2381, 2416, 2454, + 2493, 2537, 2578, 2621, 2664, 2701, 2730, 2753, + 2776, 2805, 2841, 2877, 2914, 2940, 2961, 2975, + 2984, 2993, 3008, 3028, 3044, 3054, 3055, 3054, + 3058, 3063, 3072, 3080, 3086, 3082, 3074, 3069, + 3070, 3078, 3094, 3116, 3134, 3147, 3155, 3161, + 3171, 3185, 3203, 3222, 3235, 3235, 3229, 3218, + 3210, 3205, 3190, 3171, 3144, 3109, 3055, 3002, + 2953, 2902, 2840, 2760, 2669, 2559, 2445, 2337, + 2236, 2132, 2031, 1930, 1828, 1731, 1635, 1546, + 1473, 1410, 1352, 1298, 1258, 1226, 1205, 1195, + 1206, 1238, 1269, 1305, 1354, 1404, 1461, 1534, + 1624, 1727, 1839, 1952, 2056, 2159, 2258, 2362, + 2465, 2569, 2668, 2751, 2819, 2882, 2944, 3005, + 3063, 3111, 3143, 3152, 3148, 3135, 3115, 3092, + 3068, 3039, 2996, 2942, 2881, 2812, 2744, 2679, + 2611, 2549, 2481, 2412, 2346, 2283, 2230, 2185, + 2142, 2090, 2025, 1945, 1869, 1809, 1762, 1720, + 1681, 1633, 1574, 1519, 1480, 1451, 1427, 1397, + 1363, 1325, 1286, 1258, 1241, 1236, 1234, 1229, + 1226, 1224, 1222, 1220, 1230, 1252, 1284, 1329, + 1379, 1436, 1490, 1540, 1591, 1652, 1720, 1787, + 1850, 1907, 1961, 2016, 2078, 2145, 2213, 2274, + 2319, 2349, 2369, 2380, 2387, 2400, 2411, 2407, + 2392, 2366, 2329, 2292, 2255, 2225, 2192, 2149, + 2101, 2046, 1995, 1956, 1932, 1913, 1897, 1880, + 1851, 1825, 1806, 1799, 1808, 1830, 1854, 1880, + 1905, 1935, 1978, 2031, 2093, 2154, 2209, 2259, + 2315, 2369, 2428, 2497, 2564, 2630, 2685, 2733, + 2777, 2822, 2862, 2904, 2943, 2976, 3003, 3026, + 3043, 3062, 3076, 3079, 3077, 3076, 3075, 3063, + 3048, 3035, 3029, 3022, 3021, 3021, 3020, 3012, + 3004, 3001, 2998, 3004, 3013, 3022, 3031, 3035, + 3038, 3044, 3054, 3058, 3057, 3050, 3036, 3019, + 2998, 2976, 2955, 2925, 2883, 2829, 2770, 2691, + 2600, 2506, 2403, 2296, 2176, 2054, 1938, 1819, + 1703, 1592, 1488, 1383, 1281, 1183, 1096, 1024, + 961, 917, 890, 874, 873, 880, 901, 937, + 983, 1040, 1112, 1195, 1283, 1390, 1504, 1623, + 1753, 1883, 2011, 2131, 2245, 2356, 2464, 2566, + 2664, 2752, 2833, 2906, 2968, 3010, 3039, 3068, + 3070, 3054, 3033, 3002, 2960, 2908, 2853, 2792, + 2724, 2645, 2564, 2476, 2380, 2289, 2199, 2116, + 2039, 1969, 1899, 1839, 1780, 1722, 1670, 1626, + 1585, 1544, 1503, 1462, 1412, 1370, 1340, 1320, + 1299, 1272, 1252, 1224, 1193, 1168, 1156, 1155, + 1152, 1147, 1140, 1129, 1116, 1113, 1115, 1130, + 1143, 1146, 1152, 1169, 1187, 1215, 1258, 1301, + 1345, 1385, 1428, 1469, 1511, 1555, 1611, 1669, + 1716, 1761, 1802, 1841, 1880, 1920, 1959, 1995, + 2024, 2045, 2060, 2069, 2073, 2071, 2067, 2057, + 2039, 2006, 1965, 1921, 1879, 1835, 1799, 1764, + 1727, 1688, 1654, 1621, 1596, 1575, 1562, 1556, + 1549, 1545, 1545, 1557, 1578, 1610, 1654, 1700, + 1752, 1808, 1869, 1935, 2007, 2089, 2173, 2253, + 2327, 2396, 2458, 2518, 2580, 2640, 2694, 2739, + 2772, 2798, 2824, 2852, 2878, 2901, 2925, 2935, + 2940, 2938, 2935, 2931, 2927, 2927, 2921, 2911, + 2897, 2881, 2866, 2861, 2861, 2860, 2860, 2859, + 2858, 2855, 2858, 2860, 2863, 2864, 2863, 2856, + 2841, 2817, 2798, 2777, 2750, 2716, 2676, 2629, + 2570, 2498, 2413, 2325, 2232, 2122, 2010, 1907, + 1791, 1673, 1558, 1448, 1348, 1253, 1159, 1073, + 993, 920, 863, 823, 799, 791, 793, 806, + 836, 870, 913, 973, 1048, 1135, 1229, 1332, + 1440, 1556, 1679, 1806, 1939, 2067, 2184, 2295, + 2398, 2490, 2579, 2663, 2733, 2800, 2849, 2882, + 2903, 2910, 2900, 2880, 2851, 2810, 2755, 2692, + 2623, 2550, 2473, 2393, 2308, 2220, 2127, 2035, + 1944, 1859, 1783, 1713, 1649, 1596, 1549, 1509, + 1478, 1445, 1415, 1385, 1360, 1340, 1317, 1291, + 1271, 1259, 1243, 1229, 1219, 1212, 1199, 1181, + 1170, 1164, 1165, 1161, 1158, 1156, 1153, 1149, + 1150, 1159, 1173, 1185, 1196, 1212, 1236, 1264, + 1297, 1339, 1383, 1424, 1464, 1507, 1547, 1584, + 1627, 1668, 1711, 1747, 1781, 1813, 1845, 1872, + 1901, 1928, 1947, 1958, 1964, 1965, 1962, 1954, + 1943, 1927, 1906, 1875, 1838, 1802, 1770, 1737, + 1702, 1671, 1644, 1620, 1597, 1577, 1565, 1556, + 1550, 1547, 1549, 1557, 1572, 1587, 1610, 1645, + 1686, 1734, 1786, 1845, 1906, 1973, 2045, 2126, + 2209, 2289, 2365, 2435, 2502, 2571, 2632, 2690, + 2745, 2789, 2826, 2859, 2890, 2916, 2935, 2955, + 2975, 2991, 2997, 2994, 2989, 2977, 2966, 2959, + 2952, 2949, 2937, 2913, 2888, 2865, 2848, 2834, + 2820, 2794, 2762, 2729, 2699, 2671, 2644, 2619, + 2584, 2538, 2488, 2428, 2368, 2301, 2224, 2142, + 2053, 1956, 1853, 1754, 1662, 1572, 1481, 1390, + 1308, 1226, 1147, 1074, 1012, 962, 921, 893, + 877, 865, 870, 889, 924, 970, 1024, 1086, + 1153, 1230, 1315, 1407, 1510, 1618, 1729, 1841, + 1944, 2043, 2141, 2233, 2319, 2402, 2475, 2538, + 2598, 2649, 2685, 2714, 2732, 2734, 2725, 2703, + 2663, 2611, 2549, 2481, 2415, 2348, 2276, 2196, + 2114, 2031, 1949, 1867, 1792, 1723, 1661, 1605, + 1552, 1505, 1468, 1436, 1411, 1383, 1352, 1314, + 1281, 1252, 1236, 1221, 1201, 1186, 1171, 1157, + 1149, 1149, 1146, 1136, 1132, 1127, 1123, 1124, + 1135, 1145, 1155, 1163, 1160, 1169, 1187, 1210, + 1238, 1273, 1311, 1355, 1404, 1452, 1503, 1550, + 1598, 1647, 1691, 1729, 1764, 1798, 1828, 1857, + 1885, 1910, 1928, 1939, 1953, 1964, 1968, 1963, + 1955, 1941, 1919, 1892, 1865, 1834, 1804, 1772, + 1731, 1695, 1659, 1627, 1603, 1584, 1566, 1557, + 1554, 1551, 1552, 1560, 1580, 1595, 1617, 1646, + 1679, 1724, 1772, 1825, 1882, 1938, 1994, 2063, + 2135, 2205, 2276, 2347, 2419, 2491, 2564, 2640, + 2709, 2770, 2815, 2857, 2897, 2932, 2966, 2993, + 3017, 3035, 3045, 3052, 3059, 3067, 3068, 3072, + 3071, 3054, 3030, 3006, 2988, 2967, 2945, 2926, + 2897, 2854, 2807, 2758, 2711, 2665, 2621, 2573, + 2512, 2443, 2366, 2289, 2212, 2128, 2034, 1924, + 1801, 1677, 1567, 1465, 1369, 1283, 1202, 1126, + 1051, 982, 931, 896, 866, 842, 835, 845, + 865, 900, 951, 1014, 1086, 1160, 1242, 1332, + 1430, 1535, 1650, 1772, 1896, 2020, 2142, 2253, + 2352, 2438, 2514, 2578, 2632, 2675, 2708, 2731, + 2748, 2755, 2752, 2738, 2707, 2660, 2601, 2531, + 2453, 2371, 2289, 2206, 2121, 2038, 1951, 1867, + 1784, 1701, 1624, 1556, 1497, 1452, 1413, 1382, + 1366, 1357, 1345, 1330, 1316, 1299, 1272, 1237, + 1203, 1181, 1167, 1153, 1142, 1134, 1123, 1102, + 1086, 1080, 1077, 1072, 1067, 1071, 1079, 1087, + 1099, 1120, 1149, 1174, 1197, 1227, 1260, 1301, + 1348, 1402, 1464, 1528, 1587, 1642, 1694, 1739, + 1779, 1814, 1845, 1873, 1894, 1913, 1928, 1946, + 1962, 1974, 1982, 1978, 1964, 1939, 1912, 1883, + 1856, 1827, 1793, 1758, 1719, 1677, 1640, 1610, + 1583, 1561, 1542, 1537, 1538, 1546, 1567, 1592, + 1623, 1659, 1689, 1718, 1751, 1791, 1831, 1877, + 1930, 1990, 2051, 2110, 2172, 2236, 2297, 2353, + 2402, 2449, 2495, 2541, 2584, 2619, 2648, 2671, + 2693, 2711, 2727, 2742, 2753, 2769, 2782, 2803, + 2829, 2851, 2878, 2904, 2927, 2941, 2950, 2951, + 2942, 2928, 2917, 2901, 2876, 2843, 2803, 2766, + 2714, 2660, 2605, 2539, 2459, 2361, 2250, 2134, + 2021, 1900, 1768, 1634, 1507, 1377, 1254, 1147, + 1050, 960, 877, 803, 754, 726, 703, 690, + 699, 722, 757, 805, 874, 956, 1044, 1134, + 1238, 1357, 1481, 1608, 1737, 1864, 1991, 2113, + 2225, 2328, 2418, 2488, 2545, 2587, 2618, 2635, + 2642, 2639, 2620, 2592, 2552, 2505, 2447, 2375, + 2296, 2214, 2126, 2035, 1947, 1857, 1771, 1686, + 1604, 1532, 1471, 1415, 1371, 1338, 1316, 1304, + 1307, 1318, 1330, 1339, 1343, 1344, 1338, 1328, + 1319, 1297, 1262, 1225, 1196, 1172, 1148, 1120, + 1093, 1068, 1037, 1005, 987, 976, 965, 949, + 943, 942, 943, 953, 976, 1006, 1038, 1073, + 1118, 1173, 1236, 1308, 1381, 1456, 1531, 1599, + 1659, 1718, 1767, 1807, 1843, 1878, 1908, 1926, + 1936, 1943, 1945, 1941, 1934, 1917, 1890, 1851, + 1806, 1761, 1719, 1673, 1624, 1579, 1538, 1496, + 1460, 1442, 1435, 1437, 1447, 1467, 1499, 1536, + 1581, 1632, 1683, 1737, 1795, 1853, 1914, 1979, + 2042, 2105, 2168, 2238, 2308, 2369, 2428, 2482, + 2533, 2582, 2623, 2661, 2688, 2700, 2712, 2724, + 2733, 2739, 2735, 2729, 2724, 2719, 2718, 2734, + 2756, 2772, 2784, 2800, 2822, 2836, 2839, 2823, + 2803, 2780, 2749, 2714, 2676, 2636, 2582, 2508, + 2439, 2379, 2307, 2207, 2097, 1977, 1841, 1695, + 1563, 1455, 1351, 1237, 1117, 1015, 923, 843, + 781, 739, 709, 686, 675, 696, 742, 803, + 874, 961, 1055, 1146, 1237, 1334, 1440, 1562, + 1693, 1830, 1968, 2097, 2218, 2322, 2415, 2498, + 2564, 2606, 2631, 2638, 2623, 2603, 2579, 2547, + 2506, 2451, 2371, 2276, 2176, 2077, 1988, 1900, + 1818, 1734, 1648, 1571, 1500, 1429, 1366, 1308, + 1252, 1206, 1176, 1163, 1164, 1186, 1215, 1244, + 1267, 1279, 1285, 1271, 1246, 1230, 1216, 1196, + 1172, 1147, 1109, 1061, 1018, 988, 970, 944, + 908, 878, 858, 847, 850, 874, 915, 942, + 958, 979, 1013, 1060, 1118, 1193, 1280, 1361, + 1435, 1512, 1598, 1679, 1755, 1819, 1866, 1903, + 1928, 1939, 1954, 1973, 1977, 1973, 1961, 1934, + 1892, 1842, 1790, 1744, 1700, 1654, 1600, 1540, + 1483, 1428, 1385, 1354, 1329, 1309, 1296, 1298, + 1318, 1358, 1414, 1485, 1560, 1628, 1696, 1767, + 1842, 1913, 1991, 2071, 2150, 2229, 2292, 2350, + 2414, 2479, 2535, 2582, 2628, 2658, 2673, 2682, + 2700, 2721, 2728, 2725, 2719, 2707, 2679, 2653, + 2642, 2645, 2649, 2649, 2658, 2676, 2697, 2726, + 2755, 2770, 2767, 2755, 2739, 2722, 2696, 2663, + 2621, 2565, 2499, 2432, 2359, 2262, 2157, 2046, + 1915, 1769, 1624, 1487, 1368, 1254, 1134, 1031, + 931, 833, 759, 706, 669, 645, 635, 651, + 689, 745, 819, 914, 1021, 1131, 1240, 1348, + 1460, 1580, 1706, 1839, 1977, 2111, 2231, 2338, + 2431, 2513, 2577, 2616, 2638, 2643, 2627, 2592, + 2550, 2503, 2451, 2386, 2304, 2208, 2103, 1997, + 1897, 1801, 1719, 1645, 1576, 1513, 1455, 1402, + 1358, 1322, 1296, 1270, 1253, 1244, 1252, 1269, + 1290, 1315, 1335, 1346, 1342, 1325, 1299, 1269, + 1236, 1190, 1140, 1090, 1038, 986, 931, 880, + 837, 794, 755, 723, 711, 714, 726, 754, + 795, 844, 896, 954, 1020, 1100, 1186, 1273, + 1369, 1472, 1574, 1672, 1766, 1855, 1932, 1995, + 2040, 2069, 2094, 2106, 2103, 2096, 2079, 2048, + 2006, 1953, 1897, 1834, 1774, 1708, 1641, 1579, + 1520, 1465, 1414, 1377, 1348, 1328, 1321, 1319, + 1329, 1361, 1410, 1471, 1540, 1618, 1698, 1779, + 1866, 1952, 2034, 2117, 2192, 2258, 2320, 2377, + 2431, 2479, 2521, 2558, 2581, 2596, 2610, 2617, + 2616, 2618, 2625, 2624, 2610, 2601, 2597, 2589, + 2584, 2589, 2594, 2612, 2633, 2651, 2692, 2745, + 2787, 2813, 2835, 2854, 2852, 2837, 2821, 2803, + 2774, 2715, 2641, 2566, 2481, 2384, 2272, 2143, + 2003, 1843, 1666, 1507, 1374, 1251, 1128, 1015, + 915, 821, 744, 691, 659, 650, 654, 671, + 713, 783, 872, 979, 1108, 1238, 1364, 1477, + 1592, 1713, 1838, 1966, 2090, 2207, 2314, 2405, + 2475, 2525, 2559, 2571, 2561, 2537, 2497, 2435, + 2363, 2295, 2229, 2157, 2073, 1981, 1880, 1778, + 1689, 1613, 1551, 1506, 1470, 1436, 1418, 1406, + 1398, 1399, 1408, 1421, 1435, 1449, 1461, 1480, + 1502, 1516, 1514, 1500, 1473, 1432, 1372, 1303, + 1236, 1162, 1081, 995, 917, 848, 785, 718, + 669, 632, 595, 575, 574, 601, 646, 693, + 755, 835, 929, 1024, 1124, 1236, 1354, 1468, + 1576, 1688, 1800, 1903, 1985, 2051, 2106, 2150, + 2168, 2162, 2149, 2130, 2093, 2045, 1989, 1929, + 1862, 1792, 1715, 1639, 1573, 1511, 1451, 1398, + 1359, 1335, 1321, 1323, 1331, 1356, 1402, 1453, + 1507, 1576, 1665, 1755, 1838, 1929, 2023, 2110, + 2190, 2261, 2323, 2373, 2415, 2449, 2473, 2497, + 2513, 2504, 2491, 2485, 2468, 2443, 2430, 2413, + 2380, 2358, 2355, 2354, 2349, 2368, 2388, 2403, + 2436, 2478, 2526, 2594, 2673, 2745, 2809, 2877, + 2926, 2942, 2962, 2981, 2972, 2937, 2882, 2829, + 2752, 2666, 2568, 2448, 2320, 2183, 2012, 1813, + 1625, 1455, 1286, 1138, 1015, 902, 802, 715, + 646, 613, 614, 626, 649, 694, 772, 872, + 983, 1118, 1271, 1428, 1569, 1695, 1806, 1920, + 2040, 2151, 2251, 2344, 2415, 2460, 2491, 2500, + 2491, 2458, 2398, 2319, 2231, 2136, 2038, 1941, + 1856, 1782, 1709, 1633, 1556, 1487, 1428, 1387, + 1366, 1364, 1378, 1396, 1416, 1443, 1479, 1520, + 1565, 1604, 1637, 1658, 1671, 1679, 1685, 1674, + 1649, 1602, 1528, 1432, 1320, 1199, 1073, 955, + 842, 731, 635, 553, 482, 426, 391, 382, + 389, 409, 450, 515, 603, 706, 824, 959, + 1108, 1257, 1397, 1531, 1672, 1808, 1928, 2040, + 2137, 2213, 2259, 2286, 2291, 2285, 2256, 2196, + 2120, 2038, 1952, 1861, 1764, 1679, 1604, 1528, + 1451, 1384, 1332, 1293, 1267, 1256, 1265, 1294, + 1334, 1386, 1453, 1535, 1634, 1741, 1845, 1948, + 2053, 2151, 2234, 2305, 2380, 2451, 2504, 2523, + 2527, 2531, 2528, 2509, 2474, 2446, 2422, 2382, + 2322, 2274, 2253, 2240, 2215, 2184, 2172, 2186, + 2199, 2212, 2257, 2327, 2392, 2450, 2522, 2612, + 2714, 2823, 2921, 3008, 3092, 3154, 3180, 3186, + 3189, 3174, 3128, 3049, 2951, 2839, 2711, 2572, + 2418, 2254, 2092, 1912, 1708, 1505, 1315, 1151, + 1010, 895, 805, 739, 696, 670, 667, 710, + 786, 872, 967, 1070, 1196, 1336, 1482, 1634, + 1793, 1945, 2069, 2157, 2225, 2301, 2370, 2412, + 2438, 2451, 2442, 2407, 2349, 2283, 2213, 2133, + 2031, 1925, 1823, 1731, 1643, 1573, 1531, 1507, + 1497, 1485, 1485, 1492, 1520, 1560, 1611, 1676, + 1738, 1796, 1848, 1893, 1934, 1964, 1978, 1976, + 1957, 1904, 1815, 1726, 1631, 1513, 1380, 1243, + 1097, 940, 788, 649, 532, 436, 351, 290, + 258, 256, 276, 316, 391, 494, 613, 739, + 878, 1029, 1181, 1343, 1509, 1669, 1819, 1947, + 2052, 2145, 2220, 2263, 2282, 2284, 2264, 2223, + 2158, 2081, 1997, 1914, 1827, 1736, 1646, 1560, + 1483, 1424, 1377, 1346, 1339, 1346, 1359, 1391, + 1444, 1512, 1579, 1658, 1751, 1849, 1944, 2040, + 2133, 2221, 2300, 2372, 2426, 2464, 2490, 2496, + 2484, 2467, 2437, 2400, 2360, 2309, 2255, 2205, + 2169, 2130, 2080, 2051, 2049, 2068, 2081, 2113, + 2173, 2239, 2309, 2396, 2499, 2606, 2715, 2815, + 2917, 3026, 3140, 3237, 3323, 3408, 3472, 3491, + 3454, 3398, 3342, 3252, 3136, 3009, 2868, 2715, + 2552, 2390, 2240, 2090, 1934, 1769, 1609, 1465, + 1338, 1221, 1116, 1058, 1049, 1040, 1032, 1052, + 1100, 1169, 1245, 1330, 1438, 1550, 1650, 1740, + 1838, 1933, 2015, 2072, 2112, 2149, 2167, 2156, + 2133, 2126, 2121, 2105, 2072, 2027, 1981, 1930, + 1881, 1839, 1802, 1768, 1740, 1723, 1721, 1739, + 1773, 1812, 1866, 1924, 1988, 2047, 2102, 2159, + 2210, 2251, 2274, 2286, 2278, 2254, 2212, 2157, + 2084, 1999, 1909, 1802, 1678, 1548, 1416, 1278, + 1139, 997, 841, 704, 599, 505, 421, 370, + 363, 374, 395, 448, 538, 646, 759, 880, + 1015, 1157, 1299, 1422, 1541, 1671, 1790, 1879, + 1949, 2008, 2060, 2084, 2077, 2065, 2043, 2003, + 1939, 1867, 1803, 1735, 1659, 1589, 1536, 1507, + 1486, 1466, 1462, 1485, 1534, 1587, 1638, 1703, + 1781, 1853, 1917, 1987, 2058, 2121, 2172, 2215, + 2258, 2301, 2331, 2335, 2341, 2355, 2355, 2327, + 2291, 2261, 2221, 2172, 2122, 2080, 2050, 2030, + 2012, 2015, 2042, 2060, 2081, 2126, 2184, 2241, + 2296, 2369, 2449, 2526, 2596, 2663, 2741, 2830, + 2900, 2954, 3003, 3058, 3092, 3101, 3128, 3167, + 3178, 3160, 3129, 3100, 3050, 2972, 2880, 2785, + 2696, 2597, 2481, 2383, 2299, 2221, 2146, 2075, + 2018, 1959, 1883, 1804, 1739, 1681, 1619, 1568, + 1548, 1541, 1536, 1536, 1548, 1577, 1613, 1648, + 1678, 1710, 1737, 1750, 1758, 1779, 1804, 1822, + 1826, 1831, 1845, 1852, 1858, 1872, 1904, 1943, + 1970, 1991, 2015, 2044, 2070, 2084, 2097, 2110, + 2117, 2118, 2120, 2135, 2155, 2171, 2188, 2210, + 2226, 2223, 2208, 2194, 2173, 2142, 2097, 2046, + 1988, 1918, 1836, 1761, 1699, 1622, 1528, 1438, + 1355, 1269, 1186, 1109, 1036, 968, 906, 845, + 798, 773, 757, 749, 762, 803, 857, 915, + 984, 1067, 1151, 1229, 1305, 1380, 1451, 1518, + 1568, 1613, 1657, 1693, 1716, 1736, 1756, 1768, + 1769, 1759, 1750, 1750, 1744, 1728, 1709, 1700, + 1702, 1700, 1700, 1712, 1735, 1766, 1799, 1839, + 1887, 1935, 1969, 1999, 2036, 2069, 2092, 2106, + 2117, 2130, 2136, 2136, 2145, 2153, 2148, 2145, + 2142, 2141, 2136, 2131, 2134, 2147, 2154, 2157, + 2164, 2171, 2176, 2200, 2244, 2290, 2326, 2368, + 2436, 2502, 2560, 2631, 2712, 2769, 2814, 2855, + 2894, 2939, 2991, 3028, 3042, 3069, 3115, 3144, + 3139, 3149, 3177, 3146, 3045, 2956, 2888, 2804, + 2708, 2608, 2497, 2401, 2333, 2263, 2194, 2157, + 2126, 2058, 1970, 1902, 1862, 1818, 1760, 1719, + 1681, 1625, 1582, 1558, 1531, 1528, 1528, 1526, + 1534, 1553, 1588, 1610, 1631, 1655, 1670, 1654, + 1639, 1651, 1670, 1683, 1721, 1789, 1857, 1919, + 1977, 2027, 2076, 2120, 2145, 2162, 2177, 2191, + 2200, 2201, 2211, 2226, 2230, 2219, 2210, 2200, + 2188, 2183, 2180, 2179, 2162, 2132, 2093, 2045, + 1983, 1911, 1840, 1773, 1711, 1638, 1572, 1539, + 1512, 1456, 1381, 1314, 1248, 1178, 1112, 1042, + 980, 936, 887, 833, 809, 817, 825, 832, + 859, 909, 961, 1014, 1085, 1169, 1246, 1316, + 1375, 1420, 1468, 1524, 1575, 1623, 1672, 1715, + 1746, 1773, 1802, 1822, 1833, 1823, 1807, 1794, + 1778, 1761, 1754, 1754, 1768, 1792, 1804, 1818, + 1845, 1882, 1918, 1951, 1984, 2014, 2036, 2047, + 2062, 2071, 2068, 2066, 2068, 2068, 2064, 2063, + 2077, 2103, 2118, 2120, 2135, 2152, 2149, 2139, + 2148, 2171, 2185, 2192, 2211, 2254, 2303, 2353, + 2404, 2436, 2463, 2510, 2546, 2562, 2586, 2620, + 2648, 2674, 2701, 2718, 2744, 2786, 2828, 2847, + 2860, 2897, 2940, 2944, 2953, 2989, 3012, 3010, + 3010, 3007, 2977, 2931, 2881, 2830, 2764, 2696, + 2632, 2553, 2463, 2383, 2308, 2227, 2147, 2068, + 1981, 1885, 1804, 1738, 1656, 1584, 1538, 1514, + 1501, 1484, 1482, 1504, 1534, 1573, 1613, 1649, + 1691, 1734, 1762, 1782, 1814, 1847, 1865, 1877, + 1896, 1922, 1940, 1954, 1973, 1997, 2022, 2036, + 2039, 2043, 2052, 2057, 2055, 2059, 2061, 2064, + 2065, 2076, 2094, 2119, 2139, 2155, 2175, 2187, + 2186, 2175, 2156, 2131, 2096, 2051, 1997, 1944, + 1877, 1783, 1686, 1620, 1554, 1449, 1335, 1249, + 1153, 1045, 978, 932, 869, 820, 804, 793, + 790, 821, 881, 942, 1009, 1099, 1189, 1267, + 1349, 1437, 1508, 1563, 1617, 1660, 1676, 1686, + 1705, 1723, 1722, 1712, 1703, 1688, 1666, 1651, + 1646, 1636, 1634, 1650, 1663, 1682, 1726, 1772, + 1822, 1888, 1957, 2014, 2065, 2121, 2172, 2209, + 2237, 2255, 2252, 2240, 2225, 2204, 2169, 2139, + 2119, 2081, 2047, 2036, 2029, 2002, 1986, 2001, + 2023, 2039, 2065, 2114, 2155, 2197, 2257, 2326, + 2387, 2446, 2502, 2539, 2590, 2671, 2725, 2742, + 2786, 2852, 2893, 2909, 2931, 2955, 2967, 2974, + 2990, 3006, 3012, 3030, 3055, 3078, 3110, 3146, + 3172, 3187, 3175, 3122, 3050, 2998, 2952, 2876, + 2779, 2702, 2649, 2594, 2518, 2453, 2423, 2375, + 2289, 2205, 2122, 2041, 1980, 1915, 1848, 1793, + 1727, 1661, 1602, 1558, 1544, 1537, 1531, 1556, + 1597, 1638, 1679, 1727, 1763, 1782, 1783, 1771, + 1775, 1793, 1826, 1875, 1938, 2019, 2096, 2144, + 2174, 2207, 2230, 2232, 2226, 2229, 2232, 2235, + 2238, 2249, 2267, 2275, 2267, 2261, 2266, 2270, + 2278, 2291, 2310, 2326, 2314, 2272, 2217, 2158, + 2089, 2015, 1952, 1906, 1868, 1820, 1771, 1747, + 1731, 1670, 1566, 1474, 1385, 1287, 1202, 1122, + 1035, 976, 956, 932, 901, 904, 930, 952, + 991, 1055, 1130, 1195, 1253, 1314, 1372, 1419, + 1463, 1505, 1539, 1569, 1616, 1675, 1730, 1765, + 1786, 1802, 1815, 1814, 1802, 1780, 1758, 1764, + 1780, 1789, 1814, 1862, 1914, 1967, 2019, 2068, + 2111, 2153, 2194, 2211, 2219, 2230, 2220, 2196, + 2171, 2142, 2109, 2083, 2068, 2048, 2031, 2030, + 2039, 2044, 2040, 2048, 2071, 2099, 2123, 2159, + 2208, 2266, 2333, 2404, 2458, 2498, 2553, 2617, + 2651, 2660, 2681, 2704, 2706, 2691, 2674, 2667, + 2662, 2652, 2653, 2663, 2680, 2704, 2738, 2777, + 2833, 2895, 2936, 2970, 3020, 3065, 3101, 3148, + 3207, 3260, 3300, 3332, 3338, 3311, 3244, 3157, + 3055, 2947, 2826, 2691, 2553, 2429, 2328, 2240, + 2156, 2069, 1987, 1916, 1854, 1798, 1759, 1717, + 1672, 1653, 1667, 1676, 1669, 1679, 1708, 1740, + 1781, 1833, 1874, 1906, 1930, 1941, 1929, 1913, + 1895, 1866, 1836, 1814, 1812, 1829, 1856, 1895, + 1946, 1994, 2042, 2084, 2128, 2170, 2203, 2235, + 2266, 2292, 2311, 2320, 2325, 2338, 2348, 2342, + 2331, 2325, 2320, 2301, 2262, 2216, 2163, 2097, + 2025, 1953, 1890, 1838, 1796, 1768, 1755, 1738, + 1678, 1583, 1524, 1524, 1492, 1387, 1313, 1302, + 1264, 1200, 1181, 1187, 1175, 1151, 1115, 1105, + 1128, 1150, 1177, 1219, 1268, 1316, 1358, 1394, + 1436, 1476, 1523, 1577, 1629, 1681, 1720, 1745, + 1779, 1820, 1839, 1841, 1836, 1835, 1843, 1849, + 1852, 1870, 1909, 1941, 1944, 1944, 1968, 1999, + 2008, 2017, 2038, 2055, 2055, 2050, 2057, 2070, + 2073, 2060, 2049, 2050, 2058, 2059, 2054, 2064, + 2087, 2092, 2088, 2084, 2103, 2136, 2159, 2183, + 2222, 2267, 2310, 2349, 2391, 2434, 2465, 2475, + 2489, 2517, 2542, 2564, 2576, 2602, 2640, 2683, + 2727, 2763, 2792, 2822, 2893, 2982, 3023, 3033, + 3073, 3122, 3156, 3207, 3257, 3268, 3288, 3328, + 3359, 3391, 3399, 3342, 3235, 3125, 3034, 2927, + 2795, 2671, 2547, 2464, 2432, 2398, 2365, 2327, + 2260, 2199, 2151, 2078, 2010, 1966, 1924, 1892, + 1861, 1812, 1760, 1710, 1682, 1660, 1624, 1618, + 1643, 1664, 1687, 1723, 1746, 1744, 1728, 1693, + 1662, 1659, 1673, 1709, 1777, 1874, 1986, 2078, + 2131, 2162, 2187, 2193, 2185, 2180, 2179, 2174, + 2171, 2187, 2212, 2224, 2217, 2197, 2177, 2170, + 2173, 2182, 2197, 2213, 2218, 2200, 2168, 2126, + 2074, 2021, 1980, 1956, 1951, 1960, 1976, 1994, + 1990, 1953, 1870, 1770, 1693, 1623, 1514, 1393, + 1338, 1331, 1292, 1241, 1226, 1199, 1124, 1047, + 1013, 1026, 1043, 1046, 1072, 1135, 1198, 1244, + 1300, 1372, 1438, 1487, 1540, 1604, 1674, 1726, + 1742, 1749, 1765, 1768, 1732, 1679, 1657, 1657, + 1664, 1678, 1705, 1744, 1778, 1791, 1795, 1820, + 1856, 1881, 1907, 1952, 1996, 2032, 2074, 2104, + 2119, 2124, 2110, 2079, 2046, 2023, 2009, 1982, + 1947, 1923, 1905, 1880, 1860, 1867, 1885, 1908, + 1937, 1991, 2068, 2132, 2179, 2234, 2293, 2334, + 2370, 2401, 2419, 2438, 2479, 2513, 2518, 2531, + 2549, 2544, 2525, 2524, 2537, 2549, 2556, 2573, + 2607, 2654, 2705, 2766, 2848, 2924, 2965, 3009, + 3095, 3191, 3244, 3263, 3285, 3322, 3360, 3369, + 3358, 3366, 3377, 3362, 3309, 3223, 3100, 2971, + 2853, 2705, 2544, 2429, 2334, 2258, 2244, 2247, + 2249, 2259, 2246, 2209, 2162, 2093, 2036, 1997, + 1927, 1841, 1792, 1772, 1753, 1701, 1644, 1621, + 1614, 1607, 1606, 1603, 1600, 1609, 1609, 1587, + 1573, 1569, 1570, 1597, 1651, 1730, 1838, 1959, + 2065, 2153, 2212, 2247, 2253, 2234, 2202, 2168, + 2139, 2119, 2113, 2118, 2127, 2127, 2128, 2135, + 2136, 2143, 2153, 2172, 2190, 2190, 2179, 2166, + 2147, 2123, 2095, 2068, 2062, 2066, 2078, 2096, + 2113, 2110, 2076, 2028, 1963, 1880, 1789, 1692, + 1585, 1439, 1286, 1214, 1227, 1225, 1179, 1161, + 1195, 1237, 1278, 1329, 1359, 1366, 1356, 1329, + 1322, 1337, 1354, 1373, 1427, 1494, 1557, 1610, + 1653, 1676, 1670, 1652, 1633, 1618, 1592, 1550, + 1524, 1539, 1592, 1648, 1708, 1783, 1849, 1916, + 1987, 2036, 2066, 2101, 2110, 2080, 2044, 2026, + 2007, 1983, 1963, 1957, 1956, 1956, 1944, 1929, + 1928, 1926, 1899, 1866, 1847, 1847, 1861, 1889, + 1921, 1962, 2034, 2115, 2179, 2234, 2301, 2358, + 2384, 2393, 2392, 2381, 2362, 2343, 2330, 2339, + 2362, 2383, 2408, 2442, 2475, 2524, 2594, 2642, + 2654, 2663, 2705, 2764, 2806, 2840, 2899, 2984, + 3073, 3150, 3210, 3274, 3351, 3398, 3413, 3414, + 3426, 3448, 3427, 3394, 3394, 3422, 3435, 3389, + 3293, 3187, 3082, 2982, 2890, 2789, 2677, 2584, + 2551, 2552, 2545, 2534, 2520, 2465, 2386, 2306, + 2218, 2135, 2067, 1985, 1891, 1796, 1711, 1655, + 1602, 1532, 1459, 1434, 1451, 1476, 1514, 1567, + 1615, 1641, 1652, 1656, 1658, 1666, 1684, 1714, + 1771, 1860, 1952, 2039, 2107, 2133, 2122, 2096, + 2060, 2029, 2009, 1992, 1984, 2002, 2044, 2093, + 2131, 2166, 2195, 2222, 2254, 2291, 2333, 2381, + 2411, 2416, 2396, 2362, 2316, 2259, 2200, 2145, + 2107, 2091, 2088, 2089, 2084, 2057, 2020, 1972, + 1921, 1875, 1833, 1805, 1787, 1760, 1725, 1711, + 1724, 1723, 1665, 1582, 1539, 1528, 1519, 1470, + 1395, 1321, 1257, 1221, 1211, 1204, 1206, 1241, + 1307, 1386, 1481, 1564, 1612, 1640, 1645, 1639, + 1637, 1644, 1652, 1669, 1688, 1710, 1743, 1777, + 1792, 1785, 1773, 1763, 1752, 1748, 1750, 1751, + 1761, 1784, 1804, 1820, 1848, 1890, 1937, 1973, + 1999, 2027, 2053, 2064, 2054, 2025, 1990, 1950, + 1912, 1883, 1867, 1856, 1844, 1858, 1887, 1904, + 1929, 1966, 1997, 2011, 2021, 2044, 2090, 2135, + 2170, 2194, 2221, 2265, 2308, 2339, 2360, 2365, + 2374, 2383, 2393, 2411, 2432, 2433, 2417, 2442, + 2509, 2565, 2589, 2630, 2706, 2777, 2825, 2879, + 2951, 3017, 3067, 3106, 3145, 3206, 3269, 3305, + 3331, 3370, 3399, 3399, 3409, 3429, 3426, 3423, + 3438, 3448, 3428, 3388, 3318, 3224, 3143, 3055, + 2938, 2822, 2753, 2717, 2689, 2666, 2655, 2661, + 2657, 2613, 2524, 2431, 2341, 2221, 2102, 2012, + 1921, 1819, 1714, 1615, 1549, 1530, 1516, 1486, + 1483, 1518, 1560, 1594, 1627, 1650, 1647, 1627, + 1606, 1601, 1617, 1644, 1689, 1759, 1844, 1919, + 1969, 1991, 1983, 1960, 1934, 1899, 1879, 1887, + 1909, 1937, 1996, 2073, 2145, 2204, 2262, 2319, + 2371, 2416, 2452, 2479, 2500, 2503, 2474, 2425, + 2365, 2308, 2251, 2209, 2191, 2197, 2208, 2216, + 2229, 2240, 2232, 2203, 2160, 2115, 2081, 2062, + 2057, 2063, 2082, 2102, 2109, 2102, 2086, 2055, + 2006, 1946, 1855, 1713, 1552, 1432, 1352, 1247, + 1135, 1105, 1156, 1213, 1273, 1373, 1474, 1529, + 1555, 1553, 1526, 1488, 1435, 1396, 1396, 1421, + 1447, 1484, 1523, 1547, 1561, 1565, 1553, 1534, + 1524, 1516, 1511, 1525, 1554, 1587, 1630, 1687, + 1742, 1811, 1896, 1976, 2036, 2089, 2132, 2128, + 2082, 2033, 1984, 1932, 1874, 1837, 1834, 1856, + 1881, 1912, 1958, 2005, 2033, 2043, 2056, 2062, + 2060, 2052, 2051, 2059, 2071, 2088, 2103, 2109, + 2114, 2124, 2127, 2114, 2101, 2088, 2075, 2049, + 2015, 1989, 1971, 1978, 2007, 2040, 2083, 2137, + 2211, 2308, 2398, 2456, 2487, 2520, 2553, 2590, + 2637, 2610, 2541, 2576, 2666, 2721, 2798, 2921, + 3018, 3073, 3113, 3155, 3193, 3195, 3196, 3234, + 3295, 3344, 3386, 3442, 3477, 3483, 3516, 3567, + 3562, 3505, 3425, 3332, 3226, 3113, 3003, 2915, + 2846, 2762, 2686, 2652, 2632, 2626, 2646, 2648, + 2600, 2514, 2408, 2265, 2114, 1969, 1837, 1697, + 1544, 1430, 1392, 1388, 1372, 1366, 1399, 1443, + 1472, 1489, 1481, 1450, 1434, 1427, 1410, 1403, + 1418, 1449, 1494, 1555, 1620, 1690, 1760, 1808, + 1831, 1839, 1830, 1823, 1830, 1841, 1857, 1901, + 1974, 2050, 2131, 2226, 2331, 2429, 2521, 2589, + 2625, 2644, 2641, 2605, 2553, 2498, 2446, 2401, + 2368, 2349, 2345, 2357, 2375, 2392, 2406, 2406, + 2386, 2341, 2282, 2228, 2182, 2144, 2109, 2078, + 2060, 2044, 2018, 1989, 1961, 1934, 1897, 1845, + 1788, 1732, 1671, 1601, 1516, 1439, 1390, 1356, + 1315, 1272, 1251, 1253, 1265, 1276, 1291, 1306, + 1319, 1320, 1325, 1343, 1362, 1369, 1373, 1381, + 1393, 1409, 1439, 1474, 1514, 1554, 1591, 1634, + 1669, 1688, 1684, 1682, 1694, 1712, 1736, 1770, + 1812, 1866, 1925, 1980, 2018, 2044, 2056, 2048, + 2034, 2023, 2012, 1992, 1969, 1961, 1960, 1964, + 1961, 1956, 1950, 1952, 1952, 1947, 1946, 1939, + 1924, 1908, 1891, 1874, 1865, 1863, 1854, 1854, + 1864, 1870, 1863, 1855, 1852, 1846, 1824, 1794, + 1780, 1781, 1785, 1791, 1802, 1816, 1839, 1868, + 1903, 1943, 1974, 1996, 2020, 2039, 2066, 2101, + 2126, 2145, 2173, 2219, 2276, 2326, 2383, 2457, + 2529, 2596, 2678, 2775, 2858, 2928, 3002, 3073, + 3156, 3217, 3222, 3232, 3276, 3292, 3278, 3276, + 3286, 3298, 3326, 3372, 3409, 3426, 3448, 3477, + 3507, 3517, 3507, 3499, 3475, 3430, 3384, 3331, + 3252, 3169, 3102, 3032, 2937, 2838, 2773, 2714, + 2632, 2546, 2452, 2363, 2276, 2179, 2062, 1935, + 1831, 1751, 1652, 1538, 1472, 1461, 1462, 1453, + 1460, 1505, 1543, 1560, 1562, 1537, 1486, 1430, + 1380, 1344, 1329, 1335, 1370, 1432, 1511, 1599, + 1677, 1734, 1790, 1847, 1884, 1926, 1987, 2058, + 2126, 2195, 2258, 2320, 2373, 2411, 2448, 2487, + 2526, 2572, 2614, 2641, 2658, 2661, 2637, 2591, + 2545, 2506, 2478, 2464, 2477, 2514, 2556, 2588, + 2604, 2602, 2572, 2518, 2446, 2365, 2292, 2233, + 2181, 2132, 2089, 2049, 2002, 1947, 1891, 1842, + 1802, 1771, 1752, 1737, 1724, 1714, 1703, 1677, + 1641, 1606, 1585, 1577, 1578, 1594, 1610, 1607, + 1584, 1557, 1530, 1489, 1431, 1367, 1306, 1285, + 1323, 1372, 1373, 1384, 1451, 1526, 1581, 1625, + 1663, 1702, 1742, 1767, 1791, 1811, 1811, 1794, + 1771, 1771, 1786, 1799, 1812, 1831, 1854, 1872, + 1884, 1894, 1914, 1926, 1917, 1921, 1956, 1998, + 2021, 2032, 2043, 2061, 2074, 2051, 2014, 1986, + 1959, 1926, 1888, 1848, 1817, 1794, 1764, 1740, + 1734, 1741, 1755, 1765, 1781, 1802, 1810, 1809, + 1808, 1798, 1776, 1754, 1729, 1708, 1694, 1692, + 1680, 1667, 1657, 1655, 1647, 1641, 1651, 1658, + 1673, 1705, 1741, 1766, 1792, 1835, 1890, 1935, + 1957, 1977, 2017, 2055, 2080, 2109, 2140, 2164, + 2188, 2224, 2263, 2305, 2344, 2396, 2466, 2534, + 2617, 2713, 2807, 2896, 2988, 3086, 3178, 3240, + 3270, 3278, 3263, 3229, 3190, 3154, 3122, 3091, + 3079, 3114, 3189, 3260, 3320, 3390, 3475, 3555, + 3606, 3610, 3599, 3605, 3578, 3521, 3455, 3383, + 3306, 3208, 3112, 3042, 2970, 2890, 2812, 2744, + 2699, 2661, 2598, 2528, 2484, 2433, 2374, 2329, + 2285, 2244, 2187, 2104, 2015, 1908, 1774, 1629, + 1506, 1424, 1369, 1336, 1349, 1409, 1490, 1561, + 1624, 1652, 1664, 1676, 1661, 1644, 1666, 1708, + 1753, 1807, 1861, 1918, 1961, 1974, 1972, 1982, + 2004, 2041, 2097, 2170, 2258, 2338, 2399, 2453, + 2491, 2511, 2525, 2541, 2584, 2645, 2696, 2737, + 2767, 2767, 2730, 2658, 2561, 2472, 2398, 2340, + 2309, 2314, 2344, 2376, 2398, 2402, 2387, 2353, + 2298, 2240, 2195, 2154, 2115, 2075, 2035, 1984, + 1919, 1833, 1744, 1672, 1617, 1581, 1569, 1581, + 1606, 1630, 1642, 1640, 1628, 1607, 1581, 1567, + 1578, 1602, 1643, 1691, 1733, 1760, 1766, 1759, + 1733, 1704, 1681, 1673, 1688, 1724, 1778, 1837, + 1898, 1950, 1994, 2018, 2006, 1947, 1860, 1802, + 1808, 1852, 1877, 1871, 1876, 1905, 1928, 1927, + 1913, 1887, 1844, 1813, 1817, 1858, 1912, 1934, + 1926, 1913, 1900, 1874, 1832, 1788, 1751, 1724, + 1708, 1705, 1715, 1720, 1702, 1674, 1656, 1661, + 1676, 1684, 1686, 1701, 1723, 1732, 1718, 1693, + 1667, 1641, 1611, 1590, 1586, 1595, 1614, 1630, + 1644, 1658, 1660, 1638, 1616, 1619, 1628, 1629, + 1638, 1662, 1703, 1733, 1745, 1760, 1780, 1787, + 1779, 1769, 1774, 1787, 1798, 1794, 1791, 1788, + 1786, 1790, 1795, 1810, 1831, 1853, 1884, 1930, + 1974, 2000, 2014, 2016, 2009, 1999, 1991, 1991, + 1995, 2005, 2030, 2059, 2084, 2107, 2125, 2147, + 2175, 2207, 2246, 2290, 2337, 2392, 2451, 2507, + 2555, 2598, 2638, 2667, 2690, 2719, 2744, 2751, + 2748, 2745, 2745, 2760, 2783, 2827, 2871, 2902, + 2943, 3006, 3067, 3102, 3129, 3176, 3221, 3233, + 3258, 3285, 3304, 3307, 3285, 3257, 3210, 3162, + 3135, 3116, 3096, 3072, 3061, 3066, 3069, 3044, + 3013, 2994, 2960, 2933, 2904, 2868, 2849, 2832, + 2808, 2778, 2711, 2622, 2529, 2419, 2281, 2128, + 1981, 1840, 1737, 1683, 1663, 1682, 1732, 1810, + 1909, 2005, 2075, 2105, 2088, 2029, 1944, 1831, + 1726, 1639, 1568, 1521, 1501, 1511, 1545, 1591, + 1631, 1669, 1715, 1770, 1836, 1901, 1958, 2015, + 2062, 2089, 2103, 2105, 2089, 2074, 2069, 2074, + 2094, 2116, 2134, 2150, 2150, 2128, 2089, 2045, + 2016, 2010, 2029, 2077, 2155, 2245, 2333, 2399, + 2435, 2435, 2393, 2327, 2242, 2154, 2072, 1999, + 1945, 1904, 1870, 1845, 1828, 1820, 1829, 1846, + 1880, 1921, 1966, 2007, 2030, 2033, 2009, 1959, + 1893, 1818, 1749, 1706, 1681, 1674, 1689, 1707, + 1726, 1736, 1732, 1724, 1711, 1701, 1702, 1719, + 1750, 1792, 1844, 1893, 1928, 1950, 1957, 1952, + 1938, 1923, 1907, 1889, 1877, 1865, 1862, 1864, + 1867, 1866, 1850, 1822, 1803, 1810, 1830, 1855, + 1887, 1930, 1989, 2050, 2084, 2070, 2027, 1966, + 1895, 1822, 1755, 1707, 1691, 1694, 1722, 1770, + 1814, 1842, 1859, 1856, 1841, 1830, 1820, 1814, + 1803, 1791, 1782, 1769, 1750, 1730, 1705, 1676, + 1653, 1648, 1652, 1649, 1649, 1652, 1651, 1647, + 1635, 1625, 1628, 1632, 1641, 1667, 1695, 1713, + 1724, 1715, 1695, 1674, 1649, 1621, 1594, 1576, + 1580, 1597, 1617, 1645, 1685, 1719, 1738, 1755, + 1776, 1797, 1812, 1810, 1801, 1798, 1806, 1810, + 1805, 1790, 1780, 1790, 1806, 1817, 1832, 1843, + 1868, 1901, 1919, 1932, 1942, 1950, 1961, 1968, + 1973, 1983, 1991, 1993, 1994, 1993, 1983, 1976, + 1976, 1979, 1987, 2000, 2010, 2033, 2072, 2108, + 2148, 2196, 2244, 2299, 2353, 2397, 2440, 2468, + 2478, 2473, 2451, 2426, 2426, 2449, 2477, 2503, + 2537, 2609, 2715, 2815, 2883, 2932, 2965, 2970, + 2953, 2930, 2929, 2967, 3017, 3056, 3089, 3121, + 3185, 3277, 3343, 3378, 3378, 3376, 3385, 3349, + 3291, 3264, 3246, 3209, 3174, 3163, 3193, 3258, + 3315, 3361, 3385, 3377, 3372, 3372, 3338, 3251, + 3163, 3068, 2932, 2807, 2675, 2534, 2433, 2362, + 2322, 2314, 2331, 2364, 2376, 2350, 2292, 2214, + 2120, 2012, 1907, 1840, 1802, 1771, 1764, 1746, + 1706, 1661, 1587, 1504, 1444, 1419, 1420, 1455, + 1516, 1579, 1640, 1699, 1727, 1725, 1703, 1664, + 1628, 1624, 1655, 1699, 1741, 1783, 1822, 1836, + 1818, 1792, 1780, 1799, 1857, 1940, 2039, 2144, + 2251, 2331, 2360, 2349, 2315, 2264, 2199, 2150, + 2137, 2145, 2177, 2222, 2254, 2275, 2288, 2285, + 2271, 2257, 2249, 2257, 2272, 2281, 2286, 2269, + 2227, 2166, 2100, 2037, 1978, 1938, 1924, 1930, + 1954, 1988, 2010, 2017, 2007, 1985, 1947, 1910, + 1885, 1872, 1877, 1884, 1894, 1899, 1897, 1885, + 1866, 1840, 1814, 1807, 1810, 1823, 1842, 1870, + 1901, 1926, 1941, 1952, 1960, 1968, 1977, 1987, + 2003, 2022, 2040, 2058, 2069, 2068, 2065, 2062, + 2061, 2068, 2082, 2107, 2141, 2176, 2213, 2243, + 2261, 2262, 2234, 2179, 2126, 2097, 2086, 2073, + 2058, 2058, 2082, 2107, 2107, 2088, 2059, 2022, + 1981, 1951, 1924, 1896, 1875, 1861, 1863, 1873, + 1875, 1868, 1861, 1852, 1834, 1817, 1803, 1788, + 1766, 1729, 1687, 1655, 1637, 1615, 1587, 1579, + 1605, 1641, 1678, 1710, 1739, 1767, 1773, 1767, + 1752, 1738, 1706, 1677, 1654, 1649, 1664, 1682, + 1694, 1707, 1738, 1773, 1797, 1815, 1836, 1858, + 1880, 1882, 1877, 1879, 1877, 1869, 1852, 1843, + 1840, 1840, 1844, 1852, 1862, 1872, 1883, 1890, + 1894, 1892, 1896, 1906, 1916, 1923, 1931, 1937, + 1941, 1948, 1950, 1941, 1932, 1931, 1928, 1921, + 1916, 1910, 1905, 1913, 1931, 1961, 1990, 2008, + 2024, 2042, 2056, 2063, 2043, 2011, 1982, 1956, + 1936, 1927, 1932, 1950, 1979, 2012, 2046, 2082, + 2113, 2128, 2137, 2142, 2148, 2161, 2180, 2196, + 2213, 2248, 2299, 2350, 2405, 2460, 2499, 2530, + 2546, 2550, 2556, 2556, 2547, 2548, 2577, 2640, + 2720, 2786, 2846, 2921, 3004, 3063, 3069, 3056, + 3055, 3065, 3067, 3060, 3049, 3054, 3077, 3103, + 3126, 3137, 3145, 3161, 3187, 3206, 3211, 3231, + 3246, 3242, 3228, 3203, 3182, 3176, 3157, 3118, + 3075, 3031, 3006, 2990, 2952, 2903, 2849, 2812, + 2790, 2763, 2745, 2712, 2653, 2579, 2502, 2404, + 2267, 2098, 1929, 1827, 1771, 1732, 1734, 1804, + 1919, 2028, 2098, 2107, 2069, 1992, 1851, 1667, + 1499, 1371, 1291, 1254, 1250, 1289, 1363, 1435, + 1495, 1544, 1583, 1627, 1676, 1733, 1789, 1827, + 1845, 1849, 1833, 1798, 1746, 1692, 1667, 1686, + 1750, 1843, 1955, 2066, 2162, 2232, 2266, 2261, + 2230, 2198, 2180, 2188, 2219, 2271, 2335, 2398, + 2437, 2442, 2422, 2386, 2341, 2290, 2242, 2209, + 2207, 2215, 2226, 2232, 2230, 2232, 2228, 2219, + 2214, 2219, 2226, 2229, 2216, 2188, 2141, 2071, + 1991, 1905, 1834, 1782, 1761, 1775, 1819, 1878, + 1938, 1990, 2025, 2038, 2028, 2001, 1958, 1917, + 1876, 1841, 1811, 1792, 1783, 1781, 1782, 1793, + 1813, 1841, 1874, 1912, 1946, 1977, 1996, 2002, + 2000, 1987, 1971, 1955, 1947, 1952, 1966, 1985, + 2007, 2032, 2052, 2065, 2076, 2081, 2080, 2083, + 2090, 2103, 2120, 2139, 2159, 2181, 2201, 2211, + 2215, 2214, 2204, 2192, 2175, 2156, 2135, 2117, + 2102, 2086, 2077, 2075, 2081, 2084, 2078, 2081, + 2093, 2099, 2076, 2020, 1937, 1824, 1714, 1648, + 1607, 1576, 1560, 1579, 1647, 1740, 1800, 1814, + 1801, 1770, 1725, 1675, 1627, 1576, 1531, 1481, + 1439, 1424, 1430, 1437, 1449, 1470, 1511, 1561, + 1622, 1687, 1744, 1780, 1781, 1758, 1726, 1704, + 1679, 1638, 1611, 1619, 1643, 1675, 1713, 1751, + 1786, 1810, 1824, 1833, 1846, 1858, 1865, 1864, + 1862, 1858, 1856, 1856, 1859, 1858, 1851, 1842, + 1840, 1843, 1843, 1842, 1842, 1845, 1838, 1830, + 1827, 1836, 1849, 1863, 1877, 1888, 1902, 1916, + 1915, 1893, 1865, 1837, 1810, 1797, 1799, 1806, + 1817, 1834, 1864, 1897, 1929, 1960, 1981, 2007, + 2031, 2035, 2034, 2028, 2019, 2006, 1982, 1964, + 1965, 1983, 2006, 2033, 2067, 2104, 2144, 2179, + 2199, 2203, 2195, 2192, 2185, 2176, 2171, 2173, + 2194, 2222, 2244, 2259, 2284, 2315, 2342, 2376, + 2405, 2415, 2426, 2436, 2443, 2460, 2474, 2481, + 2488, 2505, 2544, 2598, 2652, 2706, 2760, 2798, + 2814, 2836, 2865, 2865, 2833, 2807, 2795, 2803, + 2827, 2847, 2877, 2928, 2958, 2979, 3006, 3042, + 3081, 3090, 3065, 3050, 3061, 3071, 3063, 3036, + 3006, 2987, 2962, 2932, 2920, 2919, 2895, 2866, + 2855, 2855, 2853, 2828, 2756, 2623, 2409, 2184, + 2063, 1996, 1882, 1807, 1871, 2060, 2301, 2485, + 2555, 2552, 2477, 2278, 1995, 1698, 1429, 1241, + 1139, 1114, 1204, 1368, 1522, 1640, 1719, 1756, + 1761, 1742, 1745, 1784, 1820, 1830, 1820, 1789, + 1722, 1606, 1446, 1308, 1235, 1253, 1354, 1533, + 1763, 1996, 2199, 2322, 2338, 2264, 2138, 2010, + 1902, 1827, 1805, 1859, 1970, 2091, 2185, 2220, + 2213, 2189, 2150, 2102, 2083, 2113, 2184, 2253, + 2304, 2335, 2342, 2316, 2258, 2188, 2128, 2099, + 2117, 2163, 2209, 2240, 2237, 2199, 2137, 2062, + 1982, 1911, 1879, 1900, 1971, 2061, 2149, 2224, + 2266, 2259, 2213, 2139, 2046, 1958, 1890, 1844, + 1823, 1821, 1826, 1839, 1859, 1879, 1897, 1923, + 1966, 2014, 2061, 2091, 2106, 2103, 2069, 2004, + 1927, 1856, 1808, 1787, 1785, 1809, 1867, 1943, + 2022, 2090, 2145, 2185, 2208, 2215, 2211, 2201, + 2186, 2172, 2156, 2140, 2126, 2120, 2121, 2132, + 2154, 2184, 2218, 2253, 2282, 2309, 2320, 2319, + 2308, 2289, 2271, 2258, 2243, 2230, 2231, 2233, + 2225, 2217, 2211, 2196, 2178, 2162, 2141, 2114, + 2090, 2078, 2077, 2063, 2049, 2059, 2070, 2077, + 2073, 2050, 2013, 1985, 1942, 1879, 1823, 1787, + 1762, 1756, 1764, 1774, 1792, 1795, 1793, 1805, + 1809, 1801, 1789, 1770, 1752, 1739, 1712, 1678, + 1656, 1643, 1633, 1629, 1646, 1681, 1722, 1753, + 1776, 1804, 1824, 1830, 1822, 1805, 1784, 1763, + 1740, 1727, 1731, 1745, 1762, 1776, 1805, 1843, + 1870, 1883, 1901, 1915, 1917, 1915, 1908, 1901, + 1899, 1893, 1873, 1862, 1859, 1864, 1870, 1877, + 1892, 1910, 1927, 1939, 1945, 1944, 1940, 1938, + 1932, 1922, 1911, 1904, 1908, 1915, 1919, 1923, + 1931, 1939, 1944, 1947, 1953, 1964, 1973, 1977, + 1986, 2006, 2027, 2033, 2031, 2040, 2061, 2078, + 2085, 2087, 2099, 2114, 2124, 2130, 2140, 2153, + 2165, 2178, 2196, 2223, 2250, 2268, 2279, 2292, + 2310, 2333, 2344, 2344, 2344, 2346, 2347, 2352, + 2350, 2345, 2346, 2361, 2383, 2408, 2426, 2436, + 2455, 2474, 2476, 2473, 2484, 2485, 2479, 2479, + 2477, 2470, 2467, 2461, 2456, 2464, 2470, 2482, + 2504, 2522, 2537, 2556, 2561, 2556, 2547, 2534, + 2522, 2509, 2485, 2473, 2487, 2502, 2512, 2513, + 2527, 2553, 2558, 2535, 2528, 2544, 2556, 2542, + 2518, 2513, 2521, 2527, 2520, 2500, 2497, 2511, + 2517, 2501, 2467, 2427, 2396, 2367, 2310, 2253, + 2226, 2226, 2250, 2280, 2302, 2331, 2358, 2366, + 2357, 2320, 2263, 2197, 2131, 2069, 2016, 1979, + 1949, 1933, 1934, 1943, 1951, 1964, 1982, 2007, + 2036, 2056, 2066, 2068, 2057, 2030, 1980, 1911, + 1844, 1795, 1766, 1751, 1754, 1781, 1832, 1887, + 1936, 1974, 2007, 2027, 2032, 2025, 2006, 1989, + 1976, 1963, 1948, 1934, 1918, 1915, 1914, 1919, + 1931, 1953, 1990, 2033, 2069, 2096, 2117, 2127, + 2125, 2111, 2084, 2056, 2040, 2029, 2023, 2025, + 2032, 2038, 2046, 2057, 2067, 2073, 2077, 2083, + 2095, 2107, 2113, 2121, 2123, 2122, 2121, 2117, + 2109, 2102, 2101, 2100, 2102, 2104, 2103, 2104, + 2104, 2101, 2096, 2093, 2091, 2093, 2100, 2108, + 2121, 2134, 2141, 2137, 2130, 2118, 2103, 2085, + 2068, 2055, 2047, 2042, 2046, 2052, 2059, 2069, + 2080, 2094, 2103, 2113, 2120, 2120, 2119, 2110, + 2098, 2084, 2072, 2058, 2047, 2040, 2039, 2044, + 2064, 2075, 2086, 2092, 2089, 2095, 2104, 2112, + 2113, 2104, 2082, 2056, 2033, 2026, 2027, 2025, + 2025, 2023, 2018, 2018, 2010, 1989, 1975, 1966, + 1946, 1919, 1910, 1920, 1932, 1939, 1939, 1939, + 1943, 1925, 1878, 1815, 1771, 1740, 1694, 1656, + 1659, 1689, 1722, 1751, 1766, 1779, 1792, 1791, + 1778, 1756, 1730, 1697, 1667, 1642, 1629, 1615, + 1589, 1580, 1583, 1593, 1621, 1656, 1696, 1743, + 1775, 1796, 1810, 1810, 1797, 1762, 1719, 1681, + 1649, 1632, 1627, 1640, 1670, 1702, 1741, 1785, + 1821, 1848, 1865, 1875, 1882, 1877, 1856, 1835, + 1815, 1796, 1775, 1749, 1738, 1742, 1756, 1774, + 1799, 1834, 1869, 1896, 1916, 1931, 1929, 1918, + 1905, 1888, 1869, 1852, 1842, 1849, 1860, 1872, + 1889, 1910, 1933, 1954, 1974, 1990, 2007, 2021, + 2029, 2028, 2034, 2041, 2042, 2045, 2058, 2072, + 2082, 2092, 2113, 2137, 2156, 2171, 2183, 2201, + 2225, 2242, 2248, 2260, 2279, 2300, 2322, 2337, + 2350, 2369, 2385, 2396, 2395, 2397, 2412, 2430, + 2446, 2459, 2471, 2493, 2516, 2539, 2555, 2570, + 2589, 2606, 2626, 2650, 2658, 2659, 2672, 2697, + 2709, 2714, 2721, 2737, 2762, 2772, 2768, 2775, + 2799, 2820, 2818, 2803, 2790, 2789, 2780, 2753, + 2717, 2681, 2647, 2577, 2477, 2416, 2401, 2371, + 2325, 2324, 2389, 2484, 2552, 2565, 2540, 2494, + 2418, 2288, 2121, 1974, 1863, 1782, 1728, 1721, + 1757, 1808, 1862, 1900, 1913, 1916, 1922, 1923, + 1922, 1918, 1907, 1895, 1866, 1812, 1734, 1642, + 1550, 1471, 1429, 1439, 1501, 1606, 1729, 1852, + 1956, 2028, 2050, 2026, 1979, 1920, 1854, 1789, + 1754, 1754, 1777, 1803, 1819, 1830, 1846, 1863, + 1880, 1905, 1951, 2014, 2077, 2127, 2174, 2199, + 2191, 2146, 2082, 2012, 1948, 1913, 1908, 1928, + 1967, 2013, 2062, 2107, 2139, 2153, 2149, 2143, + 2144, 2152, 2162, 2179, 2203, 2220, 2218, 2197, + 2166, 2128, 2089, 2058, 2039, 2040, 2058, 2085, + 2114, 2144, 2169, 2176, 2163, 2141, 2124, 2113, + 2099, 2085, 2077, 2071, 2061, 2044, 2021, 1995, + 1970, 1945, 1927, 1926, 1942, 1970, 2004, 2038, + 2065, 2087, 2093, 2090, 2081, 2063, 2039, 2018, + 2001, 1994, 1993, 1996, 2001, 2009, 2017, 2026, + 2039, 2057, 2080, 2107, 2130, 2151, 2170, 2180, + 2182, 2172, 2152, 2128, 2104, 2084, 2072, 2073, + 2079, 2094, 2116, 2139, 2159, 2174, 2187, 2194, + 2195, 2190, 2186, 2185, 2182, 2172, 2161, 2153, + 2139, 2125, 2116, 2109, 2103, 2101, 2104, 2118, + 2141, 2162, 2177, 2188, 2189, 2185, 2173, 2158, + 2145, 2129, 2114, 2099, 2091, 2085, 2077, 2070, + 2065, 2058, 2056, 2052, 2051, 2062, 2071, 2077, + 2080, 2079, 2072, 2059, 2042, 2019, 1997, 1981, + 1970, 1959, 1958, 1961, 1970, 1976, 1976, 1977, + 1979, 1976, 1974, 1969, 1960, 1954, 1952, 1951, + 1949, 1948, 1941, 1937, 1933, 1927, 1923, 1923, + 1927, 1930, 1931, 1932, 1920, 1892, 1884, 1894, + 1895, 1884, 1871, 1875, 1890, 1907, 1909, 1885, + 1865, 1864, 1874, 1884, 1883, 1878, 1870, 1865, + 1858, 1846, 1829, 1823, 1829, 1832, 1834, 1849, + 1874, 1902, 1917, 1920, 1920, 1929, 1941, 1948, + 1947, 1938, 1939, 1946, 1950, 1954, 1960, 1971, + 1979, 1989, 1998, 2011, 2026, 2046, 2066, 2079, + 2083, 2080, 2083, 2086, 2086, 2076, 2060, 2049, + 2052, 2060, 2067, 2076, 2081, 2089, 2101, 2114, + 2124, 2128, 2128, 2129, 2126, 2125, 2127, 2126, + 2121, 2117, 2109, 2098, 2093, 2096, 2109, 2119, + 2123, 2130, 2141, 2159, 2170, 2172, 2169, 2168, + 2175, 2172, 2163, 2165, 2168, 2170, 2170, 2169, + 2169, 2177, 2185, 2189, 2182, 2186, 2193, 2199, + 2206, 2218, 2224, 2217, 2215, 2212, 2209, 2205, + 2202, 2198, 2193, 2193, 2200, 2207, 2208, 2205, + 2208, 2208, 2205, 2207, 2209, 2208, 2208, 2212, + 2215, 2224, 2234, 2239, 2242, 2240, 2240, 2243, + 2239, 2233, 2238, 2245, 2241, 2242, 2243, 2243, + 2244, 2242, 2241, 2242, 2247, 2253, 2257, 2260, + 2268, 2274, 2271, 2262, 2258, 2256, 2252, 2244, + 2231, 2226, 2225, 2224, 2222, 2218, 2214, 2211, + 2208, 2209, 2212, 2213, 2215, 2218, 2220, 2220, + 2216, 2208, 2199, 2191, 2178, 2165, 2151, 2144, + 2140, 2137, 2131, 2127, 2128, 2127, 2123, 2118, + 2111, 2108, 2101, 2093, 2086, 2080, 2071, 2063, + 2052, 2039, 2028, 2016, 2007, 1998, 1990, 1987, + 1985, 1987, 1990, 1992, 1995, 1995, 1992, 1986, + 1979, 1973, 1966, 1955, 1945, 1938, 1929, 1926, + 1922, 1919, 1918, 1923, 1925, 1929, 1936, 1942, + 1944, 1946, 1947, 1945, 1942, 1937, 1934, 1930, + 1925, 1923, 1924, 1928, 1932, 1938, 1944, 1950, + 1959, 1969, 1974, 1979, 1984, 1985, 1983, 1983, + 1983, 1981, 1980, 1975, 1975, 1972, 1976, 1981, + 1983, 1986, 1987, 1989, 1990, 1990, 1992, 1993, + 1992, 1996, 1998, 1998, 1995, 1994, 1993, 1991, + 1988, 1982, 1977, 1973, 1970, 1968, 1965, 1963, + 1966, 1968, 1969, 1971, 1974, 1979, 1984, 1985, + 1987, 1988, 1985, 1979, 1973, 1965, 1957, 1954, + 1950, 1947, 1948, 1948, 1952, 1959, 1966, 1974, + 1980, 1986, 1990, 1992, 1993, 1994, 1992, 1987, + 1979, 1975, 1976, 1977, 1973, 1973, 1977, 1986, + 1995, 2004, 2008, 2018, 2026, 2025, 2026, 2024, + 2021, 2019, 2013, 2009, 2006, 2005, 2007, 2007, + 2011, 2018, 2028, 2038, 2047, 2056, 2063, 2074, + 2083, 2087, 2087, 2089, 2090, 2087, 2086, 2085, + 2090, 2094, 2094, 2105, 2118, 2127, 2131, 2136, + 2145, 2153, 2156, 2155, 2150, 2152, 2156, 2158, + 2155, 2154, 2158, 2165, 2167, 2165, 2166, 2170, + 2177, 2184, 2185, 2190, 2195, 2199, 2202, 2200, + 2198, 2197, 2199, 2199, 2196, 2193, 2197, 2202, + 2203, 2203, 2206, 2208, 2208, 2209, 2210, 2210, + 2210, 2212, 2213, 2214, 2214, 2215, 2215, 2214, + 2216, 2217, 2212, 2208, 2212, 2214, 2213, 2215, + 2216, 2222, 2226, 2226, 2229, 2225, 2221, 2224, + 2222, 2215, 2208, 2203, 2196, 2192, 2184, 2175, + 2170, 2165, 2163, 2159, 2154, 2150, 2146, 2142, + 2138, 2137, 2133, 2130, 2126, 2124, 2121, 2113, + 2104, 2094, 2087, 2081, 2075, 2064, 2058, 2054, + 2052, 2049, 2045, 2044, 2042, 2039, 2038, 2032, + 2028, 2025, 2022, 2020, 2015, 2008, 1999, 1993, + 1988, 1982, 1974, 1970, 1972, 1972, 1975, 1977, + 1977, 1980, 1980, 1976, 1973, 1973, 1970, 1966, + 1962, 1961, 1957, 1955, 1954, 1955, 1956, 1956, + 1958, 1961, 1969, 1975, 1978, 1981, 1983, 1984, + 1988, 1985, 1982, 1981, 1980, 1980, 1982, 1985, + 1990, 1997, 2003, 2010, 2015, 2021, 2027, 2030, + 2033, 2035, 2036, 2039, 2042, 2044, 2045, 2049, + 2050, 2050, 2052, 2055, 2056, 2058, 2061, 2066, + 2070, 2069, 2073, 2074, 2076, 2079, 2081, 2079, + 2077, 2076, 2074, 2075, 2074, 2072, 2070, 2070, + 2070, 2069, 2066, 2064, 2062, 2063, 2060, 2059, + 2060, 2061, 2061, 2057, 2055, 2053, 2049, 2043, + 2036, 2027, 2021, 2012, 2010, 1999, 1994, 1992, + 1987, 1980, 1972, 1973, 1972, 1968, 1965, 1965, + 1966, 1967, 1963, 1958, 1954, 1947, 1945, 1940, + 1935, 1933, 1930, 1929, 1931, 1933, 1933, 1933, + 1933, 1934, 1935, 1936, 1934, 1932, 1934, 1934, + 1933, 1935, 1933, 1932, 1934, 1933, 1930, 1928, + 1931, 1930, 1931, 1932, 1931, 1934, 1932, 1932, + 1932, 1934, 1937, 1936, 1937, 1940, 1943, 1942, + 1946, 1945, 1944, 1944, 1942, 1944, 1946, 1948, + 1947, 1949, 1953, 1956, 1958, 1961, 1964, 1968, + 1970, 1971, 1975, 1976, 1979, 1981, 1982, 1985, + 1988, 1990, 1992, 1997, 2002, 2009, 2013, 2018, + 2027, 2033, 2039, 2042, 2049, 2054, 2061, 2062, + 2062, 2066, 2069, 2076, 2080, 2084, 2089, 2094, + 2099, 2105, 2110, 2114, 2120, 2125, 2130, 2137, + 2141, 2146, 2152, 2159, 2164, 2168, 2172, 2177, + 2182, 2186, 2187, 2192, 2197, 2201, 2205, 2210, + 2218, 2220, 2224, 2228, 2232, 2238, 2243, 2246, + 2249, 2252, 2250, 2248, 2248, 2246, 2249, 2250, + 2252, 2252, 2252, 2258, 2262, 2264, 2268, 2271, + 2272, 2274, 2271, 2269, 2268, 2268, 2264, 2262, + 2261, 2261, 2255, 2251, 2249, 2248, 2248, 2243, + 2241, 2244, 2246, 2249, 2248, 2247, 2246, 2246, + 2245, 2240, 2238, 2237, 2241, 2240, 2240, 2239, + 2240, 2240, 2238, 2236, 2234, 2233, 2230, 2226, + 2222, 2222, 2219, 2215, 2213, 2209, 2204, 2201, + 2193, 2185, 2182, 2175, 2169, 2164, 2161, 2154, + 2150, 2143, 2134, 2132, 2127, 2122, 2114, 2109, + 2104, 2097, 2092, 2085, 2077, 2068, 2060, 2054, + 2049, 2045, 2039, 2035, 2033, 2033, 2031, 2029, + 2027, 2023, 2023, 2018, 2015, 2013, 2010, 2008, + 2008, 2005, 2001, 2002, 1997, 1996, 1993, 1991, + 1991, 1995, 1996, 1996, 1997, 1998, 1999, 1999, + 1995, 1994, 1998, 1996, 1996, 1997, 1999, 2001, + 2002, 2006, 2009, 2011, 2012, 2015, 2017, 2020, + 2023, 2031, 2035, 2039, 2041, 2042, 2047, 2049, + 2048, 2049, 2052, 2056, 2058, 2060, 2064, 2068, + 2071, 2073, 2071, 2073, 2077, 2079, 2077, 2078, + 2077, 2077, 2076, 2073, 2073, 2071, 2069, 2068, + 2069, 2066, 2068, 2070, 2069, 2070, 2068, 2070, + 2067, 2067, 2064, 2062, 2059, 2056, 2050, 2048, + 2047, 2044, 2041, 2040, 2038, 2038, 2036, 2036, + 2035, 2035, 2035, 2033, 2035, 2032, 2030, 2027, + 2024, 2019, 2015, 2014, 2013, 2011, 2011, 2011, + 2011, 2010, 2012, 2012, 2009, 2009, 2005, 2004, + 2002, 1997, 1995, 1991, 1990, 1989, 1985, 1983, + 1982, 1982, 1980, 1978, 1978, 1980, 1980, 1980, + 1984, 1986, 1984, 1984, 1986, 1987, 1987, 1986, + 1987, 1986, 1987, 1988, 1989, 1989, 1987, 1990, + 1992, 1996, 1998, 2002, 2007, 2011, 2015, 2018, + 2021, 2026, 2028, 2028, 2028, 2026, 2026, 2025, + 2024, 2024, 2024, 2025, 2027, 2033, 2033, 2034, + 2038, 2040, 2043, 2041, 2044, 2043, 2042, 2040, + 2036, 2036, 2038, 2040, 2043, 2044, 2045, 2048, + 2049, 2055, 2058, 2059, 2061, 2064, 2064, 2064, + 2064, 2064, 2063, 2064, 2064, 2064, 2065, 2066, + 2067, 2070, 2074, 2076, 2078, 2077, 2079, 2074, + 2075, 2074, 2071, 2073, 2073, 2074, 2075, 2077, + 2079, 2079, 2080, 2080, 2079, 2083, 2087, 2091, + 2093, 2093, 2097, 2098, 2100, 2105, 2108, 2107, + 2109, 2111, 2112, 2116, 2119, 2121, 2123, 2126, + 2131, 2134, 2138, 2140, 2143, 2144, 2148, 2149, + 2151, 2152, 2152, 2154, 2152, 2155, 2156, 2157, + 2158, 2162, 2165, 2165, 2167, 2169, 2171, 2170, + 2173, 2171, 2172, 2174, 2174, 2171, 2168, 2169, + 2168, 2163, 2162, 2164, 2166, 2167, 2169, 2165, + 2167, 2166, 2165, 2165, 2165, 2162, 2160, 2160, + 2159, 2156, 2153, 2152, 2152, 2146, 2143, 2141, + 2139, 2136, 2133, 2129, 2125, 2120, 2114, 2111, + 2108, 2103, 2100, 2092, 2091, 2091, 2087, 2080, + 2076, 2076, 2073, 2068, 2065, 2061, 2056, 2053, + 2050, 2044, 2039, 2036, 2032, 2028, 2024, 2024, + 2021, 2018, 2017, 2017, 2013, 2007, 2006, 2001, + 1996, 1997, 1992, 1990, 1988, 1982, 1979, 1977, + 1973, 1970, 1967, 1965, 1963, 1961, 1960, 1958, + 1954, 1955, 1951, 1949, 1947, 1941, 1937, 1935, + 1935, 1934, 1934, 1931, 1933, 1935, 1936, 1936, + 1936, 1937, 1939, 1939, 1942, 1943, 1946, 1945, + 1944, 1945, 1946, 1948, 1949, 1950, 1952, 1949, + 1948, 1948, 1947, 1946, 1946, 1949, 1949, 1949, + 1952, 1954, 1956, 1955, 1953, 1954, 1954, 1955, + 1957, 1953, 1952, 1950, 1948, 1948, 1948, 1948, + 1947, 1949, 1949, 1947, 1946, 1948, 1951, 1950, + 1951, 1953, 1953, 1952, 1955, 1955, 1953, 1951, + 1952, 1953, 1951, 1950, 1950, 1953, 1954, 1953, + 1954, 1951, 1952, 1953, 1953, 1952, 1953, 1954, + 1956, 1955, 1954, 1955, 1953, 1953, 1953, 1951, + 1951, 1951, 1950, 1954, 1955, 1956, 1956, 1957, + 1956, 1961, 1964, 1965, 1969, 1970, 1974, 1978, + 1980, 1981, 1981, 1983, 1983, 1986, 1987, 1992, + 1997, 2000, 2002, 2006, 2011, 2016, 2020, 2027, + 2031, 2033, 2039, 2044, 2046, 2049, 2053, 2058, + 2059, 2060, 2061, 2064, 2067, 2072, 2077, 2081, + 2086, 2090, 2096, 2100, 2102, 2104, 2108, 2111, + 2115, 2115, 2116, 2118, 2120, 2119, 2119, 2119, + 2118, 2119, 2119, 2120, 2120, 2120, 2124, 2128, + 2127, 2127, 2127, 2127, 2129, 2127, 2125, 2124, + 2124, 2125, 2124, 2125, 2123, 2122, 2123, 2122, + 2121, 2122, 2125, 2128, 2129, 2132, 2134, 2133, + 2134, 2136, 2135, 2137, 2136, 2134, 2137, 2137, + 2138, 2139, 2137, 2134, 2139, 2139, 2141, 2142, + 2145, 2150, 2152, 2154, 2156, 2159, 2159, 2160, + 2160, 2159, 2160, 2160, 2159, 2160, 2163, 2166, + 2166, 2166, 2165, 2166, 2168, 2169, 2171, 2174, + 2178, 2176, 2176, 2176, 2177, 2177, 2176, 2174, + 2174, 2177, 2181, 2181, 2182, 2183, 2186, 2188, + 2189, 2191, 2190, 2191, 2188, 2186, 2186, 2185, + 2183, 2185, 2186, 2184, 2183, 2183, 2182, 2183, + 2180, 2180, 2177, 2175, 2175, 2172, 2168, 2165, + 2165, 2165, 2163, 2162, 2162, 2158, 2158, 2154, + 2150, 2146, 2143, 2138, 2139, 2134, 2130, 2124, + 2122, 2117, 2116, 2109, 2104, 2099, 2097, 2089, + 2084, 2079, 2072, 2068, 2064, 2061, 2055, 2048, + 2043, 2041, 2034, 2032, 2028, 2022, 2019, 2012, + 2008, 2005, 2001, 1996, 1991, 1989, 1988, 1985, + 1982, 1978, 1974, 1972, 1970, 1967, 1964, 1960, + 1961, 1959, 1955, 1952, 1951, 1949, 1949, 1947, + 1944, 1945, 1944, 1944, 1942, 1941, 1940, 1937, + 1934, 1931, 1932, 1931, 1931, 1932, 1932, 1930, + 1929, 1927, 1926, 1926, 1928, 1931, 1933, 1935, + 1935, 1935, 1937, 1938, 1940, 1941, 1937, 1938, + 1940, 1940, 1942, 1942, 1943, 1945, 1947, 1948, + 1950, 1954, 1953, 1955, 1957, 1959, 1961, 1965, + 1965, 1965, 1966, 1968, 1971, 1971, 1972, 1972, + 1974, 1975, 1975, 1978, 1980, 1980, 1982, 1983, + 1983, 1984, 1986, 1988, 1992, 1993, 1994, 1997, + 1996, 1994, 1994, 1998, 1999, 2002, 2004, 2007, + 2009, 2010, 2012, 2013, 2017, 2020, 2022, 2024, + 2027, 2027, 2030, 2034, 2037, 2039, 2041, 2045, + 2049, 2050, 2052, 2055, 2055, 2057, 2060, 2062, + 2067, 2072, 2075, 2077, 2078, 2082, 2085, 2089, + 2090, 2094, 2095, 2098, 2099, 2103, 2107, 2108, + 2111, 2113, 2115, 2115, 2117, 2116, 2117, 2118, + 2120, 2121, 2124, 2125, 2126, 2126, 2127, 2129, + 2129, 2129, 2129, 2131, 2129, 2129, 2129, 2128, + 2128, 2126, 2127, 2127, 2128, 2128, 2126, 2126, + 2125, 2126, 2125, 2124, 2121, 2120, 2119, 2118, + 2118, 2118, 2116, 2114, 2114, 2116, 2115, 2115, + 2111, 2110, 2110, 2110, 2107, 2108, 2108, 2106, + 2109, 2109, 2110, 2110, 2109, 2108, 2107, 2103, + 2102, 2102, 2102, 2101, 2099, 2101, 2098, 2096, + 2093, 2093, 2094, 2093, 2094, 2095, 2095, 2097, + 2094, 2090, 2091, 2088, 2084, 2083, 2083, 2082, + 2079, 2076, 2076, 2076, 2076, 2073, 2073, 2071, + 2068, 2069, 2068, 2066, 2063, 2063, 2063, 2065, + 2064, 2063, 2062, 2063, 2065, 2065, 2068, 2068, + 2066, 2068, 2066, 2062, 2064, 2067, 2063, 2063, + 2063, 2063, 2064, 2061, 2060, 2062, 2061, 2061, + 2059, 2061, 2060, 2057, 2059, 2059, 2058, 2058, + 2055, 2053, 2054, 2052, 2047, 2044, 2041, 2042, + 2040, 2041, 2041, 2042, 2039, 2039, 2040, 2042, + 2042, 2040, 2040, 2036, 2036, 2037, 2035, 2034, + 2034, 2032, 2031, 2028, 2027, 2026, 2023, 2025, + 2026, 2028, 2027, 2027, 2028, 2026, 2026, 2027, + 2025, 2022, 2019, 2016, 2011, 2010, 2008, 2008, + 2004, 2001, 1999, 1998, 1996, 1997, 1994, 1992, + 1993, 1990, 1989, 1985, 1984, 1983, 1980, 1979, + 1975, 1970, 1969, 1971, 1970, 1969, 1969, 1969, + 1970, 1971, 1973, 1975, 1974, 1974, 1974, 1975, + 1972, 1974, 1974, 1974, 1976, 1972, 1973, 1973, + 1973, 1973, 1969, 1972, 1972, 1977, 1981, 1984, + 1987, 1989, 1989, 1990, 1991, 1991, 1990, 1991, + 1989, 1987, 1985, 1988, 1987, 1986, 1987, 1988, + 1989, 1988, 1992, 1993, 1992, 1994, 1995, 1995, + 1994, 1993, 1991, 1994, 1992, 1990, 1992, 1990, + 1994, 1994, 1997, 1997, 1999, 2001, 2002, 2003, + 2003, 2003, 2005, 2003, 2000, 2000, 2001, 2003, + 2004, 2004, 2002, 2002, 2003, 2002, 2002, 2002, + 2003, 2002, 2001, 2005, 2003, 2001, 2001, 2003, + 2002, 2001, 2001, 2000, 2002, 2000, 2002, 2002, + 2002, 2003, 2002, 2005, 2004, 2004, 2008, 2007, + 2008, 2010, 2013, 2018, 2019, 2020, 2021, 2022, + 2023, 2023, 2024, 2024, 2022, 2022, 2023, 2025, + 2026, 2026, 2029, 2030, 2030, 2032, 2032, 2034, + 2032, 2033, 2031, 2033, 2035, 2036, 2037, 2037, + 2036, 2035, 2038, 2040, 2040, 2040, 2039, 2039, + 2040, 2041, 2040, 2040, 2039, 2041, 2040, 2039, + 2041, 2039, 2038, 2038, 2041, 2042, 2042, 2044, + 2042, 2042, 2040, 2042, 2044, 2043, 2043, 2045, + 2045, 2044, 2047, 2048, 2048, 2049, 2050, 2049, + 2051, 2052, 2053, 2056, 2055, 2055, 2056, 2056, + 2059, 2056, 2058, 2056, 2055, 2056, 2054, 2058, + 2059, 2059, 2059, 2058, 2057, 2058, 2056, 2056, + 2059, 2060, 2060, 2062, 2064, 2064, 2063, 2065, + 2065, 2066, 2064, 2065, 2067, 2064, 2064, 2064, + 2066, 2064, 2066, 2064, 2064, 2066, 2065, 2065, + 2064, 2064, 2063, 2064, 2063, 2063, 2064, 2063, + 2064, 2066, 2066, 2068, 2068, 2063, 2062, 2062, + 2063, 2065, 2065, 2063, 2062, 2064, 2064, 2067, + 2064, 2065, 2066, 2062, 2063, 2064, 2064, 2065, + 2066, 2064, 2066, 2069, 2069, 2070, 2070, 2070, + 2068, 2069, 2071, 2073, 2074, 2077, 2076, 2079, + 2080, 2082, 2082, 2083, 2083, 2082, 2082, 2081, + 2083, 2083, 2080, 2081, 2081, 2083, 2083, 2083, + 2083, 2080, 2081, 2084, 2085, 2084, 2085, 2085, + 2083, 2082, 2080, 2081, 2080, 2080, 2078, 2079, + 2077, 2076, 2076, 2076, 2078, 2076, 2077, 2078, + 2080, 2080, 2082, 2084, 2082, 2082, 2082, 2081, + 2082, 2082, 2083, 2083, 2084, 2085, 2086, 2086, + 2084, 2085, 2086, 2087, 2087, 2089, 2088, 2085, + 2086, 2089, 2088, 2087, 2086, 2086, 2086, 2090, + 2089, 2089, 2090, 2092, 2094, 2095, 2095, 2097, + 2098, 2099, 2100, 2099, 2101, 2104, 2102, 2101, + 2101, 2101, 2103, 2102, 2099, 2096, 2097, 2098, + 2097, 2097, 2099, 2099, 2100, 2100, 2102, 2105, + 2104, 2100, 2099, 2096, 2097, 2095, 2092, 2094, + 2092, 2089, 2089, 2088, 2088, 2085, 2085, 2083, + 2082, 2081, 2080, 2081, 2082, 2082, 2080, 2080, + 2080, 2079, 2080, 2078, 2076, 2074, 2073, 2073, + 2073, 2072, 2071, 2067, 2067, 2069, 2070, 2072, + 2074, 2077, 2078, 2078, 2080, 2078, 2076, 2076, + 2073, 2073, 2071, 2070, 2071, 2069, 2069, 2069, + 2069, 2068, 2069, 2069, 2068, 2068, 2068, 2069, + 2068, 2066, 2064, 2064, 2063, 2062, 2061, 2055, + 2058, 2059, 2057, 2056, 2055, 2058, 2057, 2055, + 2054, 2055, 2056, 2055, 2055, 2055, 2052, 2053, + 2055, 2054, 2055, 2052, 2051, 2051, 2050, 2049, + 2049, 2050, 2048, 2049, 2049, 2049, 2050, 2052, + 2052, 2052, 2052, 2053, 2054, 2057, 2057, 2058, + 2058, 2058, 2061, 2061, 2062, 2064, 2065, 2066, + 2068, 2067, 2070, 2071, 2073, 2075, 2075, 2076, + 2078, 2078, 2077, 2076, 2080, 2077, 2079, 2080, + 2081, 2079, 2076, 2075, 2074, 2077, 2075, 2071, + 2071, 2070, 2070, 2073, 2073, 2076, 2074, 2071, + 2072, 2072, 2071, 2072, 2069, 2066, 2064, 2062, + 2061, 2062, 2063, 2062, 2064, 2062, 2060, 2062, + 2062, 2061, 2061, 2060, 2056, 2057, 2057, 2055, + 2056, 2056, 2055, 2056, 2057, 2057, 2058, 2059, + 2060, 2059, 2062, 2065, 2067, 2068, 2067, 2067, + 2067, 2066, 2066, 2065, 2063, 2060, 2064, 2067, + 2067, 2065, 2063, 2062, 2063, 2063, 2061, 2061, + 2060, 2060, 2059, 2059, 2061, 2060, 2064, 2064, + 2063, 2062, 2061, 2061, 2060, 2060, 2059, 2057, + 2056, 2055, 2056, 2058, 2058, 2060, 2058, 2060, + 2060, 2057, 2056, 2055, 2055, 2054, 2052, 2051, + 2052, 2048, 2048, 2050, 2051, 2046, 2044, 2043, + 2045, 2045, 2042, 2044, 2044, 2045, 2046, 2048, + 2047, 2049, 2045, 2043, 2042, 2042, 2040, 2039, + 2040, 2039, 2042, 2041, 2042, 2044, 2043, 2041, + 2040, 2039, 2036, 2038, 2039, 2040, 2042, 2043, + 2042, 2042, 2043, 2043, 2042, 2042, 2041, 2042, + 2041, 2044, 2044, 2041, 2042, 2043, 2040, 2041, + 2040, 2038, 2038, 2036, 2034, 2034, 2035, 2032, + 2032, 2031, 2032, 2031, 2029, 2030, 2029, 2029, + 2027, 2025, 2024, 2025, 2022, 2021, 2016, 2012, + 2012, 2014, 2014, 2014, 2013, 2011, 2010, 2008, + 2010, 2009, 2008, 2007, 2006, 2008, 2009, 2010, + 2011, 2008, 2009, 2011, 2010, 2012, 2012, 2011, + 2011, 2008, 2010, 2012, 2012, 2014, 2014, 2013, + 2007, 2012, 2017, 2018, 2016, 2013, 2011, 2015, + 2016, 2018, 2020, 2019, 2018, 2020, 2021, 2023, + 2024, 2023, 2026, 2024, 2025, 2027, 2027, 2026, + 2025, 2026, 2026, 2024, 2025, 2024, 2019, 2017, + 2015, 2012, 2010, 2009, 2010, 2010, 2008, 2005, + 2007, 2008, 2004, 2002, 1999, 1995, 1994, 1997, + 1997, 1997, 1996, 1995, 2000, 2001, 1998, 1998, + 1994, 1994, 1993, 1993, 1990, 1991, 1991, 1991, + 1996, 1993, 1995, 1995, 1997, 1994, 1994, 1994, + 1993, 1993, 1990, 1990, 1992, 1994, 1996, 1998, + 1998, 1998, 2000, 2002, 2001, 2001, 2000, 1998, + 2003, 2004, 2002, 2003, 2006, 2006, 2007, 2004, + 2002, 2001, 2000, 2000, 2002, 2001, 2002, 2003, + 2003, 2005, 2002, 2003, 2004, 2004, 2003, 1999, + 1996, 1998, 2000, 2001, 2001, 2000, 2001, 2003, + 2007, 2006, 2006, 2006, 2007, 2005, 2009, 2008, + 2008, 2011, 2011, 2017, 2016, 2016, 2019, 2021, + 2022, 2023, 2020, 2019, 2021, 2022, 2022, 2019, + 2020, 2021, 2022, 2021, 2025, 2027, 2025, 2025, + 2026, 2028, 2029, 2031, 2029, 2030, 2033, 2034, + 2034, 2031, 2030, 2032, 2033, 2032, 2033, 2032, + 2032, 2033, 2033, 2033, 2034, 2033, 2033, 2035, + 2034, 2032, 2033, 2034, 2030, 2028, 2026, 2026, + 2029, 2028, 2028, 2027, 2029, 2031, 2033, 2034, + 2034, 2033, 2032, 2034, 2034, 2032, 2031, 2034, + 2032, 2034, 2030, 2032, 2033, 2031, 2032, 2031, + 2030, 2031, 2031, 2030, 2029, 2028, 2027, 2028, + 2029, 2029, 2027, 2027, 2027, 2028, 2029, 2025, + 2024, 2022, 2022, 2025, 2026, 2027, 2026, 2027, + 2030, 2032, 2030, 2030, 2028, 2029, 2028, 2027, + 2028, 2030, 2032, 2030, 2032, 2033, 2032, 2031, + 2030, 2033, 2031, 2031, 2034, 2033, 2039, 2039, + 2039, 2041, 2043, 2043, 2041, 2039, 2038, 2038, + 2039, 2040, 2041, 2040, 2044, 2044, 2043, 2044, + 2044, 2047, 2049, 2045, 2046, 2046, 2044, 2046, + 2046, 2046, 2047, 2043, 2040, 2041, 2040, 2041, + 2045, 2044, 2044, 2046, 2043, 2042, 2042, 2041, + 2041, 2041, 2042, 2043, 2043, 2044, 2044, 2042, + 2042, 2044, 2044, 2044, 2046, 2045, 2046, 2046, + 2044, 2043, 2044, 2041, 2040, 2042, 2043, 2042, + 2043, 2047, 2046, 2048, 2045, 2045, 2046, 2046, + 2045, 2046, 2046, 2044, 2042, 2042, 2043, 2045, + 2047, 2046, 2046, 2048, 2048, 2049, 2050, 2049, + 2047, 2047, 2048, 2050, 2050, 2049, 2050, 2050, + 2051, 2050, 2048, 2048, 2047, 2044, 2044, 2043, + 2042, 2043, 2041, 2040, 2041, 2039, 2038, 2038, + 2038, 2038, 2039, 2036, 2034, 2034, 2031, 2031, + 2031, 2029, 2028, 2027, 2028, 2028, 2026, 2025, + 2027, 2030, 2028, 2027, 2025, 2024, 2023, 2020, + 2021, 2020, 2018, 2021, 2021, 2020, 2018, 2020, + 2019, 2021, 2026, 2027, 2027, 2027, 2028, 2027, + 2028, 2026, 2029, 2026, 2025, 2028, 2029, 2030, + 2033, 2034, 2034, 2034, 2036, 2036, 2039, 2041, + 2041, 2040, 2039, 2036, 2033, 2030, 2032, 2031, + 2029, 2034, 2039, 2044, 2048, 2051, 2054, 2055, + 2054, 2057, 2059, 2056, 2053, 2050, 2048, 2044, + 2037, 2033, 2030, 2026, 2027, 2028, 2031, 2037, + 2042, 2046, 2051, 2051, 2056, 2056, 2052, 2048, + 2044, 2037, 2029, 2023, 2014, 2007, 2003, 2002, + 2001, 1999, 1952, 1835, 1745, 1700, 1674, 1683, + 1730, 1806, 1892, 1979, 2053, 2095, 2102, 2106, + 2121, 2130, 2119, 2100, 2071, 2028, 1984, 1947, + 1918, 1900, 1904, 1935, 1979, 2022, 2068, 2117, + 2154, 2185, 2200, 2203, 2195, 2171, 2138, 2103, + 2079, 2045, 2012, 2001, 2006, 2014, 2025, 2046, + 2071, 2087, 2104, 2123, 2137, 2145, 2147, 2156, + 2150, 2130, 2105, 2082, 2044, 2005, 1982, 1967, + 1967, 1976, 1996, 1991, 1900, 1837, 1827, 1801, + 1808, 1817, 1847, 1897, 1932, 1965, 1973, 1967, + 1969, 2007, 2030, 2021, 2003, 1972, 1936, 1895, + 1870, 1845, 1822, 1827, 1856, 1892, 1915, 1937, + 1964, 1985, 2006, 2025, 2041, 2046, 2029, 2015, + 2001, 1988, 1969, 1936, 1912, 1908, 1909, 1918, + 1931, 1948, 1974, 2003, 2029, 2050, 2066, 2074, + 2075, 2065, 2045, 2027, 2012, 1990, 1967, 1957, + 1960, 1970, 1981, 1996, 2015, 2026, 2040, 2054, + 2058, 2051, 2049, 2056, 2058, 2049, 2029, 2008, + 1991, 1985, 1983, 1975, 1951, 1915, 1878, 1859, + 1850, 1841, 1846, 1863, 1891, 1923, 1957, 1977, + 1975, 1960, 1953, 1956, 1965, 1970, 1964, 1957, + 1943, 1933, 1923, 1910, 1898, 1892, 1897, 1914, + 1945, 1973, 2000, 2018, 2031, 2040, 2038, 2026, + 2002, 1975, 1954, 1945, 1942, 1938, 1941, 1951, + 1964, 1971, 1972, 1970, 1979, 1989, 1996, 2004, + 2013, 2012, 2009, 2022, 2016, 1991, 1975, 1980, + 1974, 1947, 1934, 1950, 1976, 2002, 2023, 2035, + 2041, 2047, 2053, 2046, 2030, 2021, 2017, 2011, + 2015, 2021, 2010, 1991, 1984, 1996, 2011, 2016, + 2013, 2008, 2006, 2017, 2024, 2023, 2026, 2032, + 2031, 2030, 2029, 2025, 2004, 1987, 1996, 2021, + 2041, 2042, 2035, 2033, 2031, 2026, 2011, 1998, + 1989, 1977, 1963, 1956, 1957, 1951, 1941, 1935, + 1939, 1951, 1956, 1956, 1952, 1948, 1950, 1950, + 1945, 1938, 1908, 1840, 1792, 1779, 1765, 1742, + 1726, 1745, 1771, 1801, 1839, 1877, 1904, 1924, + 1950, 1965, 1975, 1976, 1957, 1929, 1906, 1900, + 1888, 1864, 1847, 1846, 1861, 1881, 1909, 1945, + 1986, 2019, 2043, 2056, 2062, 2055, 2026, 2000, + 1988, 1976, 1954, 1935, 1934, 1950, 1972, 1984, + 1998, 2022, 2047, 2060, 2063, 2064, 2062, 2057, + 2046, 2040, 2033, 2016, 2000, 1991, 1978, 1969, + 1972, 1995, 2016, 2028, 2051, 2070, 2071, 2066, + 2059, 2044, 2023, 2007, 2003, 1999, 1984, 1970, + 1965, 1963, 1962, 1970, 1982, 1988, 1993, 1996, + 2001, 2005, 2000, 2001, 1999, 1991, 1984, 1972, + 1960, 1944, 1929, 1920, 1919, 1935, 1958, 1974, + 1980, 1991, 2005, 2018, 2015, 1997, 1984, 1971, + 1956, 1948, 1945, 1940, 1945, 1963, 1973, 1972, + 1975, 1981, 1986, 1988, 1995, 2009, 2020, 2032, + 2035, 2026, 2008, 1991, 1973, 1962, 1964, 1971, + 1981, 1999, 2025, 2050, 2063, 2068, 2062, 2052, + 2044, 2038, 2033, 2028, 2027, 2028, 2031, 2031, + 2033, 2029, 2021, 2019, 2017, 2021, 2031, 2044, + 2058, 2068, 2075, 2074, 2067, 2056, 2044, 2031, + 2015, 2002, 2000, 1997, 2001, 2010, 2012, 2025, + 2035, 2041, 2044, 2046, 2048, 2043, 2039, 2035, + 2036, 2032, 2025, 2016, 2004, 1989, 1982, 1983, + 1989, 1998, 2008, 2021, 2032, 2036, 2037, 2035, + 2031, 2021, 2012, 2011, 2008, 2002, 1999, 2000, + 2001, 2003, 2011, 2021, 2025, 2024, 2027, 2033, + 2036, 2036, 2038, 2039, 2042, 2040, 2037, 2034, + 2027, 2019, 2013, 2012, 2013, 2018, 2030, 2043, + 2057, 2067, 2074, 2075, 2069, 2060, 2051, 2044, + 2036, 2030, 2031, 2033, 2037, 2040, 2043, 2043, + 2048, 2053, 2054, 2054, 2061, 2069, 2066, 2060, + 2059, 2056, 2052, 2050, 2054, 2057, 2053, 2055, + 2055, 2059, 2060, 2063, 2067, 2069, 2068, 2070, + 2067, 2058, 2047, 2043, 2042, 2039, 2040, 2047, + 2051, 2050, 2052, 2055, 2058, 2056, 2055, 2053, + 2053, 2049, 2047, 2045, 2040, 2036, 2031, 2028, + 2026, 2026, 2032, 2039, 2047, 2053, 2058, 2061, + 2060, 2062, 2056, 2046, 2043, 2040, 2040, 2037, + 2036, 2037, 2041, 2042, 2044, 2048, 2048, 2050, + 2056, 2062, 2066, 2068, 2071, 2072, 2070, 2069, + 2066, 2057, 2048, 2044, 2044, 2047, 2050, 2055, + 2061, 2067, 2072, 2078, 2083, 2085, 2088, 2087, + 2084, 2083, 2076, 2071, 2067, 2062, 2060, 2060, + 2058, 2056, 2059, 2065, 2073, 2079, 2088, 2089, + 2093, 2097, 2097, 2092, 2084, 2078, 2074, 2067, + 2060, 2058, 2056, 2058, 2058, 2065, 2067, 2073, + 2077, 2081, 2080, 2074, 2072, 2069, 2067, 2063, + 2062, 2059, 2061, 2060, 2057, 2055, 2054, 2057, + 2061, 2065, 2067, 2065, 2063, 2063, 2061, 2058, + 2053, 2052, 2050, 2051, 2053, 2057, 2059, 2061, + 2060, 2058, 2060, 2058, 2061, 2068, 2071, 2070, + 2066, 2069, 2067, 2061, 2055, 2052, 2054, 2054, + 2055, 2056, 2061, 2063, 2065, 2066, 2071, 2076, + 2080, 2082, 2081, 2080, 2075, 2068, 2058, 2048, + 2040, 2036, 2035, 2040, 2050, 2059, 2070, 2083, + 2092, 2097, 2094, 2091, 2087, 2077, 2070, 2062, + 2054, 2049, 2048, 2048, 2046, 2044, 2051, 2058, + 2067, 2075, 2088, 2091, 2085, 2077, 2068, 2063, + 2056, 2056, 2062, 2064, 2061, 2056, 2051, 2046, + 2044, 2047, 2050, 2057, 2063, 2064, 2061, 2056, + 2057, 2059, 2063, 2068, 2068, 2068, 2063, 2054, + 2043, 2036, 2033, 2035, 2039, 2045, 2048, 2051, + 2049, 2047, 2048, 2046, 2052, 2057, 2058, 2058, + 2054, 2046, 2040, 2039, 2036, 2037, 2041, 2045, + 2049, 2052, 2049, 2042, 2030, 2022, 2020, 2022, + 2029, 2039, 2048, 2058, 2064, 2062, 2056, 2045, + 2040, 2036, 2032, 2029, 2024, 2020, 2014, 2012, + 2016, 2023, 2034, 2043, 2051, 2053, 2052, 2048, + 2041, 2034, 2030, 2028, 2027, 2024, 2016, 2008, + 2003, 2001, 2003, 2009, 2019, 2026, 2032, 2033, + 2033, 2032, 2033, 2036, 2038, 2038, 2034, 2035, + 2031, 2029, 2024, 2023, 2024, 2027, 2027, 2026, + 2020, 2017, 2018, 2022, 2026, 2031, 2038, 2039, + 2038, 2039, 2038, 2036, 2030, 2024, 2022, 2020, + 2016, 2012, 2011, 2011, 2013, 2018, 2025, 2028, + 2026, 2024, 2018, 2014, 2008, 2003, 2001, 2007, + 2014, 2025, 2029, 2026, 2019, 2008, 1999, 1990, + 1985, 1984, 1989, 1995, 2007, 2015, 2015, 2015, + 2014, 2013, 2012, 2016, 2016, 2015, 2014, 2008, + 2001, 1991, 1987, 1984, 1986, 1989, 1995, 2004, + 2009, 2011, 2010, 2006, 2000, 1996, 1997, 1996, + 2000, 2000, 1999, 2002, 2001, 2000, 1997, 1994, + 1989, 1988, 1986, 1981, 1977, 1979, 1982, 1986, + 1990, 1998, 2000, 2002, 2001, 2000, 1993, 1983, + 1977, 1970, 1963, 1960, 1963, 1962, 1965, 1966, + 1967, 1969, 1968, 1972, 1976, 1979, 1983, 1984, + 1985, 1986, 1982, 1975, 1969, 1963, 1960, 1958, + 1961, 1965, 1969, 1972, 1976, 1980, 1983, 1988, + 1989, 1990, 1991, 1990, 1986, 1984, 1983, 1980, + 1974, 1972, 1973, 1977, 1984, 1992, 1997, 2000, + 2005, 2009, 2009, 2003, 1998, 1992, 1986, 1983, + 1977, 1973, 1969, 1968, 1974, 1977, 1984, 1992, + 1998, 2004, 2001, 1996, 1990, 1986, 1984, 1982, + 1982, 1986, 1988, 1990, 1988, 1986, 1984, 1984, + 1983, 1984, 1988, 1993, 1998, 2003, 2005, 2001, + 1996, 1991, 1986, 1983, 1979, 1982, 1983, 1986, + 1991, 1992, 1990, 1986, 1984, 1980, 1982, 1982, + 1984, 1986, 1984, 1987, 1987, 1982, 1984, 1986, + 1983, 1984, 1985, 1987, 1986, 1985, 1982, 1982, + 1984, 1985, 1988, 1986, 1988, 1990, 1991, 1992, + 1993, 1992, 1991, 1991, 1988, 1987, 1990, 1991, + 1994, 1997, 2001, 2001, 1999, 1995, 1988, 1984, + 1980, 1976, 1976, 1982, 1985, 1987, 1989, 1991, + 1993, 1993, 1996, 1999, 2003, 2005, 2004, 2004, + 2002, 1998, 1994, 1989, 1986, 1984, 1983, 1984, + 1983, 1981, 1985, 1986, 1986, 1986, 1988, 1992, + 1997, 2000, 1999, 1996, 1991, 1991, 1988, 1982, + 1983, 1980, 1981, 1984, 1984, 1985, 1985, 1989, + 1991, 1994, 1999, 1996, 1994, 1989, 1988, 1988, + 1979, 1980, 1979, 1980, 1979, 1980, 1982, 1984, + 1985, 1986, 1988, 1988, 1992, 1991, 1989, 1987, + 1988, 1987, 1987, 1991, 1994, 1999, 2003, 2001, + 2000, 1999, 1996, 1991, 1990, 1990, 1991, 1990, + 1992, 1994, 1993, 1997, 1997, 2002, 2009, 2016, + 2022, 2025, 2028, 2027, 2024, 2024, 2024, 2022, + 2025, 2024, 2022, 2021, 2019, 2017, 2014, 2017, + 2020, 2023, 2026, 2030, 2034, 2036, 2033, 2032, + 2030, 2029, 2027, 2021, 2019, 2017, 2016, 2019, + 2027, 2031, 2033, 2035, 2032, 2030, 2024, 2022, + 2016, 2015, 2017, 2014, 2013, 2013, 2012, 2012, + 2014, 2017, 2023, 2029, 2033, 2036, 2037, 2034, + 2032, 2029, 2029, 2029, 2030, 2030, 2032, 2030, + 2026, 2021, 2019, 2021, 2027, 2033, 2038, 2040, + 2044, 2047, 2043, 2038, 2035, 2033, 2031, 2030, + 2030, 2030, 2031, 2033, 2038, 2039, 2038, 2037, + 2039, 2038, 2037, 2035, 2036, 2039, 2042, 2043, + 2041, 2042, 2042, 2040, 2036, 2037, 2040, 2040, + 2042, 2046, 2049, 2046, 2044, 2044, 2043, 2040, + 2036, 2039, 2042, 2045, 2048, 2043, 2040, 2037, + 2036, 2034, 2033, 2032, 2032, 2032, 2036, 2037, + 2040, 2041, 2042, 2043, 2047, 2051, 2051, 2049, + 2047, 2043, 2035, 2031, 2027, 2025, 2026, 2024, + 2030, 2034, 2036, 2038, 2039, 2045, 2052, 2054, + 2055, 2054, 2053, 2052, 2051, 2048, 2046, 2044, + 2048, 2048, 2046, 2046, 2047, 2046, 2047, 2048, + 2049, 2051, 2051, 2052, 2051, 2052, 2052, 2055, + 2062, 2064, 2067, 2068, 2066, 2068, 2067, 2066, + 2069, 2069, 2070, 2072, 2071, 2071, 2067, 2062, + 2061, 2063, 2064, 2067, 2067, 2067, 2071, 2071, + 2074, 2079, 2080, 2081, 2080, 2078, 2074, 2072, + 2068, 2062, 2060, 2061, 2064, 2065, 2069, 2073, + 2076, 2081, 2084, 2089, 2091, 2094, 2093, 2093, + 2090, 2086, 2085, 2081, 2081, 2081, 2082, 2082, + 2081, 2081, 2080, 2078, 2080, 2084, 2086, 2090, + 2096, 2095, 2095, 2093, 2091, 2085, 2086, 2088, + 2088, 2090, 2091, 2091, 2089, 2088, 2089, 2088, + 2087, 2089, 2089, 2092, 2096, 2099, 2102, 2101, + 2100, 2102, 2102, 2098, 2096, 2092, 2089, 2086, + 2084, 2086, 2093, 2097, 2105, 2111, 2115, 2116, + 2114, 2112, 2111, 2112, 2113, 2116, 2114, 2119, + 2124, 2127, 2122, 2115, 2114, 2111, 2111, 2112, + 2114, 2115, 2118, 2123, 2127, 2131, 2133, 2135, + 2136, 2135, 2131, 2130, 2130, 2131, 2130, 2129, + 2131, 2135, 2136, 2139, 2139, 2137, 2133, 2130, + 2126, 2124, 2129, 2129, 2129, 2126, 2126, 2128, + 2128, 2126, 2127, 2127, 2132, 2134, 2131, 2129, + 2126, 2124, 2122, 2119, 2115, 2112, 2110, 2111, + 2112, 2114, 2114, 2116, 2115, 2118, 2121, 2125, + 2126, 2124, 2124, 2120, 2118, 2115, 2113, 2110, + 2111, 2111, 2109, 2108, 2110, 2112, 2115, 2119, + 2121, 2123, 2123, 2121, 2121, 2120, 2123, 2124, + 2125, 2127, 2128, 2129, 2127, 2124, 2119, 2114, + 2112, 2110, 2111, 2114, 2114, 2118, 2123, 2126, + 2127, 2125, 2126, 2130, 2131, 2133, 2130, 2128, + 2125, 2120, 2118, 2117, 2116, 2119, 2129, 2132, + 2133, 2134, 2131, 2132, 2131, 2134, 2137, 2139, + 2140, 2139, 2138, 2133, 2130, 2126, 2123, 2123, + 2127, 2128, 2130, 2134, 2133, 2134, 2137, 2140, + 2142, 2144, 2144, 2141, 2136, 2133, 2128, 2121, + 2118, 2120, 2127, 2129, 2134, 2138, 2138, 2138, + 2134, 2133, 2131, 2133, 2134, 2131, 2126, 2121, + 2115, 2108, 2109, 2114, 2120, 2128, 2136, 2141, + 2142, 2142, 2143, 2139, 2139, 2139, 2137, 2135, + 2128, 2123, 2116, 2110, 2108, 2108, 2110, 2116, + 2119, 2122, 2128, 2129, 2126, 2123, 2125, 2127, + 2130, 2128, 2124, 2119, 2113, 2106, 2104, 2105, + 2107, 2110, 2115, 2118, 2118, 2118, 2118, 2115, + 2114, 2115, 2115, 2115, 2114, 2112, 2111, 2111, + 2110, 2112, 2115, 2116, 2117, 2119, 2116, 2115, + 2112, 2111, 2110, 2108, 2107, 2105, 2106, 2106, + 2106, 2106, 2106, 2106, 2107, 2108, 2108, 2107, + 2110, 2113, 2115, 2113, 2108, 2103, 2094, 2086, + 2084, 2086, 2087, 2084, 2085, 2089, 2090, 2091, + 2096, 2100, 2103, 2105, 2110, 2108, 2105, 2098, + 2093, 2091, 2087, 2089, 2094, 2099, 2101, 2101, + 2097, 2094, 2093, 2090, 2096, 2104, 2109, 2110, + 2108, 2104, 2102, 2102, 2104, 2108, 2113, 2117, + 2120, 2119, 2118, 2118, 2113, 2115, 2119, 2120, + 2125, 2126, 2121, 2117, 2111, 2108, 2110, 2112, + 2116, 2121, 2127, 2129, 2130, 2127, 2128, 2128, + 2130, 2134, 2137, 2136, 2133, 2129, 2124, 2119, + 2115, 2115, 2117, 2121, 2127, 2131, 2132, 2132, + 2131, 2131, 2135, 2138, 2140, 2138, 2136, 2130, + 2124, 2122, 2123, 2125, 2132, 2138, 2144, 2147, + 2147, 2146, 2144, 2144, 2143, 2143, 2144, 2143, + 2138, 2133, 2127, 2121, 2118, 2121, 2128, 2135, + 2143, 2151, 2154, 2152, 2151, 2147, 2143, 2142, + 2142, 2139, 2135, 2134, 2133, 2133, 2134, 2135, + 2136, 2140, 2144, 2143, 2143, 2144, 2144, 2144, + 2144, 2145, 2148, 2146, 2145, 2144, 2143, 2139, + 2139, 2138, 2139, 2140, 2141, 2144, 2149, 2152, + 2155, 2157, 2158, 2160, 2160, 2160, 2157, 2156, + 2153, 2151, 2152, 2152, 2149, 2148, 2148, 2147, + 2149, 2152, 2158, 2161, 2165, 2164, 2165, 2166, + 2166, 2164, 2161, 2163, 2163, 2163, 2160, 2157, + 2157, 2156, 2153, 2155, 2159, 2162, 2163, 2166, + 2171, 2171, 2170, 2166, 2161, 2157, 2153, 2153, + 2155, 2155, 2152, 2153, 2155, 2157, 2159, 2160, + 2165, 2168, 2167, 2167, 2161, 2156, 2154, 2152, + 2152, 2154, 2155, 2157, 2156, 2159, 2156, 2157, + 2157, 2158, 2159, 2163, 2169, 2166, 2162, 2158, + 2154, 2153, 2151, 2148, 2152, 2158, 2156, 2155, + 2157, 2159, 2156, 2154, 2154, 2157, 2156, 2158, + 2160, 2158, 2156, 2153, 2151, 2149, 2146, 2150, + 2155, 2156, 2159, 2160, 2161, 2163, 2166, 2168, + 2168, 2169, 2170, 2169, 2164, 2157, 2152, 2150, + 2150, 2148, 2150, 2155, 2162, 2165, 2170, 2172, + 2177, 2181, 2184, 2184, 2182, 2180, 2175, 2171, + 2164, 2160, 2156, 2157, 2161, 2162, 2164, 2167, + 2165, 2163, 2165, 2165, 2167, 2169, 2171, 2172, + 2172, 2171, 2170, 2170, 2173, 2176, 2172, 2171, + 2171, 2171, 2165, 2160, 2153, 2154, 2159, 2167, + 2170, 2170, 2171, 2173, 2172, 2170, 2169, 2171, + 2174, 2176, 2180, 2179, 2174, 2170, 2168, 2168, + 2167, 2167, 2168, 2169, 2171, 2169, 2169, 2171, + 2173, 2177, 2179, 2185, 2189, 2191, 2188, 2181, + 2179, 2178, 2176, 2179, 2182, 2183, 2178, 2177, + 2172, 2165, 2159, 2158, 2164, 2168, 2169, 2173, + 2173, 2170, 2173, 2175, 2177, 2179, 2185, 2189, + 2193, 2190, 2186, 2183, 2180, 2182, 2182, 2184, + 2188, 2188, 2185, 2180, 2174, 2172, 2171, 2170, + 2173, 2178, 2178, 2178, 2176, 2177, 2177, 2179, + 2184, 2188, 2194, 2199, 2200, 2198, 2193, 2188, + 2182, 2177, 2175, 2172, 2172, 2172, 2174, 2173, + 2175, 2173, 2179, 2186, 2190, 2197, 2200, 2201, + 2196, 2190, 2185, 2180, 2176, 2174, 2169, 2167, + 2164, 2162, 2158, 2157, 2158, 2162, 2169, 2177, + 2185, 2190, 2192, 2192, 2186, 2180, 2175, 2173, + 2169, 2166, 2165, 2162, 2158, 2153, 2152, 2155, + 2161, 2168, 2176, 2185, 2185, 2184, 2181, 2180, + 2176, 2174, 2175, 2177, 2181, 2185, 2185, 2179, + 2177, 2172, 2169, 2170, 2172, 2174, 2175, 2176, + 2172, 2170, 2171, 2174, 2179, 2185, 2191, 2198, + 2203, 2202, 2197, 2190, 2190, 2190, 2188, 2190, + 2188, 2183, 2178, 2173, 2168, 2167, 2166, 2173, + 2180, 2188, 2199, 2202, 2205, 2202, 2201, 2195, + 2192, 2191, 2190, 2189, 2186, 2182, 2179, 2177, + 2175, 2176, 2178, 2185, 2189, 2193, 2196, 2195, + 2197, 2195, 2192, 2193, 2194, 2196, 2196, 2189, + 2183, 2181, 2180, 2182, 2185, 2190, 2198, 2201, + 2206, 2203, 2198, 2192, 2186, 2185, 2182, 2179, + 2178, 2179, 2175, 2175, 2180, 2186, 2191, 2195, + 2199, 2201, 2199, 2196, 2190, 2190, 2185, 2184, + 2182, 2179, 2177, 2170, 2164, 2162, 2162, 2165, + 2169, 2173, 2180, 2186, 2191, 2193, 2194, 2193, + 2193, 2192, 2190, 2186, 2185, 2182, 2175, 2172, + 2171, 2171, 2172, 2174, 2179, 2180, 2182, 2188, + 2190, 2191, 2192, 2192, 2192, 2190, 2188, 2190, + 2188, 2185, 2183, 2182, 2181, 2179, 2178, 2178, + 2175, 2175, 2175, 2176, 2179, 2180, 2183, 2182, + 2179, 2179, 2178, 2177, 2179, 2180, 2187, 2188, + 2192, 2194, 2194, 2193, 2191, 2192, 2192, 2188, + 2185, 2183, 2183, 2182, 2180, 2184, 2186, 2191, + 2195, 2199, 2200, 2203, 2201, 2201, 2203, 2206, + 2208, 2207, 2209, 2205, 2198, 2193, 2186, 2185, + 2183, 2188, 2190, 2194, 2198, 2199, 2200, 2199, + 2200, 2202, 2203, 2204, 2202, 2202, 2200, 2192, + 2186, 2183, 2177, 2174, 2172, 2166, 2164, 2161, + 2160, 2158, 2158, 2160, 2161, 2167, 2169, 2169, + 2165, 2162, 2160, 2161, 2161, 2162, 2164, 2167, + 2167, 2165, 2161, 2156, 2155, 2150, 2146, 2147, + 2150, 2152, 2156, 2158, 2161, 2164, 2166, 2166, + 2165, 2165, 2163, 2163, 2161, 2159, 2158, 2157, + 2160, 2157, 2158, 2156, 2153, 2148, 2147, 2150, + 2154, 2155, 2159, 2162, 2166, 2165, 2165, 2166, + 2164, 2163, 2158, 2154, 2152, 2151, 2151, 2151, + 2148, 2147, 2147, 2147, 2148, 2149, 2154, 2158, + 2162, 2165, 2166, 2170, 2172, 2172, 2172, 2169, + 2169, 2166, 2164, 2162, 2160, 2159, 2159, 2162, + 2166, 2167, 2168, 2170, 2172, 2172, 2174, 2175, + 2177, 2178, 2183, 2185, 2181, 2179, 2176, 2174, + 2169, 2164, 2162, 2163, 2161, 2165, 2165, 2165, + 2169, 2171, 2173, 2175, 2177, 2178, 2177, 2177, + 2176, 2174, 2174, 2176, 2177, 2177, 2177, 2174, + 2173, 2170, 2167, 2167, 2170, 2173, 2179, 2182, + 2182, 2183, 2183, 2185, 2188, 2190, 2192, 2194, + 2193, 2193, 2192, 2191, 2190, 2191, 2194, 2194, + 2196, 2201, 2203, 2202, 2198, 2198, 2199, 2205, + 2208, 2214, 2218, 2220, 2218, 2220, 2218, 2219, + 2220, 2219, 2218, 2216, 2213, 2212, 2214, 2210, + 2210, 2212, 2213, 2215, 2217, 2216, 2217, 2218, + 2220, 2223, 2223, 2226, 2228, 2228, 2224, 2223, + 2220, 2219, 2218, 2219, 2218, 2216, 2216, 2218, + 2221, 2221, 2225, 2230, 2238, 2245, 2250, 2250, + 2250, 2249, 2241, 2237, 2235, 2232, 2230, 2227, + 2227, 2230, 2230, 2231, 2235, 2238, 2238, 2240, + 2244, 2246, 2244, 2243, 2244, 2246, 2247, 2246, + 2243, 2239, 2237, 2233, 2231, 2230, 2231, 2231, + 2234, 2237, 2240, 2243, 2242, 2239, 2238, 2240, + 2243, 2242, 2243, 2246, 2250, 2253, 2251, 2249, + 2251, 2250, 2249, 2249, 2249, 2247, 2247, 2247, + 2247, 2246, 2246, 2248, 2249, 2251, 2253, 2254, + 2256, 2258, 2258, 2261, 2261, 2260, 2261, 2258, + 2257, 2252, 2251, 2252, 2247, 2245, 2244, 2243, + 2245, 2241, 2239, 2239, 2241, 2241, 2242, 2243, + 2246, 2244, 2241, 2237, 2235, 2235, 2232, 2231, + 2231, 2232, 2230, 2230, 2229, 2230, 2233, 2233, + 2233, 2237, 2239, 2239, 2238, 2237, 2239, 2242, + 2244, 2244, 2245, 2243, 2236, 2232, 2227, 2223, + 2225, 2226, 2230, 2232, 2235, 2234, 2234, 2234, + 2235, 2240, 2240, 2245, 2248, 2249, 2245, 2239, + 2235, 2231, 2226, 2224, 2223, 2219, 2218, 2217, + 2217, 2217, 2221, 2223, 2227, 2230, 2232, 2233, + 2231, 2231, 2228, 2226, 2226, 2224, 2219, 2218, + 2216, 2211, 2211, 2213, 2217, 2218, 2221, 2223, + 2226, 2231, 2235, 2242, 2248, 2251, 2251, 2253, + 2254, 2259, 2259, 2254, 2255, 2254, 2250, 2246, + 2241, 2238, 2232, 2231, 2234, 2239, 2241, 2243, + 2248, 2250, 2254, 2256, 2259, 2262, 2264, 2263, + 2261, 2255, 2251, 2246, 2240, 2233, 2230, 2233, + 2232, 2228, 2224, 2223, 2222, 2221, 2223, 2227, + 2230, 2235, 2234, 2232, 2230, 2231, 2230, 2232, + 2232, 2232, 2229, 2227, 2228, 2225, 2224, 2224, + 2227, 2229, 2227, 2228, 2227, 2228, 2230, 2230, + 2229, 2231, 2233, 2233, 2231, 2226, 2226, 2223, + 2223, 2223, 2225, 2228, 2227, 2228, 2226, 2226, + 2224, 2221, 2223, 2224, 2225, 2227, 2229, 2227, + 2228, 2225, 2224, 2223, 2226, 2224, 2224, 2226, + 2225, 2226, 2226, 2226, 2225, 2224, 2225, 2227, + 2225, 2223, 2223, 2227, 2227, 2226, 2227, 2226, + 2226, 2225, 2226, 2228, 2227, 2229, 2229, 2232, + 2231, 2232, 2230, 2233, 2232, 2232, 2231, 2230, + 2231, 2230, 2230, 2231, 2231, 2233, 2234, 2235, + 2235, 2231, 2228, 2227, 2226, 2224, 2222, 2222, + 2222, 2224, 2221, 2220, 2217, 2215, 2213, 2214, + 2215, 2216, 2215, 2212, 2211, 2209, 2211, 2212, + 2209, 2211, 2212, 2210, 2206, 2203, 2199, 2197, + 2198, 2199, 2203, 2207, 2210, 2212, 2214, 2216, + 2219, 2220, 2222, 2224, 2226, 2227, 2223, 2217, + 2212, 2206, 2203, 2197, 2193, 2193, 2195, 2199, + 2203, 2209, 2213, 2216, 2218, 2223, 2225, 2227, + 2228, 2222, 2219, 2214, 2213, 2213, 2213, 2210, + 2210, 2207, 2207, 2206, 2204, 2201, 2204, 2207, + 2209, 2212, 2214, 2216, 2215, 2211, 2206, 2204, + 2203, 2199, 2200, 2198, 2199, 2202, 2200, 2199, + 2198, 2198, 2198, 2200, 2201, 2199, 2201, 2199, + 2198, 2193, 2192, 2191, 2190, 2190, 2192, 2192, + 2192, 2191, 2191, 2191, 2193, 2193, 2194, 2193, + 2192, 2192, 2188, 2185, 2182, 2181, 2177, 2177, + 2178, 2175, 2176, 2174, 2175, 2172, 2173, 2172, + 2172, 2172, 2170, 2169, 2164, 2158, 2153, 2149, + 2144, 2143, 2138, 2134, 2132, 2135, 2138, 2137, + 2138, 2140, 2144, 2147, 2148, 2149, 2150, 2147, + 2144, 2143, 2141, 2139, 2136, 2134, 2132, 2132, + 2133, 2132, 2131, 2136, 2138, 2142, 2146, 2146, + 2147, 2146, 2148, 2147, 2142, 2140, 2139, 2138, + 2138, 2133, 2130, 2126, 2122, 2121, 2123, 2124, + 2123, 2125, 2127, 2128, 2126, 2125, 2123, 2120, + 2117, 2112, 2110, 2107, 2104, 2102, 2096, 2092, + 2091, 2091, 2087, 2086, 2087, 2089, 2090, 2089, + 2087, 2086, 2088, 2090, 2094, 2095, 2095, 2093, + 2089, 2085, 2081, 2078, 2077, 2075, 2075, 2074, + 2073, 2073, 2069, 2066, 2065, 2064, 2064, 2062, + 2064, 2064, 2065, 2067, 2067, 2067, 2066, 2067, + 2065, 2064, 2064, 2062, 2059, 2055, 2053, 2053, + 2055, 2054, 2055, 2054, 2054, 2050, 2050, 2051, + 2051, 2051, 2052, 2055, 2059, 2060, 2058, 2058, + 2052, 2049, 2047, 2044, 2044, 2046, 2045, 2050, + 2051, 2052, 2051, 2052, 2055, 2053, 2055, 2056, + 2052, 2051, 2052, 2049, 2046, 2045, 2046, 2044, + 2043, 2043, 2043, 2041, 2042, 2043, 2045, 2047, + 2049, 2050, 2049, 2049, 2047, 2046, 2045, 2041, + 2042, 2041, 2041, 2038, 2039, 2038, 2036, 2036, + 2033, 2029, 2030, 2028, 2029, 2033, 2030, 2032, + 2031, 2030, 2030, 2030, 2029, 2028, 2031, 2030, + 2031, 2028, 2028, 2029, 2025, 2022, 2019, 2017, + 2013, 2011, 2010, 2009, 2011, 2012, 2013, 2016, + 2017, 2019, 2020, 2019, 2018, 2012, 2011, 2012, + 2012, 2013, 2009, 2008, 2007, 2008, 2008, 2011, + 2012, 2009, 2008, 2007, 2006, 2004, 2003, 2002, + 2003, 2001, 2001, 2001, 2002, 2002, 2005, 2004, + 2005, 2003, 2000, 2000, 1998, 1997, 1996, 1994, + 1990, 1987, 1983, 1985, 1985, 1988, 1991, 1994, + 1999, 2000, 1999, 1997, 1998, 1997, 1994, 1994, + 1993, 1990, 1988, 1985, 1979, 1977, 1977, 1977, + 1979, 1981, 1978, 1980, 1979, 1982, 1981, 1981, + 1983, 1983, 1983, 1984, 1983, 1985, 1983, 1977, + 1976, 1976, 1977, 1976, 1977, 1979, 1977, 1976, + 1971, 1966, 1965, 1963, 1962, 1965, 1968, 1967, + 1968, 1967, 1967, 1963, 1965, 1964, 1965, 1967, + 1969, 1968, 1964, 1962, 1960, 1957, 1955, 1953, + 1949, 1949, 1948, 1949, 1950, 1951, 1953, 1957, + 1963, 1964, 1963, 1965, 1960, 1959, 1957, 1951, + 1948, 1946, 1943, 1941, 1941, 1940, 1937, 1936, + 1939, 1939, 1941, 1944, 1944, 1945, 1945, 1946, + 1944, 1945, 1941, 1940, 1940, 1940, 1941, 1939, + 1935, 1936, 1936, 1934, 1933, 1934, 1935, 1937, + 1936, 1934, 1938, 1938, 1938, 1938, 1939, 1938, + 1938, 1939, 1939, 1940, 1937, 1936, 1932, 1933, + 1933, 1934, 1932, 1933, 1933, 1936, 1937, 1936, + 1941, 1944, 1946, 1948, 1952, 1954, 1953, 1950, + 1949, 1947, 1946, 1943, 1942, 1939, 1940, 1940, + 1940, 1938, 1939, 1940, 1940, 1940, 1942, 1945, + 1949, 1949, 1947, 1946, 1947, 1944, 1939, 1937, + 1938, 1936, 1936, 1939, 1937, 1938, 1937, 1935, + 1934, 1935, 1933, 1932, 1930, 1932, 1932, 1932, + 1933, 1933, 1936, 1938, 1942, 1945, 1947, 1948, + 1948, 1952, 1951, 1949, 1947, 1947, 1948, 1946, + 1945, 1945, 1945, 1946, 1944, 1945, 1948, 1952, + 1958, 1959, 1962, 1964, 1965, 1963, 1964, 1960, + 1957, 1956, 1951, 1947, 1943, 1942, 1938, 1939, + 1935, 1937, 1939, 1940, 1943, 1946, 1949, 1950, + 1948, 1947, 1948, 1948, 1947, 1943, 1938, 1939, + 1938, 1937, 1934, 1935, 1933, 1934, 1936, 1940, + 1941, 1942, 1943, 1943, 1946, 1944, 1944, 1944, + 1945, 1946, 1946, 1945, 1946, 1945, 1944, 1942, + 1939, 1936, 1937, 1935, 1935, 1936, 1935, 1937, + 1938, 1939, 1938, 1939, 1938, 1940, 1938, 1937, + 1936, 1935, 1932, 1929, 1926, 1925, 1921, 1921, + 1918, 1915, 1912, 1915, 1916, 1915, 1917, 1918, + 1921, 1925, 1927, 1924, 1921, 1918, 1920, 1918, + 1917, 1920, 1924, 1923, 1925, 1925, 1923, 1922, + 1923, 1926, 1929, 1929, 1932, 1936, 1937, 1936, + 1934, 1934, 1932, 1934, 1933, 1932, 1932, 1927, + 1926, 1926, 1926, 1927, 1925, 1924, 1923, 1923, + 1922, 1923, 1921, 1921, 1921, 1922, 1922, 1923, + 1922, 1923, 1925, 1926, 1927, 1927, 1927, 1928, + 1926, 1925, 1922, 1921, 1922, 1922, 1922, 1922, + 1920, 1921, 1921, 1918, 1919, 1919, 1923, 1924, + 1929, 1931, 1934, 1932, 1931, 1932, 1931, 1932, + 1933, 1931, 1931, 1930, 1931, 1932, 1930, 1930, + 1931, 1930, 1932, 1932, 1931, 1932, 1932, 1928, + 1928, 1930, 1931, 1932, 1932, 1933, 1932, 1930, + 1929, 1927, 1925, 1924, 1924, 1924, 1925, 1924, + 1925, 1927, 1927, 1927, 1924, 1925, 1928, 1927, + 1926, 1925, 1923, 1925, 1926, 1927, 1924, 1922, + 1921, 1919, 1921, 1918, 1917, 1918, 1921, 1922, + 1926, 1928, 1928, 1928, 1927, 1928, 1929, 1931, + 1931, 1930, 1932, 1932, 1928, 1930, 1928, 1927, + 1929, 1931, 1934, 1937, 1937, 1937, 1936, 1938, + 1938, 1939, 1937, 1938, 1937, 1937, 1936, 1933, + 1932, 1932, 1931, 1930, 1931, 1930, 1930, 1930, + 1932, 1932, 1932, 1934, 1936, 1937, 1937, 1936, + 1935, 1936, 1938, 1938, 1938, 1937, 1934, 1937, + 1934, 1928, 1930, 1928, 1930, 1930, 1932, 1934, + 1939, 1940, 1939, 1944, 1943, 1945, 1945, 1943, + 1940, 1940, 1942, 1939, 1942, 1938, 1936, 1935, + 1933, 1930, 1934, 1932, 1929, 1930, 1929, 1931, + 1929, 1927, 1928, 1926, 1925, 1923, 1920, 1920, + 1916, 1915, 1915, 1913, 1912, 1913, 1914, 1914, + 1911, 1911, 1909, 1907, 1909, 1909, 1907, 1909, + 1908, 1907, 1908, 1908, 1910, 1912, 1912, 1910, + 1910, 1913, 1912, 1915, 1916, 1913, 1914, 1911, + 1912, 1911, 1911, 1912, 1913, 1913, 1913, 1914, + 1916, 1916, 1914, 1912, 1911, 1909, 1909, 1907, + 1903, 1903, 1904, 1906, 1907, 1909, 1911, 1912, + 1913, 1912, 1913, 1913, 1912, 1914, 1913, 1913, + 1911, 1909, 1907, 1907, 1907, 1911, 1914, 1917, + 1920, 1922, 1925, 1927, 1928, 1929, 1927, 1927, + 1926, 1927, 1928, 1926, 1927, 1928, 1929, 1934, + 1937, 1938, 1939, 1940, 1941, 1940, 1938, 1937, + 1934, 1933, 1933, 1932, 1930, 1928, 1927, 1928, + 1928, 1928, 1930, 1934, 1936, 1934, 1936, 1938, + 1940, 1937, 1938, 1936, 1934, 1930, 1928, 1927, + 1929, 1928, 1925, 1928, 1930, 1932, 1936, 1940, + 1942, 1944, 1944, 1940, 1944, 1943, 1944, 1942, + 1941, 1941, 1942, 1941, 1943, 1944, 1946, 1950, + 1950, 1953, 1950, 1949, 1947, 1945, 1946, 1946, + 1946, 1948, 1950, 1948, 1946, 1946, 1947, 1946, + 1946, 1948, 1948, 1950, 1951, 1949, 1949, 1949, + 1948, 1944, 1942, 1946, 1945, 1946, 1944, 1949, + 1950, 1952, 1954, 1956, 1957, 1955, 1954, 1953, + 1952, 1949, 1948, 1949, 1950, 1951, 1955, 1956, + 1960, 1962, 1963, 1962, 1963, 1965, 1966, 1970, + 1970, 1969, 1967, 1964, 1962, 1959, 1958, 1957, + 1956, 1956, 1956, 1960, 1960, 1963, 1964, 1965, + 1965, 1966, 1964, 1963, 1962, 1960, 1959, 1958, + 1958, 1957, 1957, 1958, 1955, 1954, 1956, 1956, + 1956, 1957, 1957, 1958, 1959, 1959, 1957, 1958, + 1961, 1960, 1957, 1956, 1954, 1957, 1958, 1959, + 1958, 1957, 1961, 1961, 1963, 1959, 1960, 1963, + 1963, 1963, 1964, 1965, 1965, 1966, 1965, 1967, + 1965, 1967, 1968, 1966, 1971, 1971, 1970, 1969, + 1970, 1971, 1971, 1972, 1971, 1972, 1970, 1970, + 1969, 1967, 1967, 1966, 1967, 1971, 1972, 1974, + 1977, 1976, 1976, 1975, 1974, 1974, 1974, 1973, + 1971, 1972, 1973, 1973, 1973, 1974, 1974, 1975, + 1977, 1979, 1979, 1977, 1979, 1980, 1978, 1978, + 1976, 1976, 1975, 1975, 1974, 1973, 1971, 1974, + 1976, 1977, 1978, 1977, 1977, 1976, 1980, 1981, + 1977, 1977, 1977, 1976, 1975, 1977, 1975, 1974, + 1969, 1970, 1969, 1969, 1965, 1965, 1965, 1966, + 1968, 1967, 1970, 1971, 1972, 1973, 1974, 1973, + 1972, 1975, 1978, 1977, 1976, 1976, 1978, 1978, + 1979, 1981, 1980, 1980, 1981, 1980, 1981, 1980, + 1980, 1981, 1979, 1979, 1977, 1979, 1980, 1982, + 1983, 1984, 1985, 1987, 1992, 1994, 1996, 1997, + 1993, 1992, 1990, 1990, 1989, 1989, 1987, 1987, + 1988, 1986, 1988, 1992, 1993, 1993, 1993, 1994, + 1994, 1997, 1999, 2001, 2003, 2000, 1999, 1996, + 1997, 1996, 1996, 1995, 1996, 1996, 1994, 1994, + 1995, 1998, 1999, 2000, 2001, 2001, 2001, 2001, + 1999, 2001, 2004, 2003, 2006, 2008, 2005, 2007, + 2008, 2007, 2005, 2005, 2001, 2001, 2002, 2000, + 2001, 2002, 2000, 2001, 2003, 2001, 1997, 1994, + 1995, 1999, 2001, 2003, 2008, 2005, 2003, 2002, + 2001, 2001, 2000, 1999, 2000, 2001, 1998, 1997, + 1997, 1996, 1996, 1994, 1994, 1995, 1995, 1997, + 1996, 1996, 1999, 2001, 2001, 2003, 2006, 2004, + 2005, 2003, 2004, 2000, 1999, 1997, 1997, 1997, + 1994, 1994, 1993, 1993, 1994, 1996, 1995, 1994, + 1992, 1993, 1991, 1991, 1990, 1992, 1991, 1987, + 1986, 1986, 1985, 1984, 1986, 1982, 1980, 1979, + 1976, 1978, 1973, 1977, 1978, 1978, 1979, 1980, + 1981, 1981, 1983, 1982, 1983, 1985, 1982, 1985, + 1985, 1983, 1982, 1980, 1980, 1982, 1981, 1984, + 1986, 1986, 1986, 1986, 1984, 1982, 1984, 1987, + 1988, 1990, 1990, 1988, 1986, 1985, 1985, 1984, + 1983, 1983, 1984, 1986, 1986, 1986, 1986, 1986, + 1985, 1985, 1984, 1987, 1987, 1988, 1985, 1983, + 1981, 1979, 1980, 1976, 1974, 1977, 1978, 1979, + 1981, 1981, 1980, 1981, 1980, 1983, 1985, 1987, + 1986, 1984, 1983, 1981, 1980, 1978, 1980, 1978, + 1979, 1979, 1975, 1975, 1975, 1973, 1972, 1971, + 1971, 1969, 1971, 1970, 1970, 1969, 1966, 1964, + 1964, 1964, 1965, 1966, 1968, 1968, 1966, 1968, + 1967, 1967, 1968, 1964, 1962, 1964, 1962, 1963, + 1960, 1960, 1959, 1961, 1964, 1963, 1966, 1966, + 1968, 1969, 1971, 1968, 1967, 1969, 1969, 1969, + 1970, 1968, 1966, 1964, 1966, 1964, 1962, 1964, + 1964, 1962, 1961, 1961, 1958, 1957, 1958, 1958, + 1959, 1957, 1956, 1958, 1958, 1959, 1960, 1960, + 1961, 1960, 1961, 1958, 1958, 1956, 1955, 1954, + 1951, 1949, 1948, 1950, 1951, 1952, 1953, 1954, + 1955, 1955, 1956, 1957, 1958, 1956, 1954, 1954, + 1954, 1951, 1948, 1946, 1946, 1946, 1945, 1946, + 1946, 1946, 1946, 1946, 1946, 1946, 1945, 1943, + 1945, 1944, 1941, 1940, 1939, 1941, 1941, 1938, + 1939, 1941, 1944, 1941, 1941, 1939, 1938, 1939, + 1936, 1931, 1931, 1933, 1932, 1932, 1931, 1932, + 1933, 1933, 1934, 1934, 1936, 1937, 1934, 1935, + 1933, 1932, 1931, 1930, 1928, 1927, 1927, 1927, + 1928, 1930, 1928, 1928, 1930, 1930, 1930, 1930, + 1930, 1929, 1927, 1925, 1924, 1922, 1922, 1923, + 1918, 1917, 1915, 1916, 1917, 1916, 1916, 1915, + 1914, 1915, 1917, 1918, 1920, 1918, 1916, 1917, + 1916, 1914, 1912, 1913, 1914, 1913, 1914, 1914, + 1912, 1909, 1908, 1910, 1912, 1912, 1913, 1914, + 1914, 1913, 1912, 1914, 1914, 1915, 1914, 1913, + 1912, 1910, 1910, 1909, 1905, 1906, 1910, 1910, + 1910, 1906, 1908, 1905, 1903, 1906, 1908, 1908, + 1909, 1910, 1906, 1905, 1905, 1905, 1905, 1905, + 1907, 1907, 1908, 1910, 1911, 1911, 1909, 1910, + 1910, 1909, 1907, 1905, 1903, 1903, 1904, 1905, + 1907, 1905, 1905, 1906, 1906, 1907, 1909, 1909, + 1911, 1911, 1911, 1910, 1910, 1907, 1907, 1907, + 1906, 1905, 1903, 1902, 1905, 1903, 1906, 1907, + 1907, 1909, 1907, 1908, 1910, 1907, 1907, 1908, + 1908, 1905, 1904, 1903, 1903, 1903, 1904, 1905, + 1907, 1908, 1907, 1907, 1906, 1904, 1907, 1905, + 1905, 1906, 1903, 1902, 1901, 1901, 1901, 1898, + 1896, 1895, 1895, 1895, 1894, 1896, 1897, 1900, + 1896, 1896, 1898, 1897, 1898, 1901, 1900, 1899, + 1901, 1901, 1901, 1899, 1899, 1899, 1898, 1901, + 1903, 1904, 1904, 1905, 1906, 1905, 1903, 1903, + 1907, 1906, 1907, 1908, 1908, 1911, 1909, 1908, + 1911, 1911, 1913, 1916, 1917, 1915, 1915, 1913, + 1913, 1912, 1913, 1915, 1915, 1914, 1916, 1915, + 1917, 1918, 1916, 1918, 1920, 1920, 1922, 1921, + 1922, 1920, 1919, 1916, 1916, 1917, 1917, 1917, + 1918, 1921, 1920, 1921, 1919, 1920, 1922, 1921, + 1920, 1922, 1922, 1922, 1921, 1918, 1918, 1918, + 1919, 1919, 1919, 1919, 1919, 1920, 1920, 1925, + 1925, 1923, 1922, 1922, 1922, 1923, 1922, 1923, + 1922, 1919, 1919, 1919, 1919, 1920, 1919, 1921, + 1921, 1921, 1920, 1921, 1920, 1921, 1921, 1920, + 1921, 1924, 1924, 1923, 1922, 1923, 1921, 1923, + 1923, 1922, 1923, 1922, 1923, 1920, 1917, 1918, + 1916, 1917, 1921, 1922, 1922, 1923, 1925, 1925, + 1926, 1925, 1928, 1926, 1925, 1928, 1927, 1926, + 1926, 1925, 1925, 1925, 1922, 1923, 1923, 1925, + 1927, 1925, 1924, 1925, 1926, 1926, 1924, 1926, + 1924, 1922, 1925, 1925, 1925, 1925, 1925, 1926, + 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1926, + 1927, 1926, 1926, 1926, 1926, 1926, 1927, 1926, + 1924, 1927, 1927, 1929, 1928, 1926, 1926, 1926, + 1925, 1926, 1926, 1927, 1931, 1932, 1932, 1932, + 1933, 1931, 1931, 1931, 1929, 1928, 1928, 1930, + 1931, 1931, 1931, 1931, 1931, 1929, 1932, 1932, + 1932, 1933, 1930, 1932, 1933, 1936, 1936, 1935, + 1933, 1932, 1930, 1931, 1931, 1932, 1932, 1932, + 1935, 1934, 1934, 1937, 1937, 1937, 1938, 1935, + 1935, 1935, 1935, 1936, 1937, 1937, 1939, 1941, + 1942, 1942, 1942, 1942, 1944, 1943, 1944, 1944, + 1943, 1943, 1944, 1946, 1949, 1949, 1947, 1947, + 1945, 1945, 1946, 1943, 1942, 1947, 1944, 1943, + 1942, 1942, 1943, 1944, 1945, 1946, 1949, 1949, + 1948, 1951, 1949, 1950, 1950, 1948, 1949, 1944, + 1945, 1946, 1946, 1946, 1944, 1945, 1949, 1950, + 1953, 1953, 1954, 1954, 1954, 1953, 1954, 1957, + 1955, 1957, 1958, 1956, 1955, 1953, 1953, 1952, + 1951, 1953, 1954, 1955, 1955, 1955, 1952, 1953, + 1954, 1951, 1953, 1952, 1953, 1956, 1957, 1957, + 1955, 1954, 1957, 1950, 1948, 1950, 1949, 1951, + 1950, 1947, 1946, 1943, 1943, 1942, 1942, 1944, + 1944, 1947, 1948, 1947, 1947, 1949, 1949, 1949, + 1951, 1950, 1946, 1945, 1945, 1945, 1942, 1939, + 1943, 1943, 1943, 1943, 1944, 1947, 1945, 1943, + 1944, 1946, 1947, 1949, 1949, 1948, 1949, 1951, + 1947, 1946, 1944, 1943, 1945, 1944, 1943, 1942, + 1940, 1940, 1939, 1940, 1941, 1939, 1939, 1939, + 1942, 1943, 1943, 1942, 1943, 1944, 1947, 1946, + 1946, 1948, 1946, 1944, 1943, 1941, 1941, 1940, + 1941, 1942, 1944, 1944, 1945, 1944, 1945, 1946, + 1943, 1945, 1945, 1946, 1944, 1945, 1945, 1947, + 1947, 1946, 1942, 1942, 1940, 1938, 1937, 1936, + 1936, 1936, 1936, 1936, 1936, 1937, 1937, 1939, + 1940, 1942, 1941, 1940, 1938, 1938, 1938, 1939, + 1938, 1935, 1936, 1935, 1934, 1934, 1933, 1934, + 1934, 1934, 1933, 1932, 1933, 1933, 1933, 1929, + 1928, 1929, 1929, 1928, 1928, 1929, 1927, 1928, + 1929, 1929, 1928, 1930, 1931, 1929, 1927, 1927, + 1925, 1926, 1926, 1928, 1928, 1927, 1925, 1923, + 1923, 1924, 1925, 1924, 1927, 1929, 1930, 1928, + 1927, 1929, 1928, 1927, 1927, 1927, 1926, 1927, + 1928, 1927, 1930, 1930, 1929, 1930, 1926, 1927, + 1929, 1932, 1933, 1933, 1931, 1929, 1927, 1927, + 1925, 1926, 1928, 1928, 1928, 1925, 1926, 1927, + 1929, 1929, 1932, 1931, 1930, 1929, 1928, 1928, + 1926, 1926, 1925, 1927, 1927, 1927, 1924, 1924, + 1923, 1923, 1922, 1923, 1925, 1921, 1921, 1920, + 1922, 1923, 1921, 1921, 1921, 1918, 1918, 1916, + 1916, 1915, 1914, 1913, 1913, 1913, 1911, 1910, + 1910, 1909, 1908, 1908, 1908, 1909, 1912, 1911, + 1909, 1909, 1907, 1908, 1910, 1907, 1907, 1906, + 1907, 1906, 1905, 1902, 1902, 1900, 1899, 1900, + 1900, 1901, 1901, 1901, 1902, 1902, 1901, 1901, + 1898, 1898, 1899, 1900, 1899, 1899, 1898, 1896, + 1895, 1895, 1893, 1892, 1893, 1890, 1890, 1889, + 1889, 1891, 1891, 1893, 1894, 1897, 1898, 1898, + 1897, 1899, 1898, 1897, 1897, 1896, 1896, 1895, + 1892, 1891, 1891, 1888, 1889, 1893, 1893, 1895, + 1895, 1896, 1899, 1902, 1900, 1899, 1899, 1900, + 1901, 1901, 1901, 1900, 1901, 1901, 1903, 1900, + 1902, 1903, 1904, 1902, 1902, 1903, 1902, 1901, + 1902, 1903, 1902, 1900, 1900, 1896, 1892, 1891, + 1897, 1899, 1902, 1908, 1907, 1914, 1916, 1917, + 1918, 1918, 1917, 1912, 1904, 1898, 1891, 1886, + 1885, 1884, 1886, 1885, 1888, 1894, 1900, 1911, + 1917, 1923, 1927, 1931, 1930, 1927, 1920, 1915, + 1911, 1902, 1894, 1887, 1883, 1883, 1887, 1891, + 1894, 1900, 1906, 1915, 1922, 1925, 1930, 1931, + 1931, 1925, 1921, 1915, 1907, 1901, 1898, 1895, + 1891, 1893, 1897, 1901, 1905, 1912, 1921, 1923, + 1929, 1934, 1936, 1937, 1934, 1932, 1928, 1924, + 1918, 1915, 1910, 1908, 1908, 1910, 1910, 1910, + 1914, 1918, 1922, 1925, 1928, 1927, 1929, 1927, + 1930, 1929, 1928, 1927, 1924, 1922, 1921, 1921, + 1921, 1921, 1918, 1918, 1920, 1920, 1920, 1920, + 1922, 1927, 1931, 1930, 1932, 1933, 1933, 1937, + 1935, 1935, 1935, 1932, 1930, 1929, 1928, 1926, + 1926, 1926, 1927, 1928, 1930, 1933, 1936, 1939, + 1941, 1945, 1945, 1947, 1946, 1942, 1939, 1935, + 1932, 1929, 1928, 1928, 1927, 1929, 1931, 1935, + 1936, 1938, 1939, 1942, 1945, 1946, 1949, 1949, + 1946, 1946, 1943, 1939, 1937, 1934, 1935, 1934, + 1934, 1934, 1933, 1935, 1938, 1940, 1942, 1942, + 1944, 1943, 1944, 1943, 1944, 1944, 1943, 1943, + 1942, 1941, 1941, 1941, 1941, 1941, 1942, 1943, + 1942, 1943, 1945, 1946, 1947, 1947, 1948, 1950, + 1949, 1948, 1947, 1945, 1947, 1949, 1949, 1948, + 1950, 1952, 1948, 1950, 1954, 1952, 1952, 1955, + 1955, 1956, 1956, 1955, 1957, 1956, 1956, 1957, + 1960, 1958, 1959, 1960, 1959, 1960, 1963, 1964, + 1963, 1963, 1962, 1964, 1964, 1964, 1964, 1965, + 1967, 1967, 1966, 1964, 1965, 1962, 1961, 1961, + 1962, 1960, 1962, 1961, 1961, 1962, 1963, 1966, + 1968, 1969, 1967, 1968, 1967, 1967, 1966, 1967, + 1969, 1967, 1968, 1966, 1967, 1967, 1968, 1966, + 1966, 1969, 1970, 1973, 1972, 1974, 1978, 1976, + 1976, 1977, 1979, 1978, 1975, 1974, 1972, 1972, + 1971, 1969, 1969, 1970, 1971, 1972, 1974, 1976, + 1979, 1980, 1979, 1980, 1981, 1982, 1982, 1982, + 1980, 1978, 1980, 1980, 1978, 1976, 1977, 1979, + 1979, 1977, 1978, 1979, 1981, 1982, 1986, 1987, + 1988, 1989, 1989, 1994, 1993, 1995, 1994, 1993, + 1993, 1994, 1997, 1997, 1995, 1993, 1993, 1993, + 1995, 1995, 1997, 1996, 2000, 2002, 2001, 2001, + 2000, 2002, 2002, 2001, 2000, 2001, 2001, 2000, + 2001, 1998, 1998, 1998, 1998, 1997, 1997, 1998, + 1996, 1996, 1997, 1998, 2000, 1999, 2000, 2000, + 2000, 2003, 2002, 2001, 2001, 2002, 2004, 2005, + 2002, 2001, 2001, 2001, 2001, 1998, 2000, 1999, + 2000, 2000, 1998, 1999, 2001, 2000, 2002, 2004, + 2005, 2007, 2006, 2006, 2004, 2004, 2004, 2003, + 2003, 2001, 2001, 2000, 2000, 1999, 1999, 1998, + 1996, 1998, 1998, 1998, 1996, 1997, 1996, 1994, + 1995, 1995, 1994, 1997, 1997, 1997, 2002, 2002, + 2000, 2000, 1999, 2000, 1998, 2000, 2001, 2001, + 2001, 1999, 1998, 1998, 1999, 1999, 1999, 2000, + 2003, 2006, 2006, 2008, 2006, 2004, 2006, 2007, + 2008, 2007, 2007, 2006, 2005, 2007, 2006, 2010, + 2009, 2007, 2008, 2010, 2011, 2011, 2012, 2013, + 2012, 2014, 2011, 2012, 2014, 2013, 2015, 2013, + 2015, 2013, 2012, 2014, 2014, 2012, 2013, 2010, + 2010, 2012, 2013, 2014, 2014, 2011, 2013, 2014, + 2013, 2011, 2010, 2011, 2009, 2009, 2008, 2008, + 2007, 2006, 2005, 2005, 2004, 2005, 2005, 2004, + 2004, 2003, 2003, 2004, 2006, 2007, 2008, 2007, + 2008, 2010, 2011, 2009, 2008, 2006, 2007, 2007, + 2007, 2005, 2005, 2006, 2005, 2007, 2009, 2008, + 2008, 2008, 2008, 2007, 2006, 2004, 2004, 2005, + 2004, 2004, 2003, 2003, 2002, 2002, 2001, 2000, + 2000, 1999, 2000, 1997, 2000, 2000, 1999, 1999, + 2000, 2002, 2002, 2004, 2003, 2003, 2003, 2003, + 2002, 2003, 2006, 2007, 2007, 2009, 2007, 2006, + 2005, 2005, 2004, 2002, 2001, 2001, 2002, 2000, + 1999, 1996, 1999, 2000, 1999, 2001, 2001, 2000, + 1998, 2000, 2001, 2001, 2001, 2001, 2000, 1999, + 1998, 1998, 2000, 2000, 2000, 1999, 1998, 1996, + 1994, 1992, 1992, 1993, 1994, 1993, 1995, 1994, + 1993, 1998, 1999, 1996, 1994, 1995, 1995, 1996, + 1994, 1994, 1995, 1995, 1994, 1994, 1992, 1992, + 1993, 1992, 1992, 1993, 1994, 1994, 1994, 1996, + 1996, 1996, 1996, 1996, 1995, 1997, 1997, 1998, + 2001, 2000, 2000, 1998, 1999, 2000, 1999, 2000, + 1999, 1998, 1998, 1997, 1999, 2001, 2000, 2000, + 2001, 1998, 1998, 1997, 1998, 1998, 1998, 1998, + 1998, 1997, 1994, 1995, 1997, 1997, 1995, 1996, + 1995, 1993, 1995, 1994, 1997, 1995, 1995, 1994, + 1997, 1997, 1996, 1998, 1999, 1998, 1997, 1999, + 1999, 1999, 1999, 1998, 1997, 1995, 1998, 1999, + 1999, 1997, 1998, 1999, 1998, 1999, 2000, 2000, + 1998, 1998, 1997, 1992, 1994, 1996, 1993, 1994, + 1993, 1995, 1995, 1997, 1994, 1995, 1995, 1995, + 1994, 1993, 1993, 1992, 1991, 1993, 1992, 1993, + 1992, 1991, 1993, 1991, 1992, 1992, 1991, 1992, + 1989, 1990, 1990, 1992, 1990, 1991, 1991, 1991, + 1989, 1991, 1989, 1990, 1989, 1990, 1991, 1990, + 1990, 1990, 1990, 1990, 1991, 1993, 1991, 1991, + 1991, 1992, 1993, 1994, 1993, 1994, 1994, 1994, + 1995, 1995, 2000, 2000, 1999, 2001, 2000, 1997, + 1999, 1998, 1996, 1997, 1996, 1996, 1996, 1995, + 1997, 1997, 1997, 1996, 1995, 1997, 1997, 1999, + 1999, 2000, 1999, 1999, 2000, 2001, 2000, 2002, + 2005, 2004, 2007, 2006, 2006, 2005, 2005, 2006, + 2006, 2008, 2007, 2008, 2009, 2009, 2011, 2013, + 2013, 2013, 2017, 2017, 2019, 2020, 2019, 2021, + 2021, 2021, 2022, 2022, 2023, 2022, 2024, 2023, + 2027, 2025, 2027, 2027, 2026, 2029, 2029, 2027, + 2029, 2030, 2029, 2029, 2031, 2029, 2028, 2030, + 2029, 2033, 2032, 2035, 2032, 2031, 2032, 2027, + 2031, 2030, 2029, 2030, 2030, 2029, 2030, 2034, + 2033, 2033, 2036, 2038, 2038, 2039, 2038, 2040, + 2040, 2041, 2040, 2040, 2039, 2040, 2040, 2043, + 2044, 2044, 2044, 2044, 2045, 2047, 2045, 2047, + 2048, 2047, 2048, 2048, 2049, 2051, 2051, 2051, + 2051, 2054, 2052, 2049, 2051, 2051, 2049, 2050, + 2050, 2050, 2052, 2050, 2052, 2052, 2051, 2051, + 2051, 2050, 2051, 2050, 2052, 2053, 2053, 2052, + 2054, 2053, 2052, 2053, 2054, 2052, 2056, 2057, + 2057, 2056, 2057, 2056, 2056, 2057, 2057, 2056, + 2056, 2056, 2059, 2058, 2058, 2059, 2059, 2059, + 2059, 2061, 2059, 2059, 2059, 2062, 2062, 2061, + 2062, 2061, 2062, 2063, 2063, 2064, 2064, 2064, + 2064, 2062, 2061, 2061, 2061, 2061, 2059, 2058, + 2059, 2061, 2062, 2059, 2059, 2061, 2060, 2059, + 2060, 2060, 2062, 2062, 2064, 2067, 2064, 2066, + 2067, 2066, 2066, 2066, 2067, 2067, 2066, 2066, + 2066, 2066, 2069, 2068, 2066, 2069, 2067, 2067, + 2069, 2069, 2070, 2069, 2071, 2072, 2074, 2072, + 2071, 2073, 2073, 2073, 2071, 2073, 2076, 2073, + 2071, 2072, 2074, 2072, 2075, 2073, 2074, 2077, + 2079, 2080, 2081, 2084, 2083, 2083, 2082, 2086, + 2087, 2086, 2086, 2086, 2088, 2089, 2088, 2088, + 2088, 2088, 2090, 2090, 2090, 2090, 2093, 2093, + 2093, 2094, 2093, 2097, 2098, 2096, 2096, 2094, + 2095, 2096, 2096, 2092, 2095, 2097, 2094, 2096, + 2095, 2097, 2097, 2095, 2095, 2097, 2097, 2097, + 2095, 2094, 2097, 2097, 2098, 2097, 2096, 2096, + 2096, 2099, 2100, 2100, 2098, 2099, 2099, 2099, + 2102, 2104, 2103, 2103, 2105, 2104, 2105, 2104, + 2106, 2107, 2107, 2106, 2107, 2109, 2110, 2110, + 2111, 2113, 2115, 2113, 2114, 2116, 2114, 2116, + 2113, 2114, 2112, 2112, 2112, 2111, 2114, 2114, + 2112, 2112, 2112, 2115, 2116, 2115, 2114, 2112, + 2113, 2114, 2114, 2114, 2114, 2114, 2114, 2112, + 2113, 2115, 2113, 2115, 2114, 2115, 2117, 2115, + 2116, 2116, 2117, 2118, 2116, 2116, 2117, 2117, + 2117, 2118, 2118, 2120, 2121, 2120, 2117, 2116, + 2118, 2120, 2121, 2120, 2120, 2122, 2121, 2124, + 2122, 2120, 2123, 2121, 2121, 2123, 2121, 2121, + 2121, 2119, 2119, 2118, 2115, 2117, 2119, 2117, + 2116, 2115, 2115, 2115, 2114, 2113, 2112, 2113, + 2111, 2111, 2111, 2112, 2110, 2111, 2111, 2111, + 2111, 2111, 2112, 2111, 2111, 2112, 2111, 2110, + 2111, 2113, 2113, 2111, 2111, 2109, 2110, 2109, + 2107, 2109, 2110, 2112, 2111, 2112, 2109, 2109, + 2110, 2110, 2109, 2112, 2112, 2110, 2108, 2108, + 2108, 2109, 2107, 2108, 2112, 2111, 2109, 2108, + 2109, 2111, 2112, 2108, 2106, 2107, 2108, 2107, + 2107, 2106, 2106, 2107, 2107, 2107, 2107, 2109, + 2109, 2112, 2111, 2108, 2106, 2108, 2108, 2105, + 2106, 2107, 2106, 2107, 2105, 2104, 2105, 2105, + 2104, 2104, 2103, 2102, 2101, 2100, 2098, 2099, + 2098, 2098, 2098, 2097, 2099, 2099, 2097, 2094, + 2095, 2097, 2094, 2094, 2090, 2092, 2093, 2093, + 2094, 2094, 2094, 2093, 2094, 2094, 2094, 2093, + 2090, 2093, 2092, 2089, 2092, 2091, 2092, 2088, + 2088, 2090, 2088, 2087, 2087, 2088, 2087, 2088, + 2086, 2087, 2087, 2088, 2089, 2085, 2085, 2086, + 2088, 2087, 2086, 2088, 2087, 2085, 2085, 2086, + 2087, 2086, 2085, 2084, 2085, 2085, 2087, 2089, + 2091, 2091, 2086, 2086, 2085, 2083, 2083, 2082, + 2081, 2084, 2085, 2085, 2082, 2081, 2082, 2080, + 2082, 2084, 2082, 2082, 2082, 2079, 2080, 2080, + 2079, 2078, 2077, 2076, 2076, 2075, 2076, 2076, + 2077, 2074, 2077, 2077, 2075, 2075, 2075, 2074, + 2074, 2074, 2075, 2075, 2072, 2073, 2071, 2072, + 2072, 2070, 2070, 2068, 2070, 2068, 2069, 2068, + 2067, 2068, 2069, 2066, 2063, 2065, 2067, 2065, + 2065, 2065, 2064, 2064, 2062, 2063, 2062, 2061, + 2061, 2060, 2063, 2060, 2059, 2058, 2055, 2058, + 2059, 2059, 2061, 2058, 2057, 2057, 2058, 2058, + 2058, 2057, 2056, 2054, 2054, 2055, 2056, 2058, + 2058, 2058, 2054, 2058, 2060, 2059, 2056, 2056, + 2055, 2056, 2058, 2057, 2057, 2057, 2056, 2056, + 2057, 2058, 2058, 2058, 2058, 2058, 2058, 2058, + 2059, 2059, 2059, 2060, 2061, 2060, 2059, 2059, + 2060, 2061, 2062, 2063, 2065, 2063, 2062, 2061, + 2062, 2063, 2064, 2064, 2061, 2061, 2062, 2065, + 2067, 2065, 2068, 2065, 2066, 2066, 2066, 2067, + 2068, 2069, 2070, 2068, 2068, 2068, 2066, 2066, + 2066, 2068, 2070, 2068, 2071, 2070, 2068, 2067, + 2066, 2068, 2069, 2068, 2067, 2069, 2067, 2067, + 2070, 2069, 2068, 2067, 2066, 2066, 2068, 2069, + 2069, 2069, 2069, 2071, 2071, 2069, 2070, 2070, + 2067, 2070, 2072, 2073, 2074, 2073, 2068, 2069, + 2071, 2073, 2075, 2077, 2080, 2078, 2079, 2078, + 2078, 2078, 2078, 2077, 2076, 2078, 2076, 2079, + 2079, 2079, 2078, 2079, 2080, 2079, 2081, 2080, + 2082, 2084, 2084, 2085, 2085, 2086, 2088, 2089, + 2087, 2087, 2088, 2090, 2090, 2090, 2091, 2092, + 2093, 2093, 2092, 2094, 2093, 2095, 2093, 2093, + 2093, 2094, 2093, 2095, 2096, 2097, 2095, 2092, + 2097, 2093, 2093, 2094, 2096, 2095, 2092, 2092, + 2093, 2093, 2093, 2095, 2093, 2092, 2092, 2090, + 2090, 2091, 2091, 2092, 2094, 2095, 2096, 2094, + 2096, 2097, 2094, 2097, 2096, 2094, 2096, 2096, + 2096, 2097, 2097, 2097, 2094, 2095, 2097, 2098, + 2100, 2099, 2099, 2099, 2098, 2100, 2100, 2097, + 2099, 2100, 2101, 2100, 2100, 2102, 2102, 2100, + 2100, 2100, 2102, 2103, 2106, 2104, 2102, 2101, + 2101, 2101, 2099, 2100, 2102, 2103, 2103, 2103, + 2102, 2101, 2103, 2105, 2104, 2106, 2104, 2105, + 2105, 2105, 2105, 2102, 2101, 2102, 2103, 2103, + 2103, 2102, 2101, 2102, 2103, 2101, 2105, 2102, + 2103, 2104, 2104, 2103, 2104, 2104, 2103, 2105, + 2103, 2102, 2103, 2103, 2105, 2104, 2101, 2100, + 2099, 2099, 2100, 2101, 2101, 2099, 2100, 2100, + 2101, 2103, 2104, 2104, 2105, 2103, 2103, 2104, + 2103, 2103, 2102, 2100, 2100, 2101, 2101, 2100, + 2101, 2099, 2098, 2099, 2099, 2102, 2101, 2099, + 2099, 2098, 2100, 2103, 2103, 2104, 2107, 2106, + 2108, 2107, 2105, 2107, 2104, 2104, 2105, 2105, + 2104, 2104, 2107, 2107, 2107, 2108, 2107, 2108, + 2108, 2109, 2110, 2111, 2112, 2111, 2110, 2110, + 2111, 2110, 2111, 2112, 2113, 2114, 2114, 2112, + 2112, 2112, 2116, 2116, 2115, 2116, 2116, 2118, + 2119, 2120, 2119, 2121, 2122, 2120, 2122, 2125, + 2125, 2124, 2124, 2125, 2124, 2123, 2123, 2123, + 2121, 2122, 2122, 2125, 2124, 2123, 2124, 2126, + 2123, 2125, 2126, 2126, 2125, 2125, 2124, 2125, + 2125, 2124, 2126, 2126, 2127, 2127, 2125, 2127, + 2126, 2128, 2128, 2126, 2127, 2129, 2129, 2131, + 2131, 2131, 2131, 2132, 2130, 2130, 2132, 2132, + 2132, 2130, 2132, 2132, 2134, 2136, 2136, 2137, + 2139, 2138, 2138, 2136, 2136, 2136, 2135, 2132, + 2133, 2132, 2133, 2133, 2132, 2134, 2132, 2133, + 2136, 2131, 2132, 2133, 2133, 2135, 2134, 2134, + 2133, 2132, 2132, 2133, 2135, 2133, 2133, 2132, + 2133, 2133, 2133, 2134, 2135, 2136, 2135, 2133, + 2135, 2137, 2136, 2136, 2137, 2136, 2139, 2138, + 2137, 2138, 2137, 2139, 2138, 2138, 2139, 2139, + 2137, 2137, 2139, 2136, 2132, 2134, 2134, 2132, + 2130, 2132, 2132, 2129, 2128, 2126, 2126, 2128, + 2129, 2128, 2127, 2128, 2128, 2127, 2129, 2130, + 2130, 2128, 2128, 2128, 2129, 2129, 2131, 2132, + 2130, 2128, 2129, 2130, 2128, 2127, 2128, 2128, + 2128, 2128, 2129, 2131, 2131, 2132, 2132, 2132, + 2131, 2132, 2131, 2130, 2130, 2132, 2131, 2127, + 2130, 2127, 2127, 2127, 2128, 2124, 2123, 2124, + 2124, 2124, 2124, 2125, 2124, 2122, 2121, 2121, + 2119, 2120, 2119, 2118, 2117, 2118, 2118, 2114, + 2114, 2113, 2113, 2115, 2112, 2114, 2114, 2111, + 2111, 2111, 2111, 2109, 2110, 2110, 2109, 2108, + 2111, 2113, 2110, 2110, 2107, 2109, 2108, 2106, + 2108, 2106, 2107, 2106, 2108, 2109, 2109, 2108, + 2108, 2109, 2108, 2107, 2110, 2108, 2104, 2103, + 2105, 2106, 2104, 2104, 2103, 2103, 2102, 2102, + 2102, 2103, 2103, 2101, 2102, 2101, 2103, 2106, + 2105, 2102, 2104, 2103, 2102, 2100, 2101, 2102, + 2099, 2101, 2102, 2104, 2102, 2101, 2101, 2101, 2103, 2102, 2103, 2105, 2103, 2104, 2102, 2102 }; diff --git a/keyboards/planck/keymaps/synth_wavetable/config.h b/keyboards/planck/keymaps/synth_wavetable/config.h index 77d0c445c0ed..930b26b00016 100644 --- a/keyboards/planck/keymaps/synth_wavetable/config.h +++ b/keyboards/planck/keymaps/synth_wavetable/config.h @@ -1,3 +1,20 @@ +/* +Copyright 2020 Jack Humbert + +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 2 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 . +*/ + #pragma once #ifdef AUDIO_ENABLE @@ -37,4 +54,3 @@ // Most tactile encoders have detents every 4 stages #define ENCODER_RESOLUTION 4 - diff --git a/keyboards/planck/keymaps/synth_wavetable/keymap.c b/keyboards/planck/keymaps/synth_wavetable/keymap.c index 2b3bce790f42..a0d71067938e 100644 --- a/keyboards/planck/keymaps/synth_wavetable/keymap.c +++ b/keyboards/planck/keymaps/synth_wavetable/keymap.c @@ -15,9 +15,6 @@ */ #include QMK_KEYBOARD_H -#include "audio.h" - -extern keymap_config_t keymap_config; enum planck_layers { _QWERTY, diff --git a/keyboards/planck/keymaps/synth_wavetable/wavetable.h b/keyboards/planck/keymaps/synth_wavetable/wavetable.h index 0de8ee46cc82..89a0eefcbb7e 100644 --- a/keyboards/planck/keymaps/synth_wavetable/wavetable.h +++ b/keyboards/planck/keymaps/synth_wavetable/wavetable.h @@ -1,2180 +1,2197 @@ +/* +Copyright 2020 Jack Humbert + +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 2 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 . +*/ + #define AUDIO_DAC_WAVETABLE_CUSTOM_LENGTH 64 static const dacsample_t dac_wavetable_custom[64][256] = { { - 3038, 4095, 3745, 3945, 3779, 3889, 3782, 3850, + 3038, 4095, 3745, 3945, 3779, 3889, 3782, 3850, 3775, 3817, 3766, 3788, 3755, 3762, 3743, 3738, - 3729, 3716, 3715, 3695, 3700, 3676, 3683, 3658, - 3667, 3642, 3649, 3626, 3632, 3611, 3614, 3596, - 3596, 3581, 3579, 3567, 3561, 3552, 3544, 3537, - 3528, 3522, 3511, 3507, 3495, 3491, 3479, 3476, - 3464, 3460, 3449, 3444, 3433, 3428, 3419, 3412, - 3404, 3397, 3389, 3382, 3374, 3366, 3359, 3351, - 3345, 3336, 3330, 3322, 3314, 3307, 3299, 3293, - 3285, 3279, 3270, 3265, 3255, 3251, 3241, 3237, - 3227, 3223, 3213, 3208, 3200, 3194, 3187, 3179, - 3173, 3165, 3161, 3150, 3149, 3136, 3137, 3121, - 3125, 3107, 3112, 3093, 3099, 3080, 3086, 3068, - 3072, 3056, 3058, 3045, 3043, 3036, 3027, 3027, - 3010, 3019, 2992, 3013, 2974, 3007, 2955, 3002, - 2935, 2999, 2913, 2998, 2886, 3006, 2842, 3067, - 2464, 221, 205, 228, 215, 260, 231, 285, - 249, 307, 270, 326, 291, 344, 313, 359, - 335, 374, 357, 388, 378, 403, 399, 416, - 419, 431, 438, 445, 457, 460, 475, 476, - 492, 492, 509, 508, 525, 524, 540, 541, - 555, 558, 571, 574, 586, 591, 601, 607, - 616, 624, 631, 639, 647, 656, 662, 671, - 677, 687, 692, 702, 708, 718, 723, 733, - 738, 748, 753, 763, 768, 777, 783, 792, - 798, 806, 812, 820, 827, 834, 842, 848, - 857, 862, 872, 875, 887, 888, 901, 902, - 915, 915, 929, 929, 943, 942, 956, 956, - 969, 971, 981, 986, 992, 1001, 1003, 1017, - 1013, 1032, 1023, 1048, 1033, 1064, 1043, 1079, - 1054, 1093, 1065, 1106, 1078, 1118, 1092, 1127, + 3729, 3716, 3715, 3695, 3700, 3676, 3683, 3658, + 3667, 3642, 3649, 3626, 3632, 3611, 3614, 3596, + 3596, 3581, 3579, 3567, 3561, 3552, 3544, 3537, + 3528, 3522, 3511, 3507, 3495, 3491, 3479, 3476, + 3464, 3460, 3449, 3444, 3433, 3428, 3419, 3412, + 3404, 3397, 3389, 3382, 3374, 3366, 3359, 3351, + 3345, 3336, 3330, 3322, 3314, 3307, 3299, 3293, + 3285, 3279, 3270, 3265, 3255, 3251, 3241, 3237, + 3227, 3223, 3213, 3208, 3200, 3194, 3187, 3179, + 3173, 3165, 3161, 3150, 3149, 3136, 3137, 3121, + 3125, 3107, 3112, 3093, 3099, 3080, 3086, 3068, + 3072, 3056, 3058, 3045, 3043, 3036, 3027, 3027, + 3010, 3019, 2992, 3013, 2974, 3007, 2955, 3002, + 2935, 2999, 2913, 2998, 2886, 3006, 2842, 3067, + 2464, 221, 205, 228, 215, 260, 231, 285, + 249, 307, 270, 326, 291, 344, 313, 359, + 335, 374, 357, 388, 378, 403, 399, 416, + 419, 431, 438, 445, 457, 460, 475, 476, + 492, 492, 509, 508, 525, 524, 540, 541, + 555, 558, 571, 574, 586, 591, 601, 607, + 616, 624, 631, 639, 647, 656, 662, 671, + 677, 687, 692, 702, 708, 718, 723, 733, + 738, 748, 753, 763, 768, 777, 783, 792, + 798, 806, 812, 820, 827, 834, 842, 848, + 857, 862, 872, 875, 887, 888, 901, 902, + 915, 915, 929, 929, 943, 942, 956, 956, + 969, 971, 981, 986, 992, 1001, 1003, 1017, + 1013, 1032, 1023, 1048, 1033, 1064, 1043, 1079, + 1054, 1093, 1065, 1106, 1078, 1118, 1092, 1127, 1109, 1132, 1130, 1132, 1160, 1118, 1217, 1036 }, { - 2048, 2049, 2056, 2071, 2096, 2130, 2174, 2225, - 2280, 2337, 2392, 2444, 2490, 2529, 2559, 2581, - 2593, 2597, 2594, 2589, 2585, 2588, 2603, 2635, - 2685, 2755, 2842, 2943, 3050, 3157, 3258, 3347, - 3423, 3485, 3535, 3577, 3612, 3641, 3665, 3682, - 3692, 3694, 3692, 3689, 3690, 3700, 3724, 3761, - 3811, 3867, 3924, 3972, 4005, 4019, 4013, 3993, - 3964, 3936, 3915, 3906, 3912, 3931, 3959, 3990, - 4020, 4043, 4059, 4067, 4068, 4063, 4051, 4030, - 3997, 3946, 3875, 3782, 3671, 3546, 3419, 3299, - 3197, 3120, 3072, 3053, 3062, 3091, 3133, 3180, - 3224, 3257, 3276, 3277, 3259, 3221, 3163, 3084, - 2986, 2870, 2741, 2607, 2474, 2351, 2245, 2161, - 2102, 2069, 2058, 2067, 2091, 2124, 2160, 2195, - 2222, 2239, 2245, 2238, 2219, 2191, 2155, 2116, - 2077, 2042, 2014, 1995, 1987, 1991, 2003, 2023, - 2048, 2074, 2101, 2124, 2144, 2158, 2166, 2170, - 2172, 2175, 2181, 2195, 2221, 2260, 2315, 2384, - 2465, 2555, 2648, 2740, 2826, 2903, 2971, 3029, - 3076, 3114, 3142, 3159, 3167, 3167, 3160, 3153, - 3150, 3157, 3180, 3222, 3283, 3362, 3452, 3546, - 3636, 3715, 3777, 3823, 3854, 3874, 3889, 3905, - 3923, 3944, 3968, 3989, 4007, 4019, 4026, 4030, - 4033, 4040, 4051, 4066, 4081, 4090, 4086, 4063, - 4019, 3956, 3878, 3794, 3716, 3651, 3606, 3586, - 3589, 3612, 3647, 3688, 3728, 3760, 3781, 3787, - 3780, 3757, 3718, 3661, 3584, 3485, 3366, 3230, - 3085, 2938, 2801, 2683, 2589, 2525, 2492, 2486, - 2503, 2537, 2580, 2624, 2663, 2691, 2703, 2698, - 2674, 2633, 2574, 2500, 2415, 2322, 2228, 2139, - 2059, 1994, 1945, 1914, 1900, 1901, 1913, 1933, + 2048, 2049, 2056, 2071, 2096, 2130, 2174, 2225, + 2280, 2337, 2392, 2444, 2490, 2529, 2559, 2581, + 2593, 2597, 2594, 2589, 2585, 2588, 2603, 2635, + 2685, 2755, 2842, 2943, 3050, 3157, 3258, 3347, + 3423, 3485, 3535, 3577, 3612, 3641, 3665, 3682, + 3692, 3694, 3692, 3689, 3690, 3700, 3724, 3761, + 3811, 3867, 3924, 3972, 4005, 4019, 4013, 3993, + 3964, 3936, 3915, 3906, 3912, 3931, 3959, 3990, + 4020, 4043, 4059, 4067, 4068, 4063, 4051, 4030, + 3997, 3946, 3875, 3782, 3671, 3546, 3419, 3299, + 3197, 3120, 3072, 3053, 3062, 3091, 3133, 3180, + 3224, 3257, 3276, 3277, 3259, 3221, 3163, 3084, + 2986, 2870, 2741, 2607, 2474, 2351, 2245, 2161, + 2102, 2069, 2058, 2067, 2091, 2124, 2160, 2195, + 2222, 2239, 2245, 2238, 2219, 2191, 2155, 2116, + 2077, 2042, 2014, 1995, 1987, 1991, 2003, 2023, + 2048, 2074, 2101, 2124, 2144, 2158, 2166, 2170, + 2172, 2175, 2181, 2195, 2221, 2260, 2315, 2384, + 2465, 2555, 2648, 2740, 2826, 2903, 2971, 3029, + 3076, 3114, 3142, 3159, 3167, 3167, 3160, 3153, + 3150, 3157, 3180, 3222, 3283, 3362, 3452, 3546, + 3636, 3715, 3777, 3823, 3854, 3874, 3889, 3905, + 3923, 3944, 3968, 3989, 4007, 4019, 4026, 4030, + 4033, 4040, 4051, 4066, 4081, 4090, 4086, 4063, + 4019, 3956, 3878, 3794, 3716, 3651, 3606, 3586, + 3589, 3612, 3647, 3688, 3728, 3760, 3781, 3787, + 3780, 3757, 3718, 3661, 3584, 3485, 3366, 3230, + 3085, 2938, 2801, 2683, 2589, 2525, 2492, 2486, + 2503, 2537, 2580, 2624, 2663, 2691, 2703, 2698, + 2674, 2633, 2574, 2500, 2415, 2322, 2228, 2139, + 2059, 1994, 1945, 1914, 1900, 1901, 1913, 1933, 1957, 1983, 2006, 2025, 2038, 2046, 2049, 2048 }, { - 2048, 2053, 2074, 2119, 2191, 2291, 2416, 2559, - 2710, 2860, 3000, 3124, 3225, 3301, 3350, 3371, - 3364, 3334, 3288, 3234, 3182, 3144, 3127, 3137, - 3173, 3231, 3304, 3378, 3441, 3483, 3495, 3475, - 3423, 3344, 3243, 3128, 3002, 2867, 2726, 2581, - 2433, 2286, 2142, 2001, 1865, 1731, 1597, 1460, - 1317, 1171, 1023, 881, 750, 637, 546, 476, - 423, 380, 341, 300, 254, 205, 154, 109, - 75, 56, 55, 72, 105, 153, 217, 296, - 395, 513, 651, 806, 972, 1139, 1299, 1444, - 1572, 1680, 1772, 1855, 1935, 2018, 2110, 2212, - 2323, 2442, 2563, 2680, 2786, 2877, 2944, 2982, - 2986, 2951, 2877, 2771, 2640, 2498, 2360, 2238, - 2145, 2087, 2069, 2088, 2140, 2215, 2303, 2392, - 2469, 2524, 2550, 2543, 2505, 2437, 2346, 2241, - 2132, 2031, 1949, 1893, 1870, 1878, 1915, 1974, - 2048, 2128, 2206, 2276, 2332, 2371, 2394, 2402, - 2403, 2404, 2417, 2449, 2510, 2603, 2728, 2882, - 3056, 3236, 3410, 3564, 3690, 3783, 3842, 3868, - 3864, 3833, 3777, 3700, 3604, 3495, 3378, 3261, - 3150, 3048, 2958, 2877, 2801, 2723, 2637, 2536, - 2420, 2289, 2146, 1997, 1847, 1698, 1552, 1410, - 1271, 1133, 999, 870, 748, 637, 536, 446, - 364, 288, 216, 150, 92, 49, 29, 37, - 76, 144, 235, 339, 444, 541, 623, 689, - 741, 784, 826, 874, 933, 1009, 1101, 1209, - 1330, 1461, 1598, 1739, 1877, 2007, 2123, 2219, - 2291, 2338, 2364, 2374, 2378, 2385, 2404, 2443, - 2503, 2585, 2684, 2794, 2904, 3004, 3084, 3136, - 3154, 3133, 3070, 2965, 2823, 2650, 2458, 2261, - 2075, 1914, 1787, 1701, 1656, 1649, 1675, 1726, + 2048, 2053, 2074, 2119, 2191, 2291, 2416, 2559, + 2710, 2860, 3000, 3124, 3225, 3301, 3350, 3371, + 3364, 3334, 3288, 3234, 3182, 3144, 3127, 3137, + 3173, 3231, 3304, 3378, 3441, 3483, 3495, 3475, + 3423, 3344, 3243, 3128, 3002, 2867, 2726, 2581, + 2433, 2286, 2142, 2001, 1865, 1731, 1597, 1460, + 1317, 1171, 1023, 881, 750, 637, 546, 476, + 423, 380, 341, 300, 254, 205, 154, 109, + 75, 56, 55, 72, 105, 153, 217, 296, + 395, 513, 651, 806, 972, 1139, 1299, 1444, + 1572, 1680, 1772, 1855, 1935, 2018, 2110, 2212, + 2323, 2442, 2563, 2680, 2786, 2877, 2944, 2982, + 2986, 2951, 2877, 2771, 2640, 2498, 2360, 2238, + 2145, 2087, 2069, 2088, 2140, 2215, 2303, 2392, + 2469, 2524, 2550, 2543, 2505, 2437, 2346, 2241, + 2132, 2031, 1949, 1893, 1870, 1878, 1915, 1974, + 2048, 2128, 2206, 2276, 2332, 2371, 2394, 2402, + 2403, 2404, 2417, 2449, 2510, 2603, 2728, 2882, + 3056, 3236, 3410, 3564, 3690, 3783, 3842, 3868, + 3864, 3833, 3777, 3700, 3604, 3495, 3378, 3261, + 3150, 3048, 2958, 2877, 2801, 2723, 2637, 2536, + 2420, 2289, 2146, 1997, 1847, 1698, 1552, 1410, + 1271, 1133, 999, 870, 748, 637, 536, 446, + 364, 288, 216, 150, 92, 49, 29, 37, + 76, 144, 235, 339, 444, 541, 623, 689, + 741, 784, 826, 874, 933, 1009, 1101, 1209, + 1330, 1461, 1598, 1739, 1877, 2007, 2123, 2219, + 2291, 2338, 2364, 2374, 2378, 2385, 2404, 2443, + 2503, 2585, 2684, 2794, 2904, 3004, 3084, 3136, + 3154, 3133, 3070, 2965, 2823, 2650, 2458, 2261, + 2075, 1914, 1787, 1701, 1656, 1649, 1675, 1726, 1791, 1861, 1927, 1981, 2020, 2043, 2051, 2050 }, { - 2048, 2051, 2065, 2095, 2144, 2212, 2298, 2397, - 2504, 2612, 2716, 2811, 2894, 2961, 3011, 3042, - 3055, 3052, 3036, 3014, 2996, 2988, 3001, 3040, - 3108, 3204, 3324, 3459, 3598, 3728, 3841, 3930, - 3992, 4029, 4045, 4045, 4032, 4009, 3975, 3930, - 3874, 3809, 3738, 3665, 3596, 3534, 3481, 3436, - 3397, 3357, 3312, 3255, 3184, 3099, 3003, 2900, - 2795, 2693, 2595, 2503, 2413, 2325, 2235, 2143, - 2048, 1950, 1850, 1750, 1651, 1554, 1460, 1370, - 1287, 1215, 1159, 1122, 1105, 1107, 1124, 1147, - 1168, 1179, 1172, 1143, 1091, 1019, 931, 836, - 741, 655, 584, 535, 510, 514, 549, 618, - 721, 856, 1019, 1201, 1388, 1569, 1730, 1862, - 1956, 2012, 2029, 2013, 1971, 1911, 1844, 1779, - 1725, 1690, 1676, 1686, 1719, 1771, 1838, 1913, - 1989, 2059, 2115, 2152, 2167, 2161, 2136, 2097, - 2048, 1994, 1942, 1894, 1856, 1829, 1813, 1805, - 1803, 1800, 1788, 1762, 1715, 1643, 1544, 1420, - 1276, 1120, 962, 811, 675, 558, 463, 390, - 337, 304, 290, 294, 316, 353, 399, 447, - 489, 517, 526, 513, 479, 430, 375, 322, - 283, 264, 269, 297, 345, 405, 473, 542, - 612, 682, 754, 829, 910, 996, 1086, 1179, - 1273, 1366, 1459, 1553, 1649, 1747, 1848, 1949, - 2048, 2141, 2227, 2305, 2375, 2440, 2505, 2574, - 2649, 2733, 2825, 2923, 3023, 3122, 3215, 3300, - 3373, 3433, 3476, 3499, 3496, 3465, 3403, 3313, - 3200, 3073, 2945, 2829, 2735, 2672, 2644, 2652, - 2691, 2756, 2836, 2921, 3000, 3062, 3101, 3111, - 3090, 3036, 2950, 2835, 2695, 2539, 2375, 2214, - 2069, 1947, 1855, 1795, 1766, 1765, 1786, 1824, + 2048, 2051, 2065, 2095, 2144, 2212, 2298, 2397, + 2504, 2612, 2716, 2811, 2894, 2961, 3011, 3042, + 3055, 3052, 3036, 3014, 2996, 2988, 3001, 3040, + 3108, 3204, 3324, 3459, 3598, 3728, 3841, 3930, + 3992, 4029, 4045, 4045, 4032, 4009, 3975, 3930, + 3874, 3809, 3738, 3665, 3596, 3534, 3481, 3436, + 3397, 3357, 3312, 3255, 3184, 3099, 3003, 2900, + 2795, 2693, 2595, 2503, 2413, 2325, 2235, 2143, + 2048, 1950, 1850, 1750, 1651, 1554, 1460, 1370, + 1287, 1215, 1159, 1122, 1105, 1107, 1124, 1147, + 1168, 1179, 1172, 1143, 1091, 1019, 931, 836, + 741, 655, 584, 535, 510, 514, 549, 618, + 721, 856, 1019, 1201, 1388, 1569, 1730, 1862, + 1956, 2012, 2029, 2013, 1971, 1911, 1844, 1779, + 1725, 1690, 1676, 1686, 1719, 1771, 1838, 1913, + 1989, 2059, 2115, 2152, 2167, 2161, 2136, 2097, + 2048, 1994, 1942, 1894, 1856, 1829, 1813, 1805, + 1803, 1800, 1788, 1762, 1715, 1643, 1544, 1420, + 1276, 1120, 962, 811, 675, 558, 463, 390, + 337, 304, 290, 294, 316, 353, 399, 447, + 489, 517, 526, 513, 479, 430, 375, 322, + 283, 264, 269, 297, 345, 405, 473, 542, + 612, 682, 754, 829, 910, 996, 1086, 1179, + 1273, 1366, 1459, 1553, 1649, 1747, 1848, 1949, + 2048, 2141, 2227, 2305, 2375, 2440, 2505, 2574, + 2649, 2733, 2825, 2923, 3023, 3122, 3215, 3300, + 3373, 3433, 3476, 3499, 3496, 3465, 3403, 3313, + 3200, 3073, 2945, 2829, 2735, 2672, 2644, 2652, + 2691, 2756, 2836, 2921, 3000, 3062, 3101, 3111, + 3090, 3036, 2950, 2835, 2695, 2539, 2375, 2214, + 2069, 1947, 1855, 1795, 1766, 1765, 1786, 1824, 1871, 1920, 1965, 2003, 2029, 2044, 2050, 2049 }, { - 2048, 2061, 2117, 2228, 2396, 2610, 2844, 3065, - 3240, 3343, 3358, 3283, 3125, 2900, 2629, 2337, - 2048, 1783, 1558, 1379, 1241, 1136, 1049, 971, - 900, 843, 815, 838, 930, 1103, 1358, 1680, - 2048, 2435, 2816, 3170, 3479, 3729, 3908, 4008, - 4025, 3959, 3819, 3616, 3364, 3076, 2757, 2413, - 2048, 1667, 1285, 922, 601, 347, 175, 92, - 93, 168, 304, 490, 722, 998, 1315, 1668, - 2048, 2437, 2818, 3173, 3483, 3736, 3919, 4021, - 4035, 3956, 3788, 3544, 3247, 2924, 2605, 2309, - 2048, 1819, 1614, 1422, 1234, 1050, 878, 733, - 633, 597, 635, 751, 939, 1186, 1471, 1768, - 2048, 2280, 2443, 2523, 2523, 2457, 2354, 2241, - 2146, 2087, 2067, 2081, 2113, 2142, 2149, 2118, - 2048, 1944, 1824, 1711, 1629, 1601, 1637, 1740, - 1896, 2080, 2261, 2404, 2481, 2478, 2394, 2243, - 2048, 1835, 1634, 1468, 1354, 1299, 1300, 1342, - 1408, 1479, 1540, 1586, 1625, 1670, 1744, 1865, - 2048, 2292, 2585, 2903, 3215, 3491, 3707, 3846, - 3899, 3864, 3745, 3550, 3296, 2999, 2682, 2360, - 2048, 1749, 1462, 1186, 917, 661, 432, 250, - 137, 112, 184, 351, 600, 912, 1268, 1651, - 2048, 2444, 2828, 3184, 3496, 3749, 3932, 4040, - 4072, 4031, 3919, 3739, 3493, 3185, 2828, 2441, - 2048, 1675, 1346, 1074, 862, 705, 592, 516, - 476, 475, 524, 632, 806, 1046, 1343, 1684, - 2048, 2412, 2755, 3051, 3279, 3421, 3468, 3421, - 3295, 3116, 2914, 2717, 2543, 2398, 2277, 2166, - 2048, 1909, 1744, 1557, 1361, 1178, 1031, 940, - 919, 975, 1102, 1284, 1497, 1708, 1886, 2004, - 2048, 2018, 1931, 1812, 1689, 1590, 1536, 1534, + 2048, 2061, 2117, 2228, 2396, 2610, 2844, 3065, + 3240, 3343, 3358, 3283, 3125, 2900, 2629, 2337, + 2048, 1783, 1558, 1379, 1241, 1136, 1049, 971, + 900, 843, 815, 838, 930, 1103, 1358, 1680, + 2048, 2435, 2816, 3170, 3479, 3729, 3908, 4008, + 4025, 3959, 3819, 3616, 3364, 3076, 2757, 2413, + 2048, 1667, 1285, 922, 601, 347, 175, 92, + 93, 168, 304, 490, 722, 998, 1315, 1668, + 2048, 2437, 2818, 3173, 3483, 3736, 3919, 4021, + 4035, 3956, 3788, 3544, 3247, 2924, 2605, 2309, + 2048, 1819, 1614, 1422, 1234, 1050, 878, 733, + 633, 597, 635, 751, 939, 1186, 1471, 1768, + 2048, 2280, 2443, 2523, 2523, 2457, 2354, 2241, + 2146, 2087, 2067, 2081, 2113, 2142, 2149, 2118, + 2048, 1944, 1824, 1711, 1629, 1601, 1637, 1740, + 1896, 2080, 2261, 2404, 2481, 2478, 2394, 2243, + 2048, 1835, 1634, 1468, 1354, 1299, 1300, 1342, + 1408, 1479, 1540, 1586, 1625, 1670, 1744, 1865, + 2048, 2292, 2585, 2903, 3215, 3491, 3707, 3846, + 3899, 3864, 3745, 3550, 3296, 2999, 2682, 2360, + 2048, 1749, 1462, 1186, 917, 661, 432, 250, + 137, 112, 184, 351, 600, 912, 1268, 1651, + 2048, 2444, 2828, 3184, 3496, 3749, 3932, 4040, + 4072, 4031, 3919, 3739, 3493, 3185, 2828, 2441, + 2048, 1675, 1346, 1074, 862, 705, 592, 516, + 476, 475, 524, 632, 806, 1046, 1343, 1684, + 2048, 2412, 2755, 3051, 3279, 3421, 3468, 3421, + 3295, 3116, 2914, 2717, 2543, 2398, 2277, 2166, + 2048, 1909, 1744, 1557, 1361, 1178, 1031, 940, + 919, 975, 1102, 1284, 1497, 1708, 1886, 2004, + 2048, 2018, 1931, 1812, 1689, 1590, 1536, 1534, 1585, 1676, 1786, 1894, 1981, 2035, 2056, 2053 }, { - 2048, 2072, 2162, 2326, 2531, 2717, 2808, 2744, - 2504, 2112, 1636, 1162, 781, 560, 536, 708, - 1040, 1468, 1922, 2340, 2681, 2929, 3082, 3144, - 3108, 2958, 2676, 2261, 1739, 1174, 654, 273, - 103, 179, 496, 1009, 1653, 2344, 2997, 3529, - 3874, 3994, 3882, 3563, 3082, 2497, 1866, 1246, - 698, 284, 64, 82, 347, 829, 1459, 2145, - 2795, 3334, 3712, 3900, 3885, 3668, 3262, 2702, - 2048, 1375, 770, 310, 56, 39, 261, 696, - 1287, 1952, 2594, 3120, 3458, 3578, 3497, 3260, - 2927, 2549, 2159, 1774, 1409, 1084, 836, 709, - 741, 951, 1327, 1819, 2353, 2844, 3211, 3395, - 3374, 3170, 2846, 2488, 2179, 1975, 1891, 1901, - 1956, 2008, 2027, 2015, 1996, 2006, 2073, 2203, - 2370, 2529, 2630, 2636, 2539, 2368, 2176, 2032, - 1989, 2070, 2251, 2471, 2649, 2712, 2622, 2385, - 2048, 1681, 1362, 1153, 1086, 1157, 1334, 1565, - 1803, 2019, 2207, 2378, 2545, 2706, 2837, 2892, - 2819, 2583, 2185, 1674, 1130, 653, 328, 216, - 337, 675, 1182, 1782, 2392, 2928, 3328, 3557, - 3606, 3490, 3229, 2845, 2359, 1803, 1223, 690, - 283, 77, 118, 409, 910, 1551, 2247, 2916, - 3483, 3886, 4077, 4031, 3750, 3266, 2640, 1948, - 1273, 689, 261, 35, 43, 291, 753, 1368, - 2048, 2691, 3210, 3550, 3691, 3645, 3437, 3096, - 2649, 2126, 1569, 1033, 587, 298, 216, 362, - 722, 1248, 1866, 2486, 3015, 3375, 3519, 3446, - 3200, 2855, 2490, 2166, 1911, 1723, 1584, 1478, - 1404, 1379, 1435, 1593, 1858, 2201, 2566, 2885, - 3090, 3140, 3027, 2785, 2480, 2196, 2006, 1951, - 2026, 2183, 2350, 2459, 2469, 2375, 2208, 2022, + 2048, 2072, 2162, 2326, 2531, 2717, 2808, 2744, + 2504, 2112, 1636, 1162, 781, 560, 536, 708, + 1040, 1468, 1922, 2340, 2681, 2929, 3082, 3144, + 3108, 2958, 2676, 2261, 1739, 1174, 654, 273, + 103, 179, 496, 1009, 1653, 2344, 2997, 3529, + 3874, 3994, 3882, 3563, 3082, 2497, 1866, 1246, + 698, 284, 64, 82, 347, 829, 1459, 2145, + 2795, 3334, 3712, 3900, 3885, 3668, 3262, 2702, + 2048, 1375, 770, 310, 56, 39, 261, 696, + 1287, 1952, 2594, 3120, 3458, 3578, 3497, 3260, + 2927, 2549, 2159, 1774, 1409, 1084, 836, 709, + 741, 951, 1327, 1819, 2353, 2844, 3211, 3395, + 3374, 3170, 2846, 2488, 2179, 1975, 1891, 1901, + 1956, 2008, 2027, 2015, 1996, 2006, 2073, 2203, + 2370, 2529, 2630, 2636, 2539, 2368, 2176, 2032, + 1989, 2070, 2251, 2471, 2649, 2712, 2622, 2385, + 2048, 1681, 1362, 1153, 1086, 1157, 1334, 1565, + 1803, 2019, 2207, 2378, 2545, 2706, 2837, 2892, + 2819, 2583, 2185, 1674, 1130, 653, 328, 216, + 337, 675, 1182, 1782, 2392, 2928, 3328, 3557, + 3606, 3490, 3229, 2845, 2359, 1803, 1223, 690, + 283, 77, 118, 409, 910, 1551, 2247, 2916, + 3483, 3886, 4077, 4031, 3750, 3266, 2640, 1948, + 1273, 689, 261, 35, 43, 291, 753, 1368, + 2048, 2691, 3210, 3550, 3691, 3645, 3437, 3096, + 2649, 2126, 1569, 1033, 587, 298, 216, 362, + 722, 1248, 1866, 2486, 3015, 3375, 3519, 3446, + 3200, 2855, 2490, 2166, 1911, 1723, 1584, 1478, + 1404, 1379, 1435, 1593, 1858, 2201, 2566, 2885, + 3090, 3140, 3027, 2785, 2480, 2196, 2006, 1951, + 2026, 2183, 2350, 2459, 2469, 2375, 2208, 2022, 1871, 1793, 1798, 1865, 1955, 2028, 2061, 2057 }, { - 2048, 1736, 1511, 1423, 1476, 1630, 1822, 1987, - 2083, 2101, 2063, 2006, 1968, 1967, 2000, 2045, - 2073, 2061, 2011, 1944, 1899, 1908, 1981, 2099, - 2218, 2291, 2292, 2226, 2129, 2054, 2044, 2111, - 2237, 2375, 2471, 2480, 2385, 2198, 1962, 1735, - 1574, 1515, 1563, 1694, 1861, 2022, 2148, 2232, - 2282, 2305, 2299, 2254, 2154, 1996, 1798, 1599, - 1449, 1393, 1464, 1664, 1967, 2319, 2651, 2890, - 2979, 2896, 2660, 2325, 1964, 1648, 1430, 1334, - 1360, 1494, 1707, 1967, 2238, 2480, 2658, 2740, - 2709, 2561, 2310, 1987, 1639, 1327, 1114, 1056, - 1181, 1476, 1889, 2335, 2720, 2967, 3034, 2923, - 2673, 2345, 2010, 1727, 1537, 1455, 1475, 1580, - 1747, 1955, 2184, 2411, 2607, 2733, 2751, 2632, - 2378, 2025, 1643, 1320, 1132, 1123, 1287, 1573, - 1902, 2192, 2386, 2461, 2433, 2339, 2225, 2123, - 2048, 1993, 1946, 1898, 1854, 1834, 1865, 1966, - 2133, 2334, 2512, 2611, 2593, 2463, 2263, 2058, - 1913, 1862, 1902, 1996, 2088, 2130, 2099, 2001, - 1871, 1755, 1694, 1710, 1795, 1918, 2036, 2111, - 2130, 2104, 2062, 2034, 2032, 2044, 2044, 2008, - 1930, 1832, 1756, 1745, 1830, 2008, 2250, 2502, - 2700, 2790, 2741, 2556, 2273, 1955, 1672, 1483, - 1414, 1463, 1600, 1789, 1998, 2202, 2383, 2519, - 2590, 2574, 2460, 2253, 1979, 1682, 1414, 1233, - 1183, 1291, 1551, 1925, 2344, 2723, 2981, 3065, - 2964, 2707, 2356, 1983, 1656, 1424, 1315, 1335, - 1468, 1686, 1950, 2223, 2467, 2652, 2748, 2736, - 2601, 2347, 2004, 1624, 1283, 1058, 1009, 1154, - 1466, 1873, 2285, 2614, 2801, 2826, 2710, 2501, - 2259, 2036, 1862, 1751, 1697, 1692, 1733, 1822, + 2048, 1736, 1511, 1423, 1476, 1630, 1822, 1987, + 2083, 2101, 2063, 2006, 1968, 1967, 2000, 2045, + 2073, 2061, 2011, 1944, 1899, 1908, 1981, 2099, + 2218, 2291, 2292, 2226, 2129, 2054, 2044, 2111, + 2237, 2375, 2471, 2480, 2385, 2198, 1962, 1735, + 1574, 1515, 1563, 1694, 1861, 2022, 2148, 2232, + 2282, 2305, 2299, 2254, 2154, 1996, 1798, 1599, + 1449, 1393, 1464, 1664, 1967, 2319, 2651, 2890, + 2979, 2896, 2660, 2325, 1964, 1648, 1430, 1334, + 1360, 1494, 1707, 1967, 2238, 2480, 2658, 2740, + 2709, 2561, 2310, 1987, 1639, 1327, 1114, 1056, + 1181, 1476, 1889, 2335, 2720, 2967, 3034, 2923, + 2673, 2345, 2010, 1727, 1537, 1455, 1475, 1580, + 1747, 1955, 2184, 2411, 2607, 2733, 2751, 2632, + 2378, 2025, 1643, 1320, 1132, 1123, 1287, 1573, + 1902, 2192, 2386, 2461, 2433, 2339, 2225, 2123, + 2048, 1993, 1946, 1898, 1854, 1834, 1865, 1966, + 2133, 2334, 2512, 2611, 2593, 2463, 2263, 2058, + 1913, 1862, 1902, 1996, 2088, 2130, 2099, 2001, + 1871, 1755, 1694, 1710, 1795, 1918, 2036, 2111, + 2130, 2104, 2062, 2034, 2032, 2044, 2044, 2008, + 1930, 1832, 1756, 1745, 1830, 2008, 2250, 2502, + 2700, 2790, 2741, 2556, 2273, 1955, 1672, 1483, + 1414, 1463, 1600, 1789, 1998, 2202, 2383, 2519, + 2590, 2574, 2460, 2253, 1979, 1682, 1414, 1233, + 1183, 1291, 1551, 1925, 2344, 2723, 2981, 3065, + 2964, 2707, 2356, 1983, 1656, 1424, 1315, 1335, + 1468, 1686, 1950, 2223, 2467, 2652, 2748, 2736, + 2601, 2347, 2004, 1624, 1283, 1058, 1009, 1154, + 1466, 1873, 2285, 2614, 2801, 2826, 2710, 2501, + 2259, 2036, 1862, 1751, 1697, 1692, 1733, 1822, 1963, 2154, 2374, 2582, 2721, 2742, 2619, 2369 }, { - 2048, 2099, 2228, 2259, 1999, 1514, 1195, 1450, - 2280, 3163, 3424, 2780, 1605, 678, 618, 1447, - 2593, 3312, 3203, 2425, 1510, 990, 1120, 1807, - 2685, 3258, 3119, 2226, 1045, 353, 712, 2001, - 3423, 4031, 3396, 1899, 483, 41, 848, 2389, - 3692, 3949, 3033, 1544, 405, 291, 1255, 2722, - 3811, 3831, 2719, 1136, 90, 268, 1555, 3114, - 3964, 3614, 2324, 895, 183, 617, 1954, 3388, - 4020, 3424, 1949, 514, 27, 798, 2345, 3693, - 3997, 3089, 1590, 481, 425, 1338, 2538, 3274, - 3197, 2470, 1563, 978, 1033, 1728, 2698, 3356, - 3224, 2300, 1137, 500, 836, 1934, 3058, 3478, - 2986, 2018, 1282, 1194, 1621, 2108, 2314, 2242, - 2102, 2039, 2030, 2009, 2004, 2101, 2286, 2386, - 2222, 1832, 1496, 1506, 1876, 2312, 2478, 2313, - 2077, 2067, 2276, 2385, 2108, 1542, 1143, 1321, - 2048, 2836, 3127, 2729, 1951, 1338, 1247, 1633, - 2172, 2537, 2581, 2321, 1874, 1441, 1300, 1669, - 2465, 3215, 3317, 2530, 1269, 374, 507, 1646, - 3076, 3872, 3523, 2269, 928, 339, 820, 2008, - 3150, 3579, 3074, 1933, 812, 393, 1006, 2361, - 3636, 3973, 3084, 1503, 242, 106, 1176, 2779, - 3923, 3906, 2735, 1128, 88, 267, 1552, 3134, - 4033, 3701, 2345, 796, 14, 497, 1947, 3438, - 4019, 3364, 1958, 721, 380, 1054, 2279, 3324, - 3589, 2905, 1647, 566, 367, 1237, 2668, 3752, - 3780, 2721, 1257, 332, 511, 1607, 2838, 3413, - 3085, 2234, 1489, 1248, 1506, 2001, 2450, 2652, - 2503, 2030, 1460, 1167, 1432, 2176, 2932, 3161, - 2674, 1808, 1170, 1163, 1680, 2239, 2430, 2258, - 2059, 2108, 2334, 2426, 2195, 1777, 1510, 1606, + 2048, 2099, 2228, 2259, 1999, 1514, 1195, 1450, + 2280, 3163, 3424, 2780, 1605, 678, 618, 1447, + 2593, 3312, 3203, 2425, 1510, 990, 1120, 1807, + 2685, 3258, 3119, 2226, 1045, 353, 712, 2001, + 3423, 4031, 3396, 1899, 483, 41, 848, 2389, + 3692, 3949, 3033, 1544, 405, 291, 1255, 2722, + 3811, 3831, 2719, 1136, 90, 268, 1555, 3114, + 3964, 3614, 2324, 895, 183, 617, 1954, 3388, + 4020, 3424, 1949, 514, 27, 798, 2345, 3693, + 3997, 3089, 1590, 481, 425, 1338, 2538, 3274, + 3197, 2470, 1563, 978, 1033, 1728, 2698, 3356, + 3224, 2300, 1137, 500, 836, 1934, 3058, 3478, + 2986, 2018, 1282, 1194, 1621, 2108, 2314, 2242, + 2102, 2039, 2030, 2009, 2004, 2101, 2286, 2386, + 2222, 1832, 1496, 1506, 1876, 2312, 2478, 2313, + 2077, 2067, 2276, 2385, 2108, 1542, 1143, 1321, + 2048, 2836, 3127, 2729, 1951, 1338, 1247, 1633, + 2172, 2537, 2581, 2321, 1874, 1441, 1300, 1669, + 2465, 3215, 3317, 2530, 1269, 374, 507, 1646, + 3076, 3872, 3523, 2269, 928, 339, 820, 2008, + 3150, 3579, 3074, 1933, 812, 393, 1006, 2361, + 3636, 3973, 3084, 1503, 242, 106, 1176, 2779, + 3923, 3906, 2735, 1128, 88, 267, 1552, 3134, + 4033, 3701, 2345, 796, 14, 497, 1947, 3438, + 4019, 3364, 1958, 721, 380, 1054, 2279, 3324, + 3589, 2905, 1647, 566, 367, 1237, 2668, 3752, + 3780, 2721, 1257, 332, 511, 1607, 2838, 3413, + 3085, 2234, 1489, 1248, 1506, 2001, 2450, 2652, + 2503, 2030, 1460, 1167, 1432, 2176, 2932, 3161, + 2674, 1808, 1170, 1163, 1680, 2239, 2430, 2258, + 2059, 2108, 2334, 2426, 2195, 1777, 1510, 1606, 1957, 2266, 2327, 2193, 2057, 2033, 2068, 2069 }, { - 2048, 2119, 2229, 2372, 2541, 2724, 2909, 3085, - 3240, 3368, 3466, 3533, 3571, 3581, 3566, 3529, - 3473, 3403, 3326, 3251, 3188, 3144, 3128, 3145, - 3195, 3276, 3382, 3503, 3628, 3747, 3850, 3932, - 3992, 4032, 4055, 4067, 4071, 4069, 4061, 4047, - 4025, 3996, 3965, 3934, 3910, 3898, 3902, 3922, - 3956, 3998, 4040, 4074, 4093, 4093, 4074, 4041, - 4002, 3964, 3935, 3920, 3921, 3936, 3961, 3991, - 4020, 4044, 4062, 4073, 4078, 4078, 4073, 4060, - 4035, 3994, 3932, 3848, 3744, 3626, 3504, 3389, - 3291, 3220, 3180, 3174, 3198, 3247, 3313, 3388, - 3462, 3527, 3577, 3607, 3615, 3598, 3553, 3479, - 3374, 3240, 3081, 2904, 2720, 2541, 2379, 2245, - 2146, 2087, 2069, 2088, 2140, 2218, 2311, 2410, - 2503, 2580, 2633, 2654, 2639, 2585, 2492, 2361, - 2199, 2014, 1817, 1619, 1435, 1273, 1142, 1045, - 984, 959, 967, 1005, 1067, 1148, 1238, 1328, - 1408, 1468, 1498, 1493, 1450, 1369, 1254, 1113, - 956, 796, 643, 508, 397, 311, 251, 214, - 196, 195, 211, 240, 283, 334, 391, 445, - 489, 515, 519, 496, 449, 380, 299, 215, - 137, 74, 31, 7, 0, 3, 10, 16, - 18, 14, 8, 2, 0, 2, 8, 16, - 23, 25, 22, 13, 4, 0, 7, 31, - 76, 139, 215, 296, 371, 432, 472, 486, - 476, 445, 398, 345, 291, 244, 207, 183, - 172, 177, 199, 241, 305, 395, 510, 648, - 800, 958, 1109, 1242, 1347, 1416, 1448, 1443, - 1404, 1338, 1255, 1164, 1077, 1002, 947, 918, - 919, 954, 1024, 1129, 1268, 1436, 1624, 1822, - 2017, 2197, 2351, 2472, 2554, 2597, 2602, 2571, + 2048, 2119, 2229, 2372, 2541, 2724, 2909, 3085, + 3240, 3368, 3466, 3533, 3571, 3581, 3566, 3529, + 3473, 3403, 3326, 3251, 3188, 3144, 3128, 3145, + 3195, 3276, 3382, 3503, 3628, 3747, 3850, 3932, + 3992, 4032, 4055, 4067, 4071, 4069, 4061, 4047, + 4025, 3996, 3965, 3934, 3910, 3898, 3902, 3922, + 3956, 3998, 4040, 4074, 4093, 4093, 4074, 4041, + 4002, 3964, 3935, 3920, 3921, 3936, 3961, 3991, + 4020, 4044, 4062, 4073, 4078, 4078, 4073, 4060, + 4035, 3994, 3932, 3848, 3744, 3626, 3504, 3389, + 3291, 3220, 3180, 3174, 3198, 3247, 3313, 3388, + 3462, 3527, 3577, 3607, 3615, 3598, 3553, 3479, + 3374, 3240, 3081, 2904, 2720, 2541, 2379, 2245, + 2146, 2087, 2069, 2088, 2140, 2218, 2311, 2410, + 2503, 2580, 2633, 2654, 2639, 2585, 2492, 2361, + 2199, 2014, 1817, 1619, 1435, 1273, 1142, 1045, + 984, 959, 967, 1005, 1067, 1148, 1238, 1328, + 1408, 1468, 1498, 1493, 1450, 1369, 1254, 1113, + 956, 796, 643, 508, 397, 311, 251, 214, + 196, 195, 211, 240, 283, 334, 391, 445, + 489, 515, 519, 496, 449, 380, 299, 215, + 137, 74, 31, 7, 0, 3, 10, 16, + 18, 14, 8, 2, 0, 2, 8, 16, + 23, 25, 22, 13, 4, 0, 7, 31, + 76, 139, 215, 296, 371, 432, 472, 486, + 476, 445, 398, 345, 291, 244, 207, 183, + 172, 177, 199, 241, 305, 395, 510, 648, + 800, 958, 1109, 1242, 1347, 1416, 1448, 1443, + 1404, 1338, 1255, 1164, 1077, 1002, 947, 918, + 919, 954, 1024, 1129, 1268, 1436, 1624, 1822, + 2017, 2197, 2351, 2472, 2554, 2597, 2602, 2571, 2510, 2427, 2331, 2232, 2141, 2070, 2027, 2018 }, { - 2048, 2055, 2083, 2142, 2236, 2366, 2526, 2705, - 2891, 3068, 3227, 3358, 3455, 3515, 3537, 3522, - 3473, 3396, 3302, 3199, 3101, 3015, 2946, 2896, - 2859, 2827, 2789, 2734, 2652, 2541, 2399, 2232, - 2048, 1853, 1656, 1461, 1273, 1094, 929, 779, - 649, 541, 454, 384, 327, 277, 229, 182, - 139, 106, 93, 108, 158, 244, 363, 506, - 666, 832, 999, 1165, 1330, 1499, 1674, 1857, - 2048, 2243, 2440, 2635, 2825, 3005, 3173, 3324, - 3453, 3552, 3614, 3635, 3614, 3558, 3476, 3382, - 3291, 3215, 3159, 3125, 3110, 3105, 3100, 3084, - 3048, 2986, 2897, 2783, 2647, 2497, 2341, 2188, - 2048, 1931, 1846, 1799, 1790, 1815, 1863, 1922, - 1978, 2017, 2030, 2012, 1962, 1885, 1789, 1687, - 1592, 1517, 1473, 1467, 1501, 1574, 1678, 1805, - 1940, 2069, 2176, 2249, 2282, 2272, 2224, 2146, - 2048, 1941, 1837, 1745, 1672, 1623, 1598, 1591, - 1596, 1599, 1590, 1558, 1495, 1398, 1269, 1117, - 956, 802, 670, 575, 523, 516, 554, 630, - 738, 873, 1027, 1196, 1372, 1550, 1724, 1890, - 2048, 2198, 2346, 2498, 2659, 2833, 3019, 3210, - 3398, 3573, 3724, 3847, 3939, 4004, 4046, 4069, - 4078, 4071, 4048, 4005, 3939, 3852, 3743, 3618, - 3479, 3331, 3173, 3006, 2830, 2642, 2446, 2245, - 2048, 1860, 1690, 1539, 1406, 1286, 1172, 1057, - 936, 808, 676, 546, 425, 322, 242, 192, - 172, 186, 235, 319, 438, 590, 769, 965, - 1166, 1356, 1526, 1668, 1779, 1864, 1931, 1988, - 2048, 2117, 2202, 2304, 2419, 2541, 2659, 2764, - 2845, 2893, 2899, 2857, 2767, 2633, 2463, 2272, - 2078, 1899, 1750, 1642, 1579, 1563, 1587, 1643, + 2048, 2055, 2083, 2142, 2236, 2366, 2526, 2705, + 2891, 3068, 3227, 3358, 3455, 3515, 3537, 3522, + 3473, 3396, 3302, 3199, 3101, 3015, 2946, 2896, + 2859, 2827, 2789, 2734, 2652, 2541, 2399, 2232, + 2048, 1853, 1656, 1461, 1273, 1094, 929, 779, + 649, 541, 454, 384, 327, 277, 229, 182, + 139, 106, 93, 108, 158, 244, 363, 506, + 666, 832, 999, 1165, 1330, 1499, 1674, 1857, + 2048, 2243, 2440, 2635, 2825, 3005, 3173, 3324, + 3453, 3552, 3614, 3635, 3614, 3558, 3476, 3382, + 3291, 3215, 3159, 3125, 3110, 3105, 3100, 3084, + 3048, 2986, 2897, 2783, 2647, 2497, 2341, 2188, + 2048, 1931, 1846, 1799, 1790, 1815, 1863, 1922, + 1978, 2017, 2030, 2012, 1962, 1885, 1789, 1687, + 1592, 1517, 1473, 1467, 1501, 1574, 1678, 1805, + 1940, 2069, 2176, 2249, 2282, 2272, 2224, 2146, + 2048, 1941, 1837, 1745, 1672, 1623, 1598, 1591, + 1596, 1599, 1590, 1558, 1495, 1398, 1269, 1117, + 956, 802, 670, 575, 523, 516, 554, 630, + 738, 873, 1027, 1196, 1372, 1550, 1724, 1890, + 2048, 2198, 2346, 2498, 2659, 2833, 3019, 3210, + 3398, 3573, 3724, 3847, 3939, 4004, 4046, 4069, + 4078, 4071, 4048, 4005, 3939, 3852, 3743, 3618, + 3479, 3331, 3173, 3006, 2830, 2642, 2446, 2245, + 2048, 1860, 1690, 1539, 1406, 1286, 1172, 1057, + 936, 808, 676, 546, 425, 322, 242, 192, + 172, 186, 235, 319, 438, 590, 769, 965, + 1166, 1356, 1526, 1668, 1779, 1864, 1931, 1988, + 2048, 2117, 2202, 2304, 2419, 2541, 2659, 2764, + 2845, 2893, 2899, 2857, 2767, 2633, 2463, 2272, + 2078, 1899, 1750, 1642, 1579, 1563, 1587, 1643, 1721, 1807, 1890, 1961, 2012, 2041, 2052, 2050 }, { - 2048, 2060, 2109, 2207, 2360, 2560, 2787, 3015, - 3217, 3368, 3451, 3458, 3391, 3257, 3067, 2840, - 2593, 2344, 2110, 1900, 1717, 1554, 1404, 1253, - 1093, 924, 753, 596, 475, 410, 418, 507, - 673, 905, 1189, 1509, 1849, 2196, 2537, 2858, - 3146, 3391, 3587, 3732, 3830, 3884, 3899, 3876, - 3811, 3695, 3524, 3294, 3012, 2689, 2345, 1999, - 1666, 1358, 1077, 824, 599, 404, 246, 133, - 75, 80, 151, 285, 478, 721, 1006, 1323, - 1660, 2000, 2324, 2612, 2847, 3019, 3127, 3181, - 3197, 3192, 3179, 3165, 3148, 3119, 3064, 2972, - 2833, 2647, 2419, 2162, 1894, 1634, 1404, 1223, - 1109, 1072, 1113, 1222, 1379, 1556, 1726, 1867, - 1965, 2019, 2035, 2029, 2021, 2027, 2060, 2127, - 2222, 2333, 2441, 2526, 2569, 2558, 2487, 2361, - 2197, 2016, 1849, 1723, 1659, 1666, 1742, 1876, - 2048, 2234, 2412, 2562, 2670, 2729, 2742, 2718, - 2674, 2627, 2591, 2574, 2575, 2583, 2581, 2548, - 2465, 2322, 2116, 1859, 1568, 1267, 977, 719, - 508, 354, 266, 245, 291, 396, 550, 737, - 945, 1165, 1394, 1634, 1891, 2170, 2472, 2790, - 3109, 3408, 3667, 3870, 4007, 4077, 4082, 4030, - 3923, 3765, 3559, 3306, 3013, 2689, 2347, 1998, - 1653, 1320, 1006, 719, 468, 266, 126, 61, - 76, 167, 322, 524, 752, 993, 1237, 1486, - 1741, 2008, 2289, 2582, 2875, 3157, 3411, 3623, - 3780, 3872, 3893, 3841, 3715, 3523, 3282, 3013, - 2740, 2489, 2276, 2107, 1979, 1879, 1791, 1699, - 1592, 1467, 1331, 1196, 1082, 1005, 980, 1015, - 1109, 1256, 1438, 1635, 1821, 1973, 2068, 2097, - 2059, 1967, 1844, 1713, 1601, 1526, 1499, 1525, + 2048, 2060, 2109, 2207, 2360, 2560, 2787, 3015, + 3217, 3368, 3451, 3458, 3391, 3257, 3067, 2840, + 2593, 2344, 2110, 1900, 1717, 1554, 1404, 1253, + 1093, 924, 753, 596, 475, 410, 418, 507, + 673, 905, 1189, 1509, 1849, 2196, 2537, 2858, + 3146, 3391, 3587, 3732, 3830, 3884, 3899, 3876, + 3811, 3695, 3524, 3294, 3012, 2689, 2345, 1999, + 1666, 1358, 1077, 824, 599, 404, 246, 133, + 75, 80, 151, 285, 478, 721, 1006, 1323, + 1660, 2000, 2324, 2612, 2847, 3019, 3127, 3181, + 3197, 3192, 3179, 3165, 3148, 3119, 3064, 2972, + 2833, 2647, 2419, 2162, 1894, 1634, 1404, 1223, + 1109, 1072, 1113, 1222, 1379, 1556, 1726, 1867, + 1965, 2019, 2035, 2029, 2021, 2027, 2060, 2127, + 2222, 2333, 2441, 2526, 2569, 2558, 2487, 2361, + 2197, 2016, 1849, 1723, 1659, 1666, 1742, 1876, + 2048, 2234, 2412, 2562, 2670, 2729, 2742, 2718, + 2674, 2627, 2591, 2574, 2575, 2583, 2581, 2548, + 2465, 2322, 2116, 1859, 1568, 1267, 977, 719, + 508, 354, 266, 245, 291, 396, 550, 737, + 945, 1165, 1394, 1634, 1891, 2170, 2472, 2790, + 3109, 3408, 3667, 3870, 4007, 4077, 4082, 4030, + 3923, 3765, 3559, 3306, 3013, 2689, 2347, 1998, + 1653, 1320, 1006, 719, 468, 266, 126, 61, + 76, 167, 322, 524, 752, 993, 1237, 1486, + 1741, 2008, 2289, 2582, 2875, 3157, 3411, 3623, + 3780, 3872, 3893, 3841, 3715, 3523, 3282, 3013, + 2740, 2489, 2276, 2107, 1979, 1879, 1791, 1699, + 1592, 1467, 1331, 1196, 1082, 1005, 980, 1015, + 1109, 1256, 1438, 1635, 1821, 1973, 2068, 2097, + 2059, 1967, 1844, 1713, 1601, 1526, 1499, 1525, 1594, 1694, 1805, 1908, 1988, 2036, 2055, 2053 }, { - 2048, 2072, 2095, 2075, 2062, 2149, 2347, 2534, - 2584, 2527, 2537, 2732, 3017, 3166, 3074, 2884, - 2844, 3021, 3223, 3212, 2982, 2782, 2838, 3104, - 3321, 3317, 3206, 3252, 3548, 3896, 4028, 3910, - 3782, 3875, 4095, 4095, 4095, 3855, 3719, 3863, - 4080, 4065, 3759, 3424, 3355, 3556, 3739, 3649, - 3342, 3105, 3136, 3332, 3412, 3231, 2919, 2715, - 2707, 2768, 2724, 2551, 2362, 2259, 2219, 2157, - 2048, 1944, 1881, 1811, 1665, 1473, 1350, 1361, - 1417, 1359, 1150, 949, 947, 1145, 1329, 1300, - 1095, 955, 1044, 1254, 1316, 1103, 782, 627, - 713, 835, 759, 498, 306, 386, 653, 834, - 792, 690, 804, 1192, 1608, 1771, 1678, 1603, - 1778, 2118, 2309, 2159, 1822, 1629, 1734, 1954, - 1990, 1762, 1493, 1456, 1681, 1943, 2022, 1925, - 1847, 1930, 2119, 2249, 2238, 2153, 2095, 2080, - 2048, 1973, 1912, 1915, 1938, 1892, 1763, 1668, - 1723, 1885, 1968, 1842, 1593, 1438, 1481, 1578, - 1487, 1150, 775, 614, 689, 765, 627, 325, - 123, 191, 407, 501, 366, 185, 212, 466, - 698, 671, 436, 273, 366, 584, 630, 389, - 77, 8, 248, 539, 586, 384, 215, 329, - 667, 935, 929, 753, 682, 863, 1169, 1364, - 1361, 1292, 1331, 1505, 1700, 1812, 1863, 1934, - 2048, 2147, 2196, 2244, 2360, 2521, 2615, 2582, - 2519, 2589, 2834, 3096, 3182, 3084, 3009, 3147, - 3446, 3657, 3604, 3387, 3271, 3380, 3552, 3521, - 3228, 2893, 2770, 2865, 2939, 2800, 2540, 2436, - 2621, 2923, 3052, 2930, 2780, 2860, 3153, 3370, - 3268, 2930, 2671, 2689, 2844, 2820, 2484, 2039, - 1804, 1875, 2038, 2026, 1804, 1593, 1602, 1812, + 2048, 2072, 2095, 2075, 2062, 2149, 2347, 2534, + 2584, 2527, 2537, 2732, 3017, 3166, 3074, 2884, + 2844, 3021, 3223, 3212, 2982, 2782, 2838, 3104, + 3321, 3317, 3206, 3252, 3548, 3896, 4028, 3910, + 3782, 3875, 4095, 4095, 4095, 3855, 3719, 3863, + 4080, 4065, 3759, 3424, 3355, 3556, 3739, 3649, + 3342, 3105, 3136, 3332, 3412, 3231, 2919, 2715, + 2707, 2768, 2724, 2551, 2362, 2259, 2219, 2157, + 2048, 1944, 1881, 1811, 1665, 1473, 1350, 1361, + 1417, 1359, 1150, 949, 947, 1145, 1329, 1300, + 1095, 955, 1044, 1254, 1316, 1103, 782, 627, + 713, 835, 759, 498, 306, 386, 653, 834, + 792, 690, 804, 1192, 1608, 1771, 1678, 1603, + 1778, 2118, 2309, 2159, 1822, 1629, 1734, 1954, + 1990, 1762, 1493, 1456, 1681, 1943, 2022, 1925, + 1847, 1930, 2119, 2249, 2238, 2153, 2095, 2080, + 2048, 1973, 1912, 1915, 1938, 1892, 1763, 1668, + 1723, 1885, 1968, 1842, 1593, 1438, 1481, 1578, + 1487, 1150, 775, 614, 689, 765, 627, 325, + 123, 191, 407, 501, 366, 185, 212, 466, + 698, 671, 436, 273, 366, 584, 630, 389, + 77, 8, 248, 539, 586, 384, 215, 329, + 667, 935, 929, 753, 682, 863, 1169, 1364, + 1361, 1292, 1331, 1505, 1700, 1812, 1863, 1934, + 2048, 2147, 2196, 2244, 2360, 2521, 2615, 2582, + 2519, 2589, 2834, 3096, 3182, 3084, 3009, 3147, + 3446, 3657, 3604, 3387, 3271, 3380, 3552, 3521, + 3228, 2893, 2770, 2865, 2939, 2800, 2540, 2436, + 2621, 2923, 3052, 2930, 2780, 2860, 3153, 3370, + 3268, 2930, 2671, 2689, 2844, 2820, 2484, 2039, + 1804, 1875, 2038, 2026, 1804, 1593, 1602, 1812, 2013, 2049, 1961, 1906, 1958, 2053, 2091, 2066 }, { - 2048, 2070, 2146, 2287, 2483, 2702, 2900, 3027, - 3040, 2918, 2664, 2307, 1895, 1485, 1132, 876, - 736, 714, 794, 950, 1160, 1403, 1672, 1964, - 2279, 2614, 2955, 3279, 3551, 3731, 3784, 3687, - 3434, 3043, 2547, 1997, 1446, 948, 545, 265, - 123, 122, 252, 500, 850, 1280, 1768, 2284, - 2795, 3265, 3654, 3930, 4065, 4046, 3875, 3567, - 3152, 2664, 2143, 1626, 1146, 731, 405, 187, - 94, 136, 319, 637, 1073, 1592, 2150, 2693, - 3169, 3530, 3746, 3807, 3720, 3514, 3223, 2886, - 2537, 2196, 1875, 1578, 1306, 1063, 862, 723, - 671, 729, 908, 1201, 1584, 2009, 2421, 2763, - 2992, 3084, 3043, 2896, 2687, 2466, 2275, 2142, - 2070, 2044, 2037, 2021, 1974, 1892, 1789, 1690, - 1628, 1627, 1697, 1828, 1989, 2140, 2238, 2252, - 2173, 2016, 1819, 1633, 1508, 1484, 1577, 1776, - 2048, 2343, 2610, 2807, 2911, 2919, 2849, 2726, - 2581, 2434, 2291, 2147, 1986, 1794, 1565, 1306, - 1043, 816, 670, 645, 766, 1034, 1430, 1909, - 2417, 2895, 3293, 3576, 3726, 3744, 3643, 3442, - 3162, 2819, 2430, 2008, 1570, 1139, 742, 413, - 189, 97, 158, 374, 732, 1201, 1741, 2303, - 2842, 3316, 3692, 3947, 4067, 4047, 3887, 3596, - 3191, 2697, 2150, 1590, 1066, 621, 297, 117, - 94, 220, 475, 826, 1240, 1683, 2127, 2551, - 2937, 3270, 3535, 3711, 3780, 3723, 3531, 3209, - 2779, 2282, 1770, 1302, 930, 693, 608, 664, - 834, 1076, 1345, 1606, 1836, 2031, 2199, 2355, - 2509, 2665, 2811, 2922, 2971, 2931, 2792, 2562, - 2271, 1966, 1698, 1514, 1444, 1491, 1632, 1826, - 2020, 2164, 2228, 2200, 2097, 1953, 1809, 1705, + 2048, 2070, 2146, 2287, 2483, 2702, 2900, 3027, + 3040, 2918, 2664, 2307, 1895, 1485, 1132, 876, + 736, 714, 794, 950, 1160, 1403, 1672, 1964, + 2279, 2614, 2955, 3279, 3551, 3731, 3784, 3687, + 3434, 3043, 2547, 1997, 1446, 948, 545, 265, + 123, 122, 252, 500, 850, 1280, 1768, 2284, + 2795, 3265, 3654, 3930, 4065, 4046, 3875, 3567, + 3152, 2664, 2143, 1626, 1146, 731, 405, 187, + 94, 136, 319, 637, 1073, 1592, 2150, 2693, + 3169, 3530, 3746, 3807, 3720, 3514, 3223, 2886, + 2537, 2196, 1875, 1578, 1306, 1063, 862, 723, + 671, 729, 908, 1201, 1584, 2009, 2421, 2763, + 2992, 3084, 3043, 2896, 2687, 2466, 2275, 2142, + 2070, 2044, 2037, 2021, 1974, 1892, 1789, 1690, + 1628, 1627, 1697, 1828, 1989, 2140, 2238, 2252, + 2173, 2016, 1819, 1633, 1508, 1484, 1577, 1776, + 2048, 2343, 2610, 2807, 2911, 2919, 2849, 2726, + 2581, 2434, 2291, 2147, 1986, 1794, 1565, 1306, + 1043, 816, 670, 645, 766, 1034, 1430, 1909, + 2417, 2895, 3293, 3576, 3726, 3744, 3643, 3442, + 3162, 2819, 2430, 2008, 1570, 1139, 742, 413, + 189, 97, 158, 374, 732, 1201, 1741, 2303, + 2842, 3316, 3692, 3947, 4067, 4047, 3887, 3596, + 3191, 2697, 2150, 1590, 1066, 621, 297, 117, + 94, 220, 475, 826, 1240, 1683, 2127, 2551, + 2937, 3270, 3535, 3711, 3780, 3723, 3531, 3209, + 2779, 2282, 1770, 1302, 930, 693, 608, 664, + 834, 1076, 1345, 1606, 1836, 2031, 2199, 2355, + 2509, 2665, 2811, 2922, 2971, 2931, 2792, 2562, + 2271, 1966, 1698, 1514, 1444, 1491, 1632, 1826, + 2020, 2164, 2228, 2200, 2097, 1953, 1809, 1705, 1663, 1689, 1767, 1869, 1964, 2029, 2055, 2053 }, { - 2048, 2561, 2882, 1925, 1133, 2097, 3797, 4088, - 2776, 1767, 2291, 3280, 3257, 2487, 2059, 2126, - 2101, 1630, 1064, 1182, 1941, 2104, 1196, 546, - 1140, 2073, 2181, 1769, 1821, 2365, 2600, 2511, - 2925, 3644, 3507, 2704, 2607, 3268, 3505, 3065, - 2629, 2418, 2195, 2003, 2003, 1859, 1066, 110, - 157, 1030, 1220, 450, 80, 694, 1448, 1721, - 1786, 2100, 2633, 2799, 2270, 1758, 2203, 3394, - 4094, 3495, 2357, 2200, 3036, 3279, 2512, 2047, - 2132, 1482, 103, 0, 966, 2027, 1434, 250, - 475, 1883, 2525, 1973, 1589, 1913, 2175, 1995, - 1842, 2221, 3014, 3437, 3043, 2581, 2900, 3549, - 3502, 2694, 2013, 1982, 2001, 1505, 1262, 2009, - 2685, 2173, 1503, 2031, 3013, 2982, 2080, 1531, - 1740, 2035, 2040, 2150, 2357, 2095, 1711, 2170, - 3093, 3197, 2417, 1724, 1547, 1653, 1797, 1905, - 2048, 2242, 2334, 2300, 2332, 2628, 3225, 3649, - 3156, 2071, 1676, 2141, 2380, 2129, 2035, 2014, - 1542, 1048, 1384, 2197, 2109, 877, 120, 825, - 1656, 1357, 856, 1254, 1923, 2056, 2093, 2657, - 3405, 3542, 2994, 2621, 2942, 3334, 3120, 2552, - 2206, 2220, 2250, 1874, 1385, 1543, 1973, 1423, - 198, 29, 1125, 1695, 806, 0, 263, 1560, - 2130, 2050, 2522, 3231, 2971, 2280, 2656, 3851, - 4095, 3374, 2153, 1810, 2357, 2798, 2562, 2088, - 1879, 1846, 1581, 940, 509, 921, 1484, 1011, - 31, 79, 1132, 1898, 1978, 1988, 2205, 2327, - 2334, 2625, 3035, 2727, 1825, 1636, 2371, 2727, - 2323, 2121, 2341, 2265, 1886, 1866, 2171, 1986, - 1120, 626, 1239, 2015, 1854, 1326, 1485, 2132, - 2467, 2287, 2008, 2142, 2522, 2233, 1167, 733, + 2048, 2561, 2882, 1925, 1133, 2097, 3797, 4088, + 2776, 1767, 2291, 3280, 3257, 2487, 2059, 2126, + 2101, 1630, 1064, 1182, 1941, 2104, 1196, 546, + 1140, 2073, 2181, 1769, 1821, 2365, 2600, 2511, + 2925, 3644, 3507, 2704, 2607, 3268, 3505, 3065, + 2629, 2418, 2195, 2003, 2003, 1859, 1066, 110, + 157, 1030, 1220, 450, 80, 694, 1448, 1721, + 1786, 2100, 2633, 2799, 2270, 1758, 2203, 3394, + 4094, 3495, 2357, 2200, 3036, 3279, 2512, 2047, + 2132, 1482, 103, 0, 966, 2027, 1434, 250, + 475, 1883, 2525, 1973, 1589, 1913, 2175, 1995, + 1842, 2221, 3014, 3437, 3043, 2581, 2900, 3549, + 3502, 2694, 2013, 1982, 2001, 1505, 1262, 2009, + 2685, 2173, 1503, 2031, 3013, 2982, 2080, 1531, + 1740, 2035, 2040, 2150, 2357, 2095, 1711, 2170, + 3093, 3197, 2417, 1724, 1547, 1653, 1797, 1905, + 2048, 2242, 2334, 2300, 2332, 2628, 3225, 3649, + 3156, 2071, 1676, 2141, 2380, 2129, 2035, 2014, + 1542, 1048, 1384, 2197, 2109, 877, 120, 825, + 1656, 1357, 856, 1254, 1923, 2056, 2093, 2657, + 3405, 3542, 2994, 2621, 2942, 3334, 3120, 2552, + 2206, 2220, 2250, 1874, 1385, 1543, 1973, 1423, + 198, 29, 1125, 1695, 806, 0, 263, 1560, + 2130, 2050, 2522, 3231, 2971, 2280, 2656, 3851, + 4095, 3374, 2153, 1810, 2357, 2798, 2562, 2088, + 1879, 1846, 1581, 940, 509, 921, 1484, 1011, + 31, 79, 1132, 1898, 1978, 1988, 2205, 2327, + 2334, 2625, 3035, 2727, 1825, 1636, 2371, 2727, + 2323, 2121, 2341, 2265, 1886, 1866, 2171, 1986, + 1120, 626, 1239, 2015, 1854, 1326, 1485, 2132, + 2467, 2287, 2008, 2142, 2522, 2233, 1167, 733, 1793, 3076, 2860, 1469, 909, 1947, 2928, 2560 }, { - 2048, 2504, 2795, 1937, 1211, 2093, 3713, 4049, - 2790, 1746, 2327, 3617, 3862, 2964, 2133, 1958, - 2048, 1906, 1540, 1495, 1969, 2095, 1253, 469, - 957, 2084, 2288, 1309, 413, 609, 1420, 1878, - 2048, 2416, 2641, 2415, 2445, 3116, 3618, 3425, - 3094, 3057, 2976, 2556, 2157, 2260, 2607, 2510, - 2048, 1846, 1730, 1126, 470, 562, 1118, 1256, - 707, 0, 0, 657, 1800, 2252, 1982, 1778, - 2048, 2337, 2178, 2155, 3149, 4095, 3814, 2019, - 1613, 3417, 4095, 4095, 2914, 2060, 2283, 2403, - 2048, 2008, 2319, 1963, 931, 522, 1245, 2190, - 2418, 1813, 1007, 831, 1340, 1749, 1701, 1701, - 2048, 2283, 2008, 1749, 2382, 3485, 3459, 2102, - 1281, 1916, 2557, 2061, 1334, 1451, 2031, 2222, - 2048, 2033, 2105, 1834, 1584, 1987, 2435, 1916, - 981, 920, 1695, 2348, 2505, 2404, 2271, 2175, - 2048, 1874, 1791, 1820, 1787, 1507, 926, 477, - 918, 2022, 2475, 1928, 1548, 1878, 2145, 2009, - 2048, 2386, 2390, 1952, 2002, 3023, 3848, 3333, - 2518, 3030, 4095, 4095, 2947, 2084, 2100, 2270, - 2048, 1702, 1663, 1726, 1412, 921, 893, 1364, - 1762, 1577, 771, 85, 433, 1479, 2005, 1899, - 2048, 2447, 2401, 2251, 3043, 4095, 4095, 3226, - 1627, 2142, 3851, 4095, 3076, 2212, 2305, 2408, - 2048, 1782, 2003, 2215, 1703, 660, 90, 449, - 1182, 1559, 1324, 832, 814, 1398, 1831, 1842, - 2048, 2517, 2569, 2216, 2218, 2717, 3036, 2810, - 2563, 2830, 3111, 2643, 1890, 1817, 2179, 2205, - 2048, 2021, 1715, 1061, 879, 1567, 2270, 1959, - 932, 554, 1292, 2021, 1905, 1587, 1757, 2076, - 2048, 1774, 1737, 2244, 2760, 2283, 1035, 637, + 2048, 2504, 2795, 1937, 1211, 2093, 3713, 4049, + 2790, 1746, 2327, 3617, 3862, 2964, 2133, 1958, + 2048, 1906, 1540, 1495, 1969, 2095, 1253, 469, + 957, 2084, 2288, 1309, 413, 609, 1420, 1878, + 2048, 2416, 2641, 2415, 2445, 3116, 3618, 3425, + 3094, 3057, 2976, 2556, 2157, 2260, 2607, 2510, + 2048, 1846, 1730, 1126, 470, 562, 1118, 1256, + 707, 0, 0, 657, 1800, 2252, 1982, 1778, + 2048, 2337, 2178, 2155, 3149, 4095, 3814, 2019, + 1613, 3417, 4095, 4095, 2914, 2060, 2283, 2403, + 2048, 2008, 2319, 1963, 931, 522, 1245, 2190, + 2418, 1813, 1007, 831, 1340, 1749, 1701, 1701, + 2048, 2283, 2008, 1749, 2382, 3485, 3459, 2102, + 1281, 1916, 2557, 2061, 1334, 1451, 2031, 2222, + 2048, 2033, 2105, 1834, 1584, 1987, 2435, 1916, + 981, 920, 1695, 2348, 2505, 2404, 2271, 2175, + 2048, 1874, 1791, 1820, 1787, 1507, 926, 477, + 918, 2022, 2475, 1928, 1548, 1878, 2145, 2009, + 2048, 2386, 2390, 1952, 2002, 3023, 3848, 3333, + 2518, 3030, 4095, 4095, 2947, 2084, 2100, 2270, + 2048, 1702, 1663, 1726, 1412, 921, 893, 1364, + 1762, 1577, 771, 85, 433, 1479, 2005, 1899, + 2048, 2447, 2401, 2251, 3043, 4095, 4095, 3226, + 1627, 2142, 3851, 4095, 3076, 2212, 2305, 2408, + 2048, 1782, 2003, 2215, 1703, 660, 90, 449, + 1182, 1559, 1324, 832, 814, 1398, 1831, 1842, + 2048, 2517, 2569, 2216, 2218, 2717, 3036, 2810, + 2563, 2830, 3111, 2643, 1890, 1817, 2179, 2205, + 2048, 2021, 1715, 1061, 879, 1567, 2270, 1959, + 932, 554, 1292, 2021, 1905, 1587, 1757, 2076, + 2048, 1774, 1737, 2244, 2760, 2283, 1035, 637, 1788, 3057, 2821, 1509, 1006, 1957, 2836, 2504 }, { - 2048, 2448, 2705, 1949, 1297, 2089, 3594, 3952, - 2776, 1740, 2347, 3840, 4095, 3348, 2198, 1801, - 1994, 2206, 2113, 1926, 2015, 2073, 1535, 882, - 1140, 2082, 2300, 1162, 0, 0, 565, 1339, - 1170, 960, 1385, 1871, 1992, 2142, 2460, 2617, - 2629, 2757, 2854, 2594, 2196, 2427, 3507, 4095, - 3938, 2920, 2662, 3067, 3099, 2608, 2195, 2028, - 1786, 1282, 808, 955, 1777, 2367, 1886, 688, - 1, 586, 1725, 1880, 843, 258, 1065, 2058, - 2132, 2013, 2527, 3003, 2625, 2061, 2503, 3589, - 3621, 2244, 1338, 2198, 3558, 3686, 2746, 1947, - 1842, 2145, 2321, 2155, 1950, 1904, 1660, 1024, - 593, 1060, 2140, 2565, 1577, 323, 565, 1997, - 2685, 2145, 1719, 2040, 2341, 2179, 2045, 2244, - 2355, 2087, 1946, 2350, 2626, 2116, 1633, 2182, - 3093, 3120, 2374, 1774, 1637, 1732, 1850, 1936, - 2048, 2199, 2274, 2250, 2281, 2539, 3089, 3542, - 3156, 2073, 1590, 2184, 2670, 2289, 1876, 2152, - 2553, 2428, 2091, 2069, 2066, 1520, 887, 1098, - 1656, 1132, 0, 0, 782, 1984, 1924, 1117, - 690, 1029, 1618, 1893, 1959, 2147, 2351, 2330, - 2206, 2379, 3157, 4095, 4095, 3062, 2159, 2793, - 3897, 3778, 2732, 2273, 2711, 2971, 2487, 2018, - 2130, 2013, 1044, 328, 923, 1791, 1414, 226, - 0, 708, 1938, 2310, 1670, 958, 958, 1461, - 1879, 2035, 2162, 2506, 2870, 2767, 2466, 2936, - 4064, 4095, 3409, 2348, 2278, 2767, 2907, 2584, - 2334, 2371, 2327, 2100, 2069, 2158, 1901, 1584, - 1772, 1935, 1261, 335, 403, 1472, 2281, 1965, - 1120, 944, 1561, 2033, 1989, 1946, 2085, 2015, - 1628, 1297, 1503, 2326, 2936, 2317, 964, 610, + 2048, 2448, 2705, 1949, 1297, 2089, 3594, 3952, + 2776, 1740, 2347, 3840, 4095, 3348, 2198, 1801, + 1994, 2206, 2113, 1926, 2015, 2073, 1535, 882, + 1140, 2082, 2300, 1162, 0, 0, 565, 1339, + 1170, 960, 1385, 1871, 1992, 2142, 2460, 2617, + 2629, 2757, 2854, 2594, 2196, 2427, 3507, 4095, + 3938, 2920, 2662, 3067, 3099, 2608, 2195, 2028, + 1786, 1282, 808, 955, 1777, 2367, 1886, 688, + 1, 586, 1725, 1880, 843, 258, 1065, 2058, + 2132, 2013, 2527, 3003, 2625, 2061, 2503, 3589, + 3621, 2244, 1338, 2198, 3558, 3686, 2746, 1947, + 1842, 2145, 2321, 2155, 1950, 1904, 1660, 1024, + 593, 1060, 2140, 2565, 1577, 323, 565, 1997, + 2685, 2145, 1719, 2040, 2341, 2179, 2045, 2244, + 2355, 2087, 1946, 2350, 2626, 2116, 1633, 2182, + 3093, 3120, 2374, 1774, 1637, 1732, 1850, 1936, + 2048, 2199, 2274, 2250, 2281, 2539, 3089, 3542, + 3156, 2073, 1590, 2184, 2670, 2289, 1876, 2152, + 2553, 2428, 2091, 2069, 2066, 1520, 887, 1098, + 1656, 1132, 0, 0, 782, 1984, 1924, 1117, + 690, 1029, 1618, 1893, 1959, 2147, 2351, 2330, + 2206, 2379, 3157, 4095, 4095, 3062, 2159, 2793, + 3897, 3778, 2732, 2273, 2711, 2971, 2487, 2018, + 2130, 2013, 1044, 328, 923, 1791, 1414, 226, + 0, 708, 1938, 2310, 1670, 958, 958, 1461, + 1879, 2035, 2162, 2506, 2870, 2767, 2466, 2936, + 4064, 4095, 3409, 2348, 2278, 2767, 2907, 2584, + 2334, 2371, 2327, 2100, 2069, 2158, 1901, 1584, + 1772, 1935, 1261, 335, 403, 1472, 2281, 1965, + 1120, 944, 1561, 2033, 1989, 1946, 2085, 2015, + 1628, 1297, 1503, 2326, 2936, 2317, 964, 610, 1793, 3007, 2766, 1557, 1113, 1967, 2741, 2447 }, { - 2048, 2391, 2614, 1962, 1390, 2084, 3441, 3798, - 2733, 1749, 2349, 3933, 4095, 3601, 2245, 1678, - 1949, 2480, 2673, 2383, 2069, 2045, 1963, 1657, - 1630, 2067, 2213, 1389, 126, 0, 478, 1190, - 807, 179, 564, 1450, 1580, 1095, 969, 1325, - 1647, 1798, 1949, 2078, 2078, 2176, 2736, 3459, - 3495, 2877, 2778, 3608, 4095, 3832, 3049, 2830, - 3286, 3873, 3912, 3170, 2242, 1891, 2097, 2250, - 2048, 1830, 1948, 1965, 1182, 208, 570, 2072, - 2449, 693, 0, 0, 845, 2027, 1506, 582, - 844, 1928, 2383, 1996, 1740, 1958, 2133, 2012, - 1906, 2171, 2762, 3132, 2879, 2533, 2914, 3805, - 4095, 3243, 1950, 1562, 2441, 3329, 3017, 2076, - 1754, 2015, 2102, 2047, 2244, 2409, 2068, 1514, - 1479, 1988, 2180, 1686, 1404, 1975, 2465, 1917, - 1062, 1061, 1753, 2291, 2407, 2322, 2217, 2143, - 2048, 1917, 1853, 1872, 1843, 1611, 1109, 674, - 1004, 2023, 2508, 1904, 1355, 1759, 2273, 1890, - 1114, 1014, 1626, 2105, 2060, 1990, 2239, 2366, - 2228, 2562, 3518, 3922, 3105, 2107, 2178, 3174, - 3968, 3797, 3010, 2570, 2795, 3051, 2841, 2406, - 2157, 2164, 2183, 1932, 1602, 1703, 1995, 1593, - 632, 402, 1233, 1703, 667, 0, 0, 882, - 2436, 1965, 539, 279, 1239, 1921, 1852, 1776, - 2048, 2247, 2081, 1919, 2319, 3168, 3686, 3445, - 2847, 2530, 2827, 3508, 3758, 3148, 2545, 2893, - 3591, 3482, 2690, 2150, 2095, 2087, 1943, 1859, - 1850, 1637, 1317, 1517, 2233, 2422, 1719, 1252, - 1659, 1911, 1215, 442, 674, 1620, 2200, 2001, - 1621, 1677, 1967, 2049, 2087, 2327, 2405, 1960, - 1272, 921, 1332, 2380, 3036, 2331, 957, 652, + 2048, 2391, 2614, 1962, 1390, 2084, 3441, 3798, + 2733, 1749, 2349, 3933, 4095, 3601, 2245, 1678, + 1949, 2480, 2673, 2383, 2069, 2045, 1963, 1657, + 1630, 2067, 2213, 1389, 126, 0, 478, 1190, + 807, 179, 564, 1450, 1580, 1095, 969, 1325, + 1647, 1798, 1949, 2078, 2078, 2176, 2736, 3459, + 3495, 2877, 2778, 3608, 4095, 3832, 3049, 2830, + 3286, 3873, 3912, 3170, 2242, 1891, 2097, 2250, + 2048, 1830, 1948, 1965, 1182, 208, 570, 2072, + 2449, 693, 0, 0, 845, 2027, 1506, 582, + 844, 1928, 2383, 1996, 1740, 1958, 2133, 2012, + 1906, 2171, 2762, 3132, 2879, 2533, 2914, 3805, + 4095, 3243, 1950, 1562, 2441, 3329, 3017, 2076, + 1754, 2015, 2102, 2047, 2244, 2409, 2068, 1514, + 1479, 1988, 2180, 1686, 1404, 1975, 2465, 1917, + 1062, 1061, 1753, 2291, 2407, 2322, 2217, 2143, + 2048, 1917, 1853, 1872, 1843, 1611, 1109, 674, + 1004, 2023, 2508, 1904, 1355, 1759, 2273, 1890, + 1114, 1014, 1626, 2105, 2060, 1990, 2239, 2366, + 2228, 2562, 3518, 3922, 3105, 2107, 2178, 3174, + 3968, 3797, 3010, 2570, 2795, 3051, 2841, 2406, + 2157, 2164, 2183, 1932, 1602, 1703, 1995, 1593, + 632, 402, 1233, 1703, 667, 0, 0, 882, + 2436, 1965, 539, 279, 1239, 1921, 1852, 1776, + 2048, 2247, 2081, 1919, 2319, 3168, 3686, 3445, + 2847, 2530, 2827, 3508, 3758, 3148, 2545, 2893, + 3591, 3482, 2690, 2150, 2095, 2087, 1943, 1859, + 1850, 1637, 1317, 1517, 2233, 2422, 1719, 1252, + 1659, 1911, 1215, 442, 674, 1620, 2200, 2001, + 1621, 1677, 1967, 2049, 2087, 2327, 2405, 1960, + 1272, 921, 1332, 2380, 3036, 2331, 957, 652, 1807, 2930, 2695, 1612, 1229, 1978, 2645, 2391 }, { - 2048, 2334, 2522, 1976, 1490, 2079, 3258, 3593, - 2665, 1773, 2333, 3889, 4095, 3697, 2269, 1604, - 1919, 2679, 3113, 2768, 2118, 2017, 2415, 2552, - 2260, 2045, 2060, 1896, 1377, 998, 1204, 1514, - 1170, 558, 718, 1443, 1509, 781, 350, 647, - 1021, 1071, 1139, 1531, 1928, 1784, 1177, 880, - 1264, 1772, 1926, 2007, 2266, 2439, 2386, 2410, - 2792, 3438, 3834, 3414, 2357, 1705, 2214, 3417, - 4094, 3520, 2379, 2228, 3421, 4095, 3464, 2029, - 1806, 2675, 3147, 2715, 2168, 2047, 1957, 1561, - 1396, 1948, 2471, 1943, 827, 498, 1262, 2186, - 2411, 1809, 922, 606, 1091, 1557, 1271, 647, - 593, 1304, 2100, 2265, 1910, 1752, 1973, 2052, - 1898, 2005, 2283, 2056, 1407, 1270, 2012, 2828, - 2791, 2119, 1898, 2432, 2701, 2118, 1653, 2168, - 2934, 2918, 2303, 1839, 1742, 1817, 1905, 1968, - 2048, 2156, 2211, 2195, 2221, 2422, 2863, 3260, - 2987, 2070, 1612, 2188, 2750, 2353, 1795, 2236, - 3268, 3558, 2766, 1923, 2007, 2675, 2881, 2459, - 2139, 2121, 1934, 1615, 1678, 2021, 1977, 1347, - 690, 653, 1185, 1519, 1188, 713, 799, 1352, - 1768, 1592, 799, 53, 282, 1342, 1981, 1671, - 1281, 1501, 1912, 2039, 2186, 2693, 3057, 2588, - 1814, 2110, 3494, 4095, 3331, 2323, 2700, 3882, - 4095, 3396, 2161, 1766, 2478, 3411, 3618, 3112, - 2529, 2271, 2311, 2368, 2218, 2019, 1965, 1767, - 1212, 861, 1236, 1839, 1861, 1367, 1080, 1309, - 1542, 1252, 897, 1342, 2261, 2426, 1753, 1413, - 1772, 1963, 1600, 1328, 1568, 1949, 2059, 2054, - 2265, 2525, 2397, 2065, 2176, 2648, 2657, 1920, - 1034, 696, 1245, 2400, 3050, 2324, 1016, 763, + 2048, 2334, 2522, 1976, 1490, 2079, 3258, 3593, + 2665, 1773, 2333, 3889, 4095, 3697, 2269, 1604, + 1919, 2679, 3113, 2768, 2118, 2017, 2415, 2552, + 2260, 2045, 2060, 1896, 1377, 998, 1204, 1514, + 1170, 558, 718, 1443, 1509, 781, 350, 647, + 1021, 1071, 1139, 1531, 1928, 1784, 1177, 880, + 1264, 1772, 1926, 2007, 2266, 2439, 2386, 2410, + 2792, 3438, 3834, 3414, 2357, 1705, 2214, 3417, + 4094, 3520, 2379, 2228, 3421, 4095, 3464, 2029, + 1806, 2675, 3147, 2715, 2168, 2047, 1957, 1561, + 1396, 1948, 2471, 1943, 827, 498, 1262, 2186, + 2411, 1809, 922, 606, 1091, 1557, 1271, 647, + 593, 1304, 2100, 2265, 1910, 1752, 1973, 2052, + 1898, 2005, 2283, 2056, 1407, 1270, 2012, 2828, + 2791, 2119, 1898, 2432, 2701, 2118, 1653, 2168, + 2934, 2918, 2303, 1839, 1742, 1817, 1905, 1968, + 2048, 2156, 2211, 2195, 2221, 2422, 2863, 3260, + 2987, 2070, 1612, 2188, 2750, 2353, 1795, 2236, + 3268, 3558, 2766, 1923, 2007, 2675, 2881, 2459, + 2139, 2121, 1934, 1615, 1678, 2021, 1977, 1347, + 690, 653, 1185, 1519, 1188, 713, 799, 1352, + 1768, 1592, 799, 53, 282, 1342, 1981, 1671, + 1281, 1501, 1912, 2039, 2186, 2693, 3057, 2588, + 1814, 2110, 3494, 4095, 3331, 2323, 2700, 3882, + 4095, 3396, 2161, 1766, 2478, 3411, 3618, 3112, + 2529, 2271, 2311, 2368, 2218, 2019, 1965, 1767, + 1212, 861, 1236, 1839, 1861, 1367, 1080, 1309, + 1542, 1252, 897, 1342, 2261, 2426, 1753, 1413, + 1772, 1963, 1600, 1328, 1568, 1949, 2059, 2054, + 2265, 2525, 2397, 2065, 2176, 2648, 2657, 1920, + 1034, 696, 1245, 2400, 3050, 2324, 1016, 763, 1831, 2827, 2610, 1674, 1353, 1989, 2548, 2334 }, { - 2048, 2277, 2428, 1990, 1595, 2073, 3049, 3342, - 2572, 1810, 2299, 3712, 4095, 3626, 2267, 1589, - 1909, 2769, 3349, 2999, 2150, 1997, 2763, 3291, - 2819, 2024, 1903, 2466, 2932, 2799, 2368, 2132, - 2048, 1862, 1745, 1856, 1832, 1442, 1103, 1156, - 1308, 1252, 1212, 1508, 1905, 1682, 615, 0, - 1, 1020, 1235, 461, 0, 472, 1211, 1424, - 1100, 697, 708, 1259, 1913, 2154, 2014, 1912, - 2048, 2193, 2114, 2104, 2644, 3339, 3110, 2029, - 1740, 3127, 4095, 4095, 3180, 2068, 2650, 3863, - 3750, 2248, 1351, 2193, 3506, 3666, 2770, 1935, - 1786, 2199, 2674, 2737, 2430, 2203, 2224, 2222, - 2048, 1929, 2068, 2203, 1867, 1232, 1199, 2013, - 2590, 2151, 1589, 2033, 2980, 3075, 2091, 1155, - 1243, 1973, 2195, 1680, 1441, 1984, 2396, 1944, - 1293, 1318, 1836, 2218, 2295, 2234, 2162, 2111, - 2048, 1960, 1917, 1928, 1907, 1741, 1373, 1032, - 1249, 2028, 2432, 1921, 1395, 1755, 2298, 1853, - 727, 320, 1170, 2212, 2107, 1013, 427, 1035, - 1715, 1412, 760, 855, 1561, 2029, 2021, 1936, - 2048, 2221, 2244, 2215, 2391, 2686, 2742, 2490, - 2249, 2419, 3196, 4095, 4095, 3026, 2157, 2808, - 4050, 4086, 2953, 2398, 3348, 4095, 4095, 2977, - 1750, 2109, 3132, 3289, 2604, 2133, 2179, 2229, - 2048, 1914, 2025, 2135, 1861, 1261, 870, 1014, - 1435, 1663, 1397, 758, 436, 929, 1494, 1001, - 0, 0, 711, 1758, 1825, 1337, 1158, 1447, - 1683, 1541, 1408, 1710, 2133, 2168, 1981, 1969, - 2048, 2061, 2217, 2563, 2680, 2320, 1914, 2105, - 2836, 3225, 2727, 2076, 2234, 2841, 2792, 1901, - 951, 652, 1252, 2385, 2978, 2298, 1136, 936, + 2048, 2277, 2428, 1990, 1595, 2073, 3049, 3342, + 2572, 1810, 2299, 3712, 4095, 3626, 2267, 1589, + 1909, 2769, 3349, 2999, 2150, 1997, 2763, 3291, + 2819, 2024, 1903, 2466, 2932, 2799, 2368, 2132, + 2048, 1862, 1745, 1856, 1832, 1442, 1103, 1156, + 1308, 1252, 1212, 1508, 1905, 1682, 615, 0, + 1, 1020, 1235, 461, 0, 472, 1211, 1424, + 1100, 697, 708, 1259, 1913, 2154, 2014, 1912, + 2048, 2193, 2114, 2104, 2644, 3339, 3110, 2029, + 1740, 3127, 4095, 4095, 3180, 2068, 2650, 3863, + 3750, 2248, 1351, 2193, 3506, 3666, 2770, 1935, + 1786, 2199, 2674, 2737, 2430, 2203, 2224, 2222, + 2048, 1929, 2068, 2203, 1867, 1232, 1199, 2013, + 2590, 2151, 1589, 2033, 2980, 3075, 2091, 1155, + 1243, 1973, 2195, 1680, 1441, 1984, 2396, 1944, + 1293, 1318, 1836, 2218, 2295, 2234, 2162, 2111, + 2048, 1960, 1917, 1928, 1907, 1741, 1373, 1032, + 1249, 2028, 2432, 1921, 1395, 1755, 2298, 1853, + 727, 320, 1170, 2212, 2107, 1013, 427, 1035, + 1715, 1412, 760, 855, 1561, 2029, 2021, 1936, + 2048, 2221, 2244, 2215, 2391, 2686, 2742, 2490, + 2249, 2419, 3196, 4095, 4095, 3026, 2157, 2808, + 4050, 4086, 2953, 2398, 3348, 4095, 4095, 2977, + 1750, 2109, 3132, 3289, 2604, 2133, 2179, 2229, + 2048, 1914, 2025, 2135, 1861, 1261, 870, 1014, + 1435, 1663, 1397, 758, 436, 929, 1494, 1001, + 0, 0, 711, 1758, 1825, 1337, 1158, 1447, + 1683, 1541, 1408, 1710, 2133, 2168, 1981, 1969, + 2048, 2061, 2217, 2563, 2680, 2320, 1914, 2105, + 2836, 3225, 2727, 2076, 2234, 2841, 2792, 1901, + 951, 652, 1252, 2385, 2978, 2298, 1136, 936, 1864, 2700, 2513, 1742, 1484, 2000, 2449, 2277 }, { - 2048, 2220, 2334, 2004, 1704, 2067, 2818, 3053, - 2460, 1858, 2251, 3414, 4031, 3396, 2240, 1636, - 1919, 2736, 3335, 3028, 2158, 1991, 2907, 3645, - 3117, 2011, 1802, 2860, 4086, 4095, 3365, 2704, - 2925, 3282, 2971, 2401, 2313, 2568, 2620, 2422, - 2252, 2173, 2097, 2033, 2032, 1982, 1693, 1304, - 1264, 1583, 1622, 1093, 632, 815, 1302, 1412, - 933, 196, 0, 488, 1712, 2406, 1877, 671, - 1, 568, 1709, 1859, 557, 0, 319, 2073, - 2409, 947, 0, 0, 1270, 2035, 1732, 1227, - 1396, 1984, 2220, 2022, 1893, 2003, 2090, 2030, - 1975, 2111, 2427, 2640, 2519, 2335, 2587, 3208, - 3502, 2962, 1965, 1594, 2464, 3628, 3486, 2101, - 1295, 1914, 2598, 2064, 1043, 989, 2005, 2899, - 2791, 2114, 1918, 2362, 2555, 2100, 1766, 2130, - 2640, 2614, 2210, 1917, 1860, 1907, 1962, 2000, - 2048, 2113, 2146, 2137, 2154, 2281, 2567, 2837, - 2675, 2063, 1737, 2152, 2593, 2298, 1828, 2222, - 3268, 3696, 2916, 1879, 1984, 3221, 3994, 3348, - 2509, 3013, 4095, 4095, 3169, 2103, 2157, 2910, - 3405, 3203, 2647, 2357, 2471, 2597, 2469, 2233, - 2103, 2106, 2115, 1990, 1824, 1873, 2020, 1808, - 1281, 1126, 1573, 1837, 1154, 17, 0, 1100, - 2397, 1964, 283, 0, 655, 1759, 1382, 204, - 0, 692, 1932, 2342, 1581, 491, 132, 630, - 1328, 1655, 1467, 1039, 941, 1374, 1757, 1575, - 1212, 1292, 1716, 1996, 2024, 2028, 2100, 2143, - 2148, 2260, 2435, 2338, 1942, 1826, 2252, 2573, - 2323, 2152, 2746, 3548, 3505, 2575, 1821, 2134, - 3142, 3559, 2864, 2080, 2248, 2864, 2784, 1908, - 1034, 795, 1352, 2336, 2826, 2253, 1312, 1163, + 2048, 2220, 2334, 2004, 1704, 2067, 2818, 3053, + 2460, 1858, 2251, 3414, 4031, 3396, 2240, 1636, + 1919, 2736, 3335, 3028, 2158, 1991, 2907, 3645, + 3117, 2011, 1802, 2860, 4086, 4095, 3365, 2704, + 2925, 3282, 2971, 2401, 2313, 2568, 2620, 2422, + 2252, 2173, 2097, 2033, 2032, 1982, 1693, 1304, + 1264, 1583, 1622, 1093, 632, 815, 1302, 1412, + 933, 196, 0, 488, 1712, 2406, 1877, 671, + 1, 568, 1709, 1859, 557, 0, 319, 2073, + 2409, 947, 0, 0, 1270, 2035, 1732, 1227, + 1396, 1984, 2220, 2022, 1893, 2003, 2090, 2030, + 1975, 2111, 2427, 2640, 2519, 2335, 2587, 3208, + 3502, 2962, 1965, 1594, 2464, 3628, 3486, 2101, + 1295, 1914, 2598, 2064, 1043, 989, 2005, 2899, + 2791, 2114, 1918, 2362, 2555, 2100, 1766, 2130, + 2640, 2614, 2210, 1917, 1860, 1907, 1962, 2000, + 2048, 2113, 2146, 2137, 2154, 2281, 2567, 2837, + 2675, 2063, 1737, 2152, 2593, 2298, 1828, 2222, + 3268, 3696, 2916, 1879, 1984, 3221, 3994, 3348, + 2509, 3013, 4095, 4095, 3169, 2103, 2157, 2910, + 3405, 3203, 2647, 2357, 2471, 2597, 2469, 2233, + 2103, 2106, 2115, 1990, 1824, 1873, 2020, 1808, + 1281, 1126, 1573, 1837, 1154, 17, 0, 1100, + 2397, 1964, 283, 0, 655, 1759, 1382, 204, + 0, 692, 1932, 2342, 1581, 491, 132, 630, + 1328, 1655, 1467, 1039, 941, 1374, 1757, 1575, + 1212, 1292, 1716, 1996, 2024, 2028, 2100, 2143, + 2148, 2260, 2435, 2338, 1942, 1826, 2252, 2573, + 2323, 2152, 2746, 3548, 3505, 2575, 1821, 2134, + 3142, 3559, 2864, 2080, 2248, 2864, 2784, 1908, + 1034, 795, 1352, 2336, 2826, 2253, 1312, 1163, 1903, 2555, 2406, 1814, 1620, 2012, 2350, 2220 }, { - 2048, 2162, 2239, 2018, 1817, 2061, 2571, 2735, - 2332, 1916, 2190, 3018, 3473, 3030, 2190, 1738, - 1949, 2585, 3073, 2846, 2140, 1999, 2806, 3502, - 3055, 2012, 1798, 2909, 4095, 4095, 3680, 2913, - 3288, 3935, 3590, 2702, 2599, 3294, 3674, 3370, - 3014, 2978, 2933, 2572, 2176, 2355, 3177, 3803, - 3495, 2741, 2573, 3035, 3287, 2966, 2522, 2392, - 2561, 2764, 2748, 2454, 2116, 1994, 2064, 2115, - 2048, 1975, 2014, 2019, 1744, 1382, 1493, 2057, - 2214, 1451, 509, 482, 1366, 2035, 1658, 822, - 844, 1898, 2597, 1926, 735, 474, 1281, 2179, - 2390, 1822, 969, 628, 1067, 1516, 1146, 273, - 0, 841, 2149, 2578, 1584, 370, 585, 1996, - 2756, 2169, 1562, 2033, 2887, 2910, 2081, 1383, - 1479, 1997, 2143, 1819, 1683, 2010, 2245, 1990, - 1639, 1660, 1937, 2135, 2174, 2142, 2105, 2080, - 2048, 2004, 1982, 1987, 1976, 1890, 1695, 1508, - 1615, 2037, 2265, 1974, 1655, 1865, 2210, 1916, - 1114, 762, 1356, 2185, 2101, 1041, 329, 863, - 1613, 1105, 0, 0, 800, 1983, 1912, 910, - 127, 281, 1047, 1476, 1166, 733, 851, 1391, - 1784, 1613, 829, 23, 149, 1226, 1961, 1482, - 632, 672, 1462, 1829, 1265, 533, 635, 1534, - 2209, 2015, 1481, 1408, 1764, 2004, 1982, 1957, - 2048, 2114, 2059, 2003, 2143, 2453, 2663, 2596, - 2379, 2260, 2417, 2799, 3016, 2744, 2406, 2754, - 3591, 3831, 3101, 2291, 2248, 2738, 2991, 2750, - 2524, 2799, 3150, 2742, 1829, 1638, 2389, 2851, - 2436, 2185, 2913, 3805, 3668, 2608, 1817, 2132, - 3078, 3425, 2768, 2075, 2215, 2713, 2634, 1939, - 1272, 1106, 1533, 2258, 2607, 2193, 1531, 1433, + 2048, 2162, 2239, 2018, 1817, 2061, 2571, 2735, + 2332, 1916, 2190, 3018, 3473, 3030, 2190, 1738, + 1949, 2585, 3073, 2846, 2140, 1999, 2806, 3502, + 3055, 2012, 1798, 2909, 4095, 4095, 3680, 2913, + 3288, 3935, 3590, 2702, 2599, 3294, 3674, 3370, + 3014, 2978, 2933, 2572, 2176, 2355, 3177, 3803, + 3495, 2741, 2573, 3035, 3287, 2966, 2522, 2392, + 2561, 2764, 2748, 2454, 2116, 1994, 2064, 2115, + 2048, 1975, 2014, 2019, 1744, 1382, 1493, 2057, + 2214, 1451, 509, 482, 1366, 2035, 1658, 822, + 844, 1898, 2597, 1926, 735, 474, 1281, 2179, + 2390, 1822, 969, 628, 1067, 1516, 1146, 273, + 0, 841, 2149, 2578, 1584, 370, 585, 1996, + 2756, 2169, 1562, 2033, 2887, 2910, 2081, 1383, + 1479, 1997, 2143, 1819, 1683, 2010, 2245, 1990, + 1639, 1660, 1937, 2135, 2174, 2142, 2105, 2080, + 2048, 2004, 1982, 1987, 1976, 1890, 1695, 1508, + 1615, 2037, 2265, 1974, 1655, 1865, 2210, 1916, + 1114, 762, 1356, 2185, 2101, 1041, 329, 863, + 1613, 1105, 0, 0, 800, 1983, 1912, 910, + 127, 281, 1047, 1476, 1166, 733, 851, 1391, + 1784, 1613, 829, 23, 149, 1226, 1961, 1482, + 632, 672, 1462, 1829, 1265, 533, 635, 1534, + 2209, 2015, 1481, 1408, 1764, 2004, 1982, 1957, + 2048, 2114, 2059, 2003, 2143, 2453, 2663, 2596, + 2379, 2260, 2417, 2799, 3016, 2744, 2406, 2754, + 3591, 3831, 3101, 2291, 2248, 2738, 2991, 2750, + 2524, 2799, 3150, 2742, 1829, 1638, 2389, 2851, + 2436, 2185, 2913, 3805, 3668, 2608, 1817, 2132, + 3078, 3425, 2768, 2075, 2215, 2713, 2634, 1939, + 1272, 1106, 1533, 2258, 2607, 2193, 1531, 1433, 1948, 2394, 2291, 1890, 1760, 2024, 2249, 2162 }, { - 2048, 2105, 2143, 2033, 1932, 2054, 2312, 2396, - 2192, 1980, 2121, 2551, 2793, 2565, 2123, 1882, - 1994, 2341, 2615, 2495, 2100, 2020, 2490, 2908, - 2654, 2026, 1892, 2594, 3514, 3739, 3149, 2645, - 2925, 3416, 3196, 2548, 2482, 3061, 3413, 3196, - 2917, 2917, 2909, 2579, 2184, 2389, 3368, 4095, - 3938, 3011, 2828, 3622, 4095, 3770, 3023, 2835, - 3362, 4095, 4095, 3707, 2396, 1681, 2219, 3427, - 4094, 3530, 2389, 2240, 3598, 4095, 3939, 2019, - 1621, 3410, 4095, 4095, 3221, 2068, 2626, 3750, - 3621, 2232, 1405, 2183, 3439, 3644, 2793, 1924, - 1740, 2243, 2953, 3201, 2820, 2454, 2719, 3335, - 3502, 2881, 1979, 1697, 2347, 3111, 2958, 2079, - 1621, 1976, 2331, 2056, 1572, 1565, 2029, 2411, - 2355, 2074, 1997, 2168, 2238, 2067, 1946, 2077, - 2256, 2244, 2103, 2003, 1984, 2000, 2019, 2032, - 2048, 2069, 2080, 2078, 2084, 2127, 2226, 2321, - 2268, 2053, 1935, 2086, 2252, 2144, 1961, 2118, - 2553, 2751, 2430, 1970, 2017, 2626, 3049, 2749, - 2309, 2624, 3428, 3604, 2854, 2090, 2139, 2833, - 3405, 3329, 2793, 2485, 2742, 3116, 3052, 2617, - 2285, 2453, 3232, 4095, 4062, 2961, 2148, 2746, - 3897, 3959, 2917, 2395, 3395, 4095, 4095, 3220, - 1635, 2142, 3978, 4095, 3496, 2342, 2719, 3896, - 4095, 3406, 2164, 1747, 2533, 3703, 4095, 3653, - 2897, 2533, 2807, 3457, 3716, 3158, 2579, 3029, - 4064, 4095, 3279, 2318, 2260, 2748, 2965, 2704, - 2476, 2700, 2973, 2612, 1875, 1734, 2302, 2630, - 2323, 2143, 2632, 3208, 3096, 2403, 1904, 2099, - 2667, 2862, 2468, 2063, 2143, 2420, 2372, 1988, - 1628, 1543, 1774, 2158, 2340, 2123, 1781, 1732, + 2048, 2105, 2143, 2033, 1932, 2054, 2312, 2396, + 2192, 1980, 2121, 2551, 2793, 2565, 2123, 1882, + 1994, 2341, 2615, 2495, 2100, 2020, 2490, 2908, + 2654, 2026, 1892, 2594, 3514, 3739, 3149, 2645, + 2925, 3416, 3196, 2548, 2482, 3061, 3413, 3196, + 2917, 2917, 2909, 2579, 2184, 2389, 3368, 4095, + 3938, 3011, 2828, 3622, 4095, 3770, 3023, 2835, + 3362, 4095, 4095, 3707, 2396, 1681, 2219, 3427, + 4094, 3530, 2389, 2240, 3598, 4095, 3939, 2019, + 1621, 3410, 4095, 4095, 3221, 2068, 2626, 3750, + 3621, 2232, 1405, 2183, 3439, 3644, 2793, 1924, + 1740, 2243, 2953, 3201, 2820, 2454, 2719, 3335, + 3502, 2881, 1979, 1697, 2347, 3111, 2958, 2079, + 1621, 1976, 2331, 2056, 1572, 1565, 2029, 2411, + 2355, 2074, 1997, 2168, 2238, 2067, 1946, 2077, + 2256, 2244, 2103, 2003, 1984, 2000, 2019, 2032, + 2048, 2069, 2080, 2078, 2084, 2127, 2226, 2321, + 2268, 2053, 1935, 2086, 2252, 2144, 1961, 2118, + 2553, 2751, 2430, 1970, 2017, 2626, 3049, 2749, + 2309, 2624, 3428, 3604, 2854, 2090, 2139, 2833, + 3405, 3329, 2793, 2485, 2742, 3116, 3052, 2617, + 2285, 2453, 3232, 4095, 4062, 2961, 2148, 2746, + 3897, 3959, 2917, 2395, 3395, 4095, 4095, 3220, + 1635, 2142, 3978, 4095, 3496, 2342, 2719, 3896, + 4095, 3406, 2164, 1747, 2533, 3703, 4095, 3653, + 2897, 2533, 2807, 3457, 3716, 3158, 2579, 3029, + 4064, 4095, 3279, 2318, 2260, 2748, 2965, 2704, + 2476, 2700, 2973, 2612, 1875, 1734, 2302, 2630, + 2323, 2143, 2632, 3208, 3096, 2403, 1904, 2099, + 2667, 2862, 2468, 2063, 2143, 2420, 2372, 1988, + 1628, 1543, 1774, 2158, 2340, 2123, 1781, 1732, 1997, 2223, 2170, 1968, 1903, 2036, 2149, 2105 }, { - 2048, 2081, 2108, 2062, 2033, 2108, 2213, 2231, - 2171, 2169, 2313, 2495, 2523, 2399, 2282, 2198, - 2086, 2082, 2304, 2509, 2430, 2273, 2364, 2557, - 2495, 2238, 2211, 2647, 3262, 3494, 3182, 2884, - 3081, 3340, 3015, 2465, 2546, 3166, 3465, 3191, - 2875, 2836, 2831, 2605, 2347, 2539, 3295, 3937, - 3765, 3197, 3214, 3747, 3836, 3319, 3028, 3351, - 3799, 3942, 3782, 3381, 2828, 2390, 2345, 2780, - 3431, 3666, 3188, 2747, 3186, 3917, 3676, 2669, - 2404, 3379, 4095, 4095, 3542, 2912, 2971, 3195, - 2856, 2177, 2097, 2766, 3226, 2929, 2452, 2338, - 2369, 2329, 2435, 2739, 2953, 2972, 2976, 3055, - 3070, 2820, 2318, 1989, 2255, 2794, 2819, 2258, - 1859, 1983, 2135, 1924, 1650, 1723, 2062, 2302, - 2263, 2109, 2092, 2194, 2176, 2011, 1965, 2133, - 2271, 2208, 2073, 2013, 2010, 2007, 2008, 2025, - 2048, 2062, 2073, 2093, 2113, 2126, 2178, 2283, - 2302, 2132, 1953, 2000, 2163, 2178, 2096, 2181, - 2443, 2593, 2437, 2158, 2152, 2515, 2813, 2693, - 2533, 2857, 3355, 3288, 2694, 2318, 2490, 2851, - 3034, 3022, 2962, 2951, 2919, 2748, 2575, 2643, - 2816, 2840, 2969, 3484, 3859, 3453, 2747, 2699, - 3236, 3489, 3234, 3128, 3642, 4095, 4095, 3247, - 2351, 2675, 3676, 3893, 3199, 2870, 3422, 3924, - 3615, 2867, 2387, 2435, 2850, 3295, 3533, 3569, - 3399, 2991, 2695, 2959, 3443, 3394, 2993, 3131, - 3787, 3963, 3300, 2558, 2412, 2676, 2811, 2651, - 2532, 2756, 2984, 2622, 1895, 1703, 2209, 2582, - 2419, 2303, 2653, 3027, 2911, 2454, 2158, 2257, - 2522, 2573, 2384, 2295, 2416, 2406, 2088, 1777, - 1737, 1830, 1894, 1984, 2097, 2096, 1974, 1898, + 2048, 2081, 2108, 2062, 2033, 2108, 2213, 2231, + 2171, 2169, 2313, 2495, 2523, 2399, 2282, 2198, + 2086, 2082, 2304, 2509, 2430, 2273, 2364, 2557, + 2495, 2238, 2211, 2647, 3262, 3494, 3182, 2884, + 3081, 3340, 3015, 2465, 2546, 3166, 3465, 3191, + 2875, 2836, 2831, 2605, 2347, 2539, 3295, 3937, + 3765, 3197, 3214, 3747, 3836, 3319, 3028, 3351, + 3799, 3942, 3782, 3381, 2828, 2390, 2345, 2780, + 3431, 3666, 3188, 2747, 3186, 3917, 3676, 2669, + 2404, 3379, 4095, 4095, 3542, 2912, 2971, 3195, + 2856, 2177, 2097, 2766, 3226, 2929, 2452, 2338, + 2369, 2329, 2435, 2739, 2953, 2972, 2976, 3055, + 3070, 2820, 2318, 1989, 2255, 2794, 2819, 2258, + 1859, 1983, 2135, 1924, 1650, 1723, 2062, 2302, + 2263, 2109, 2092, 2194, 2176, 2011, 1965, 2133, + 2271, 2208, 2073, 2013, 2010, 2007, 2008, 2025, + 2048, 2062, 2073, 2093, 2113, 2126, 2178, 2283, + 2302, 2132, 1953, 2000, 2163, 2178, 2096, 2181, + 2443, 2593, 2437, 2158, 2152, 2515, 2813, 2693, + 2533, 2857, 3355, 3288, 2694, 2318, 2490, 2851, + 3034, 3022, 2962, 2951, 2919, 2748, 2575, 2643, + 2816, 2840, 2969, 3484, 3859, 3453, 2747, 2699, + 3236, 3489, 3234, 3128, 3642, 4095, 4095, 3247, + 2351, 2675, 3676, 3893, 3199, 2870, 3422, 3924, + 3615, 2867, 2387, 2435, 2850, 3295, 3533, 3569, + 3399, 2991, 2695, 2959, 3443, 3394, 2993, 3131, + 3787, 3963, 3300, 2558, 2412, 2676, 2811, 2651, + 2532, 2756, 2984, 2622, 1895, 1703, 2209, 2582, + 2419, 2303, 2653, 3027, 2911, 2454, 2158, 2257, + 2522, 2573, 2384, 2295, 2416, 2406, 2088, 1777, + 1737, 1830, 1894, 1984, 2097, 2096, 1974, 1898, 1956, 2060, 2088, 2032, 2001, 2056, 2110, 2082 }, { - 2048, 1781, 1533, 1328, 1188, 1124, 1143, 1240, - 1403, 1614, 1851, 2091, 2309, 2484, 2597, 2633, - 2583, 2447, 2234, 1964, 1663, 1365, 1105, 912, - 811, 812, 918, 1116, 1384, 1696, 2022, 2334, - 2610, 2832, 2990, 3078, 3096, 3046, 2937, 2779, - 2588, 2381, 2175, 1988, 1831, 1709, 1621, 1557, - 1503, 1443, 1361, 1248, 1094, 899, 665, 395, - 95, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 166, 384, 583, 766, - 938, 1107, 1283, 1476, 1697, 1953, 2250, 2587, - 2956, 3344, 3735, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 3719, 3312, 2947, 2640, 2399, 2226, 2113, - 2048, 2012, 1986, 1950, 1884, 1773, 1608, 1389, - 1126, 836, 546, 284, 83, 0, 0, 59, - 274, 587, 976, 1413, 1868, 2312, 2719, 3070, - 3346, 3538, 3638, 3645, 3564, 3409, 3198, 2956, - 2709, 2483, 2299, 2168, 2094, 2069, 2080, 2107, - 2131, 2132, 2096, 2015, 1884, 1704, 1477, 1212, - 917, 605, 291, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 195, 562, 935, 1298, 1639, 1951, 2228, 2469, - 2677, 2855, 3015, 3168, 3329, 3511, 3729, 3991, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 3769, 3464, 3233, 3077, 2987, 2951, + 2048, 1781, 1533, 1328, 1188, 1124, 1143, 1240, + 1403, 1614, 1851, 2091, 2309, 2484, 2597, 2633, + 2583, 2447, 2234, 1964, 1663, 1365, 1105, 912, + 811, 812, 918, 1116, 1384, 1696, 2022, 2334, + 2610, 2832, 2990, 3078, 3096, 3046, 2937, 2779, + 2588, 2381, 2175, 1988, 1831, 1709, 1621, 1557, + 1503, 1443, 1361, 1248, 1094, 899, 665, 395, + 95, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 166, 384, 583, 766, + 938, 1107, 1283, 1476, 1697, 1953, 2250, 2587, + 2956, 3344, 3735, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 3719, 3312, 2947, 2640, 2399, 2226, 2113, + 2048, 2012, 1986, 1950, 1884, 1773, 1608, 1389, + 1126, 836, 546, 284, 83, 0, 0, 59, + 274, 587, 976, 1413, 1868, 2312, 2719, 3070, + 3346, 3538, 3638, 3645, 3564, 3409, 3198, 2956, + 2709, 2483, 2299, 2168, 2094, 2069, 2080, 2107, + 2131, 2132, 2096, 2015, 1884, 1704, 1477, 1212, + 917, 605, 291, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 195, 562, 935, 1298, 1639, 1951, 2228, 2469, + 2677, 2855, 3015, 3168, 3329, 3511, 3729, 3991, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 3769, 3464, 3233, 3077, 2987, 2951, 2950, 2961, 2963, 2934, 2858, 2727, 2540, 2308 }, { - 2048, 1952, 1949, 1768, 1386, 1123, 1378, 2211, - 3175, 3594, 3098, 1985, 1073, 1108, 2177, 3602, - 4095, 4052, 2791, 1493, 964, 1374, 2192, 2654, - 2372, 1590, 934, 876, 1388, 2030, 2357, 2278, - 2048, 1963, 2047, 2045, 1726, 1193, 892, 1244, - 2221, 3244, 3550, 2777, 1292, 0, 0, 118, - 983, 1287, 636, 0, 0, 0, 0, 779, - 1546, 1488, 916, 452, 518, 1050, 1650, 1981, - 2048, 2115, 2382, 2741, 2875, 2608, 2181, 2155, - 2966, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 3621, 2562, 2500, 3327, - 4095, 4095, 4095, 3627, 2872, 2516, 2453, 2357, - 2048, 1668, 1511, 1672, 1890, 1743, 1060, 167, - 0, 121, 1263, 2408, 2778, 2135, 981, 181, - 286, 1100, 1823, 1683, 543, 0, 0, 0, - 0, 565, 1406, 1588, 1422, 1356, 1574, 1898, - 2048, 1971, 1925, 2214, 2846, 3444, 3531, 2971, - 2159, 1763, 2181, 3173, 3984, 3916, 2897, 1582, - 883, 1282, 2447, 3481, 3584, 2644, 1282, 365, - 373, 1108, 1940, 2337, 2229, 1947, 1840, 1956, - 2048, 1886, 1553, 1420, 1810, 2663, 3513, 3854, - 3587, 3151, 3191, 3999, 4095, 4095, 4095, 4095, - 3032, 2330, 2796, 4021, 4095, 4095, 4095, 3178, - 2396, 2381, 2873, 3295, 3253, 2807, 2325, 2091, - 2048, 1899, 1453, 865, 538, 744, 1328, 1772, - 1624, 918, 212, 166, 965, 2085, 2614, 1931, - 204, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 808, 1588, 1863, 1805, 1795, - 2048, 2419, 2597, 2452, 2221, 2322, 2954, 3842, - 4095, 4095, 3540, 2958, 3201, 4095, 4095, 4095, - 4095, 4095, 3278, 2418, 2608, 3384, 3934, 3743, + 2048, 1952, 1949, 1768, 1386, 1123, 1378, 2211, + 3175, 3594, 3098, 1985, 1073, 1108, 2177, 3602, + 4095, 4052, 2791, 1493, 964, 1374, 2192, 2654, + 2372, 1590, 934, 876, 1388, 2030, 2357, 2278, + 2048, 1963, 2047, 2045, 1726, 1193, 892, 1244, + 2221, 3244, 3550, 2777, 1292, 0, 0, 118, + 983, 1287, 636, 0, 0, 0, 0, 779, + 1546, 1488, 916, 452, 518, 1050, 1650, 1981, + 2048, 2115, 2382, 2741, 2875, 2608, 2181, 2155, + 2966, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 3621, 2562, 2500, 3327, + 4095, 4095, 4095, 3627, 2872, 2516, 2453, 2357, + 2048, 1668, 1511, 1672, 1890, 1743, 1060, 167, + 0, 121, 1263, 2408, 2778, 2135, 981, 181, + 286, 1100, 1823, 1683, 543, 0, 0, 0, + 0, 565, 1406, 1588, 1422, 1356, 1574, 1898, + 2048, 1971, 1925, 2214, 2846, 3444, 3531, 2971, + 2159, 1763, 2181, 3173, 3984, 3916, 2897, 1582, + 883, 1282, 2447, 3481, 3584, 2644, 1282, 365, + 373, 1108, 1940, 2337, 2229, 1947, 1840, 1956, + 2048, 1886, 1553, 1420, 1810, 2663, 3513, 3854, + 3587, 3151, 3191, 3999, 4095, 4095, 4095, 4095, + 3032, 2330, 2796, 4021, 4095, 4095, 4095, 3178, + 2396, 2381, 2873, 3295, 3253, 2807, 2325, 2091, + 2048, 1899, 1453, 865, 538, 744, 1328, 1772, + 1624, 918, 212, 166, 965, 2085, 2614, 1931, + 204, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 808, 1588, 1863, 1805, 1795, + 2048, 2419, 2597, 2452, 2221, 2322, 2954, 3842, + 4095, 4095, 3540, 2958, 3201, 4095, 4095, 4095, + 4095, 4095, 3278, 2418, 2608, 3384, 3934, 3743, 2950, 2165, 1934, 2315, 2887, 3143, 2906, 2416 }, { - 2048, 2249, 2630, 3002, 3260, 3501, 3941, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4049, 4012, 4008, 3770, 3277, 2720, 2299, - 2048, 1828, 1484, 998, 506, 139, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 970, 2325, 2665, 2012, 1093, - 817, 1633, 3210, 4095, 4095, 4095, 3150, 1878, - 1285, 1384, 1706, 1717, 1236, 549, 159, 400, - 1194, 2129, 2764, 2912, 2708, 2426, 2253, 2169, - 2048, 1826, 1593, 1502, 1589, 1683, 1506, 908, - 47, 0, 0, 0, 0, 102, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 276, 753, 1285, 1720, - 2048, 2395, 2870, 3414, 3810, 3864, 3601, 3308, - 3340, 3843, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 3704, 3989, 4095, - 4095, 4095, 4095, 4051, 2637, 2334, 3235, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 3282, 2286, 2136, 2589, 3105, 3255, + 2048, 2249, 2630, 3002, 3260, 3501, 3941, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4049, 4012, 4008, 3770, 3277, 2720, 2299, + 2048, 1828, 1484, 998, 506, 139, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 970, 2325, 2665, 2012, 1093, + 817, 1633, 3210, 4095, 4095, 4095, 3150, 1878, + 1285, 1384, 1706, 1717, 1236, 549, 159, 400, + 1194, 2129, 2764, 2912, 2708, 2426, 2253, 2169, + 2048, 1826, 1593, 1502, 1589, 1683, 1506, 908, + 47, 0, 0, 0, 0, 102, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 276, 753, 1285, 1720, + 2048, 2395, 2870, 3414, 3810, 3864, 3601, 3308, + 3340, 3843, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 3704, 3989, 4095, + 4095, 4095, 4095, 4051, 2637, 2334, 3235, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 3282, 2286, 2136, 2589, 3105, 3255, 2981, 2548, 2276, 2280, 2418, 2463, 2320, 2109 }, { - 2048, 1981, 2022, 2010, 1837, 1586, 1497, 1768, - 2349, 2925, 3133, 2858, 2376, 2189, 2660, 3701, - 4095, 4095, 4095, 3995, 3304, 3429, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 3832, 3750, 3782, 3652, 3274, 2774, 2342, - 2048, 1790, 1424, 922, 427, 127, 60, 23, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 24, 0, 0, 0, - 0, 0, 22, 745, 854, 467, 36, 0, - 431, 1118, 1677, 1894, 1833, 1725, 1753, 1908, - 2048, 2060, 1990, 1997, 2183, 2459, 2576, 2336, - 1788, 1254, 1108, 1472, 2077, 2413, 2102, 1214, - 260, 0, 244, 1107, 1727, 1510, 430, 0, - 0, 0, 0, 788, 1040, 227, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 40, 66, 241, 660, 1203, 1688, - 2048, 2376, 2811, 3365, 3880, 4095, 4095, 4066, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 3805, 3597, 3930, 4095, 4095, + 2048, 1981, 2022, 2010, 1837, 1586, 1497, 1768, + 2349, 2925, 3133, 2858, 2376, 2189, 2660, 3701, + 4095, 4095, 4095, 3995, 3304, 3429, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 3832, 3750, 3782, 3652, 3274, 2774, 2342, + 2048, 1790, 1424, 922, 427, 127, 60, 23, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 0, 0, 0, + 0, 0, 22, 745, 854, 467, 36, 0, + 431, 1118, 1677, 1894, 1833, 1725, 1753, 1908, + 2048, 2060, 1990, 1997, 2183, 2459, 2576, 2336, + 1788, 1254, 1108, 1472, 2077, 2413, 2102, 1214, + 260, 0, 244, 1107, 1727, 1510, 430, 0, + 0, 0, 0, 788, 1040, 227, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 40, 66, 241, 660, 1203, 1688, + 2048, 2376, 2811, 3365, 3880, 4095, 4095, 4066, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 3805, 3597, 3930, 4095, 4095, 4026, 3378, 2835, 2600, 2608, 2634, 2512, 2264 }, { - 2048, 1979, 2009, 1964, 1767, 1541, 1505, 1758, - 2132, 2275, 1927, 1182, 498, 415, 1153, 2399, - 3472, 3777, 3230, 2333, 1819, 2110, 2990, 3747, - 3706, 2764, 1532, 945, 1611, 3353, 4095, 4095, - 4095, 4095, 3789, 3389, 3945, 4095, 4095, 4095, - 3758, 2753, 2668, 3694, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4055, 3294, - 2817, 2815, 3125, 3395, 3363, 3026, 2587, 2249, - 2048, 1864, 1579, 1221, 950, 892, 965, 883, - 359, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, - 0, 0, 272, 531, 159, 0, 0, 0, - 112, 1003, 1620, 1819, 1749, 1675, 1747, 1917, - 2048, 2087, 2137, 2350, 2744, 3124, 3204, 2846, - 2219, 1720, 1692, 2143, 2708, 2905, 2525, 1832, - 1408, 1721, 2721, 3800, 4095, 3433, 1879, 361, - 0, 227, 1372, 2263, 2247, 1378, 370, 51, - 733, 1941, 2725, 2320, 702, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 265, 688, 265, 0, 0, 0, 0, 0, - 349, 696, 720, 703, 872, 1233, 1620, 1885, - 2048, 2262, 2651, 3160, 3571, 3694, 3553, 3408, - 3559, 4089, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 3630, 3510, 3867, 4095, 4095, + 2048, 1979, 2009, 1964, 1767, 1541, 1505, 1758, + 2132, 2275, 1927, 1182, 498, 415, 1153, 2399, + 3472, 3777, 3230, 2333, 1819, 2110, 2990, 3747, + 3706, 2764, 1532, 945, 1611, 3353, 4095, 4095, + 4095, 4095, 3789, 3389, 3945, 4095, 4095, 4095, + 3758, 2753, 2668, 3694, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4055, 3294, + 2817, 2815, 3125, 3395, 3363, 3026, 2587, 2249, + 2048, 1864, 1579, 1221, 950, 892, 965, 883, + 359, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 25, 0, 0, 0, + 0, 0, 272, 531, 159, 0, 0, 0, + 112, 1003, 1620, 1819, 1749, 1675, 1747, 1917, + 2048, 2087, 2137, 2350, 2744, 3124, 3204, 2846, + 2219, 1720, 1692, 2143, 2708, 2905, 2525, 1832, + 1408, 1721, 2721, 3800, 4095, 3433, 1879, 361, + 0, 227, 1372, 2263, 2247, 1378, 370, 51, + 733, 1941, 2725, 2320, 702, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 265, 688, 265, 0, 0, 0, 0, 0, + 349, 696, 720, 703, 872, 1233, 1620, 1885, + 2048, 2262, 2651, 3160, 3571, 3694, 3553, 3408, + 3559, 4089, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 3630, 3510, 3867, 4095, 4095, 3651, 3107, 2795, 2789, 2907, 2897, 2658, 2307 }, { - 2048, 1872, 1766, 1689, 1616, 1562, 1560, 1621, - 1701, 1715, 1605, 1390, 1179, 1103, 1224, 1486, - 1746, 1869, 1832, 1740, 1752, 1968, 2344, 2724, - 2953, 2991, 2957, 3045, 3380, 3923, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4063, - 3723, 3511, 3391, 3280, 3110, 2869, 2590, 2314, - 2048, 1762, 1431, 1059, 683, 332, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 50, 538, 940, 1218, 1401, 1552, 1714, 1886, - 2048, 2191, 2340, 2527, 2752, 2966, 3097, 3104, - 3013, 2909, 2869, 2903, 2942, 2891, 2712, 2471, - 2305, 2325, 2529, 2785, 2913, 2805, 2509, 2198, - 2051, 2125, 2315, 2419, 2288, 1922, 1470, 1113, - 925, 814, 584, 80, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 138, 382, 682, 1035, 1400, 1738, - 2048, 2359, 2699, 3058, 3393, 3664, 3881, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 2048, 1872, 1766, 1689, 1616, 1562, 1560, 1621, + 1701, 1715, 1605, 1390, 1179, 1103, 1224, 1486, + 1746, 1869, 1832, 1740, 1752, 1968, 2344, 2724, + 2953, 2991, 2957, 3045, 3380, 3923, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4063, + 3723, 3511, 3391, 3280, 3110, 2869, 2590, 2314, + 2048, 1762, 1431, 1059, 683, 332, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 50, 538, 940, 1218, 1401, 1552, 1714, 1886, + 2048, 2191, 2340, 2527, 2752, 2966, 3097, 3104, + 3013, 2909, 2869, 2903, 2942, 2891, 2712, 2471, + 2305, 2325, 2529, 2785, 2913, 2805, 2509, 2198, + 2051, 2125, 2315, 2419, 2288, 1922, 1470, 1113, + 925, 814, 584, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 138, 382, 682, 1035, 1400, 1738, + 2048, 2359, 2699, 3058, 3393, 3664, 3881, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4019, 3703, 3441, 3199, 2929, 2620, 2307 }, { - 2048, 2324, 2624, 2954, 3284, 3568, 3796, 4005, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 3881, 3732, - 3693, 3578, 3283, 2863, 2500, 2370, 2510, 2788, - 2985, 2945, 2673, 2325, 2089, 2063, 2189, 2312, - 2292, 2097, 1816, 1580, 1463, 1441, 1421, 1321, - 1138, 950, 855, 909, 1092, 1337, 1585, 1816, - 2048, 2293, 2541, 2762, 2946, 3128, 3378, 3746, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4031, 3757, 3452, 3099, 2725, 2371, - 2048, 1733, 1398, 1043, 710, 449, 268, 119, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 62, 277, 623, 1009, 1254, 1223, 941, - 599, 434, 584, 993, 1456, 1759, 1818, 1730, - 1683, 1824, 2153, 2532, 2794, 2860, 2799, 2761, - 2873, 3137, 3439, 3623, 3604, 3411, 3161, 2970, - 2880, 2853, 2815, 2720, 2581, 2438, 2318, 2203, - 2048, 1821, 1537, 1244, 981, 748, 506, 225, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 2048, 2324, 2624, 2954, 3284, 3568, 3796, 4005, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 3881, 3732, + 3693, 3578, 3283, 2863, 2500, 2370, 2510, 2788, + 2985, 2945, 2673, 2325, 2089, 2063, 2189, 2312, + 2292, 2097, 1816, 1580, 1463, 1441, 1421, 1321, + 1138, 950, 855, 909, 1092, 1337, 1585, 1816, + 2048, 2293, 2541, 2762, 2946, 3128, 3378, 3746, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4031, 3757, 3452, 3099, 2725, 2371, + 2048, 1733, 1398, 1043, 710, 449, 268, 119, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 62, 277, 623, 1009, 1254, 1223, 941, + 599, 434, 584, 993, 1456, 1759, 1818, 1730, + 1683, 1824, 2153, 2532, 2794, 2860, 2799, 2761, + 2873, 3137, 3439, 3623, 3604, 3411, 3161, 2970, + 2880, 2853, 2815, 2720, 2581, 2438, 2318, 2203, + 2048, 1821, 1537, 1244, 981, 748, 506, 225, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 359, 569, 812, 1113, 1444, 1762 }, { - 2048, 2136, 2184, 2258, 2362, 2450, 2495, 2543, - 2698, 3031, 3494, 3907, 4050, 3808, 3252, 2597, - 2059, 1711, 1452, 1102, 565, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 427, - 900, 1324, 1741, 2214, 2763, 3334, 3848, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 3382, 2375, 1392, 392, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 195, 503, 850, 1247, 1656, - 2048, 2448, 2907, 3435, 3967, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 3718, 2480, 1360, - 481, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 806, 1558, 2292, 3019, 3707, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4046, 3131, 2308, 1533, 749, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 2048, 2136, 2184, 2258, 2362, 2450, 2495, 2543, + 2698, 3031, 3494, 3907, 4050, 3808, 3252, 2597, + 2059, 1711, 1452, 1102, 565, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 427, + 900, 1324, 1741, 2214, 2763, 3334, 3848, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 3382, 2375, 1392, 392, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 195, 503, 850, 1247, 1656, + 2048, 2448, 2907, 3435, 3967, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 3718, 2480, 1360, + 481, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 806, 1558, 2292, 3019, 3707, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4046, 3131, 2308, 1533, 749, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 551, 1028, 1482, 1838 }, { - 2048, 1652, 1202, 705, 224, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1214, 2449, 3595, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 3911, 3359, 2788, 2223, 1730, 1342, - 1019, 683, 285, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 236, 1269, 2189, 2856, 3287, - 3595, 3868, 4095, 4095, 4063, 3715, 3216, 2650, - 2048, 1375, 591, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 386, 1403, 2358, 3256, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 3807, 3002, 2267, 1658, 1199, - 849, 542, 257, 54, 38, 267, 673, 1087, - 1334, 1350, 1222, 1104, 1090, 1126, 1049, 726, - 188, 0, 0, 0, 282, 1093, 1794, 2245, - 2504, 2743, 3095, 3544, 3939, 4095, 4046, 3813, + 2048, 1652, 1202, 705, 224, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1214, 2449, 3595, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 3911, 3359, 2788, 2223, 1730, 1342, + 1019, 683, 285, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 236, 1269, 2189, 2856, 3287, + 3595, 3868, 4095, 4095, 4063, 3715, 3216, 2650, + 2048, 1375, 591, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 386, 1403, 2358, 3256, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 3807, 3002, 2267, 1658, 1199, + 849, 542, 257, 54, 38, 267, 673, 1087, + 1334, 1350, 1222, 1104, 1090, 1126, 1049, 726, + 188, 0, 0, 0, 282, 1093, 1794, 2245, + 2504, 2743, 3095, 3544, 3939, 4095, 4046, 3813, 3592, 3498, 3518, 3536, 3436, 3179, 2817, 2428 }, { - 2048, 824, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 661, 1505, 2315, 3100, 3819, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 3826, 3648, - 3469, 3194, 2815, 2426, 2146, 2043, 2107, 2294, - 2591, 3033, 3661, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 3630, 2887, - 2048, 1109, 133, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 354, 1368, 2393, 3450, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3514, - 3057, 2966, 3065, 3137, 3087, 2988, 3006, 3240, - 3624, 3948, 4002, 3708, 3173, 2605, 2182, 1954, - 1859, 1803, 1751, 1735, 1808, 1977, 2194, 2399, - 2590, 2832, 3206, 3724, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 2048, 824, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 661, 1505, 2315, 3100, 3819, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 3826, 3648, + 3469, 3194, 2815, 2426, 2146, 2043, 2107, 2294, + 2591, 3033, 3661, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 3630, 2887, + 2048, 1109, 133, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 354, 1368, 2393, 3450, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3514, + 3057, 2966, 3065, 3137, 3087, 2988, 3006, 3240, + 3624, 3948, 4002, 3708, 3173, 2605, 2182, 1954, + 1859, 1803, 1751, 1735, 1808, 1977, 2194, 2399, + 2590, 2832, 3206, 3724, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3196 }, { - 2048, 1477, 923, 367, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 223, 940, 1648, 2184, 2491, 2611, - 2612, 2516, 2290, 1898, 1357, 736, 105, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 774, 1727, 2702, 3715, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4050, 2990, - 2048, 1224, 481, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 174, 807, - 1142, 1166, 1034, 944, 978, 1044, 964, 629, - 117, 0, 0, 0, 571, 1314, 1898, 2238, - 2420, 2586, 2817, 3071, 3233, 3221, 3048, 2808, - 2590, 2413, 2220, 1944, 1572, 1160, 775, 428, - 63, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 442, 1643, 2875, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, - 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 2048, 1477, 923, 367, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 223, 940, 1648, 2184, 2491, 2611, + 2612, 2516, 2290, 1898, 1357, 736, 105, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 774, 1727, 2702, 3715, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4050, 2990, + 2048, 1224, 481, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 174, 807, + 1142, 1166, 1034, 944, 978, 1044, 964, 629, + 117, 0, 0, 0, 571, 1314, 1898, 2238, + 2420, 2586, 2817, 3071, 3233, 3221, 3048, 2808, + 2590, 2413, 2220, 1944, 1572, 1160, 775, 428, + 63, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 442, 1643, 2875, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, + 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3458, 2696 }, { - 1987, 2084, 2164, 2206, 2261, 2413, 2694, 3034, - 3296, 3367, 3248, 3051, 2909, 2853, 2781, 2527, - 2008, 1320, 710, 426, 552, 949, 1342, 1506, - 1401, 1175, 1033, 1084, 1263, 1404, 1385, 1232, - 1112, 1214, 1614, 2226, 2867, 3375, 3694, 3867, - 3964, 4006, 3959, 3788, 3507, 3183, 2884, 2610, - 2289, 1846, 1285, 729, 350, 262, 431, 704, - 918, 1027, 1128, 1368, 1808, 2329, 2693, 2698, - 2326, 1780, 1359, 1274, 1522, 1915, 2227, 2346, - 2336, 2355, 2510, 2771, 2994, 3032, 2852, 2551, - 2286, 2163, 2180, 2259, 2327, 2370, 2421, 2501, - 2577, 2576, 2454, 2250, 2071, 2006, 2043, 2054, - 1878, 1451, 867, 332, 27, 0, 107, 208, - 231, 284, 575, 1246, 2243, 3308, 4095, 4095, - 4095, 4095, 4032, 3954, 3931, 3821, 3535, 3119, - 2706, 2412, 2246, 2115, 1902, 1565, 1157, 778, - 494, 300, 155, 42, 6, 113, 382, 742, - 1067, 1277, 1411, 1619, 2051, 2729, 3500, 4095, - 4095, 4095, 4046, 3783, 3614, 3452, 3122, 2520, - 1730, 1003, 607, 659, 1051, 1532, 1869, 1985, - 1967, 1963, 2057, 2209, 2308, 2272, 2117, 1938, - 1825, 1796, 1793, 1750, 1652, 1552, 1515, 1550, - 1597, 1579, 1488, 1407, 1460, 1699, 2044, 2314, - 2354, 2157, 1892, 1802, 2033, 2537, 3104, 3508, - 3666, 3670, 3698, 3846, 4036, 4048, 3685, 2913, - 1911, 960, 286, 0, 0, 0, 0, 0, - 0, 147, 539, 957, 1333, 1674, 2033, 2442, - 2863, 3202, 3389, 3436, 3433, 3474, 3572, 3638, - 3555, 3291, 2949, 2712, 2705, 2888, 3052, 2955, - 2488, 1760, 1030, 544, 377, 414, 461, 408, - 315, 362, 697, 1307, 2009, 2557, 2796, 2743, + 1987, 2084, 2164, 2206, 2261, 2413, 2694, 3034, + 3296, 3367, 3248, 3051, 2909, 2853, 2781, 2527, + 2008, 1320, 710, 426, 552, 949, 1342, 1506, + 1401, 1175, 1033, 1084, 1263, 1404, 1385, 1232, + 1112, 1214, 1614, 2226, 2867, 3375, 3694, 3867, + 3964, 4006, 3959, 3788, 3507, 3183, 2884, 2610, + 2289, 1846, 1285, 729, 350, 262, 431, 704, + 918, 1027, 1128, 1368, 1808, 2329, 2693, 2698, + 2326, 1780, 1359, 1274, 1522, 1915, 2227, 2346, + 2336, 2355, 2510, 2771, 2994, 3032, 2852, 2551, + 2286, 2163, 2180, 2259, 2327, 2370, 2421, 2501, + 2577, 2576, 2454, 2250, 2071, 2006, 2043, 2054, + 1878, 1451, 867, 332, 27, 0, 107, 208, + 231, 284, 575, 1246, 2243, 3308, 4095, 4095, + 4095, 4095, 4032, 3954, 3931, 3821, 3535, 3119, + 2706, 2412, 2246, 2115, 1902, 1565, 1157, 778, + 494, 300, 155, 42, 6, 113, 382, 742, + 1067, 1277, 1411, 1619, 2051, 2729, 3500, 4095, + 4095, 4095, 4046, 3783, 3614, 3452, 3122, 2520, + 1730, 1003, 607, 659, 1051, 1532, 1869, 1985, + 1967, 1963, 2057, 2209, 2308, 2272, 2117, 1938, + 1825, 1796, 1793, 1750, 1652, 1552, 1515, 1550, + 1597, 1579, 1488, 1407, 1460, 1699, 2044, 2314, + 2354, 2157, 1892, 1802, 2033, 2537, 3104, 3508, + 3666, 3670, 3698, 3846, 4036, 4048, 3685, 2913, + 1911, 960, 286, 0, 0, 0, 0, 0, + 0, 147, 539, 957, 1333, 1674, 2033, 2442, + 2863, 3202, 3389, 3436, 3433, 3474, 3572, 3638, + 3555, 3291, 2949, 2712, 2705, 2888, 3052, 2955, + 2488, 1760, 1030, 544, 377, 414, 461, 408, + 315, 362, 697, 1307, 2009, 2557, 2796, 2743, 2546, 2367, 2278, 2242, 2188, 2087, 1981, 1939 }, { - 1039, 1027, 1033, 1037, 1091, 1279, 1630, 2072, - 2464, 2687, 2739, 2725, 2771, 2905, 3017, 2936, - 2574, 2024, 1528, 1331, 1517, 1944, 2340, 2478, - 2320, 2016, 1776, 1709, 1757, 1756, 1587, 1283, - 1014, 971, 1234, 1723, 2254, 2669, 2915, 3034, - 3099, 3131, 3097, 2959, 2732, 2482, 2273, 2105, - 1904, 1591, 1168, 753, 518, 570, 873, 1271, - 1597, 1802, 1979, 2275, 2746, 3274, 3619, 3578, - 3135, 2494, 1955, 1731, 1825, 2052, 2188, 2131, - 1946, 1798, 1799, 1925, 2035, 1988, 1752, 1429, - 1176, 1099, 1197, 1389, 1600, 1810, 2049, 2332, - 2619, 2831, 2916, 2907, 2904, 2991, 3150, 3247, - 3121, 2703, 2088, 1482, 1069, 890, 832, 736, - 544, 371, 432, 878, 1662, 2532, 3179, 3416, - 3281, 2985, 2759, 2699, 2735, 2721, 2567, 2313, - 2086, 1997, 2048, 2137, 2143, 2013, 1796, 1585, - 1442, 1357, 1286, 1211, 1176, 1247, 1446, 1704, - 1900, 1956, 1920, 1945, 2188, 2677, 3264, 3709, - 3827, 3613, 3229, 2878, 2649, 2456, 2125, 1549, - 811, 162, 0, 34, 558, 1180, 1666, 1933, - 2065, 2206, 2436, 2712, 2921, 2977, 2896, 2770, - 2689, 2670, 2656, 2579, 2427, 2254, 2126, 2054, - 1981, 1834, 1605, 1382, 1292, 1391, 1602, 1747, - 1675, 1382, 1041, 895, 1094, 1592, 2178, 2628, - 2857, 2957, 3102, 3389, 3733, 3912, 3723, 3129, - 2301, 1517, 997, 790, 788, 838, 859, 880, - 983, 1211, 1522, 1827, 2061, 2234, 2405, 2611, - 2821, 2948, 2928, 2779, 2599, 2489, 2466, 2445, - 2313, 2039, 1728, 1562, 1664, 1990, 2326, 2427, - 2176, 1673, 1173, 911, 958, 1189, 1406, 1491, - 1501, 1612, 1969, 2562, 3205, 3657, 3764, 3549, + 1039, 1027, 1033, 1037, 1091, 1279, 1630, 2072, + 2464, 2687, 2739, 2725, 2771, 2905, 3017, 2936, + 2574, 2024, 1528, 1331, 1517, 1944, 2340, 2478, + 2320, 2016, 1776, 1709, 1757, 1756, 1587, 1283, + 1014, 971, 1234, 1723, 2254, 2669, 2915, 3034, + 3099, 3131, 3097, 2959, 2732, 2482, 2273, 2105, + 1904, 1591, 1168, 753, 518, 570, 873, 1271, + 1597, 1802, 1979, 2275, 2746, 3274, 3619, 3578, + 3135, 2494, 1955, 1731, 1825, 2052, 2188, 2131, + 1946, 1798, 1799, 1925, 2035, 1988, 1752, 1429, + 1176, 1099, 1197, 1389, 1600, 1810, 2049, 2332, + 2619, 2831, 2916, 2907, 2904, 2991, 3150, 3247, + 3121, 2703, 2088, 1482, 1069, 890, 832, 736, + 544, 371, 432, 878, 1662, 2532, 3179, 3416, + 3281, 2985, 2759, 2699, 2735, 2721, 2567, 2313, + 2086, 1997, 2048, 2137, 2143, 2013, 1796, 1585, + 1442, 1357, 1286, 1211, 1176, 1247, 1446, 1704, + 1900, 1956, 1920, 1945, 2188, 2677, 3264, 3709, + 3827, 3613, 3229, 2878, 2649, 2456, 2125, 1549, + 811, 162, 0, 34, 558, 1180, 1666, 1933, + 2065, 2206, 2436, 2712, 2921, 2977, 2896, 2770, + 2689, 2670, 2656, 2579, 2427, 2254, 2126, 2054, + 1981, 1834, 1605, 1382, 1292, 1391, 1602, 1747, + 1675, 1382, 1041, 895, 1094, 1592, 2178, 2628, + 2857, 2957, 3102, 3389, 3733, 3912, 3723, 3129, + 2301, 1517, 997, 790, 788, 838, 859, 880, + 983, 1211, 1522, 1827, 2061, 2234, 2405, 2611, + 2821, 2948, 2928, 2779, 2599, 2489, 2466, 2445, + 2313, 2039, 1728, 1562, 1664, 1990, 2326, 2427, + 2176, 1673, 1173, 911, 958, 1189, 1406, 1491, + 1501, 1612, 1969, 2562, 3205, 3657, 3764, 3549, 3166, 2782, 2476, 2220, 1948, 1639, 1342, 1132 }, { - 1698, 1773, 1820, 1816, 1815, 1903, 2116, 2392, - 2597, 2628, 2490, 2304, 2205, 2228, 2272, 2169, - 1833, 1355, 971, 922, 1281, 1894, 2479, 2798, - 2801, 2627, 2480, 2462, 2511, 2466, 2208, 1776, - 1348, 1125, 1199, 1500, 1857, 2122, 2250, 2295, - 2330, 2380, 2410, 2380, 2296, 2217, 2198, 2224, - 2211, 2068, 1786, 1475, 1299, 1363, 1630, 1944, - 2144, 2189, 2181, 2278, 2549, 2887, 3065, 2889, - 2353, 1666, 1131, 962, 1157, 1527, 1841, 1982, - 2007, 2066, 2260, 2552, 2792, 2830, 2629, 2287, - 1964, 1769, 1707, 1708, 1706, 1696, 1719, 1805, - 1925, 2010, 2017, 1983, 2010, 2181, 2472, 2743, - 2823, 2630, 2245, 1862, 1651, 1641, 1709, 1686, - 1512, 1300, 1266, 1568, 2165, 2818, 3229, 3226, - 2861, 2359, 1962, 1777, 1742, 1715, 1608, 1457, - 1384, 1491, 1769, 2102, 2355, 2461, 2455, 2417, - 2397, 2382, 2320, 2194, 2048, 1959, 1955, 1980, - 1926, 1730, 1454, 1267, 1336, 1700, 2220, 2658, - 2831, 2730, 2511, 2367, 2375, 2435, 2358, 2023, - 1500, 1023, 850, 1085, 1613, 2178, 2549, 2649, - 2573, 2476, 2453, 2475, 2444, 2289, 2036, 1789, - 1645, 1623, 1668, 1707, 1722, 1757, 1865, 2044, - 2221, 2309, 2288, 2232, 2258, 2417, 2627, 2712, - 2523, 2064, 1519, 1141, 1095, 1348, 1705, 1955, - 2024, 2014, 2106, 2397, 2804, 3100, 3075, 2682, - 2080, 1535, 1250, 1262, 1450, 1650, 1772, 1839, - 1932, 2093, 2286, 2428, 2466, 2419, 2361, 2343, - 2345, 2295, 2138, 1899, 1684, 1592, 1641, 1740, - 1769, 1688, 1589, 1642, 1956, 2475, 2974, 3197, - 3021, 2542, 2014, 1673, 1595, 1665, 1693, 1573, - 1374, 1286, 1466, 1913, 2451, 2843, 2941, 2767, + 1698, 1773, 1820, 1816, 1815, 1903, 2116, 2392, + 2597, 2628, 2490, 2304, 2205, 2228, 2272, 2169, + 1833, 1355, 971, 922, 1281, 1894, 2479, 2798, + 2801, 2627, 2480, 2462, 2511, 2466, 2208, 1776, + 1348, 1125, 1199, 1500, 1857, 2122, 2250, 2295, + 2330, 2380, 2410, 2380, 2296, 2217, 2198, 2224, + 2211, 2068, 1786, 1475, 1299, 1363, 1630, 1944, + 2144, 2189, 2181, 2278, 2549, 2887, 3065, 2889, + 2353, 1666, 1131, 962, 1157, 1527, 1841, 1982, + 2007, 2066, 2260, 2552, 2792, 2830, 2629, 2287, + 1964, 1769, 1707, 1708, 1706, 1696, 1719, 1805, + 1925, 2010, 2017, 1983, 2010, 2181, 2472, 2743, + 2823, 2630, 2245, 1862, 1651, 1641, 1709, 1686, + 1512, 1300, 1266, 1568, 2165, 2818, 3229, 3226, + 2861, 2359, 1962, 1777, 1742, 1715, 1608, 1457, + 1384, 1491, 1769, 2102, 2355, 2461, 2455, 2417, + 2397, 2382, 2320, 2194, 2048, 1959, 1955, 1980, + 1926, 1730, 1454, 1267, 1336, 1700, 2220, 2658, + 2831, 2730, 2511, 2367, 2375, 2435, 2358, 2023, + 1500, 1023, 850, 1085, 1613, 2178, 2549, 2649, + 2573, 2476, 2453, 2475, 2444, 2289, 2036, 1789, + 1645, 1623, 1668, 1707, 1722, 1757, 1865, 2044, + 2221, 2309, 2288, 2232, 2258, 2417, 2627, 2712, + 2523, 2064, 1519, 1141, 1095, 1348, 1705, 1955, + 2024, 2014, 2106, 2397, 2804, 3100, 3075, 2682, + 2080, 1535, 1250, 1262, 1450, 1650, 1772, 1839, + 1932, 2093, 2286, 2428, 2466, 2419, 2361, 2343, + 2345, 2295, 2138, 1899, 1684, 1592, 1641, 1740, + 1769, 1688, 1589, 1642, 1956, 2475, 2974, 3197, + 3021, 2542, 2014, 1673, 1595, 1665, 1693, 1573, + 1374, 1286, 1466, 1913, 2451, 2843, 2941, 2767, 2472, 2218, 2076, 2006, 1933, 1822, 1711, 1662 }, { - 951, 1041, 1085, 1054, 1021, 1103, 1347, 1669, - 1899, 1910, 1721, 1488, 1376, 1423, 1500, 1419, - 1094, 642, 321, 349, 753, 1341, 1831, 2037, - 1960, 1750, 1562, 1452, 1366, 1237, 1069, 945, - 951, 1087, 1258, 1350, 1327, 1264, 1269, 1380, - 1513, 1528, 1361, 1099, 939, 1036, 1369, 1732, - 1872, 1675, 1249, 858, 734, 921, 1266, 1546, - 1625, 1531, 1394, 1318, 1305, 1277, 1174, 1031, - 951, 1020, 1222, 1444, 1575, 1591, 1567, 1596, - 1677, 1700, 1527, 1134, 670, 385, 457, 862, - 1374, 1722, 1768, 1592, 1406, 1385, 1534, 1707, - 1733, 1556, 1274, 1043, 960, 994, 1037, 1015, - 951, 937, 1038, 1229, 1416, 1527, 1581, 1669, - 1851, 2065, 2134, 1893, 1335, 659, 170, 85, - 396, 890, 1303, 1500, 1536, 1575, 1725, 1943, - 2073, 1978, 1660, 1262, 960, 843, 868, 927, - 951, 961, 1025, 1167, 1326, 1408, 1377, 1312, - 1354, 1580, 1907, 2126, 2039, 1619, 1047, 603, - 477, 654, 940, 1131, 1161, 1133, 1213, 1471, - 1812, 2042, 2014, 1735, 1354, 1049, 908, 902, - 951, 1013, 1113, 1284, 1493, 1630, 1585, 1354, - 1076, 946, 1074, 1384, 1664, 1714, 1501, 1184, - 992, 1051, 1290, 1503, 1517, 1324, 1085, 997, - 1139, 1416, 1637, 1659, 1485, 1235, 1041, 957, - 951, 979, 1052, 1225, 1522, 1860, 2071, 2010, - 1671, 1215, 870, 775, 884, 1023, 1040, 933, - 855, 983, 1356, 1820, 2126, 2104, 1784, 1371, - 1096, 1056, 1176, 1291, 1286, 1169, 1031, 957, - 951, 965, 974, 1026, 1205, 1538, 1928, 2188, - 2167, 1868, 1455, 1139, 1023, 1036, 1006, 822, - 548, 389, 540, 1025, 1653, 2139, 2287, 2105, + 951, 1041, 1085, 1054, 1021, 1103, 1347, 1669, + 1899, 1910, 1721, 1488, 1376, 1423, 1500, 1419, + 1094, 642, 321, 349, 753, 1341, 1831, 2037, + 1960, 1750, 1562, 1452, 1366, 1237, 1069, 945, + 951, 1087, 1258, 1350, 1327, 1264, 1269, 1380, + 1513, 1528, 1361, 1099, 939, 1036, 1369, 1732, + 1872, 1675, 1249, 858, 734, 921, 1266, 1546, + 1625, 1531, 1394, 1318, 1305, 1277, 1174, 1031, + 951, 1020, 1222, 1444, 1575, 1591, 1567, 1596, + 1677, 1700, 1527, 1134, 670, 385, 457, 862, + 1374, 1722, 1768, 1592, 1406, 1385, 1534, 1707, + 1733, 1556, 1274, 1043, 960, 994, 1037, 1015, + 951, 937, 1038, 1229, 1416, 1527, 1581, 1669, + 1851, 2065, 2134, 1893, 1335, 659, 170, 85, + 396, 890, 1303, 1500, 1536, 1575, 1725, 1943, + 2073, 1978, 1660, 1262, 960, 843, 868, 927, + 951, 961, 1025, 1167, 1326, 1408, 1377, 1312, + 1354, 1580, 1907, 2126, 2039, 1619, 1047, 603, + 477, 654, 940, 1131, 1161, 1133, 1213, 1471, + 1812, 2042, 2014, 1735, 1354, 1049, 908, 902, + 951, 1013, 1113, 1284, 1493, 1630, 1585, 1354, + 1076, 946, 1074, 1384, 1664, 1714, 1501, 1184, + 992, 1051, 1290, 1503, 1517, 1324, 1085, 997, + 1139, 1416, 1637, 1659, 1485, 1235, 1041, 957, + 951, 979, 1052, 1225, 1522, 1860, 2071, 2010, + 1671, 1215, 870, 775, 884, 1023, 1040, 933, + 855, 983, 1356, 1820, 2126, 2104, 1784, 1371, + 1096, 1056, 1176, 1291, 1286, 1169, 1031, 957, + 951, 965, 974, 1026, 1205, 1538, 1928, 2188, + 2167, 1868, 1455, 1139, 1023, 1036, 1006, 822, + 548, 389, 540, 1025, 1653, 2139, 2287, 2105, 1769, 1482, 1334, 1279, 1213, 1092, 962, 905 }, { - 1705, 1810, 1851, 1793, 1729, 1803, 2071, 2426, - 2667, 2650, 2412, 2142, 2026, 2092, 2194, 2142, - 1878, 1538, 1355, 1478, 1855, 2278, 2533, 2547, - 2396, 2204, 2035, 1868, 1680, 1526, 1535, 1796, - 2245, 2669, 2834, 2657, 2271, 1930, 1811, 1898, - 2008, 1966, 1754, 1523, 1462, 1641, 1955, 2217, - 2316, 2290, 2266, 2334, 2459, 2523, 2444, 2257, - 2078, 1988, 1947, 1828, 1555, 1212, 1025, 1198, - 1745, 2444, 2971, 3109, 2878, 2489, 2168, 2005, - 1934, 1849, 1722, 1631, 1671, 1844, 2041, 2131, - 2083, 1993, 1996, 2131, 2293, 2317, 2134, 1851, - 1684, 1783, 2103, 2422, 2511, 2311, 1976, 1746, - 1770, 1998, 2247, 2350, 2274, 2104, 1943, 1812, - 1670, 1504, 1397, 1492, 1864, 2416, 2903, 3085, - 2900, 2499, 2127, 1942, 1906, 1857, 1671, 1393, - 1204, 1277, 1622, 2075, 2421, 2546, 2502, 2421, - 2390, 2384, 2319, 2163, 1991, 1920, 1988, 2095, - 2069, 1827, 1472, 1246, 1355, 1799, 2359, 2743, - 2786, 2547, 2232, 2025, 1959, 1943, 1880, 1778, - 1740, 1857, 2100, 2330, 2406, 2306, 2136, 2031, - 2025, 2022, 1899, 1644, 1407, 1399, 1716, 2238, - 2693, 2843, 2653, 2299, 2026, 1965, 2060, 2150, - 2116, 1973, 1823, 1744, 1719, 1672, 1577, 1518, - 1634, 1988, 2472, 2859, 2956, 2749, 2409, 2151, - 2067, 2064, 1966, 1691, 1341, 1139, 1254, 1663, - 2166, 2528, 2639, 2553, 2401, 2267, 2141, 1983, - 1813, 1736, 1849, 2129, 2405, 2467, 2232, 1832, - 1528, 1525, 1816, 2191, 2399, 2335, 2094, 1881, - 1829, 1916, 2015, 2029, 1982, 1987, 2122, 2343, - 2512, 2511, 2349, 2146, 2017, 1964, 1877, 1655, - 1335, 1111, 1198, 1657, 2314, 2862, 3060, 2889, + 1705, 1810, 1851, 1793, 1729, 1803, 2071, 2426, + 2667, 2650, 2412, 2142, 2026, 2092, 2194, 2142, + 1878, 1538, 1355, 1478, 1855, 2278, 2533, 2547, + 2396, 2204, 2035, 1868, 1680, 1526, 1535, 1796, + 2245, 2669, 2834, 2657, 2271, 1930, 1811, 1898, + 2008, 1966, 1754, 1523, 1462, 1641, 1955, 2217, + 2316, 2290, 2266, 2334, 2459, 2523, 2444, 2257, + 2078, 1988, 1947, 1828, 1555, 1212, 1025, 1198, + 1745, 2444, 2971, 3109, 2878, 2489, 2168, 2005, + 1934, 1849, 1722, 1631, 1671, 1844, 2041, 2131, + 2083, 1993, 1996, 2131, 2293, 2317, 2134, 1851, + 1684, 1783, 2103, 2422, 2511, 2311, 1976, 1746, + 1770, 1998, 2247, 2350, 2274, 2104, 1943, 1812, + 1670, 1504, 1397, 1492, 1864, 2416, 2903, 3085, + 2900, 2499, 2127, 1942, 1906, 1857, 1671, 1393, + 1204, 1277, 1622, 2075, 2421, 2546, 2502, 2421, + 2390, 2384, 2319, 2163, 1991, 1920, 1988, 2095, + 2069, 1827, 1472, 1246, 1355, 1799, 2359, 2743, + 2786, 2547, 2232, 2025, 1959, 1943, 1880, 1778, + 1740, 1857, 2100, 2330, 2406, 2306, 2136, 2031, + 2025, 2022, 1899, 1644, 1407, 1399, 1716, 2238, + 2693, 2843, 2653, 2299, 2026, 1965, 2060, 2150, + 2116, 1973, 1823, 1744, 1719, 1672, 1577, 1518, + 1634, 1988, 2472, 2859, 2956, 2749, 2409, 2151, + 2067, 2064, 1966, 1691, 1341, 1139, 1254, 1663, + 2166, 2528, 2639, 2553, 2401, 2267, 2141, 1983, + 1813, 1736, 1849, 2129, 2405, 2467, 2232, 1832, + 1528, 1525, 1816, 2191, 2399, 2335, 2094, 1881, + 1829, 1916, 2015, 2029, 1982, 1987, 2122, 2343, + 2512, 2511, 2349, 2146, 2017, 1964, 1877, 1655, + 1335, 1111, 1198, 1657, 2314, 2862, 3060, 2889, 2534, 2226, 2079, 2041, 1987, 1858, 1710, 1647 }, { - 1144, 1198, 1236, 1220, 1256, 1498, 1990, 2580, - 3014, 3122, 2948, 2697, 2556, 2538, 2499, 2288, - 1909, 1529, 1341, 1403, 1593, 1730, 1729, 1658, - 1647, 1748, 1886, 1951, 1934, 1974, 2238, 2746, - 3301, 3592, 3419, 2835, 2106, 1518, 1195, 1071, - 1019, 992, 1053, 1274, 1625, 1966, 2173, 2255, - 2364, 2643, 3076, 3449, 3501, 3131, 2477, 1826, - 1399, 1224, 1171, 1115, 1063, 1132, 1407, 1829, - 2218, 2417, 2426, 2383, 2429, 2573, 2682, 2623, - 2404, 2187, 2145, 2298, 2464, 2405, 2021, 1449, - 964, 779, 913, 1222, 1552, 1858, 2191, 2580, - 2940, 3119, 3034, 2771, 2536, 2481, 2566, 2577, - 2302, 1726, 1061, 603, 523, 776, 1178, 1581, - 1963, 2380, 2832, 3200, 3316, 3115, 2717, 2344, - 2153, 2114, 2064, 1872, 1576, 1354, 1362, 1583, - 1829, 1895, 1741, 1524, 1469, 1683, 2078, 2463, - 2706, 2818, 2888, 2952, 2932, 2709, 2273, 1779, - 1455, 1419, 1570, 1669, 1535, 1206, 921, 932, - 1318, 1939, 2561, 3025, 3314, 3477, 3507, 3315, - 2831, 2128, 1439, 1019, 968, 1161, 1361, 1415, - 1373, 1414, 1672, 2096, 2486, 2665, 2620, 2502, - 2475, 2571, 2672, 2636, 2436, 2180, 2004, 1932, - 1854, 1648, 1325, 1058, 1048, 1351, 1804, 2147, - 2226, 2111, 2030, 2171, 2533, 2940, 3191, 3203, - 3032, 2762, 2401, 1897, 1248, 607, 235, 329, - 867, 1593, 2194, 2507, 2599, 2661, 2815, 3011, - 3087, 2937, 2613, 2279, 2058, 1930, 1775, 1516, - 1222, 1063, 1161, 1467, 1789, 1956, 1962, 1964, - 2128, 2464, 2797, 2915, 2746, 2427, 2187, 2161, - 2286, 2380, 2302, 2060, 1775, 1545, 1360, 1148, - 909, 781, 967, 1553, 2391, 3157, 3555, 3510, + 1144, 1198, 1236, 1220, 1256, 1498, 1990, 2580, + 3014, 3122, 2948, 2697, 2556, 2538, 2499, 2288, + 1909, 1529, 1341, 1403, 1593, 1730, 1729, 1658, + 1647, 1748, 1886, 1951, 1934, 1974, 2238, 2746, + 3301, 3592, 3419, 2835, 2106, 1518, 1195, 1071, + 1019, 992, 1053, 1274, 1625, 1966, 2173, 2255, + 2364, 2643, 3076, 3449, 3501, 3131, 2477, 1826, + 1399, 1224, 1171, 1115, 1063, 1132, 1407, 1829, + 2218, 2417, 2426, 2383, 2429, 2573, 2682, 2623, + 2404, 2187, 2145, 2298, 2464, 2405, 2021, 1449, + 964, 779, 913, 1222, 1552, 1858, 2191, 2580, + 2940, 3119, 3034, 2771, 2536, 2481, 2566, 2577, + 2302, 1726, 1061, 603, 523, 776, 1178, 1581, + 1963, 2380, 2832, 3200, 3316, 3115, 2717, 2344, + 2153, 2114, 2064, 1872, 1576, 1354, 1362, 1583, + 1829, 1895, 1741, 1524, 1469, 1683, 2078, 2463, + 2706, 2818, 2888, 2952, 2932, 2709, 2273, 1779, + 1455, 1419, 1570, 1669, 1535, 1206, 921, 932, + 1318, 1939, 2561, 3025, 3314, 3477, 3507, 3315, + 2831, 2128, 1439, 1019, 968, 1161, 1361, 1415, + 1373, 1414, 1672, 2096, 2486, 2665, 2620, 2502, + 2475, 2571, 2672, 2636, 2436, 2180, 2004, 1932, + 1854, 1648, 1325, 1058, 1048, 1351, 1804, 2147, + 2226, 2111, 2030, 2171, 2533, 2940, 3191, 3203, + 3032, 2762, 2401, 1897, 1248, 607, 235, 329, + 867, 1593, 2194, 2507, 2599, 2661, 2815, 3011, + 3087, 2937, 2613, 2279, 2058, 1930, 1775, 1516, + 1222, 1063, 1161, 1467, 1789, 1956, 1962, 1964, + 2128, 2464, 2797, 2915, 2746, 2427, 2187, 2161, + 2286, 2380, 2302, 2060, 1775, 1545, 1360, 1148, + 909, 781, 967, 1553, 2391, 3157, 3555, 3510, 3184, 2829, 2581, 2401, 2164, 1816, 1448, 1202 }, { - 1925, 1987, 2037, 2030, 2087, 2379, 2938, 3577, - 4008, 4060, 3804, 3468, 3236, 3108, 2955, 2685, - 2367, 2173, 2208, 2399, 2553, 2539, 2413, 2363, - 2529, 2862, 3172, 3307, 3296, 3312, 3486, 3756, - 3894, 3697, 3168, 2517, 1999, 1727, 1646, 1657, - 1757, 2044, 2579, 3251, 3804, 4014, 3875, 3595, - 3425, 3440, 3489, 3352, 2942, 2387, 1919, 1686, - 1669, 1770, 1951, 2282, 2827, 3495, 4031, 4095, - 3856, 3301, 2843, 2698, 2822, 2999, 3038, 2922, - 2758, 2633, 2515, 2313, 2030, 1824, 1908, 2356, - 3005, 3555, 3790, 3733, 3585, 3526, 3555, 3514, - 3265, 2837, 2405, 2130, 2020, 1959, 1854, 1773, - 1899, 2352, 3045, 3709, 4087, 4095, 3946, 3756, - 3596, 3363, 2942, 2375, 1873, 1658, 1780, 2087, - 2371, 2544, 2685, 2914, 3234, 3491, 3522, 3319, - 3071, 3005, 3182, 3441, 3524, 3300, 2864, 2435, - 2170, 2058, 1994, 1936, 1977, 2245, 2744, 3288, - 3627, 3647, 3473, 3352, 3437, 3649, 3745, 3534, - 3032, 2435, 1947, 1640, 1475, 1427, 1580, 2054, - 2846, 3729, 4095, 4095, 4095, 3589, 3154, 2933, - 2832, 2696, 2486, 2300, 2249, 2320, 2381, 2328, - 2214, 2227, 2517, 3033, 3531, 3760, 3659, 3396, - 3207, 3191, 3247, 3196, 2970, 2671, 2458, 2387, - 2361, 2244, 2030, 1884, 2007, 2447, 3035, 3516, - 3751, 3802, 3831, 3907, 3919, 3679, 3119, 2392, - 1780, 1490, 1521, 1726, 1974, 2266, 2682, 3223, - 3730, 3979, 3863, 3510, 3189, 3093, 3188, 3257, - 3105, 2732, 2320, 2068, 2025, 2094, 2168, 2258, - 2472, 2868, 3331, 3627, 3592, 3289, 2979, 2914, - 3137, 3451, 3591, 3433, 3059, 2642, 2283, 1965, - 1659, 1444, 1506, 1980, 2784, 3620, 4095, 4095, + 1925, 1987, 2037, 2030, 2087, 2379, 2938, 3577, + 4008, 4060, 3804, 3468, 3236, 3108, 2955, 2685, + 2367, 2173, 2208, 2399, 2553, 2539, 2413, 2363, + 2529, 2862, 3172, 3307, 3296, 3312, 3486, 3756, + 3894, 3697, 3168, 2517, 1999, 1727, 1646, 1657, + 1757, 2044, 2579, 3251, 3804, 4014, 3875, 3595, + 3425, 3440, 3489, 3352, 2942, 2387, 1919, 1686, + 1669, 1770, 1951, 2282, 2827, 3495, 4031, 4095, + 3856, 3301, 2843, 2698, 2822, 2999, 3038, 2922, + 2758, 2633, 2515, 2313, 2030, 1824, 1908, 2356, + 3005, 3555, 3790, 3733, 3585, 3526, 3555, 3514, + 3265, 2837, 2405, 2130, 2020, 1959, 1854, 1773, + 1899, 2352, 3045, 3709, 4087, 4095, 3946, 3756, + 3596, 3363, 2942, 2375, 1873, 1658, 1780, 2087, + 2371, 2544, 2685, 2914, 3234, 3491, 3522, 3319, + 3071, 3005, 3182, 3441, 3524, 3300, 2864, 2435, + 2170, 2058, 1994, 1936, 1977, 2245, 2744, 3288, + 3627, 3647, 3473, 3352, 3437, 3649, 3745, 3534, + 3032, 2435, 1947, 1640, 1475, 1427, 1580, 2054, + 2846, 3729, 4095, 4095, 4095, 3589, 3154, 2933, + 2832, 2696, 2486, 2300, 2249, 2320, 2381, 2328, + 2214, 2227, 2517, 3033, 3531, 3760, 3659, 3396, + 3207, 3191, 3247, 3196, 2970, 2671, 2458, 2387, + 2361, 2244, 2030, 1884, 2007, 2447, 3035, 3516, + 3751, 3802, 3831, 3907, 3919, 3679, 3119, 2392, + 1780, 1490, 1521, 1726, 1974, 2266, 2682, 3223, + 3730, 3979, 3863, 3510, 3189, 3093, 3188, 3257, + 3105, 2732, 2320, 2068, 2025, 2094, 2168, 2258, + 2472, 2868, 3331, 3627, 3592, 3289, 2979, 2914, + 3137, 3451, 3591, 3433, 3059, 2642, 2283, 1965, + 1659, 1444, 1506, 1980, 2784, 3620, 4095, 4095, 4031, 3737, 3527, 3366, 3117, 2724, 2293, 2000 }, { - 1117, 1190, 1253, 1255, 1331, 1665, 2274, 2933, - 3330, 3305, 2964, 2552, 2241, 2014, 1766, 1479, - 1282, 1326, 1599, 1899, 1996, 1843, 1635, 1631, - 1925, 2370, 2721, 2850, 2827, 2790, 2766, 2626, - 2237, 1641, 1080, 811, 903, 1198, 1477, 1667, - 1883, 2264, 2785, 3234, 3381, 3179, 2793, 2430, - 2150, 1848, 1419, 930, 618, 693, 1149, 1751, - 2236, 2511, 2678, 2865, 3054, 3086, 2829, 2351, - 1891, 1661, 1666, 1723, 1652, 1461, 1331, 1421, - 1704, 1986, 2103, 2083, 2115, 2351, 2733, 3031, - 3045, 2777, 2407, 2101, 1865, 1577, 1177, 795, - 677, 970, 1568, 2188, 2594, 2767, 2863, 3009, - 3154, 3114, 2775, 2226, 1695, 1355, 1187, 1058, - 907, 856, 1104, 1712, 2486, 3090, 3293, 3127, - 2813, 2546, 2345, 2112, 1804, 1533, 1464, 1633, - 1869, 1930, 1727, 1422, 1300, 1520, 1986, 2451, - 2733, 2842, 2898, 2949, 2891, 2584, 2038, 1467, - 1139, 1151, 1352, 1496, 1473, 1406, 1518, 1908, - 2452, 2917, 3161, 3218, 3188, 3073, 2747, 2108, - 1260, 527, 249, 531, 1175, 1844, 2318, 2594, - 2782, 2923, 2935, 2732, 2377, 2080, 2022, 2176, - 2305, 2168, 1744, 1261, 1006, 1094, 1405, 1735, - 1989, 2229, 2534, 2852, 3006, 2864, 2498, 2159, - 2059, 2181, 2288, 2137, 1700, 1186, 861, 839, - 1049, 1375, 1794, 2366, 3076, 3715, 3966, 3636, - 2834, 1923, 1265, 989, 979, 1051, 1142, 1323, - 1650, 2041, 2319, 2386, 2341, 2398, 2670, 3025, - 3174, 2917, 2326, 1687, 1277, 1163, 1220, 1308, - 1418, 1633, 1980, 2323, 2461, 2326, 2084, 2016, - 2271, 2723, 3066, 3059, 2705, 2198, 1730, 1347, - 999, 697, 596, 878, 1557, 2395, 3041, 3286, + 1117, 1190, 1253, 1255, 1331, 1665, 2274, 2933, + 3330, 3305, 2964, 2552, 2241, 2014, 1766, 1479, + 1282, 1326, 1599, 1899, 1996, 1843, 1635, 1631, + 1925, 2370, 2721, 2850, 2827, 2790, 2766, 2626, + 2237, 1641, 1080, 811, 903, 1198, 1477, 1667, + 1883, 2264, 2785, 3234, 3381, 3179, 2793, 2430, + 2150, 1848, 1419, 930, 618, 693, 1149, 1751, + 2236, 2511, 2678, 2865, 3054, 3086, 2829, 2351, + 1891, 1661, 1666, 1723, 1652, 1461, 1331, 1421, + 1704, 1986, 2103, 2083, 2115, 2351, 2733, 3031, + 3045, 2777, 2407, 2101, 1865, 1577, 1177, 795, + 677, 970, 1568, 2188, 2594, 2767, 2863, 3009, + 3154, 3114, 2775, 2226, 1695, 1355, 1187, 1058, + 907, 856, 1104, 1712, 2486, 3090, 3293, 3127, + 2813, 2546, 2345, 2112, 1804, 1533, 1464, 1633, + 1869, 1930, 1727, 1422, 1300, 1520, 1986, 2451, + 2733, 2842, 2898, 2949, 2891, 2584, 2038, 1467, + 1139, 1151, 1352, 1496, 1473, 1406, 1518, 1908, + 2452, 2917, 3161, 3218, 3188, 3073, 2747, 2108, + 1260, 527, 249, 531, 1175, 1844, 2318, 2594, + 2782, 2923, 2935, 2732, 2377, 2080, 2022, 2176, + 2305, 2168, 1744, 1261, 1006, 1094, 1405, 1735, + 1989, 2229, 2534, 2852, 3006, 2864, 2498, 2159, + 2059, 2181, 2288, 2137, 1700, 1186, 861, 839, + 1049, 1375, 1794, 2366, 3076, 3715, 3966, 3636, + 2834, 1923, 1265, 989, 979, 1051, 1142, 1323, + 1650, 2041, 2319, 2386, 2341, 2398, 2670, 3025, + 3174, 2917, 2326, 1687, 1277, 1163, 1220, 1308, + 1418, 1633, 1980, 2323, 2461, 2326, 2084, 2016, + 2271, 2723, 3066, 3059, 2705, 2198, 1730, 1347, + 999, 697, 596, 878, 1557, 2395, 3041, 3286, 3189, 2978, 2823, 2694, 2448, 2022, 1538, 1203 }, { - 1117, 1190, 1253, 1255, 1331, 1665, 2274, 2933, - 3330, 3305, 2964, 2552, 2241, 2014, 1766, 1479, - 1282, 1326, 1599, 1899, 1996, 1843, 1635, 1631, - 1925, 2370, 2721, 2850, 2827, 2790, 2766, 2626, - 2237, 1641, 1080, 811, 903, 1198, 1477, 1667, - 1883, 2264, 2785, 3234, 3381, 3179, 2793, 2430, - 2150, 1848, 1419, 930, 618, 693, 1149, 1751, - 2236, 2511, 2678, 2865, 3054, 3086, 2829, 2351, - 1891, 1661, 1666, 1723, 1652, 1461, 1331, 1421, - 1704, 1986, 2103, 2083, 2115, 2351, 2733, 3031, - 3045, 2777, 2407, 2101, 1865, 1577, 1177, 795, - 677, 970, 1568, 2188, 2594, 2767, 2863, 3009, - 3154, 3114, 2775, 2226, 1695, 1355, 1187, 1058, - 907, 856, 1104, 1712, 2486, 3090, 3293, 3127, - 2813, 2546, 2345, 2112, 1804, 1533, 1464, 1633, - 1869, 1930, 1727, 1422, 1300, 1520, 1986, 2451, - 2733, 2842, 2898, 2949, 2891, 2584, 2038, 1467, - 1139, 1151, 1352, 1496, 1473, 1406, 1518, 1908, - 2452, 2917, 3161, 3218, 3188, 3073, 2747, 2108, - 1260, 527, 249, 531, 1175, 1844, 2318, 2594, - 2782, 2923, 2935, 2732, 2377, 2080, 2022, 2176, - 2305, 2168, 1744, 1261, 1006, 1094, 1405, 1735, - 1989, 2229, 2534, 2852, 3006, 2864, 2498, 2159, - 2059, 2181, 2288, 2137, 1700, 1186, 861, 839, - 1049, 1375, 1794, 2366, 3076, 3715, 3966, 3636, - 2834, 1923, 1265, 989, 979, 1051, 1142, 1323, - 1650, 2041, 2319, 2386, 2341, 2398, 2670, 3025, - 3174, 2917, 2326, 1687, 1277, 1163, 1220, 1308, - 1418, 1633, 1980, 2323, 2461, 2326, 2084, 2016, - 2271, 2723, 3066, 3059, 2705, 2198, 1730, 1347, - 999, 697, 596, 878, 1557, 2395, 3041, 3286, + 1117, 1190, 1253, 1255, 1331, 1665, 2274, 2933, + 3330, 3305, 2964, 2552, 2241, 2014, 1766, 1479, + 1282, 1326, 1599, 1899, 1996, 1843, 1635, 1631, + 1925, 2370, 2721, 2850, 2827, 2790, 2766, 2626, + 2237, 1641, 1080, 811, 903, 1198, 1477, 1667, + 1883, 2264, 2785, 3234, 3381, 3179, 2793, 2430, + 2150, 1848, 1419, 930, 618, 693, 1149, 1751, + 2236, 2511, 2678, 2865, 3054, 3086, 2829, 2351, + 1891, 1661, 1666, 1723, 1652, 1461, 1331, 1421, + 1704, 1986, 2103, 2083, 2115, 2351, 2733, 3031, + 3045, 2777, 2407, 2101, 1865, 1577, 1177, 795, + 677, 970, 1568, 2188, 2594, 2767, 2863, 3009, + 3154, 3114, 2775, 2226, 1695, 1355, 1187, 1058, + 907, 856, 1104, 1712, 2486, 3090, 3293, 3127, + 2813, 2546, 2345, 2112, 1804, 1533, 1464, 1633, + 1869, 1930, 1727, 1422, 1300, 1520, 1986, 2451, + 2733, 2842, 2898, 2949, 2891, 2584, 2038, 1467, + 1139, 1151, 1352, 1496, 1473, 1406, 1518, 1908, + 2452, 2917, 3161, 3218, 3188, 3073, 2747, 2108, + 1260, 527, 249, 531, 1175, 1844, 2318, 2594, + 2782, 2923, 2935, 2732, 2377, 2080, 2022, 2176, + 2305, 2168, 1744, 1261, 1006, 1094, 1405, 1735, + 1989, 2229, 2534, 2852, 3006, 2864, 2498, 2159, + 2059, 2181, 2288, 2137, 1700, 1186, 861, 839, + 1049, 1375, 1794, 2366, 3076, 3715, 3966, 3636, + 2834, 1923, 1265, 989, 979, 1051, 1142, 1323, + 1650, 2041, 2319, 2386, 2341, 2398, 2670, 3025, + 3174, 2917, 2326, 1687, 1277, 1163, 1220, 1308, + 1418, 1633, 1980, 2323, 2461, 2326, 2084, 2016, + 2271, 2723, 3066, 3059, 2705, 2198, 1730, 1347, + 999, 697, 596, 878, 1557, 2395, 3041, 3286, 3189, 2978, 2823, 2694, 2448, 2022, 1538, 1203 }, { - 1718, 1921, 1999, 1656, 1132, 1032, 1712, 2848, - 3643, 3512, 2596, 1623, 1246, 1506, 1915, 2017, - 1844, 1803, 2145, 2612, 2653, 2019, 1111, 688, - 1190, 2308, 3242, 3398, 2864, 2229, 1969, 2022, - 1965, 1564, 1094, 1081, 1711, 2557, 2915, 2470, - 1625, 1150, 1483, 2345, 3029, 3067, 2612, 2185, - 2096, 2139, 1883, 1234, 647, 732, 1629, 2782, - 3379, 3061, 2216, 1596, 1624, 2069, 2372, 2248, - 1953, 1942, 2320, 2666, 2456, 1648, 817, 673, - 1391, 2432, 3022, 2838, 2248, 1891, 2042, 2394, - 2450, 2085, 1692, 1745, 2251, 2681, 2470, 1618, - 757, 605, 1314, 2340, 2962, 2917, 2559, 2405, - 2574, 2687, 2333, 1581, 995, 1097, 1825, 2543, - 2617, 2016, 1334, 1217, 1764, 2469, 2751, 2515, - 2186, 2209, 2546, 2708, 2296, 1481, 909, 1099, - 1922, 2684, 2761, 2163, 1491, 1343, 1761, 2265, - 2393, 2177, 2070, 2401, 2954, 3126, 2538, 1473, - 689, 746, 1508, 2285, 2490, 2151, 1804, 1902, - 2355, 2664, 2482, 2010, 1796, 2145, 2747, 2934, - 2340, 1301, 593, 739, 1553, 2355, 2620, 2417, - 2233, 2394, 2701, 2669, 2100, 1381, 1161, 1710, - 2604, 3073, 2700, 1796, 1093, 1072, 1566, 2017, - 2081, 1946, 2065, 2586, 3118, 3090, 2358, 1432, - 1049, 1496, 2335, 2804, 2518, 1780, 1244, 1274, - 1656, 1913, 1860, 1810, 2187, 2986, 3642, 3514, - 2517, 1276, 618, 874, 1639, 2210, 2240, 1983, - 1918, 2192, 2465, 2316, 1768, 1353, 1601, 2477, - 3320, 3416, 2637, 1569, 968, 1111, 1625, 1943, - 1888, 1782, 2016, 2544, 2867, 2552, 1738, 1103, - 1261, 2175, 3150, 3442, 2895, 2013, 1437, 1358, - 1450, 1342, 1089, 1143, 1827, 2881, 3588, 3398, + 1718, 1921, 1999, 1656, 1132, 1032, 1712, 2848, + 3643, 3512, 2596, 1623, 1246, 1506, 1915, 2017, + 1844, 1803, 2145, 2612, 2653, 2019, 1111, 688, + 1190, 2308, 3242, 3398, 2864, 2229, 1969, 2022, + 1965, 1564, 1094, 1081, 1711, 2557, 2915, 2470, + 1625, 1150, 1483, 2345, 3029, 3067, 2612, 2185, + 2096, 2139, 1883, 1234, 647, 732, 1629, 2782, + 3379, 3061, 2216, 1596, 1624, 2069, 2372, 2248, + 1953, 1942, 2320, 2666, 2456, 1648, 817, 673, + 1391, 2432, 3022, 2838, 2248, 1891, 2042, 2394, + 2450, 2085, 1692, 1745, 2251, 2681, 2470, 1618, + 757, 605, 1314, 2340, 2962, 2917, 2559, 2405, + 2574, 2687, 2333, 1581, 995, 1097, 1825, 2543, + 2617, 2016, 1334, 1217, 1764, 2469, 2751, 2515, + 2186, 2209, 2546, 2708, 2296, 1481, 909, 1099, + 1922, 2684, 2761, 2163, 1491, 1343, 1761, 2265, + 2393, 2177, 2070, 2401, 2954, 3126, 2538, 1473, + 689, 746, 1508, 2285, 2490, 2151, 1804, 1902, + 2355, 2664, 2482, 2010, 1796, 2145, 2747, 2934, + 2340, 1301, 593, 739, 1553, 2355, 2620, 2417, + 2233, 2394, 2701, 2669, 2100, 1381, 1161, 1710, + 2604, 3073, 2700, 1796, 1093, 1072, 1566, 2017, + 2081, 1946, 2065, 2586, 3118, 3090, 2358, 1432, + 1049, 1496, 2335, 2804, 2518, 1780, 1244, 1274, + 1656, 1913, 1860, 1810, 2187, 2986, 3642, 3514, + 2517, 1276, 618, 874, 1639, 2210, 2240, 1983, + 1918, 2192, 2465, 2316, 1768, 1353, 1601, 2477, + 3320, 3416, 2637, 1569, 968, 1111, 1625, 1943, + 1888, 1782, 2016, 2544, 2867, 2552, 1738, 1103, + 1261, 2175, 3150, 3442, 2895, 2013, 1437, 1358, + 1450, 1342, 1089, 1143, 1827, 2881, 3588, 3398, 2455, 1508, 1250, 1731, 2377, 2578, 2246, 1815 }, { - 1956, 2312, 2492, 2158, 1587, 1440, 2075, 3103, - 3686, 3310, 2251, 1289, 964, 1148, 1318, 1207, - 1102, 1470, 2337, 3132, 3196, 2466, 1596, 1370, - 1972, 2846, 3266, 3016, 2500, 2211, 2166, 1932, - 1202, 279, 0, 514, 1825, 2970, 3298, 2911, - 2460, 2438, 2721, 2794, 2395, 1846, 1708, 2128, - 2613, 2496, 1639, 644, 310, 889, 1878, 2537, - 2593, 2411, 2483, 2835, 2993, 2546, 1687, 1118, - 1375, 2266, 3014, 2986, 2268, 1526, 1315, 1565, - 1757, 1572, 1273, 1419, 2191, 3093, 3371, 2751, - 1734, 1144, 1359, 2019, 2463, 2416, 2209, 2316, - 2752, 2995, 2547, 1529, 660, 598, 1311, 2116, - 2356, 2015, 1666, 1816, 2379, 2798, 2684, 2258, - 2113, 2543, 3164, 3261, 2510, 1347, 574, 613, - 1161, 1574, 1564, 1455, 1755, 2519, 3211, 3232, - 2567, 1849, 1757, 2343, 2992, 3048, 2449, 1737, - 1454, 1580, 1619, 1216, 628, 520, 1267, 2504, - 3408, 3450, 2855, 2318, 2281, 2532, 2517, 2013, - 1407, 1298, 1822, 2459, 2530, 1902, 1140, 958, - 1517, 2286, 2609, 2356, 2002, 2057, 2485, 2743, - 2396, 1643, 1184, 1516, 2413, 3111, 3038, 2338, - 1674, 1530, 1760, 1837, 1500, 1087, 1183, 1941, - 2834, 3122, 2577, 1723, 1337, 1707, 2410, 2796, - 2657, 2373, 2410, 2734, 2807, 2177, 1045, 176, - 210, 1065, 2032, 2466, 2362, 2242, 2514, 3006, - 3170, 2727, 2032, 1745, 2140, 2771, 2886, 2175, - 1096, 437, 583, 1209, 1704, 1825, 1894, 2338, - 3102, 3601, 3299, 2321, 1415, 1285, 1930, 2673, - 2829, 2339, 1732, 1513, 1639, 1648, 1264, 805, - 906, 1822, 3065, 3773, 3486, 2550, 1755, 1582, - 1830, 1959, 1751, 1543, 1806, 2530, 3118, 2944, + 1956, 2312, 2492, 2158, 1587, 1440, 2075, 3103, + 3686, 3310, 2251, 1289, 964, 1148, 1318, 1207, + 1102, 1470, 2337, 3132, 3196, 2466, 1596, 1370, + 1972, 2846, 3266, 3016, 2500, 2211, 2166, 1932, + 1202, 279, 0, 514, 1825, 2970, 3298, 2911, + 2460, 2438, 2721, 2794, 2395, 1846, 1708, 2128, + 2613, 2496, 1639, 644, 310, 889, 1878, 2537, + 2593, 2411, 2483, 2835, 2993, 2546, 1687, 1118, + 1375, 2266, 3014, 2986, 2268, 1526, 1315, 1565, + 1757, 1572, 1273, 1419, 2191, 3093, 3371, 2751, + 1734, 1144, 1359, 2019, 2463, 2416, 2209, 2316, + 2752, 2995, 2547, 1529, 660, 598, 1311, 2116, + 2356, 2015, 1666, 1816, 2379, 2798, 2684, 2258, + 2113, 2543, 3164, 3261, 2510, 1347, 574, 613, + 1161, 1574, 1564, 1455, 1755, 2519, 3211, 3232, + 2567, 1849, 1757, 2343, 2992, 3048, 2449, 1737, + 1454, 1580, 1619, 1216, 628, 520, 1267, 2504, + 3408, 3450, 2855, 2318, 2281, 2532, 2517, 2013, + 1407, 1298, 1822, 2459, 2530, 1902, 1140, 958, + 1517, 2286, 2609, 2356, 2002, 2057, 2485, 2743, + 2396, 1643, 1184, 1516, 2413, 3111, 3038, 2338, + 1674, 1530, 1760, 1837, 1500, 1087, 1183, 1941, + 2834, 3122, 2577, 1723, 1337, 1707, 2410, 2796, + 2657, 2373, 2410, 2734, 2807, 2177, 1045, 176, + 210, 1065, 2032, 2466, 2362, 2242, 2514, 3006, + 3170, 2727, 2032, 1745, 2140, 2771, 2886, 2175, + 1096, 437, 583, 1209, 1704, 1825, 1894, 2338, + 3102, 3601, 3299, 2321, 1415, 1285, 1930, 2673, + 2829, 2339, 1732, 1513, 1639, 1648, 1264, 805, + 906, 1822, 3065, 3773, 3486, 2550, 1755, 1582, + 1830, 1959, 1751, 1543, 1806, 2530, 3118, 2944, 2015, 1030, 751, 1302, 2097, 2453, 2239, 1915 }, { - 1964, 2362, 2559, 2189, 1568, 1414, 2067, 3059, - 3526, 3046, 2033, 1276, 1149, 1327, 1288, 987, - 936, 1584, 2708, 3521, 3425, 2621, 1903, 1856, - 2309, 2599, 2335, 1808, 1611, 1918, 2247, 1998, - 1166, 443, 549, 1503, 2603, 3140, 3062, 2903, - 3077, 3364, 3157, 2203, 1000, 375, 684, 1474, - 1982, 1920, 1700, 1887, 2497, 2950, 2717, 1961, - 1425, 1673, 2496, 3112, 2972, 2281, 1721, 1683, - 1882, 1764, 1217, 782, 1086, 2110, 3112, 3324, - 2695, 1899, 1625, 1901, 2178, 2031, 1671, 1687, - 2317, 3076, 3199, 2439, 1367, 825, 1111, 1751, - 2065, 1899, 1721, 2001, 2610, 2919, 2518, 1731, - 1353, 1830, 2779, 3352, 3069, 2250, 1598, 1445, - 1472, 1203, 669, 468, 1120, 2420, 3528, 3741, - 3144, 2457, 2266, 2453, 2438, 1916, 1254, 1094, - 1614, 2272, 2351, 1722, 1001, 913, 1554, 2336, - 2649, 2506, 2458, 2890, 3503, 3576, 2750, 1475, - 615, 626, 1170, 1560, 1528, 1462, 1874, 2718, - 3334, 3129, 2236, 1437, 1396, 2018, 2602, 2606, - 2183, 1928, 2145, 2474, 2310, 1544, 781, 764, - 1596, 2598, 2979, 2593, 2012, 1853, 2129, 2320, - 2047, 1576, 1549, 2236, 3140, 3434, 2781, 1683, - 980, 1029, 1443, 1618, 1441, 1379, 1878, 2749, - 3283, 2983, 2126, 1531, 1738, 2479, 2991, 2808, - 2197, 1776, 1790, 1858, 1476, 702, 214, 644, - 1885, 3131, 3627, 3348, 2903, 2803, 2914, 2686, - 1876, 935, 595, 1104, 1936, 2317, 2009, 1510, - 1471, 1978, 2486, 2467, 2030, 1820, 2285, 3129, - 3560, 3092, 2049, 1221, 1077, 1352, 1459, 1214, - 1058, 1522, 2535, 3375, 3355, 2530, 1651, 1420, - 1826, 2259, 2233, 1913, 1866, 2338, 2895, 2850, + 1964, 2362, 2559, 2189, 1568, 1414, 2067, 3059, + 3526, 3046, 2033, 1276, 1149, 1327, 1288, 987, + 936, 1584, 2708, 3521, 3425, 2621, 1903, 1856, + 2309, 2599, 2335, 1808, 1611, 1918, 2247, 1998, + 1166, 443, 549, 1503, 2603, 3140, 3062, 2903, + 3077, 3364, 3157, 2203, 1000, 375, 684, 1474, + 1982, 1920, 1700, 1887, 2497, 2950, 2717, 1961, + 1425, 1673, 2496, 3112, 2972, 2281, 1721, 1683, + 1882, 1764, 1217, 782, 1086, 2110, 3112, 3324, + 2695, 1899, 1625, 1901, 2178, 2031, 1671, 1687, + 2317, 3076, 3199, 2439, 1367, 825, 1111, 1751, + 2065, 1899, 1721, 2001, 2610, 2919, 2518, 1731, + 1353, 1830, 2779, 3352, 3069, 2250, 1598, 1445, + 1472, 1203, 669, 468, 1120, 2420, 3528, 3741, + 3144, 2457, 2266, 2453, 2438, 1916, 1254, 1094, + 1614, 2272, 2351, 1722, 1001, 913, 1554, 2336, + 2649, 2506, 2458, 2890, 3503, 3576, 2750, 1475, + 615, 626, 1170, 1560, 1528, 1462, 1874, 2718, + 3334, 3129, 2236, 1437, 1396, 2018, 2602, 2606, + 2183, 1928, 2145, 2474, 2310, 1544, 781, 764, + 1596, 2598, 2979, 2593, 2012, 1853, 2129, 2320, + 2047, 1576, 1549, 2236, 3140, 3434, 2781, 1683, + 980, 1029, 1443, 1618, 1441, 1379, 1878, 2749, + 3283, 2983, 2126, 1531, 1738, 2479, 2991, 2808, + 2197, 1776, 1790, 1858, 1476, 702, 214, 644, + 1885, 3131, 3627, 3348, 2903, 2803, 2914, 2686, + 1876, 935, 595, 1104, 1936, 2317, 2009, 1510, + 1471, 1978, 2486, 2467, 2030, 1820, 2285, 3129, + 3560, 3092, 2049, 1221, 1077, 1352, 1459, 1214, + 1058, 1522, 2535, 3375, 3355, 2530, 1651, 1420, + 1826, 2259, 2233, 1913, 1866, 2338, 2895, 2850, 2036, 1061, 736, 1277, 2114, 2503, 2272, 1916 }, { - 1639, 1664, 1562, 1341, 1360, 1915, 2829, 3528, - 3547, 2949, 2219, 1761, 1548, 1288, 877, 621, - 938, 1861, 2903, 3446, 3282, 2734, 2268, 2022, - 1771, 1321, 868, 873, 1570, 2635, 3406, 3454, - 2920, 2299, 1919, 1689, 1347, 896, 694, 1077, - 1938, 2737, 2992, 2720, 2385, 2390, 2662, 2769, - 2419, 1793, 1356, 1365, 1621, 1732, 1581, 1463, - 1732, 2345, 2832, 2753, 2162, 1583, 1512, 1960, - 2502, 2750, 2711, 2665, 2725, 2631, 2028, 958, - 0, 0, 496, 1736, 2834, 3458, 3723, 3841, - 3752, 3184, 2069, 822, 110, 289, 1094, 1902, - 2304, 2395, 2518, 2782, 2906, 2557, 1804, 1148, - 1076, 1597, 2255, 2598, 2593, 2554, 2689, 2805, - 2511, 1715, 836, 485, 898, 1731, 2409, 2656, - 2660, 2728, 2863, 2746, 2156, 1334, 853, 1093, - 1868, 2596, 2846, 2685, 2489, 2460, 2405, 2012, - 1304, 722, 730, 1335, 2064, 2430, 2399, 2364, - 2665, 3183, 3442, 3110, 2344, 1619, 1245, 1108, - 918, 647, 646, 1270, 2402, 3433, 3752, 3276, - 2479, 1920, 1759, 1753, 1669, 1610, 1864, 2469, - 3015, 2959, 2167, 1103, 447, 518, 1081, 1689, - 2157, 2652, 3327, 3959, 4051, 3323, 2069, 966, - 513, 658, 980, 1199, 1437, 1979, 2804, 3469, - 3484, 2808, 1918, 1372, 1319, 1472, 1526, 1535, - 1822, 2522, 3289, 3542, 3008, 2017, 1205, 958, - 1133, 1343, 1427, 1594, 2085, 2776, 3197, 2987, - 2297, 1689, 1605, 1967, 2306, 2280, 2009, 1884, - 2086, 2358, 2294, 1817, 1301, 1203, 1573, 2011, - 2103, 1872, 1753, 2114, 2839, 3420, 3451, 2996, - 2439, 2029, 1639, 1019, 242, 0, 205, 1436, - 2883, 3816, 3952, 3559, 3062, 2600, 2024, 1278, + 1639, 1664, 1562, 1341, 1360, 1915, 2829, 3528, + 3547, 2949, 2219, 1761, 1548, 1288, 877, 621, + 938, 1861, 2903, 3446, 3282, 2734, 2268, 2022, + 1771, 1321, 868, 873, 1570, 2635, 3406, 3454, + 2920, 2299, 1919, 1689, 1347, 896, 694, 1077, + 1938, 2737, 2992, 2720, 2385, 2390, 2662, 2769, + 2419, 1793, 1356, 1365, 1621, 1732, 1581, 1463, + 1732, 2345, 2832, 2753, 2162, 1583, 1512, 1960, + 2502, 2750, 2711, 2665, 2725, 2631, 2028, 958, + 0, 0, 496, 1736, 2834, 3458, 3723, 3841, + 3752, 3184, 2069, 822, 110, 289, 1094, 1902, + 2304, 2395, 2518, 2782, 2906, 2557, 1804, 1148, + 1076, 1597, 2255, 2598, 2593, 2554, 2689, 2805, + 2511, 1715, 836, 485, 898, 1731, 2409, 2656, + 2660, 2728, 2863, 2746, 2156, 1334, 853, 1093, + 1868, 2596, 2846, 2685, 2489, 2460, 2405, 2012, + 1304, 722, 730, 1335, 2064, 2430, 2399, 2364, + 2665, 3183, 3442, 3110, 2344, 1619, 1245, 1108, + 918, 647, 646, 1270, 2402, 3433, 3752, 3276, + 2479, 1920, 1759, 1753, 1669, 1610, 1864, 2469, + 3015, 2959, 2167, 1103, 447, 518, 1081, 1689, + 2157, 2652, 3327, 3959, 4051, 3323, 2069, 966, + 513, 658, 980, 1199, 1437, 1979, 2804, 3469, + 3484, 2808, 1918, 1372, 1319, 1472, 1526, 1535, + 1822, 2522, 3289, 3542, 3008, 2017, 1205, 958, + 1133, 1343, 1427, 1594, 2085, 2776, 3197, 2987, + 2297, 1689, 1605, 1967, 2306, 2280, 2009, 1884, + 2086, 2358, 2294, 1817, 1301, 1203, 1573, 2011, + 2103, 1872, 1753, 2114, 2839, 3420, 3451, 2996, + 2439, 2029, 1639, 1019, 242, 0, 205, 1436, + 2883, 3816, 3952, 3559, 3062, 2600, 2024, 1278, 664, 643, 1346, 2343, 2958, 2854, 2286, 1788 }, { - 1664, 1710, 1621, 1407, 1442, 2003, 2873, 3465, - 3372, 2745, 2084, 1708, 1489, 1146, 713, 612, - 1202, 2315, 3312, 3633, 3266, 2647, 2153, 1768, - 1286, 760, 609, 1212, 2410, 3513, 3856, 3344, - 2445, 1678, 1182, 798, 495, 559, 1284, 2512, - 3601, 3926, 3426, 2610, 2030, 1793, 1607, 1266, - 968, 1098, 1726, 2439, 2713, 2438, 2006, 1863, - 2044, 2194, 2047, 1785, 1847, 2396, 3057, 3245, - 2741, 1890, 1225, 956, 880, 784, 811, 1334, - 2449, 3684, 4095, 4001, 3035, 2052, 1429, 1079, - 781, 592, 827, 1619, 2608, 3172, 2997, 2384, - 1932, 1937, 2162, 2183, 1912, 1690, 1855, 2317, - 2620, 2441, 1951, 1617, 1681, 1910, 1901, 1595, - 1381, 1666, 2386, 3011, 3069, 2603, 2079, 1865, - 1879, 1787, 1488, 1298, 1590, 2308, 2924, 2932, - 2348, 1676, 1389, 1493, 1645, 1637, 1660, 2042, - 2762, 3350, 3316, 2665, 1904, 1532, 1564, 1603, - 1355, 1002, 995, 1531, 2303, 2818, 2898, 2809, - 2868, 3011, 2849, 2155, 1229, 689, 883, 1548, - 2098, 2207, 2062, 2049, 2261, 2408, 2227, 1862, - 1767, 2190, 2838, 3128, 2766, 2035, 1479, 1347, - 1410, 1328, 1118, 1157, 1721, 2593, 3217, 3234, - 2828, 2472, 2390, 2340, 1956, 1257, 718, 808, - 1498, 2286, 2699, 2716, 2652, 2684, 2608, 2120, - 1299, 686, 820, 1690, 2713, 3260, 3186, 2822, - 2502, 2202, 1692, 990, 515, 722, 1593, 2569, - 3045, 2906, 2541, 2359, 2356, 2214, 1783, 1351, - 1368, 1923, 2586, 2811, 2473, 1952, 1679, 1683, - 1634, 1326, 1011, 1176, 1997, 3075, 3770, 3769, - 3287, 2713, 2162, 1452, 521, 0, 0, 704, - 2221, 3469, 3925, 3689, 3199, 2718, 2167, 1448, + 1664, 1710, 1621, 1407, 1442, 2003, 2873, 3465, + 3372, 2745, 2084, 1708, 1489, 1146, 713, 612, + 1202, 2315, 3312, 3633, 3266, 2647, 2153, 1768, + 1286, 760, 609, 1212, 2410, 3513, 3856, 3344, + 2445, 1678, 1182, 798, 495, 559, 1284, 2512, + 3601, 3926, 3426, 2610, 2030, 1793, 1607, 1266, + 968, 1098, 1726, 2439, 2713, 2438, 2006, 1863, + 2044, 2194, 2047, 1785, 1847, 2396, 3057, 3245, + 2741, 1890, 1225, 956, 880, 784, 811, 1334, + 2449, 3684, 4095, 4001, 3035, 2052, 1429, 1079, + 781, 592, 827, 1619, 2608, 3172, 2997, 2384, + 1932, 1937, 2162, 2183, 1912, 1690, 1855, 2317, + 2620, 2441, 1951, 1617, 1681, 1910, 1901, 1595, + 1381, 1666, 2386, 3011, 3069, 2603, 2079, 1865, + 1879, 1787, 1488, 1298, 1590, 2308, 2924, 2932, + 2348, 1676, 1389, 1493, 1645, 1637, 1660, 2042, + 2762, 3350, 3316, 2665, 1904, 1532, 1564, 1603, + 1355, 1002, 995, 1531, 2303, 2818, 2898, 2809, + 2868, 3011, 2849, 2155, 1229, 689, 883, 1548, + 2098, 2207, 2062, 2049, 2261, 2408, 2227, 1862, + 1767, 2190, 2838, 3128, 2766, 2035, 1479, 1347, + 1410, 1328, 1118, 1157, 1721, 2593, 3217, 3234, + 2828, 2472, 2390, 2340, 1956, 1257, 718, 808, + 1498, 2286, 2699, 2716, 2652, 2684, 2608, 2120, + 1299, 686, 820, 1690, 2713, 3260, 3186, 2822, + 2502, 2202, 1692, 990, 515, 722, 1593, 2569, + 3045, 2906, 2541, 2359, 2356, 2214, 1783, 1351, + 1368, 1923, 2586, 2811, 2473, 1952, 1679, 1683, + 1634, 1326, 1011, 1176, 1997, 3075, 3770, 3769, + 3287, 2713, 2162, 1452, 521, 0, 0, 704, + 2221, 3469, 3925, 3689, 3199, 2718, 2167, 1448, 794, 672, 1285, 2261, 2912, 2846, 2291, 1798 }, { - 1007, 1856, 3088, 3141, 1847, 693, 1019, 2402, - 3221, 2669, 1652, 1511, 2265, 2661, 1926, 902, - 1029, 2441, 3641, 3260, 1719, 730, 1238, 2375, - 2679, 1956, 1422, 1994, 3006, 3042, 1827, 706, - 1023, 2433, 3287, 2649, 1408, 1118, 2052, 2925, - 2601, 1546, 1185, 2010, 2913, 2633, 1438, 857, - 1747, 3148, 3408, 2207, 934, 975, 2063, 2745, - 2291, 1564, 1775, 2782, 3198, 2211, 766, 519, - 1815, 3231, 3271, 2120, 1291, 1679, 2511, 2481, - 1542, 991, 1744, 3042, 3318, 2172, 930, 1040, - 2298, 3130, 2564, 1398, 1127, 2028, 2866, 2544, - 1544, 1280, 2202, 3139, 2764, 1349, 530, 1323, - 2864, 3450, 2579, 1454, 1382, 2157, 2479, 1781, - 1038, 1485, 2882, 3653, 2796, 1178, 554, 1486, - 2736, 2860, 1960, 1411, 1992, 2872, 2739, 1593, - 829, 1472, 2813, 3235, 2228, 1036, 1114, 2328, - 3157, 2624, 1479, 1185, 2020, 2769, 2363, 1324, - 1121, 2227, 3406, 3187, 1710, 604, 1030, 2335, - 2953, 2368, 1638, 1880, 2743, 2873, 1777, 620, - 857, 2375, 3534, 3105, 1716, 1022, 1666, 2595, - 2523, 1612, 1201, 1986, 3034, 2956, 1739, 846, - 1407, 2768, 3270, 2302, 1044, 990, 2114, 2978, - 2598, 1645, 1484, 2330, 2945, 2295, 996, 656, - 1854, 3341, 3494, 2243, 1092, 1233, 2166, 2501, - 1839, 1266, 1837, 3059, 3406, 2261, 808, 665, - 1934, 3095, 2878, 1764, 1266, 1962, 2817, 2600, - 1538, 1039, 1834, 2968, 2975, 1770, 819, 1333, - 2738, 3371, 2522, 1266, 1073, 1987, 2681, 2254, - 1408, 1483, 2608, 3416, 2742, 1172, 431, 1320, - 2771, 3183, 2343, 1540, 1807, 2599, 2598, 1556, - 737, 1323, 2823, 3559, 2693, 1261, 902, 1879, + 1007, 1856, 3088, 3141, 1847, 693, 1019, 2402, + 3221, 2669, 1652, 1511, 2265, 2661, 1926, 902, + 1029, 2441, 3641, 3260, 1719, 730, 1238, 2375, + 2679, 1956, 1422, 1994, 3006, 3042, 1827, 706, + 1023, 2433, 3287, 2649, 1408, 1118, 2052, 2925, + 2601, 1546, 1185, 2010, 2913, 2633, 1438, 857, + 1747, 3148, 3408, 2207, 934, 975, 2063, 2745, + 2291, 1564, 1775, 2782, 3198, 2211, 766, 519, + 1815, 3231, 3271, 2120, 1291, 1679, 2511, 2481, + 1542, 991, 1744, 3042, 3318, 2172, 930, 1040, + 2298, 3130, 2564, 1398, 1127, 2028, 2866, 2544, + 1544, 1280, 2202, 3139, 2764, 1349, 530, 1323, + 2864, 3450, 2579, 1454, 1382, 2157, 2479, 1781, + 1038, 1485, 2882, 3653, 2796, 1178, 554, 1486, + 2736, 2860, 1960, 1411, 1992, 2872, 2739, 1593, + 829, 1472, 2813, 3235, 2228, 1036, 1114, 2328, + 3157, 2624, 1479, 1185, 2020, 2769, 2363, 1324, + 1121, 2227, 3406, 3187, 1710, 604, 1030, 2335, + 2953, 2368, 1638, 1880, 2743, 2873, 1777, 620, + 857, 2375, 3534, 3105, 1716, 1022, 1666, 2595, + 2523, 1612, 1201, 1986, 3034, 2956, 1739, 846, + 1407, 2768, 3270, 2302, 1044, 990, 2114, 2978, + 2598, 1645, 1484, 2330, 2945, 2295, 996, 656, + 1854, 3341, 3494, 2243, 1092, 1233, 2166, 2501, + 1839, 1266, 1837, 3059, 3406, 2261, 808, 665, + 1934, 3095, 2878, 1764, 1266, 1962, 2817, 2600, + 1538, 1039, 1834, 2968, 2975, 1770, 819, 1333, + 2738, 3371, 2522, 1266, 1073, 1987, 2681, 2254, + 1408, 1483, 2608, 3416, 2742, 1172, 431, 1320, + 2771, 3183, 2343, 1540, 1807, 2599, 2598, 1556, + 737, 1323, 2823, 3559, 2693, 1261, 902, 1879, 2844, 2605, 1599, 1244, 2041, 2919, 2658, 1531 }, { - 1940, 2558, 3310, 3167, 1867, 350, 0, 1062, - 2800, 3765, 3383, 2325, 1683, 1824, 2122, 1810, - 973, 562, 1363, 3030, 4095, 3948, 2338, 733, - 312, 1081, 2042, 2327, 2055, 2043, 2730, 3541, - 3433, 2069, 354, 0, 660, 2465, 3674, 3555, - 2627, 1952, 1980, 2174, 1778, 840, 310, 1054, - 2820, 4095, 4095, 2750, 1016, 328, 870, 1758, - 2102, 1931, 2002, 2773, 3699, 3704, 2351, 483, - 0, 332, 2127, 3511, 3617, 2819, 2147, 2119, - 2272, 1849, 837, 165, 780, 2548, 4095, 4095, - 3056, 1293, 441, 815, 1624, 1964, 1795, 1856, - 2655, 3707, 3898, 2665, 738, 0, 137, 1836, - 3299, 3559, 2871, 2228, 2206, 2400, 2025, 983, - 161, 577, 2243, 3964, 4095, 3212, 1509, 607, - 911, 1683, 1987, 1722, 1634, 2344, 3478, 3919, - 2958, 1144, 0, 179, 1657, 3024, 3299, 2677, - 2126, 2247, 2633, 2411, 1352, 294, 368, 1792, - 3522, 4095, 3306, 1795, 924, 1157, 1829, 2014, - 1589, 1330, 1958, 3199, 3921, 3260, 1583, 231, - 275, 1525, 2778, 3042, 2448, 1949, 2189, 2781, - 2774, 1790, 573, 315, 1429, 3049, 3826, 3210, - 1931, 1202, 1494, 2155, 2234, 1577, 1016, 1432, - 2711, 3741, 3497, 2102, 754, 565, 1507, 2523, - 2671, 2061, 1640, 2072, 2958, 3236, 2353, 953, - 300, 1029, 2487, 3382, 3051, 2056, 1509, 1878, - 2532, 2499, 1601, 718, 888, 2167, 3485, 3671, - 2604, 1315, 927, 1562, 2316, 2308, 1645, 1274, - 1887, 3079, 3677, 2945, 1400, 361, 677, 1927, - 2902, 2843, 2138, 1788, 2244, 2901, 2778, 1670, - 489, 408, 1648, 3195, 3762, 3008, 1804, 1276, - 1670, 2211, 2062, 1311, 912, 1616, 3052, 3976, + 1940, 2558, 3310, 3167, 1867, 350, 0, 1062, + 2800, 3765, 3383, 2325, 1683, 1824, 2122, 1810, + 973, 562, 1363, 3030, 4095, 3948, 2338, 733, + 312, 1081, 2042, 2327, 2055, 2043, 2730, 3541, + 3433, 2069, 354, 0, 660, 2465, 3674, 3555, + 2627, 1952, 1980, 2174, 1778, 840, 310, 1054, + 2820, 4095, 4095, 2750, 1016, 328, 870, 1758, + 2102, 1931, 2002, 2773, 3699, 3704, 2351, 483, + 0, 332, 2127, 3511, 3617, 2819, 2147, 2119, + 2272, 1849, 837, 165, 780, 2548, 4095, 4095, + 3056, 1293, 441, 815, 1624, 1964, 1795, 1856, + 2655, 3707, 3898, 2665, 738, 0, 137, 1836, + 3299, 3559, 2871, 2228, 2206, 2400, 2025, 983, + 161, 577, 2243, 3964, 4095, 3212, 1509, 607, + 911, 1683, 1987, 1722, 1634, 2344, 3478, 3919, + 2958, 1144, 0, 179, 1657, 3024, 3299, 2677, + 2126, 2247, 2633, 2411, 1352, 294, 368, 1792, + 3522, 4095, 3306, 1795, 924, 1157, 1829, 2014, + 1589, 1330, 1958, 3199, 3921, 3260, 1583, 231, + 275, 1525, 2778, 3042, 2448, 1949, 2189, 2781, + 2774, 1790, 573, 315, 1429, 3049, 3826, 3210, + 1931, 1202, 1494, 2155, 2234, 1577, 1016, 1432, + 2711, 3741, 3497, 2102, 754, 565, 1507, 2523, + 2671, 2061, 1640, 2072, 2958, 3236, 2353, 953, + 300, 1029, 2487, 3382, 3051, 2056, 1509, 1878, + 2532, 2499, 1601, 718, 888, 2167, 3485, 3671, + 2604, 1315, 927, 1562, 2316, 2308, 1645, 1274, + 1887, 3079, 3677, 2945, 1400, 361, 677, 1927, + 2902, 2843, 2138, 1788, 2244, 2901, 2778, 1670, + 489, 408, 1648, 3195, 3762, 3008, 1804, 1276, + 1670, 2211, 2062, 1311, 912, 1616, 3052, 3976, 3474, 1900, 566, 489, 1470, 2418, 2532, 2072 }, { - 2305, 1950, 1626, 1814, 2468, 2972, 2698, 1651, - 599, 493, 1629, 3299, 4095, 3750, 2036, 322, - 0, 716, 2337, 3494, 3539, 2733, 1873, 1551, - 1713, 1874, 1704, 1400, 1477, 2176, 3100, 3465, - 2796, 1444, 411, 557, 1859, 3357, 3885, 3012, - 1398, 273, 466, 1773, 3173, 3670, 3055, 1956, - 1225, 1225, 1645, 1927, 1865, 1776, 2102, 2843, - 3423, 3156, 1941, 508, 0, 771, 2528, 3975, - 4081, 2811, 1147, 304, 788, 2069, 3085, 3132, - 2367, 1558, 1356, 1763, 2238, 2291, 1965, 1758, - 2067, 2709, 3020, 2475, 1275, 311, 477, 1870, - 3595, 4095, 3648, 1838, 238, 0, 953, 2472, - 3385, 3239, 2444, 1786, 1701, 1974, 2076, 1773, - 1386, 1465, 2176, 3031, 3252, 2491, 1234, 486, - 945, 2362, 3668, 3808, 2604, 928, 25, 542, - 2045, 3415, 3744, 2992, 1892, 1252, 1307, 1669, - 1826, 1700, 1681, 2158, 2993, 3517, 3093, 1773, - 411, 53, 1073, 2800, 3984, 3764, 2346, 833, - 342, 1140, 2499, 3344, 3124, 2182, 1357, 1230, - 1687, 2150, 2196, 1957, 1926, 2378, 2991, 3078, - 2252, 913, 57, 492, 2102, 3831, 4095, 3481, - 1632, 203, 113, 1246, 2634, 3287, 2946, 2155, - 1671, 1781, 2137, 2202, 1837, 1454, 1587, 2295, - 3011, 3008, 2101, 926, 482, 1281, 2841, 3994, - 3798, 2312, 588, 0, 597, 2192, 3484, 3681, - 2895, 1901, 1409, 1511, 1759, 1733, 1500, 1531, - 2148, 3075, 3557, 3017, 1650, 404, 259, 1409, - 3036, 3917, 3390, 1883, 571, 434, 1497, 2873, - 3520, 3065, 2014, 1233, 1196, 1675, 2076, 2072, - 1891, 2018, 2606, 3204, 3117, 2089, 689, 0, - 611, 2318, 3929, 4095, 3162, 1386, 241, 446, + 2305, 1950, 1626, 1814, 2468, 2972, 2698, 1651, + 599, 493, 1629, 3299, 4095, 3750, 2036, 322, + 0, 716, 2337, 3494, 3539, 2733, 1873, 1551, + 1713, 1874, 1704, 1400, 1477, 2176, 3100, 3465, + 2796, 1444, 411, 557, 1859, 3357, 3885, 3012, + 1398, 273, 466, 1773, 3173, 3670, 3055, 1956, + 1225, 1225, 1645, 1927, 1865, 1776, 2102, 2843, + 3423, 3156, 1941, 508, 0, 771, 2528, 3975, + 4081, 2811, 1147, 304, 788, 2069, 3085, 3132, + 2367, 1558, 1356, 1763, 2238, 2291, 1965, 1758, + 2067, 2709, 3020, 2475, 1275, 311, 477, 1870, + 3595, 4095, 3648, 1838, 238, 0, 953, 2472, + 3385, 3239, 2444, 1786, 1701, 1974, 2076, 1773, + 1386, 1465, 2176, 3031, 3252, 2491, 1234, 486, + 945, 2362, 3668, 3808, 2604, 928, 25, 542, + 2045, 3415, 3744, 2992, 1892, 1252, 1307, 1669, + 1826, 1700, 1681, 2158, 2993, 3517, 3093, 1773, + 411, 53, 1073, 2800, 3984, 3764, 2346, 833, + 342, 1140, 2499, 3344, 3124, 2182, 1357, 1230, + 1687, 2150, 2196, 1957, 1926, 2378, 2991, 3078, + 2252, 913, 57, 492, 2102, 3831, 4095, 3481, + 1632, 203, 113, 1246, 2634, 3287, 2946, 2155, + 1671, 1781, 2137, 2202, 1837, 1454, 1587, 2295, + 3011, 3008, 2101, 926, 482, 1281, 2841, 3994, + 3798, 2312, 588, 0, 597, 2192, 3484, 3681, + 2895, 1901, 1409, 1511, 1759, 1733, 1500, 1531, + 2148, 3075, 3557, 3017, 1650, 404, 259, 1409, + 3036, 3917, 3390, 1883, 571, 434, 1497, 2873, + 3520, 3065, 2014, 1233, 1196, 1675, 2076, 2072, + 1891, 2018, 2606, 3204, 3117, 2089, 689, 0, + 611, 2318, 3929, 4095, 3162, 1386, 241, 446, 1669, 2875, 3209, 2628, 1811, 1479, 1772, 2227 }, { - 2335, 1960, 1685, 1991, 2665, 2957, 2364, 1256, - 1187, 675, 1385, 2969, 4095, 3891, 2178, 296, - 0, 858, 2528, 3499, 3277, 2384, 1687, 1864, - 1755, 1891, 1800, 1493, 1474, 2117, 3086, 3446, - 2627, 1190, 321, 799, 2247, 3423, 3310, 3107, - 1738, 395, 255, 1464, 3033, 3737, 3149, 1995, - 1297, 1347, 1704, 1834, 1723, 1823, 2108, 2639, - 3261, 3208, 2125, 617, 0, 748, 2661, 4066, - 3914, 2447, 933, 547, 1394, 1601, 2804, 3229, - 2646, 1734, 1332, 1636, 2113, 2142, 1819, 1735, - 2218, 2881, 2971, 2189, 1720, 621, 355, 1441, - 3232, 4095, 3802, 1959, 273, 50, 1212, 2640, - 3225, 2756, 1910, 2316, 1840, 1897, 2026, 1814, - 1434, 1470, 2204, 3124, 3256, 2304, 984, 435, - 1171, 2551, 3314, 3642, 2920, 1289, 77, 298, - 1775, 3318, 3760, 2948, 1844, 1312, 1466, 1796, - 1872, 1825, 1577, 1917, 2711, 3406, 3216, 1970, - 487, 10, 1148, 2954, 3986, 3485, 1998, 851, - 972, 994, 2116, 3181, 3271, 2421, 1473, 1207, - 1641, 2110, 2109, 1863, 1914, 2408, 2823, 2479, - 2808, 1550, 347, 282, 1634, 3479, 4095, 3526, - 1607, 217, 326, 1591, 2839, 3159, 2604, 1942, - 1762, 1656, 1999, 2221, 1988, 1609, 1694, 2407, - 3070, 2862, 1756, 638, 549, 1686, 3126, 3294, - 3719, 2662, 912, 0, 407, 2032, 3459, 3612, - 2747, 1800, 1467, 1676, 1899, 1861, 1595, 1503, - 1915, 2795, 3437, 3078, 1735, 392, 309, 1631, - 3271, 3888, 3033, 1515, 651, 866, 1341, 2604, - 3487, 3253, 2196, 1262, 1125, 1617, 2009, 1977, - 1857, 2125, 2738, 3044, 2446, 2512, 1180, 155, - 433, 2025, 3791, 4095, 3137, 1246, 193, 622, + 2335, 1960, 1685, 1991, 2665, 2957, 2364, 1256, + 1187, 675, 1385, 2969, 4095, 3891, 2178, 296, + 0, 858, 2528, 3499, 3277, 2384, 1687, 1864, + 1755, 1891, 1800, 1493, 1474, 2117, 3086, 3446, + 2627, 1190, 321, 799, 2247, 3423, 3310, 3107, + 1738, 395, 255, 1464, 3033, 3737, 3149, 1995, + 1297, 1347, 1704, 1834, 1723, 1823, 2108, 2639, + 3261, 3208, 2125, 617, 0, 748, 2661, 4066, + 3914, 2447, 933, 547, 1394, 1601, 2804, 3229, + 2646, 1734, 1332, 1636, 2113, 2142, 1819, 1735, + 2218, 2881, 2971, 2189, 1720, 621, 355, 1441, + 3232, 4095, 3802, 1959, 273, 50, 1212, 2640, + 3225, 2756, 1910, 2316, 1840, 1897, 2026, 1814, + 1434, 1470, 2204, 3124, 3256, 2304, 984, 435, + 1171, 2551, 3314, 3642, 2920, 1289, 77, 298, + 1775, 3318, 3760, 2948, 1844, 1312, 1466, 1796, + 1872, 1825, 1577, 1917, 2711, 3406, 3216, 1970, + 487, 10, 1148, 2954, 3986, 3485, 1998, 851, + 972, 994, 2116, 3181, 3271, 2421, 1473, 1207, + 1641, 2110, 2109, 1863, 1914, 2408, 2823, 2479, + 2808, 1550, 347, 282, 1634, 3479, 4095, 3526, + 1607, 217, 326, 1591, 2839, 3159, 2604, 1942, + 1762, 1656, 1999, 2221, 1988, 1609, 1694, 2407, + 3070, 2862, 1756, 638, 549, 1686, 3126, 3294, + 3719, 2662, 912, 0, 407, 2032, 3459, 3612, + 2747, 1800, 1467, 1676, 1899, 1861, 1595, 1503, + 1915, 2795, 3437, 3078, 1735, 392, 309, 1631, + 3271, 3888, 3033, 1515, 651, 866, 1341, 2604, + 3487, 3253, 2196, 1262, 1125, 1617, 2009, 1977, + 1857, 2125, 2738, 3044, 2446, 2512, 1180, 155, + 433, 2025, 3791, 4095, 3137, 1246, 193, 622, 1932, 2950, 3001, 2393, 2115, 1507, 1558, 1991 }, { - 2299, 1606, 1862, 2187, 2600, 3114, 2824, 819, - 742, 762, 1777, 2857, 3979, 4095, 2607, 70, - 0, 1274, 2290, 3296, 3402, 2624, 1883, 2093, - 1423, 1682, 1942, 1277, 1503, 2618, 2805, 3895, - 2249, 1512, 0, 904, 1903, 3739, 3659, 3477, - 1378, 119, 643, 1169, 2648, 4095, 3128, 2162, - 1306, 1460, 1690, 1974, 1373, 1684, 1967, 3108, - 3257, 3304, 2323, 309, 7, 529, 2826, 4095, - 3817, 2606, 606, 565, 1564, 1755, 2924, 3206, - 2565, 1884, 1147, 1262, 2231, 2237, 2195, 2100, - 1944, 2626, 3225, 1916, 1444, 924, 395, 1723, - 3132, 4095, 3586, 1748, 42, 268, 1482, 2742, - 3110, 2570, 2025, 2385, 1828, 2180, 1616, 1958, - 1380, 1703, 2019, 3249, 3581, 2116, 685, 199, - 1554, 2900, 3289, 3588, 2850, 1045, 0, 597, - 1989, 3292, 3640, 3076, 1633, 1156, 1650, 2200, - 1884, 1603, 1349, 2034, 2754, 3521, 3437, 1599, - 744, 0, 1040, 3065, 4095, 3458, 1782, 963, - 997, 977, 1824, 3559, 3467, 2488, 1558, 699, - 1750, 1983, 2306, 1793, 2240, 2704, 2237, 2629, - 2939, 1330, 530, 545, 1391, 3086, 4095, 3624, - 1583, 443, 206, 1788, 2457, 3132, 2913, 1810, - 1654, 1539, 2375, 2330, 2305, 1378, 1366, 2269, - 3182, 3207, 1447, 648, 813, 1931, 3069, 3286, - 3459, 2647, 833, 0, 589, 2201, 3797, 3585, - 2499, 1455, 1353, 2169, 2045, 1862, 1599, 1248, - 1735, 3087, 3519, 3073, 1783, 586, 403, 1230, - 3053, 4030, 3230, 1553, 814, 1012, 1239, 2409, - 3612, 3022, 2454, 988, 1344, 1690, 2015, 2311, - 1661, 1882, 2970, 3096, 2259, 2286, 1362, 415, - 382, 2202, 4077, 4095, 2592, 1052, 470, 805, + 2299, 1606, 1862, 2187, 2600, 3114, 2824, 819, + 742, 762, 1777, 2857, 3979, 4095, 2607, 70, + 0, 1274, 2290, 3296, 3402, 2624, 1883, 2093, + 1423, 1682, 1942, 1277, 1503, 2618, 2805, 3895, + 2249, 1512, 0, 904, 1903, 3739, 3659, 3477, + 1378, 119, 643, 1169, 2648, 4095, 3128, 2162, + 1306, 1460, 1690, 1974, 1373, 1684, 1967, 3108, + 3257, 3304, 2323, 309, 7, 529, 2826, 4095, + 3817, 2606, 606, 565, 1564, 1755, 2924, 3206, + 2565, 1884, 1147, 1262, 2231, 2237, 2195, 2100, + 1944, 2626, 3225, 1916, 1444, 924, 395, 1723, + 3132, 4095, 3586, 1748, 42, 268, 1482, 2742, + 3110, 2570, 2025, 2385, 1828, 2180, 1616, 1958, + 1380, 1703, 2019, 3249, 3581, 2116, 685, 199, + 1554, 2900, 3289, 3588, 2850, 1045, 0, 597, + 1989, 3292, 3640, 3076, 1633, 1156, 1650, 2200, + 1884, 1603, 1349, 2034, 2754, 3521, 3437, 1599, + 744, 0, 1040, 3065, 4095, 3458, 1782, 963, + 997, 977, 1824, 3559, 3467, 2488, 1558, 699, + 1750, 1983, 2306, 1793, 2240, 2704, 2237, 2629, + 2939, 1330, 530, 545, 1391, 3086, 4095, 3624, + 1583, 443, 206, 1788, 2457, 3132, 2913, 1810, + 1654, 1539, 2375, 2330, 2305, 1378, 1366, 2269, + 3182, 3207, 1447, 648, 813, 1931, 3069, 3286, + 3459, 2647, 833, 0, 589, 2201, 3797, 3585, + 2499, 1455, 1353, 2169, 2045, 1862, 1599, 1248, + 1735, 3087, 3519, 3073, 1783, 586, 403, 1230, + 3053, 4030, 3230, 1553, 814, 1012, 1239, 2409, + 3612, 3022, 2454, 988, 1344, 1690, 2015, 2311, + 1661, 1882, 2970, 3096, 2259, 2286, 1362, 415, + 382, 2202, 4077, 4095, 2592, 1052, 470, 805, 2008, 3117, 3179, 2167, 1896, 1466, 1818, 2081 }, { - 1966, 2056, 2324, 2444, 1716, 1440, 1465, 1652, - 1875, 2034, 2094, 2076, 2037, 2105, 2583, 1888, - 994, 1008, 1565, 2138, 2414, 2398, 2270, 2152, - 2001, 1726, 1370, 1159, 1325, 1872, 2502, 2825, - 2599, 1908, 1177, 1358, 1754, 1897, 1956, 1973, - 1965, 1970, 2000, 2020, 1980, 1914, 1867, 1698, - 1633, 1822, 2021, 2054, 1931, 1831, 1905, 2094, - 2140, 1824, 1297, 1964, 2188, 1828, 1576, 2128, - 2255, 1961, 1600, 1533, 1823, 2209, 2347, 2115, - 1705, 1447, 1526, 1839, 2117, 2168, 2035, 1919, - 1948, 2041, 1998, 1724, 1392, 1362, 1896, 2811, - 2122, 1739, 1726, 1901, 2062, 2040, 1867, 1669, - 1531, 1527, 1740, 2238, 2702, 2377, 1984, 1563, - 1305, 1376, 1742, 2165, 2333, 2139, 1788, 1624, - 1819, 2208, 2414, 2176, 1596, 1106, 1087, 1600, - 2354, 2838, 2758, 2219, 1598, 1247, 1250, 1468, - 1734, 2029, 2451, 2851, 2030, 1593, 1481, 1600, - 1808, 1954, 2009, 2012, 1969, 1886, 1800, 1768, - 1812, 1937, 2247, 2475, 1925, 1398, 1223, 1479, - 1957, 2335, 2421, 2267, 2054, 1870, 1614, 1148, - 1402, 2051, 2361, 2381, 2151, 1806, 1621, 1674, - 1793, 1900, 1995, 2059, 2054, 1959, 1750, 1419, - 1732, 2123, 2329, 2207, 1857, 1571, 1594, 1896, - 2180, 2116, 1639, 1438, 1959, 2116, 2093, 2051, - 2049, 2037, 1956, 1739, 1214, 911, 2104, 2666, - 2618, 2292, 1979, 1758, 1557, 1351, 1268, 1485, - 2014, 2601, 2861, 2571, 1885, 1233, 989, 1278, - 1853, 2301, 2449, 2380, 2080, 1765, 1562, 1513, - 1617, 1930, 2552, 2071, 1735, 1723, 1797, 1809, - 1807, 1898, 2059, 2111, 2091, 2188, 1924, 1185, - 1048, 1869, 2546, 2656, 2239, 1647, 1338, 1500, + 1966, 2056, 2324, 2444, 1716, 1440, 1465, 1652, + 1875, 2034, 2094, 2076, 2037, 2105, 2583, 1888, + 994, 1008, 1565, 2138, 2414, 2398, 2270, 2152, + 2001, 1726, 1370, 1159, 1325, 1872, 2502, 2825, + 2599, 1908, 1177, 1358, 1754, 1897, 1956, 1973, + 1965, 1970, 2000, 2020, 1980, 1914, 1867, 1698, + 1633, 1822, 2021, 2054, 1931, 1831, 1905, 2094, + 2140, 1824, 1297, 1964, 2188, 1828, 1576, 2128, + 2255, 1961, 1600, 1533, 1823, 2209, 2347, 2115, + 1705, 1447, 1526, 1839, 2117, 2168, 2035, 1919, + 1948, 2041, 1998, 1724, 1392, 1362, 1896, 2811, + 2122, 1739, 1726, 1901, 2062, 2040, 1867, 1669, + 1531, 1527, 1740, 2238, 2702, 2377, 1984, 1563, + 1305, 1376, 1742, 2165, 2333, 2139, 1788, 1624, + 1819, 2208, 2414, 2176, 1596, 1106, 1087, 1600, + 2354, 2838, 2758, 2219, 1598, 1247, 1250, 1468, + 1734, 2029, 2451, 2851, 2030, 1593, 1481, 1600, + 1808, 1954, 2009, 2012, 1969, 1886, 1800, 1768, + 1812, 1937, 2247, 2475, 1925, 1398, 1223, 1479, + 1957, 2335, 2421, 2267, 2054, 1870, 1614, 1148, + 1402, 2051, 2361, 2381, 2151, 1806, 1621, 1674, + 1793, 1900, 1995, 2059, 2054, 1959, 1750, 1419, + 1732, 2123, 2329, 2207, 1857, 1571, 1594, 1896, + 2180, 2116, 1639, 1438, 1959, 2116, 2093, 2051, + 2049, 2037, 1956, 1739, 1214, 911, 2104, 2666, + 2618, 2292, 1979, 1758, 1557, 1351, 1268, 1485, + 2014, 2601, 2861, 2571, 1885, 1233, 989, 1278, + 1853, 2301, 2449, 2380, 2080, 1765, 1562, 1513, + 1617, 1930, 2552, 2071, 1735, 1723, 1797, 1809, + 1807, 1898, 2059, 2111, 2091, 2188, 1924, 1185, + 1048, 1869, 2546, 2656, 2239, 1647, 1338, 1500, 1926, 2232, 2194, 1935, 1853, 1585, 1647, 1843 }, { - 1659, 2675, 2749, 995, 2173, 1940, 1758, 1737, - 1805, 1884, 1945, 2020, 2163, 2406, 1786, 2321, - 991, 844, 1698, 2413, 2642, 2402, 2020, 1879, - 1873, 1701, 1340, 1179, 1629, 2362, 2546, 2823, - 2611, 635, 1054, 2099, 1830, 1970, 2091, 2189, - 2174, 2003, 1706, 1379, 1301, 1802, 2504, 3525, - 1931, 631, 1107, 1894, 2188, 2207, 2261, 2251, - 1696, 718, 3108, 1636, 1614, 2164, 1962, 1527, - 2214, 2001, 1463, 1379, 1962, 2680, 2826, 2236, - 1296, 814, 1099, 1902, 2559, 2590, 2142, 1841, - 1891, 2012, 1954, 1594, 1161, 1342, 2876, 1538, - 2388, 2161, 1968, 1905, 1876, 1872, 1781, 1648, - 1622, 1774, 2024, 1808, 1350, 3460, 2891, 1498, - 1072, 1273, 1372, 1966, 2476, 2263, 1679, 1448, - 1930, 2703, 2997, 2280, 930, 682, 802, 982, - 2550, 3717, 3622, 2527, 1167, 573, 651, 1194, - 2057, 3027, 3472, 328, 2460, 2176, 1868, 1735, - 1734, 1783, 1780, 1757, 1784, 1880, 2039, 2201, - 2229, 2073, 1483, 1629, 2971, 1691, 851, 1072, - 1864, 2609, 2790, 2451, 1961, 1515, 1103, 1847, - 2014, 1647, 1888, 2020, 2063, 2184, 2102, 1878, - 1874, 1891, 1808, 1635, 1480, 1540, 2049, 3897, - 1024, 1088, 2025, 2385, 2069, 1655, 1649, 2000, - 2132, 1527, 1310, 2922, 1737, 1758, 1870, 1969, - 2088, 2176, 2080, 1699, 1295, 1033, 1600, 2820, - 2718, 2287, 1985, 1875, 1713, 1312, 1028, 1302, - 2030, 2858, 3103, 2414, 1614, 1352, 673, 1103, - 3016, 3299, 1642, 303, 1899, 2475, 2407, 2217, - 2137, 2046, 0, 2298, 2414, 2355, 2160, 1584, - 1115, 1349, 2022, 3000, 3585, 1751, 1024, 1398, - 0, 1191, 3177, 3342, 3377, 2277, 1124, 914, + 1659, 2675, 2749, 995, 2173, 1940, 1758, 1737, + 1805, 1884, 1945, 2020, 2163, 2406, 1786, 2321, + 991, 844, 1698, 2413, 2642, 2402, 2020, 1879, + 1873, 1701, 1340, 1179, 1629, 2362, 2546, 2823, + 2611, 635, 1054, 2099, 1830, 1970, 2091, 2189, + 2174, 2003, 1706, 1379, 1301, 1802, 2504, 3525, + 1931, 631, 1107, 1894, 2188, 2207, 2261, 2251, + 1696, 718, 3108, 1636, 1614, 2164, 1962, 1527, + 2214, 2001, 1463, 1379, 1962, 2680, 2826, 2236, + 1296, 814, 1099, 1902, 2559, 2590, 2142, 1841, + 1891, 2012, 1954, 1594, 1161, 1342, 2876, 1538, + 2388, 2161, 1968, 1905, 1876, 1872, 1781, 1648, + 1622, 1774, 2024, 1808, 1350, 3460, 2891, 1498, + 1072, 1273, 1372, 1966, 2476, 2263, 1679, 1448, + 1930, 2703, 2997, 2280, 930, 682, 802, 982, + 2550, 3717, 3622, 2527, 1167, 573, 651, 1194, + 2057, 3027, 3472, 328, 2460, 2176, 1868, 1735, + 1734, 1783, 1780, 1757, 1784, 1880, 2039, 2201, + 2229, 2073, 1483, 1629, 2971, 1691, 851, 1072, + 1864, 2609, 2790, 2451, 1961, 1515, 1103, 1847, + 2014, 1647, 1888, 2020, 2063, 2184, 2102, 1878, + 1874, 1891, 1808, 1635, 1480, 1540, 2049, 3897, + 1024, 1088, 2025, 2385, 2069, 1655, 1649, 2000, + 2132, 1527, 1310, 2922, 1737, 1758, 1870, 1969, + 2088, 2176, 2080, 1699, 1295, 1033, 1600, 2820, + 2718, 2287, 1985, 1875, 1713, 1312, 1028, 1302, + 2030, 2858, 3103, 2414, 1614, 1352, 673, 1103, + 3016, 3299, 1642, 303, 1899, 2475, 2407, 2217, + 2137, 2046, 0, 2298, 2414, 2355, 2160, 1584, + 1115, 1349, 2022, 3000, 3585, 1751, 1024, 1398, + 0, 1191, 3177, 3342, 3377, 2277, 1124, 914, 1094, 1158, 1371, 2973, 3320, 3253, 614, 540 }, { - 2099, 2469, 2236, 702, 2306, 2265, 1928, 1672, - 1726, 1987, 2127, 1964, 1717, 1825, 1554, 2705, - 1775, 1502, 1837, 2050, 2091, 1947, 1738, 1739, - 1928, 2072, 2002, 1816, 1805, 1889, 1699, 2154, - 2518, 1076, 1654, 2496, 1911, 1823, 1821, 1849, - 1867, 1940, 2050, 1998, 1745, 1642, 1760, 2739, - 1747, 1219, 1994, 2375, 1945, 1549, 1785, 2277, - 2037, 959, 3051, 1449, 1562, 2284, 2050, 1433, - 2072, 2097, 1863, 1753, 1851, 1981, 1988, 1929, - 1821, 1824, 1884, 1978, 2013, 1910, 1751, 1793, - 1972, 2055, 2014, 1821, 1560, 1700, 2938, 1246, - 1937, 1827, 1891, 2013, 2000, 1913, 1785, 1739, - 1875, 2124, 2270, 1727, 862, 2745, 2341, 1478, - 1641, 2081, 1896, 1913, 2030, 1912, 1750, 1767, - 1969, 2110, 2036, 1726, 1441, 2175, 2393, 1596, - 1717, 1928, 1974, 1960, 1874, 1981, 1892, 1671, - 1728, 2290, 2824, 56, 2531, 2354, 1939, 1671, - 1684, 1912, 2091, 2064, 1866, 1685, 1736, 2015, - 2225, 2101, 1361, 1380, 2857, 1977, 1503, 1703, - 2007, 2108, 1943, 1793, 1857, 1922, 1671, 2226, - 2096, 1558, 1797, 1981, 2008, 2034, 1869, 1668, - 1813, 2043, 2128, 1982, 1677, 1472, 1753, 3561, - 869, 1194, 2258, 2509, 1963, 1436, 1561, 2174, - 2442, 1702, 1200, 2655, 1589, 1862, 2067, 1960, - 1757, 1756, 1974, 2111, 2016, 1591, 1633, 2335, - 2028, 1730, 1723, 1922, 2063, 1955, 1810, 1841, - 1901, 1979, 1939, 1732, 1897, 2363, 1614, 1272, - 2407, 2579, 1525, 879, 2556, 2497, 1674, 1351, - 1926, 2700, 844, 2684, 1928, 1498, 1787, 2108, - 2115, 1928, 1585, 1766, 2412, 1472, 1850, 2833, - 998, 1559, 2529, 2010, 2009, 1560, 1460, 2158, + 2099, 2469, 2236, 702, 2306, 2265, 1928, 1672, + 1726, 1987, 2127, 1964, 1717, 1825, 1554, 2705, + 1775, 1502, 1837, 2050, 2091, 1947, 1738, 1739, + 1928, 2072, 2002, 1816, 1805, 1889, 1699, 2154, + 2518, 1076, 1654, 2496, 1911, 1823, 1821, 1849, + 1867, 1940, 2050, 1998, 1745, 1642, 1760, 2739, + 1747, 1219, 1994, 2375, 1945, 1549, 1785, 2277, + 2037, 959, 3051, 1449, 1562, 2284, 2050, 1433, + 2072, 2097, 1863, 1753, 1851, 1981, 1988, 1929, + 1821, 1824, 1884, 1978, 2013, 1910, 1751, 1793, + 1972, 2055, 2014, 1821, 1560, 1700, 2938, 1246, + 1937, 1827, 1891, 2013, 2000, 1913, 1785, 1739, + 1875, 2124, 2270, 1727, 862, 2745, 2341, 1478, + 1641, 2081, 1896, 1913, 2030, 1912, 1750, 1767, + 1969, 2110, 2036, 1726, 1441, 2175, 2393, 1596, + 1717, 1928, 1974, 1960, 1874, 1981, 1892, 1671, + 1728, 2290, 2824, 56, 2531, 2354, 1939, 1671, + 1684, 1912, 2091, 2064, 1866, 1685, 1736, 2015, + 2225, 2101, 1361, 1380, 2857, 1977, 1503, 1703, + 2007, 2108, 1943, 1793, 1857, 1922, 1671, 2226, + 2096, 1558, 1797, 1981, 2008, 2034, 1869, 1668, + 1813, 2043, 2128, 1982, 1677, 1472, 1753, 3561, + 869, 1194, 2258, 2509, 1963, 1436, 1561, 2174, + 2442, 1702, 1200, 2655, 1589, 1862, 2067, 1960, + 1757, 1756, 1974, 2111, 2016, 1591, 1633, 2335, + 2028, 1730, 1723, 1922, 2063, 1955, 1810, 1841, + 1901, 1979, 1939, 1732, 1897, 2363, 1614, 1272, + 2407, 2579, 1525, 879, 2556, 2497, 1674, 1351, + 1926, 2700, 844, 2684, 1928, 1498, 1787, 2108, + 2115, 1928, 1585, 1766, 2412, 1472, 1850, 2833, + 998, 1559, 2529, 2010, 2009, 1560, 1460, 2158, 2552, 1961, 1049, 1816, 2175, 2885, 1132, 1374 }, { - 2298, 2981, 1544, 1907, 2114, 2357, 2312, 2031, - 1922, 2051, 2257, 2329, 2136, 1889, 1951, 2330, - 2524, 1904, 1503, 2689, 2381, 1845, 1847, 2222, - 2478, 2244, 1733, 1671, 2468, 3711, 0, 2679, - 2483, 2319, 2099, 1806, 1780, 2394, 3172, 907, - 2428, 2019, 1976, 3332, 949, 2022, 2567, 2323, - 1942, 1935, 2190, 2256, 2131, 2022, 2136, 2259, - 2068, 1982, 2103, 2405, 2424, 1147, 2599, 2418, - 2080, 1906, 1999, 2236, 2336, 2151, 1935, 1952, - 2363, 2253, 1921, 2191, 2200, 1994, 1982, 2335, - 2577, 1839, 774, 4095, 1331, 2647, 760, 2895, - 2687, 1875, 1701, 2040, 2404, 2410, 2086, 1796, - 1879, 2320, 2724, 2512, 11, 3311, 3102, 1436, - 1248, 3032, 2012, 2081, 2195, 1962, 2073, 2353, - 2250, 1298, 3430, 1288, 2013, 2392, 2304, 2042, - 1870, 2446, 1774, 2216, 2566, 1933, 1739, 2235, - 2345, 2240, 2076, 1867, 2092, 2289, 2236, 2183, - 2067, 1880, 1944, 2478, 2615, 1919, 1406, 1820, - 3158, 2882, 1131, 777, 3423, 2936, 1687, 1391, - 1985, 2647, 2670, 1894, 950, 3538, 1441, 2122, - 2405, 2205, 1920, 1914, 2189, 2417, 2283, 1842, - 1983, 2034, 2172, 2886, 2024, 916, 2464, 2887, - 2448, 1253, 1916, 2446, 2377, 2219, 2125, 1761, - 1342, 3767, 1742, 1619, 2008, 2362, 2340, 2127, - 1995, 1992, 2119, 2263, 2278, 2123, 1862, 1684, - 3480, 1143, 1973, 2577, 2351, 1813, 1654, 2372, - 3429, 458, 2493, 2385, 2266, 2090, 1932, 2110, - 1759, 3261, 1250, 2307, 2104, 1810, 2959, 1710, - 1826, 2277, 2319, 2116, 2022, 2111, 2165, 2106, - 2081, 2200, 2374, 2014, 1103, 3510, 1988, 1764, - 1659, 2400, 2848, 1755, 1832, 1996, 2283, 2580, + 2298, 2981, 1544, 1907, 2114, 2357, 2312, 2031, + 1922, 2051, 2257, 2329, 2136, 1889, 1951, 2330, + 2524, 1904, 1503, 2689, 2381, 1845, 1847, 2222, + 2478, 2244, 1733, 1671, 2468, 3711, 0, 2679, + 2483, 2319, 2099, 1806, 1780, 2394, 3172, 907, + 2428, 2019, 1976, 3332, 949, 2022, 2567, 2323, + 1942, 1935, 2190, 2256, 2131, 2022, 2136, 2259, + 2068, 1982, 2103, 2405, 2424, 1147, 2599, 2418, + 2080, 1906, 1999, 2236, 2336, 2151, 1935, 1952, + 2363, 2253, 1921, 2191, 2200, 1994, 1982, 2335, + 2577, 1839, 774, 4095, 1331, 2647, 760, 2895, + 2687, 1875, 1701, 2040, 2404, 2410, 2086, 1796, + 1879, 2320, 2724, 2512, 11, 3311, 3102, 1436, + 1248, 3032, 2012, 2081, 2195, 1962, 2073, 2353, + 2250, 1298, 3430, 1288, 2013, 2392, 2304, 2042, + 1870, 2446, 1774, 2216, 2566, 1933, 1739, 2235, + 2345, 2240, 2076, 1867, 2092, 2289, 2236, 2183, + 2067, 1880, 1944, 2478, 2615, 1919, 1406, 1820, + 3158, 2882, 1131, 777, 3423, 2936, 1687, 1391, + 1985, 2647, 2670, 1894, 950, 3538, 1441, 2122, + 2405, 2205, 1920, 1914, 2189, 2417, 2283, 1842, + 1983, 2034, 2172, 2886, 2024, 916, 2464, 2887, + 2448, 1253, 1916, 2446, 2377, 2219, 2125, 1761, + 1342, 3767, 1742, 1619, 2008, 2362, 2340, 2127, + 1995, 1992, 2119, 2263, 2278, 2123, 1862, 1684, + 3480, 1143, 1973, 2577, 2351, 1813, 1654, 2372, + 3429, 458, 2493, 2385, 2266, 2090, 1932, 2110, + 1759, 3261, 1250, 2307, 2104, 1810, 2959, 1710, + 1826, 2277, 2319, 2116, 2022, 2111, 2165, 2106, + 2081, 2200, 2374, 2014, 1103, 3510, 1988, 1764, + 1659, 2400, 2848, 1755, 1832, 1996, 2283, 2580, 2140, 1399, 2388, 2249, 2290, 2145, 2045, 1628 }, { - 1924, 2444, 2813, 2991, 2986, 2843, 2628, 2452, - 2434, 2498, 2306, 1709, 1257, 1437, 1788, 1893, - 1862, 1859, 1900, 1934, 1937, 2067, 2535, 3037, - 2605, 1507, 2993, 4095, 2387, 1241, 1643, 1400, - 1577, 1690, 1700, 1583, 1320, 1297, 897, 4095, - 1859, 4095, 3945, 1699, 4095, 2586, 839, 274, - 2773, 861, 522, 638, 3159, 670, 3569, 3585, - 2275, 2822, 3052, 2773, 1831, 1291, 2065, 1950, - 1808, 1722, 1680, 1706, 1839, 2112, 2552, 3205, - 3077, 2986, 9, 2037, 2278, 2969, 1623, 247, - 814, 3418, 3028, 3659, 3881, 1185, 3474, 610, - 706, 1054, 1511, 1892, 2219, 2487, 2671, 2743, - 2690, 2535, 2346, 2195, 2099, 2027, 1929, 1766, - 1551, 1422, 1955, 3456, 1602, 1469, 1901, 2533, - 2937, 2774, 2129, 1705, 2157, 2768, 2283, 1411, - 1188, 1551, 2052, 2447, 2685, 2751, 2625, 2315, - 1913, 1593, 1500, 1659, 1967, 2259, 2430, 2493, - 2525, 2565, 2554, 2374, 1960, 1424, 1070, 1200, - 1881, 2674, 2940, 2849, 2779, 2370, 1681, 1327, - 1582, 2205, 2654, 2062, 1522, 2701, 2513, 2191, - 1971, 1869, 1866, 1953, 2125, 2366, 2612, 2655, - 1259, 2467, 2051, 1394, 2036, 1824, 2313, 2528, - 2549, 2764, 2979, 100, 3505, 2383, 1098, 570, - 3751, 1455, 1648, 1943, 2152, 2304, 2368, 2476, - 2677, 2783, 2720, 2510, 2188, 1792, 1355, 904, - 494, 1440, 749, 4095, 3212, 2926, 4095, 1520, - 2034, 1383, 1679, 1814, 1792, 1641, 1368, 1075, - 3968, 1321, 4081, 1908, 2868, 2153, 433, 2197, - 2089, 1958, 1946, 1979, 2098, 2196, 2320, 2614, - 2993, 3269, 3108, 2003, 630, 616, 1624, 1690, - 1185, 1322, 1960, 2600, 3081, 3429, 3627, 3562, + 1924, 2444, 2813, 2991, 2986, 2843, 2628, 2452, + 2434, 2498, 2306, 1709, 1257, 1437, 1788, 1893, + 1862, 1859, 1900, 1934, 1937, 2067, 2535, 3037, + 2605, 1507, 2993, 4095, 2387, 1241, 1643, 1400, + 1577, 1690, 1700, 1583, 1320, 1297, 897, 4095, + 1859, 4095, 3945, 1699, 4095, 2586, 839, 274, + 2773, 861, 522, 638, 3159, 670, 3569, 3585, + 2275, 2822, 3052, 2773, 1831, 1291, 2065, 1950, + 1808, 1722, 1680, 1706, 1839, 2112, 2552, 3205, + 3077, 2986, 9, 2037, 2278, 2969, 1623, 247, + 814, 3418, 3028, 3659, 3881, 1185, 3474, 610, + 706, 1054, 1511, 1892, 2219, 2487, 2671, 2743, + 2690, 2535, 2346, 2195, 2099, 2027, 1929, 1766, + 1551, 1422, 1955, 3456, 1602, 1469, 1901, 2533, + 2937, 2774, 2129, 1705, 2157, 2768, 2283, 1411, + 1188, 1551, 2052, 2447, 2685, 2751, 2625, 2315, + 1913, 1593, 1500, 1659, 1967, 2259, 2430, 2493, + 2525, 2565, 2554, 2374, 1960, 1424, 1070, 1200, + 1881, 2674, 2940, 2849, 2779, 2370, 1681, 1327, + 1582, 2205, 2654, 2062, 1522, 2701, 2513, 2191, + 1971, 1869, 1866, 1953, 2125, 2366, 2612, 2655, + 1259, 2467, 2051, 1394, 2036, 1824, 2313, 2528, + 2549, 2764, 2979, 100, 3505, 2383, 1098, 570, + 3751, 1455, 1648, 1943, 2152, 2304, 2368, 2476, + 2677, 2783, 2720, 2510, 2188, 1792, 1355, 904, + 494, 1440, 749, 4095, 3212, 2926, 4095, 1520, + 2034, 1383, 1679, 1814, 1792, 1641, 1368, 1075, + 3968, 1321, 4081, 1908, 2868, 2153, 433, 2197, + 2089, 1958, 1946, 1979, 2098, 2196, 2320, 2614, + 2993, 3269, 3108, 2003, 630, 616, 1624, 1690, + 1185, 1322, 1960, 2600, 3081, 3429, 3627, 3562, 3123, 2349, 1527, 976, 714, 658, 869, 1345 }, { - 1978, 2287, 2526, 2669, 2687, 2577, 2388, 2225, - 2197, 2323, 2481, 2505, 2388, 2223, 1976, 1694, - 1507, 1450, 1453, 1439, 1427, 1561, 2010, 2746, - 3403, 3628, 4078, 3807, 2389, 899, 1003, 1447, - 1671, 1739, 1691, 1522, 1184, 554, 648, 3083, - 3818, 3891, 3918, 3834, 3555, 2432, 1470, 767, - 771, 762, 962, 883, 941, 1513, 3249, 4000, - 3729, 3335, 2717, 2321, 2333, 2123, 1688, 1383, - 1269, 1282, 1383, 1574, 1866, 2260, 2766, 3457, - 4095, 3462, 1413, 1042, 1071, 1153, 780, 812, - 1586, 3041, 4083, 3878, 3731, 3467, 2518, 32, - 304, 967, 1415, 1780, 2103, 2382, 2594, 2715, - 2729, 2642, 2496, 2374, 2319, 2292, 2230, 2098, - 1878, 1568, 1256, 1339, 1443, 1902, 2434, 2940, - 3241, 3172, 2728, 2140, 1745, 1611, 1490, 1512, - 1766, 2091, 2349, 2503, 2567, 2543, 2416, 2195, - 1936, 1741, 1692, 1804, 2010, 2210, 2339, 2400, - 2437, 2471, 2465, 2345, 2074, 1728, 1483, 1520, - 1888, 2416, 2792, 2848, 2593, 2085, 1562, 1321, - 1470, 1907, 2449, 2909, 2959, 2629, 2217, 1945, - 1799, 1740, 1744, 1802, 1916, 2092, 2334, 2643, - 2867, 2610, 1676, 1174, 1590, 2542, 2417, 2057, - 2012, 2246, 2772, 2886, 2961, 2174, 1527, 927, - 1176, 1434, 1980, 2292, 2408, 2433, 2521, 2716, - 2869, 2872, 2728, 2479, 2159, 1797, 1417, 1020, - 551, 0, 965, 3313, 4095, 4095, 4036, 1891, - 1026, 1725, 2085, 2203, 2157, 1975, 1642, 1080, - 858, 1439, 3279, 3362, 2978, 2705, 2345, 2051, - 1614, 1552, 1722, 1899, 1989, 2034, 2174, 2497, - 2904, 3160, 3029, 2405, 1550, 993, 950, 1074, - 1350, 1848, 2358, 2732, 2971, 3126, 3193, 3108, + 1978, 2287, 2526, 2669, 2687, 2577, 2388, 2225, + 2197, 2323, 2481, 2505, 2388, 2223, 1976, 1694, + 1507, 1450, 1453, 1439, 1427, 1561, 2010, 2746, + 3403, 3628, 4078, 3807, 2389, 899, 1003, 1447, + 1671, 1739, 1691, 1522, 1184, 554, 648, 3083, + 3818, 3891, 3918, 3834, 3555, 2432, 1470, 767, + 771, 762, 962, 883, 941, 1513, 3249, 4000, + 3729, 3335, 2717, 2321, 2333, 2123, 1688, 1383, + 1269, 1282, 1383, 1574, 1866, 2260, 2766, 3457, + 4095, 3462, 1413, 1042, 1071, 1153, 780, 812, + 1586, 3041, 4083, 3878, 3731, 3467, 2518, 32, + 304, 967, 1415, 1780, 2103, 2382, 2594, 2715, + 2729, 2642, 2496, 2374, 2319, 2292, 2230, 2098, + 1878, 1568, 1256, 1339, 1443, 1902, 2434, 2940, + 3241, 3172, 2728, 2140, 1745, 1611, 1490, 1512, + 1766, 2091, 2349, 2503, 2567, 2543, 2416, 2195, + 1936, 1741, 1692, 1804, 2010, 2210, 2339, 2400, + 2437, 2471, 2465, 2345, 2074, 1728, 1483, 1520, + 1888, 2416, 2792, 2848, 2593, 2085, 1562, 1321, + 1470, 1907, 2449, 2909, 2959, 2629, 2217, 1945, + 1799, 1740, 1744, 1802, 1916, 2092, 2334, 2643, + 2867, 2610, 1676, 1174, 1590, 2542, 2417, 2057, + 2012, 2246, 2772, 2886, 2961, 2174, 1527, 927, + 1176, 1434, 1980, 2292, 2408, 2433, 2521, 2716, + 2869, 2872, 2728, 2479, 2159, 1797, 1417, 1020, + 551, 0, 965, 3313, 4095, 4095, 4036, 1891, + 1026, 1725, 2085, 2203, 2157, 1975, 1642, 1080, + 858, 1439, 3279, 3362, 2978, 2705, 2345, 2051, + 1614, 1552, 1722, 1899, 1989, 2034, 2174, 2497, + 2904, 3160, 3029, 2405, 1550, 993, 950, 1074, + 1350, 1848, 2358, 2732, 2971, 3126, 3193, 3108, 2807, 2308, 1746, 1299, 1076, 1091, 1304, 1631 }, { - 1974, 2482, 2875, 3104, 3130, 2965, 2685, 2444, - 2398, 2432, 1941, 1529, 1311, 1281, 1417, 1638, - 1741, 1802, 1867, 1875, 1834, 1943, 2424, 3078, - 2950, 3018, 3414, 3767, 1893, 292, 1172, 1495, - 1619, 1650, 1618, 1519, 1311, 830, 542, 2902, - 3970, 3585, 3716, 4095, 3246, 2351, 1679, 1158, - 715, 432, 429, 557, 1153, 2006, 2746, 3118, - 3104, 2866, 2619, 2497, 2500, 2536, 2518, 2417, - 2251, 2029, 1729, 1335, 915, 637, 609, 848, - 1492, 2361, 3139, 3618, 3787, 3748, 3570, 3205, - 2516, 1447, 246, 0, 141, 0, 1344, 3608, - 3264, 2852, 2669, 2550, 2442, 2336, 2235, 2148, - 2085, 2047, 2016, 1955, 1850, 1735, 1654, 1631, - 1679, 1810, 2036, 2349, 2723, 2936, 2377, 1778, - 1434, 1578, 2217, 2631, 2160, 1995, 2078, 2414, - 2843, 2278, 1754, 1414, 1251, 1265, 1475, 1865, - 2337, 2726, 2890, 2798, 2540, 2262, 2057, 1923, - 1798, 1655, 1563, 1640, 1947, 2381, 2691, 2628, - 2133, 1456, 1160, 1408, 1536, 2233, 2960, 3266, - 3025, 2384, 1601, 1562, 1834, 1990, 2038, 2014, - 1962, 1916, 1895, 1901, 1924, 1944, 1932, 1833, - 1534, 1899, 2945, 3446, 3179, 2286, 1999, 2217, - 2057, 1587, 814, 1088, 1536, 1786, 1929, 2092, - 2305, 2494, 2576, 2539, 2454, 2421, 2474, 2546, - 2514, 2299, 1938, 1557, 1276, 1131, 1077, 1094, - 1249, 1656, 2360, 3211, 3866, 3997, 3421, 2169, - 772, 1352, 1724, 1879, 1916, 1860, 1692, 1325, - 485, 1603, 3374, 3302, 2657, 2380, 2388, 2362, - 1822, 1674, 1777, 1871, 1880, 1838, 1921, 2255, - 2723, 3033, 2863, 2051, 920, 840, 1432, 1622, - 1483, 1466, 2179, 2729, 3087, 3321, 3428, 3313, + 1974, 2482, 2875, 3104, 3130, 2965, 2685, 2444, + 2398, 2432, 1941, 1529, 1311, 1281, 1417, 1638, + 1741, 1802, 1867, 1875, 1834, 1943, 2424, 3078, + 2950, 3018, 3414, 3767, 1893, 292, 1172, 1495, + 1619, 1650, 1618, 1519, 1311, 830, 542, 2902, + 3970, 3585, 3716, 4095, 3246, 2351, 1679, 1158, + 715, 432, 429, 557, 1153, 2006, 2746, 3118, + 3104, 2866, 2619, 2497, 2500, 2536, 2518, 2417, + 2251, 2029, 1729, 1335, 915, 637, 609, 848, + 1492, 2361, 3139, 3618, 3787, 3748, 3570, 3205, + 2516, 1447, 246, 0, 141, 0, 1344, 3608, + 3264, 2852, 2669, 2550, 2442, 2336, 2235, 2148, + 2085, 2047, 2016, 1955, 1850, 1735, 1654, 1631, + 1679, 1810, 2036, 2349, 2723, 2936, 2377, 1778, + 1434, 1578, 2217, 2631, 2160, 1995, 2078, 2414, + 2843, 2278, 1754, 1414, 1251, 1265, 1475, 1865, + 2337, 2726, 2890, 2798, 2540, 2262, 2057, 1923, + 1798, 1655, 1563, 1640, 1947, 2381, 2691, 2628, + 2133, 1456, 1160, 1408, 1536, 2233, 2960, 3266, + 3025, 2384, 1601, 1562, 1834, 1990, 2038, 2014, + 1962, 1916, 1895, 1901, 1924, 1944, 1932, 1833, + 1534, 1899, 2945, 3446, 3179, 2286, 1999, 2217, + 2057, 1587, 814, 1088, 1536, 1786, 1929, 2092, + 2305, 2494, 2576, 2539, 2454, 2421, 2474, 2546, + 2514, 2299, 1938, 1557, 1276, 1131, 1077, 1094, + 1249, 1656, 2360, 3211, 3866, 3997, 3421, 2169, + 772, 1352, 1724, 1879, 1916, 1860, 1692, 1325, + 485, 1603, 3374, 3302, 2657, 2380, 2388, 2362, + 1822, 1674, 1777, 1871, 1880, 1838, 1921, 2255, + 2723, 3033, 2863, 2051, 920, 840, 1432, 1622, + 1483, 1466, 2179, 2729, 3087, 3321, 3428, 3313, 2880, 2155, 1339, 723, 458, 499, 853, 1398 }, { - 2279, 2196, 2046, 1841, 1621, 1468, 1478, 1682, - 1981, 2172, 2058, 1578, 1603, 1950, 2077, 2075, - 2013, 1946, 1898, 1848, 1763, 1631, 1488, 1448, - 1612, 1884, 2125, 2292, 2378, 2372, 2259, 2020, - 1630, 1020, 0, 1267, 2810, 2483, 2166, 2366, - 3306, 2194, 1046, 725, 1498, 1846, 1907, 1695, - 1498, 1747, 2090, 2433, 2596, 2448, 2018, 1500, - 1142, 1098, 1352, 1750, 2108, 2310, 2340, 2238, - 2048, 1801, 1550, 1398, 1482, 1896, 2603, 1967, - 1676, 1600, 1639, 1732, 1835, 1922, 2015, 2173, - 2124, 2066, 1991, 1537, 1367, 1433, 1626, 1856, - 2058, 2186, 2208, 2120, 1947, 1754, 1650, 1828, - 2055, 1266, 1253, 1769, 2332, 2499, 2108, 1342, - 1447, 2148, 2385, 2317, 2024, 1567, 936, 850, - 1389, 2093, 2694, 2927, 2690, 2117, 1485, 1062, - 1250, 1474, 1423, 1730, 2003, 2236, 2408, 2460, - 2333, 2031, 1654, 1353, 1243, 1334, 1540, 1754, - 1927, 2090, 2286, 2487, 2568, 2383, 1892, 1253, - 771, 729, 1201, 1984, 2690, 2961, 2668, 1948, - 1188, 1675, 1847, 1892, 1871, 1789, 1633, 1343, - 592, 1891, 3408, 2563, 2227, 1999, 1802, 1619, - 1456, 1343, 1324, 1459, 1807, 2286, 2475, 2255, - 2021, 1904, 1852, 1813, 1759, 1681, 1589, 1523, - 1555, 1773, 2269, 2057, 1921, 1968, 2072, 2100, - 2003, 1824, 1657, 1561, 1535, 1547, 1591, 1712, - 1955, 2290, 2567, 2580, 2192, 1458, 763, 1698, - 1995, 1819, 1036, 1630, 2202, 2731, 2993, 1909, - 1342, 1142, 1288, 1852, 2834, 1816, 1329, 1438, - 1885, 2275, 2331, 2041, 1606, 1686, 1699, 1684, - 1779, 1942, 2064, 2106, 2069, 1940, 1660, 1087, - 1472, 2026, 2215, 2204, 2118, 1966, 1691, 1679, + 2279, 2196, 2046, 1841, 1621, 1468, 1478, 1682, + 1981, 2172, 2058, 1578, 1603, 1950, 2077, 2075, + 2013, 1946, 1898, 1848, 1763, 1631, 1488, 1448, + 1612, 1884, 2125, 2292, 2378, 2372, 2259, 2020, + 1630, 1020, 0, 1267, 2810, 2483, 2166, 2366, + 3306, 2194, 1046, 725, 1498, 1846, 1907, 1695, + 1498, 1747, 2090, 2433, 2596, 2448, 2018, 1500, + 1142, 1098, 1352, 1750, 2108, 2310, 2340, 2238, + 2048, 1801, 1550, 1398, 1482, 1896, 2603, 1967, + 1676, 1600, 1639, 1732, 1835, 1922, 2015, 2173, + 2124, 2066, 1991, 1537, 1367, 1433, 1626, 1856, + 2058, 2186, 2208, 2120, 1947, 1754, 1650, 1828, + 2055, 1266, 1253, 1769, 2332, 2499, 2108, 1342, + 1447, 2148, 2385, 2317, 2024, 1567, 936, 850, + 1389, 2093, 2694, 2927, 2690, 2117, 1485, 1062, + 1250, 1474, 1423, 1730, 2003, 2236, 2408, 2460, + 2333, 2031, 1654, 1353, 1243, 1334, 1540, 1754, + 1927, 2090, 2286, 2487, 2568, 2383, 1892, 1253, + 771, 729, 1201, 1984, 2690, 2961, 2668, 1948, + 1188, 1675, 1847, 1892, 1871, 1789, 1633, 1343, + 592, 1891, 3408, 2563, 2227, 1999, 1802, 1619, + 1456, 1343, 1324, 1459, 1807, 2286, 2475, 2255, + 2021, 1904, 1852, 1813, 1759, 1681, 1589, 1523, + 1555, 1773, 2269, 2057, 1921, 1968, 2072, 2100, + 2003, 1824, 1657, 1561, 1535, 1547, 1591, 1712, + 1955, 2290, 2567, 2580, 2192, 1458, 763, 1698, + 1995, 1819, 1036, 1630, 2202, 2731, 2993, 1909, + 1342, 1142, 1288, 1852, 2834, 1816, 1329, 1438, + 1885, 2275, 2331, 2041, 1606, 1686, 1699, 1684, + 1779, 1942, 2064, 2106, 2069, 1940, 1660, 1087, + 1472, 2026, 2215, 2204, 2118, 1966, 1691, 1679, 1969, 2028, 1853, 1400, 1193, 1701, 2076, 2258 }, { - 2084, 2007, 2033, 2179, 2411, 2617, 2660, 2466, - 2097, 1732, 1555, 1632, 1858, 2024, 1955, 1623, - 1136, 625, 1234, 1712, 2121, 2454, 2702, 2873, - 2976, 3011, 2962, 2795, 2457, 1905, 1840, 2225, - 2377, 2208, 1524, 1695, 2066, 2151, 2080, 1907, - 1634, 1214, 462, 498, 1595, 2495, 3312, 2586, - 2206, 2032, 2016, 2142, 2357, 2511, 2491, 2398, - 2385, 2535, 2903, 2783, 2397, 2106, 1917, 1809, - 1778, 1839, 1977, 2104, 2076, 1772, 1187, 711, - 1265, 1519, 1606, 1578, 1443, 1129, 1080, 2214, - 3585, 4095, 3795, 3636, 3792, 3998, 2811, 1929, - 1447, 1217, 1030, 812, 683, 851, 1401, 2164, - 2767, 2855, 2327, 1433, 643, 374, 758, 1597, - 2511, 3177, 3493, 3554, 3493, 3321, 2894, 2032, - 1194, 1977, 2284, 2397, 2397, 2311, 2145, 1894, - 1549, 1075, 625, 1121, 1481, 1663, 1693, 1674, - 1732, 1935, 2244, 2554, 2771, 2876, 2920, 2957, - 2974, 2899, 2671, 2325, 2013, 1910, 2072, 2352, - 2441, 2048, 1087, 0, 824, 1237, 1469, 1617, - 1714, 1765, 1732, 1478, 1188, 3153, 4095, 4095, - 4095, 4095, 2770, 981, 1235, 1454, 1479, 1428, - 1319, 1132, 794, 25, 829, 2188, 2980, 3127, - 2836, 2442, 2205, 2192, 2294, 2361, 2327, 2242, - 2205, 2259, 2350, 2372, 2259, 2048, 1854, 1787, - 1878, 2061, 2231, 2314, 2296, 2191, 1991, 1659, - 1187, 672, 673, 528, 1256, 2661, 4095, 3440, - 3037, 2800, 2620, 2461, 2317, 2194, 2102, 2051, - 2043, 2043, 1976, 1822, 1654, 1532, 1474, 1475, - 1527, 1611, 1700, 1786, 1889, 2036, 2231, 2419, - 2501, 2470, 2431, 2455, 2562, 2770, 3156, 4014, - 3029, 1936, 1119, 505, 696, 858, 752, 640, + 2084, 2007, 2033, 2179, 2411, 2617, 2660, 2466, + 2097, 1732, 1555, 1632, 1858, 2024, 1955, 1623, + 1136, 625, 1234, 1712, 2121, 2454, 2702, 2873, + 2976, 3011, 2962, 2795, 2457, 1905, 1840, 2225, + 2377, 2208, 1524, 1695, 2066, 2151, 2080, 1907, + 1634, 1214, 462, 498, 1595, 2495, 3312, 2586, + 2206, 2032, 2016, 2142, 2357, 2511, 2491, 2398, + 2385, 2535, 2903, 2783, 2397, 2106, 1917, 1809, + 1778, 1839, 1977, 2104, 2076, 1772, 1187, 711, + 1265, 1519, 1606, 1578, 1443, 1129, 1080, 2214, + 3585, 4095, 3795, 3636, 3792, 3998, 2811, 1929, + 1447, 1217, 1030, 812, 683, 851, 1401, 2164, + 2767, 2855, 2327, 1433, 643, 374, 758, 1597, + 2511, 3177, 3493, 3554, 3493, 3321, 2894, 2032, + 1194, 1977, 2284, 2397, 2397, 2311, 2145, 1894, + 1549, 1075, 625, 1121, 1481, 1663, 1693, 1674, + 1732, 1935, 2244, 2554, 2771, 2876, 2920, 2957, + 2974, 2899, 2671, 2325, 2013, 1910, 2072, 2352, + 2441, 2048, 1087, 0, 824, 1237, 1469, 1617, + 1714, 1765, 1732, 1478, 1188, 3153, 4095, 4095, + 4095, 4095, 2770, 981, 1235, 1454, 1479, 1428, + 1319, 1132, 794, 25, 829, 2188, 2980, 3127, + 2836, 2442, 2205, 2192, 2294, 2361, 2327, 2242, + 2205, 2259, 2350, 2372, 2259, 2048, 1854, 1787, + 1878, 2061, 2231, 2314, 2296, 2191, 1991, 1659, + 1187, 672, 673, 528, 1256, 2661, 4095, 3440, + 3037, 2800, 2620, 2461, 2317, 2194, 2102, 2051, + 2043, 2043, 1976, 1822, 1654, 1532, 1474, 1475, + 1527, 1611, 1700, 1786, 1889, 2036, 2231, 2419, + 2501, 2470, 2431, 2455, 2562, 2770, 3156, 4014, + 3029, 1936, 1119, 505, 696, 858, 752, 640, 1462, 2286, 2867, 3090, 3001, 2745, 2465, 2238 }, { - 2258, 2290, 2417, 2658, 2973, 3251, 3352, 3201, - 2860, 2505, 2321, 2374, 2560, 2670, 2531, 2115, - 1533, 918, 1416, 1778, 2070, 2285, 2419, 2481, - 2484, 2428, 2301, 2070, 1683, 1099, 1019, 1408, - 1581, 1450, 821, 1063, 1519, 1701, 1738, 1680, - 1529, 1233, 605, 763, 1977, 2985, 3901, 3262, - 2954, 2837, 2860, 3007, 3224, 3362, 3307, 3161, - 3080, 3146, 3416, 3186, 2682, 2266, 1948, 1710, - 1551, 1488, 1510, 1531, 1408, 1023, 374, 0, - 375, 619, 716, 717, 629, 380, 412, 1642, - 3121, 4054, 3575, 3547, 3836, 4095, 3115, 2355, - 1985, 1857, 1758, 1612, 1539, 1743, 2310, 3072, - 3653, 3701, 3115, 2145, 1264, 891, 1160, 1875, - 2659, 3193, 3376, 3306, 3120, 2831, 2298, 1343, - 426, 1147, 1410, 1497, 1491, 1418, 1284, 1084, - 807, 416, 63, 669, 1147, 1455, 1615, 1727, - 1916, 2244, 2672, 3091, 3406, 3595, 3708, 3795, - 3846, 3786, 3554, 3185, 2831, 2670, 2758, 2948, - 2936, 2432, 1352, 17, 838, 1124, 1232, 1261, - 1248, 1198, 1078, 750, 403, 2327, 4029, 3456, - 3518, 3701, 2009, 284, 617, 927, 1055, 1114, - 1122, 1056, 839, 191, 1111, 2580, 3472, 3709, - 3495, 3163, 2973, 2990, 3104, 3167, 3111, 2988, - 2897, 2881, 2890, 2819, 2605, 2285, 1977, 1794, - 1770, 1840, 1904, 1887, 1779, 1596, 1331, 949, - 441, 0, 0, 0, 537, 1988, 3802, 2902, - 2585, 2443, 2365, 2314, 2281, 2269, 2286, 2340, - 2430, 2519, 2531, 2443, 2327, 2244, 2207, 2214, - 2255, 2312, 2359, 2388, 2421, 2486, 2589, 2678, - 2654, 2515, 2366, 2282, 2284, 2393, 2689, 3468, - 2415, 1266, 411, 0, 0, 127, 46, 0, + 2258, 2290, 2417, 2658, 2973, 3251, 3352, 3201, + 2860, 2505, 2321, 2374, 2560, 2670, 2531, 2115, + 1533, 918, 1416, 1778, 2070, 2285, 2419, 2481, + 2484, 2428, 2301, 2070, 1683, 1099, 1019, 1408, + 1581, 1450, 821, 1063, 1519, 1701, 1738, 1680, + 1529, 1233, 605, 763, 1977, 2985, 3901, 3262, + 2954, 2837, 2860, 3007, 3224, 3362, 3307, 3161, + 3080, 3146, 3416, 3186, 2682, 2266, 1948, 1710, + 1551, 1488, 1510, 1531, 1408, 1023, 374, 0, + 375, 619, 716, 717, 629, 380, 412, 1642, + 3121, 4054, 3575, 3547, 3836, 4095, 3115, 2355, + 1985, 1857, 1758, 1612, 1539, 1743, 2310, 3072, + 3653, 3701, 3115, 2145, 1264, 891, 1160, 1875, + 2659, 3193, 3376, 3306, 3120, 2831, 2298, 1343, + 426, 1147, 1410, 1497, 1491, 1418, 1284, 1084, + 807, 416, 63, 669, 1147, 1455, 1615, 1727, + 1916, 2244, 2672, 3091, 3406, 3595, 3708, 3795, + 3846, 3786, 3554, 3185, 2831, 2670, 2758, 2948, + 2936, 2432, 1352, 17, 838, 1124, 1232, 1261, + 1248, 1198, 1078, 750, 403, 2327, 4029, 3456, + 3518, 3701, 2009, 284, 617, 927, 1055, 1114, + 1122, 1056, 839, 191, 1111, 2580, 3472, 3709, + 3495, 3163, 2973, 2990, 3104, 3167, 3111, 2988, + 2897, 2881, 2890, 2819, 2605, 2285, 1977, 1794, + 1770, 1840, 1904, 1887, 1779, 1596, 1331, 949, + 441, 0, 0, 0, 537, 1988, 3802, 2902, + 2585, 2443, 2365, 2314, 2281, 2269, 2286, 2340, + 2430, 2519, 2531, 2443, 2327, 2244, 2207, 2214, + 2255, 2312, 2359, 2388, 2421, 2486, 2589, 2678, + 2654, 2515, 2366, 2282, 2284, 2393, 2689, 3468, + 2415, 1266, 411, 0, 0, 127, 46, 0, 852, 1745, 2408, 2723, 2735, 2585, 2416, 2301 }, { - 2185, 2170, 2249, 2442, 2711, 2942, 2998, 2803, - 2420, 2025, 1803, 1822, 1976, 2058, 1894, 1457, - 857, 229, 718, 1076, 1368, 1587, 1730, 1806, - 1827, 1793, 1693, 1493, 1141, 595, 558, 991, - 1213, 1133, 558, 855, 1367, 1607, 1703, 1705, - 1613, 1376, 806, 1021, 2290, 3352, 4095, 3728, - 3467, 3392, 3454, 3636, 3884, 4049, 4017, 3890, - 3822, 3896, 4095, 3941, 3432, 3007, 2675, 2419, - 2238, 2150, 2142, 2130, 1971, 1548, 856, 289, - 769, 966, 1015, 968, 831, 532, 515, 1697, - 3129, 4016, 3493, 3422, 3671, 3972, 2878, 2086, - 1687, 1532, 1411, 1246, 1156, 1348, 1907, 2662, - 3242, 3290, 2708, 1746, 875, 515, 800, 1533, - 2337, 2892, 3098, 3053, 2893, 2630, 2124, 1196, - 307, 1055, 1344, 1457, 1476, 1428, 1316, 1137, - 880, 506, 170, 789, 1280, 1597, 1765, 1883, - 2074, 2404, 2832, 3249, 3559, 3741, 3847, 3925, - 3966, 3894, 3649, 3267, 2899, 2723, 2796, 2972, - 2944, 2425, 1330, 0, 789, 1062, 1158, 1176, - 1153, 1095, 966, 632, 279, 2200, 3899, 3324, - 3385, 3569, 1879, 157, 493, 808, 941, 1006, - 1021, 961, 751, 110, 1038, 2513, 3413, 3656, - 3448, 3122, 2937, 2959, 3077, 3143, 3090, 2969, - 2878, 2864, 2872, 2800, 2584, 2262, 1951, 1765, - 1737, 1804, 1864, 1844, 1732, 1545, 1277, 892, - 383, 0, 0, 0, 479, 1933, 3751, 2856, - 2546, 2411, 2343, 2302, 2281, 2282, 2313, 2383, - 2489, 2596, 2626, 2558, 2462, 2398, 2382, 2409, - 2471, 2548, 2614, 2662, 2712, 2794, 2912, 3014, - 3002, 2872, 2730, 2651, 2655, 2764, 3057, 3829, - 2767, 1607, 736, 79, 241, 388, 280, 179, + 2185, 2170, 2249, 2442, 2711, 2942, 2998, 2803, + 2420, 2025, 1803, 1822, 1976, 2058, 1894, 1457, + 857, 229, 718, 1076, 1368, 1587, 1730, 1806, + 1827, 1793, 1693, 1493, 1141, 595, 558, 991, + 1213, 1133, 558, 855, 1367, 1607, 1703, 1705, + 1613, 1376, 806, 1021, 2290, 3352, 4095, 3728, + 3467, 3392, 3454, 3636, 3884, 4049, 4017, 3890, + 3822, 3896, 4095, 3941, 3432, 3007, 2675, 2419, + 2238, 2150, 2142, 2130, 1971, 1548, 856, 289, + 769, 966, 1015, 968, 831, 532, 515, 1697, + 3129, 4016, 3493, 3422, 3671, 3972, 2878, 2086, + 1687, 1532, 1411, 1246, 1156, 1348, 1907, 2662, + 3242, 3290, 2708, 1746, 875, 515, 800, 1533, + 2337, 2892, 3098, 3053, 2893, 2630, 2124, 1196, + 307, 1055, 1344, 1457, 1476, 1428, 1316, 1137, + 880, 506, 170, 789, 1280, 1597, 1765, 1883, + 2074, 2404, 2832, 3249, 3559, 3741, 3847, 3925, + 3966, 3894, 3649, 3267, 2899, 2723, 2796, 2972, + 2944, 2425, 1330, 0, 789, 1062, 1158, 1176, + 1153, 1095, 966, 632, 279, 2200, 3899, 3324, + 3385, 3569, 1879, 157, 493, 808, 941, 1006, + 1021, 961, 751, 110, 1038, 2513, 3413, 3656, + 3448, 3122, 2937, 2959, 3077, 3143, 3090, 2969, + 2878, 2864, 2872, 2800, 2584, 2262, 1951, 1765, + 1737, 1804, 1864, 1844, 1732, 1545, 1277, 892, + 383, 0, 0, 0, 479, 1933, 3751, 2856, + 2546, 2411, 2343, 2302, 2281, 2282, 2313, 2383, + 2489, 2596, 2626, 2558, 2462, 2398, 2382, 2409, + 2471, 2548, 2614, 2662, 2712, 2794, 2912, 3014, + 3002, 2872, 2730, 2651, 2655, 2764, 3057, 3829, + 2767, 1607, 736, 79, 241, 388, 280, 179, 1024, 1882, 2507, 2783, 2752, 2559, 2345, 2185 } }; From e173b36afb898609c5d14708d6bef1d02d9eb7fe Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Sun, 7 Feb 2021 15:58:14 -0800 Subject: [PATCH 139/153] Remove figlet? comments --- quantum/audio/audio.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 140fc92f3143..163e72fa9754 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -65,11 +65,6 @@ typedef struct { // uint8_t timbre; // range: [0,100] TODO: this currently kept track of globally, should we do this per tone instead? } musical_tone_t; -// ____ __ ___ -// / __ \__ __/ /_ / (_)____ -// / /_/ / / / / __ \/ / / ___/ -// / ____/ /_/ / /_/ / / / /__ -// /_/ \__,_/_.___/_/_/\___/ // public interface /** @@ -224,11 +219,6 @@ uint16_t audio_ms_to_duration(uint16_t duration_ms); void audio_startup(void); -// __ __ __ -// / / / /___ __________/ / ______ __________ -// / /_/ / __ `/ ___/ __ / | /| / / __ `/ ___/ _ / -// / __ / /_/ / / / /_/ /| |/ |/ / /_/ / / / __/ -// /_/ /_/\__,_/_/ \__,_/ |__/|__/\__,_/_/ \___/ // hardware interface // implementation in the driver_avr/arm_* respective parts @@ -278,12 +268,6 @@ float audio_get_processed_frequency(uint8_t tone_index); */ bool audio_update_state(void); -// __ -// / / ___ ____ _____ ________ __ -// / / / _ \/ __ `/ __ `/ ___/ / / / -// / /___/ __/ /_/ / /_/ / /__/ /_/ / -// /_____/\___/\__, /\__,_/\___/\__, / -// /____/ /____/ // legacy and back-warts compatibility stuff // LEGACY defines - TODO: remove and replace these in all keyboards using them From abeb77c3f9c420af81054c4f9d40a6b95c97504a Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Sun, 7 Feb 2021 16:09:34 -0800 Subject: [PATCH 140/153] Add DAC config to audio driver docs --- docs/audio_driver.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/audio_driver.md b/docs/audio_driver.md index 997f20bfb1ac..b44a3813f06b 100644 --- a/docs/audio_driver.md +++ b/docs/audio_driver.md @@ -59,6 +59,26 @@ This driver needs one Timer per enabled/used DAC channel, to trigger conversion; only needs one timer (GPTD6, Tim6) to trigger the DAC unit to do a conversion; the audio state updates are in turn triggered during the DAC callback. +### DAC Config + + +```c + /* zero crossing (or approach, whereas zero == DAC_OFF_VALUE, which can be configured to anything from 0 to DAC_SAMPLE_MAX) + * ============================*=*========================== AUDIO_DAC_SAMPLE_MAX + * * * + * * * + * --------------------------------------------------------- + * * * } AUDIO_DAC_SAMPLE_MAX/100 + * --------------------------------------------------------- AUDIO_DAC_OFF_VALUE + * * * } AUDIO_DAC_SAMPLE_MAX/100 + * --------------------------------------------------------- + * * + * * * + * * * + * =====*=*================================================= 0x0 + */ +``` + ### PWM hardware :id=pwm-hardware From 30006b7327dc3e84853d70dc5e8c02b14e13c284 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Sun, 7 Feb 2021 16:18:56 -0800 Subject: [PATCH 141/153] Apply suggestions from code review Co-authored-by: Jack Humbert --- quantum/audio/musical_notes.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/quantum/audio/musical_notes.h b/quantum/audio/musical_notes.h index e75878ff3d37..49eee3e70320 100644 --- a/quantum/audio/musical_notes.h +++ b/quantum/audio/musical_notes.h @@ -33,7 +33,7 @@ #define QUARTER_NOTE(note) MUSICAL_NOTE(note, 16) #define EIGHTH_NOTE(note) MUSICAL_NOTE(note, 8) #define SIXTEENTH_NOTE(note) MUSICAL_NOTE(note, 4) -#define THIRTYTWOTH_NOTE(note) MUSICAL_NOTE(note, 2) +#define THIRTYSECOND_NOTE(note) MUSICAL_NOTE(note, 2) #define BREVE_DOT_NOTE(note) MUSICAL_NOTE(note, 128 + 64) #define WHOLE_DOT_NOTE(note) MUSICAL_NOTE(note, 64 + 32) @@ -41,6 +41,7 @@ #define QUARTER_DOT_NOTE(note) MUSICAL_NOTE(note, 16 + 8) #define EIGHTH_DOT_NOTE(note) MUSICAL_NOTE(note, 8 + 4) #define SIXTEENTH_DOT_NOTE(note) MUSICAL_NOTE(note, 4 + 2) +#define THIRTYSECOND_DOT_NOTE(note) MUSICAL_NOTE(note, 2 + 1) // duration of 64 units == one beat == one whole note // with a tempo of 60bpm this comes to a length of one second @@ -52,13 +53,14 @@ #define Q__NOTE(n) QUARTER_NOTE(n) #define E__NOTE(n) EIGHTH_NOTE(n) #define S__NOTE(n) SIXTEENTH_NOTE(n) -#define T__NOTE(n) THIRTYTWOTH_NOTE(n) +#define T__NOTE(n) THIRTYSECOND_NOTE(n) #define BD_NOTE(n) BREVE_DOT_NOTE(n) #define WD_NOTE(n) WHOLE_DOT_NOTE(n) #define HD_NOTE(n) HALF_DOT_NOTE(n) #define QD_NOTE(n) QUARTER_DOT_NOTE(n) #define ED_NOTE(n) EIGHTH_DOT_NOTE(n) #define SD_NOTE(n) SIXTEENTH_DOT_NOTE(n) +#define TD_NOTE(n) THIRTYSECOND_DOT_NOTE(n) // Note Timbre // Changes how the notes sound From 356d9f44996c2c0079f5bcc4e89109358c104b6e Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Sun, 7 Feb 2021 16:21:46 -0800 Subject: [PATCH 142/153] Add license header to py files --- util/audio_generate_dac_lut.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/util/audio_generate_dac_lut.py b/util/audio_generate_dac_lut.py index e8c7be851625..d13bdb36309b 100644 --- a/util/audio_generate_dac_lut.py +++ b/util/audio_generate_dac_lut.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright 2019 Jack Humbert +# +# 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 2 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 . +# AUDIO_DAC_BUFFER_SIZE=256 AUDIO_DAC_SAMPLE_MAX=4095 From 630e1e2320981c753627a5d26cbc051bfa1424f7 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Sun, 7 Feb 2021 16:26:58 -0800 Subject: [PATCH 143/153] correct license header --- util/audio_generate_dac_lut.py | 1 + 1 file changed, 1 insertion(+) diff --git a/util/audio_generate_dac_lut.py b/util/audio_generate_dac_lut.py index d13bdb36309b..6895e5791635 100644 --- a/util/audio_generate_dac_lut.py +++ b/util/audio_generate_dac_lut.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 # # Copyright 2019 Jack Humbert +# Copyright 2020 JohSchneider # # 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 From 5ec4004088e61e7f7b9caa6bb2da40c3cda7bf3f Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Sun, 7 Feb 2021 16:33:59 -0800 Subject: [PATCH 144/153] Add JohSchneider's name to modified files AKA credit where credit's due --- quantum/audio/audio.c | 3 ++- quantum/audio/audio.h | 1 + quantum/audio/driver_avr_pwm.h | 1 + quantum/audio/driver_avr_pwm_hardware.c | 1 + quantum/audio/driver_chibios_dac.h | 1 + quantum/audio/driver_chibios_dac_additive.c | 1 + quantum/audio/driver_chibios_dac_basic.c | 1 + quantum/audio/driver_chibios_pwm.h | 1 + quantum/audio/driver_chibios_pwm_hardware.c | 1 + quantum/audio/driver_chibios_pwm_software.c | 1 + quantum/audio/musical_notes.h | 1 + quantum/audio/voices.c | 1 + quantum/audio/voices.h | 1 + 13 files changed, 14 insertions(+), 1 deletion(-) diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 8f13d65dce5e..46277dd70bf1 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -1,5 +1,6 @@ /* Copyright 2016-2020 Jack Humbert - * + * Copyright 2020 JohSchneider + * 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 2 of the License, or diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 163e72fa9754..6f1dc139d319 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -1,4 +1,5 @@ /* Copyright 2016-2020 Jack Humbert + * Copyright 2020 JohSchneider * * 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 diff --git a/quantum/audio/driver_avr_pwm.h b/quantum/audio/driver_avr_pwm.h index a3335cc56b40..d6eb3571dac9 100644 --- a/quantum/audio/driver_avr_pwm.h +++ b/quantum/audio/driver_avr_pwm.h @@ -1,4 +1,5 @@ /* Copyright 2020 Jack Humbert + * Copyright 2020 JohSchneider * * 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 diff --git a/quantum/audio/driver_avr_pwm_hardware.c b/quantum/audio/driver_avr_pwm_hardware.c index a1fe60cde913..492b9bfb0435 100644 --- a/quantum/audio/driver_avr_pwm_hardware.c +++ b/quantum/audio/driver_avr_pwm_hardware.c @@ -1,4 +1,5 @@ /* Copyright 2016 Jack Humbert + * Copyright 2020 JohSchneider * * 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 diff --git a/quantum/audio/driver_chibios_dac.h b/quantum/audio/driver_chibios_dac.h index c2761e85bbf7..07cd622ead2a 100644 --- a/quantum/audio/driver_chibios_dac.h +++ b/quantum/audio/driver_chibios_dac.h @@ -1,4 +1,5 @@ /* Copyright 2019 Jack Humbert + * Copyright 2020 JohSchneider * * 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 diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c index 91b13dbb71e0..db304adb8774 100644 --- a/quantum/audio/driver_chibios_dac_additive.c +++ b/quantum/audio/driver_chibios_dac_additive.c @@ -1,4 +1,5 @@ /* Copyright 2016-2019 Jack Humbert + * Copyright 2020 JohSchneider * * 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 diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c index b763ea2886b9..9a1c9a8c19c8 100644 --- a/quantum/audio/driver_chibios_dac_basic.c +++ b/quantum/audio/driver_chibios_dac_basic.c @@ -1,4 +1,5 @@ /* Copyright 2016-2020 Jack Humbert + * Copyright 2020 JohSchneider * * 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 diff --git a/quantum/audio/driver_chibios_pwm.h b/quantum/audio/driver_chibios_pwm.h index 25b08e38a2bd..86cab916e1e2 100644 --- a/quantum/audio/driver_chibios_pwm.h +++ b/quantum/audio/driver_chibios_pwm.h @@ -1,4 +1,5 @@ /* Copyright 2020 Jack Humbert + * Copyright 2020 JohSchneider * * 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 diff --git a/quantum/audio/driver_chibios_pwm_hardware.c b/quantum/audio/driver_chibios_pwm_hardware.c index 64c0598fdd33..3c7d89b290b3 100644 --- a/quantum/audio/driver_chibios_pwm_hardware.c +++ b/quantum/audio/driver_chibios_pwm_hardware.c @@ -1,4 +1,5 @@ /* Copyright 2020 Jack Humbert + * Copyright 2020 JohSchneider * * 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 diff --git a/quantum/audio/driver_chibios_pwm_software.c b/quantum/audio/driver_chibios_pwm_software.c index c4051deb4032..15c3e98b6a96 100644 --- a/quantum/audio/driver_chibios_pwm_software.c +++ b/quantum/audio/driver_chibios_pwm_software.c @@ -1,4 +1,5 @@ /* Copyright 2020 Jack Humbert + * Copyright 2020 JohSchneider * * 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 diff --git a/quantum/audio/musical_notes.h b/quantum/audio/musical_notes.h index 49eee3e70320..ddd7d374f576 100644 --- a/quantum/audio/musical_notes.h +++ b/quantum/audio/musical_notes.h @@ -1,4 +1,5 @@ /* Copyright 2016 Jack Humbert + * Copyright 2020 JohSchneider * * 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 diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 4999402b0f25..8988d827e9b8 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -1,4 +1,5 @@ /* Copyright 2016 Jack Humbert + * Copyright 2020 JohSchneider * * 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 diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h index 52892e61fbc1..578350d337df 100644 --- a/quantum/audio/voices.h +++ b/quantum/audio/voices.h @@ -1,4 +1,5 @@ /* Copyright 2016 Jack Humbert + * Copyright 2020 JohSchneider * * 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 From c6ea7592bbeb27d5ac6ea8f385a79014f123d078 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Sun, 7 Feb 2021 17:41:41 -0800 Subject: [PATCH 145/153] Set executable permission and change interpeter --- util/audio_generate_dac_lut.py | 0 util/sample_parser.py | 2 +- util/wavetable_parser.py | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 util/audio_generate_dac_lut.py mode change 100644 => 100755 util/sample_parser.py mode change 100644 => 100755 util/wavetable_parser.py diff --git a/util/audio_generate_dac_lut.py b/util/audio_generate_dac_lut.py old mode 100644 new mode 100755 diff --git a/util/sample_parser.py b/util/sample_parser.py old mode 100644 new mode 100755 index a1d6f6f92d84..70e193aee7cb --- a/util/sample_parser.py +++ b/util/sample_parser.py @@ -1,4 +1,4 @@ -#! /bin/python +#!/usr/bin/env python3 # # Copyright 2019 Jack Humbert # diff --git a/util/wavetable_parser.py b/util/wavetable_parser.py old mode 100644 new mode 100755 index 1c9b47cd3848..be0f01f7b451 --- a/util/wavetable_parser.py +++ b/util/wavetable_parser.py @@ -1,4 +1,4 @@ -#! /bin/python +#!/usr/bin/env python3 # # Copyright 2019 Jack Humbert # From c71264a880aef178f9e708adc35f654a0591b0af Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Sun, 7 Feb 2021 17:49:16 -0800 Subject: [PATCH 146/153] Add 'wave' to pip requirements --- requirements-dev.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements-dev.txt b/requirements-dev.txt index 1db3b6d73315..caae27741ab5 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,3 +6,4 @@ nose2 flake8 pep8-naming yapf +wave From 4970cc2479ed99336daefe827a9972f85c9d6be5 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Sun, 7 Feb 2021 18:19:15 -0800 Subject: [PATCH 147/153] Improve documentation --- docs/audio_driver.md | 48 +++++++++++++++++++++++++++++++++++++++++++ docs/feature_audio.md | 44 +++++++++++++++++++++------------------ 2 files changed, 72 insertions(+), 20 deletions(-) diff --git a/docs/audio_driver.md b/docs/audio_driver.md index b44a3813f06b..89e286760e70 100644 --- a/docs/audio_driver.md +++ b/docs/audio_driver.md @@ -17,6 +17,7 @@ The possible configurations are: | two speakers | C4,C5 or C6 | B4, B5 or B7 | Currently there is only one/default driver for AVR based boards, which is automatically configured to: + ```make AUDIO_DRIVER = pwm_hardware ``` @@ -54,13 +55,60 @@ piezo speakers are marked with :one: for the first/primary and :two: for the sec The default driver for ARM boards, in absence of an overriding configuration. This driver needs one Timer per enabled/used DAC channel, to trigger conversion; and a third timer to trigger state updates with the audio-core. +Additionally, in the board config, you'll want to make changes to enable the DACs, GPT for Timers 6, 7 and 8: + +``` c +//halconf.h: +#define HAL_USE_DAC TRUE +#define HAL_USE_GPT TRUE +``` + +``` c +// mcuconf.h: +#define STM32_DAC_USE_DAC1_CH1 TRUE +#define STM32_DAC_USE_DAC1_CH2 TRUE +#define STM32_GPT_USE_TIM6 TRUE +#define STM32_GPT_USE_TIM7 TRUE +#define STM32_GPT_USE_TIM8 TRUE +``` + ### DAC additive :id=dac-additive only needs one timer (GPTD6, Tim6) to trigger the DAC unit to do a conversion; the audio state updates are in turn triggered during the DAC callback. +Additionally, in the board config, you'll want to make changes to enable the DACs, GPT for Timer 6: + +``` c +//halconf.h: +#define HAL_USE_DAC TRUE +#define HAL_USE_GPT TRUE +``` + +``` c +// mcuconf.h: +#define STM32_DAC_USE_DAC1_CH1 TRUE +#define STM32_DAC_USE_DAC1_CH2 TRUE +#define STM32_GPT_USE_TIM6 TRUE +``` + ### DAC Config +| Define | Defaults | Description --------------------------------------------------------------------------------------------- | +| `AUDIO_DAC_SAMPLE_MAX` | `4095U` | Highest value allowed. Lower value means lower volume. And 4095U is the upper limit, since this is limited to a 12 bit value. Only effects non-pregenerated samples. | +| `AUDIO_DAC_OFF_VALUE` | `AUDIO_DAC_SAMPLE_MAX / 2` | The value of the DAC when notplaying anything. Some setups may require a high (`AUDIO_DAC_SAMPLE_MAX`) or low (`0`) value here. | +| `AUDIO_MAX_SIMULTANEOUS_TONES` | __see next table__ | The number of tones that can be played simultaneously. A value that is too high may freeze the controller or glitch out when too many tones are being played. | +| `AUDIO_DAC_SAMPLE_RATE` | __see next table__ | Effective bit rate of the DAC (in hertz), higher limits simultaneous tones, and lower sacrifices quality. | + +There are a number of predefined quality settings that you can use, with "sane minimum" being the default. You can use custom values by simply defining the sample rate and number of simultaneous tones, instead of using one of the listed presets. + +| Define | Sample Rate | Simultaneous tones | +| `AUDIO_DAC_QUALITY_VERY_LOW` | `11025U` | `8` | +| `AUDIO_DAC_QUALITY_LOW` | `22040U` | `4` | +| `AUDIO_DAC_QUALITY_HIGH` | `44100U` | `2` | +| `AUDIO_DAC_QUALITY_VERY_HIGH` | `88200U` | `1` | +| `AUDIO_DAC_QUALITY_SANE_MINIMUM` | `16384U` | `8` | + ```c /* zero crossing (or approach, whereas zero == DAC_OFF_VALUE, which can be configured to anything from 0 to DAC_SAMPLE_MAX) diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 355593bd7d99..9e7ba75f5212 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md @@ -9,17 +9,18 @@ On Atmega32U4 based boards, up to two simultaneous tones can be rendered. With one speaker connected to a PWM capable pin on PORTC driven by timer 3 and the other on one of the PWM pins on PORTB driven by timer 1. The following pins can be configured as audio outputs in `config.h` - for one speaker set eiter one out of: -`#define AUDIO_PIN C4` -`#define AUDIO_PIN C5` -`#define AUDIO_PIN C6` -`#define AUDIO_PIN B5` -`#define AUDIO_PIN B6` -`#define AUDIO_PIN B7` + +* `#define AUDIO_PIN C4` +* `#define AUDIO_PIN C5` +* `#define AUDIO_PIN C6` +* `#define AUDIO_PIN B5` +* `#define AUDIO_PIN B6` +* `#define AUDIO_PIN B7` and *optionally*, for a second speaker, one of: -`#define AUDIO_PIN_ALT B5` -`#define AUDIO_PIN_ALT B6` -`#define AUDIO_PIN_ALT B7` +* `#define AUDIO_PIN_ALT B5` +* `#define AUDIO_PIN_ALT B6` +* `#define AUDIO_PIN_ALT B7` ### Wiring per speaker is - for example with a piezo buzzer - the black lead to Ground, and the red lead connected to the selected AUDIO_PIN for the primary; and similarly with AUDIO_PIN_ALT for the secondary. @@ -28,13 +29,14 @@ per speaker is - for example with a piezo buzzer - the black lead to Ground, and ## ARM based boards for more technical details, see the notes on [Audio driver](audio_driver.md). + ### DAC (basic) Most STM32 MCUs have DAC peripherals, with a notable exception of the STM32F1xx series. Generally, the DAC peripheral drives pins A4 or A5. To enable DAC-based audio output on STM32 devices, add `AUDIO_DRIVER = dac_basic` to `rules.mk` and set in `config.h` either: -`#define AUDIO_PIN A4` -OR -`#define AUDIO_PIN A5` + +`#define AUDIO_PIN A4` or `#define AUDIO_PIN A5` the other DAC channel can optionally be used with a secondary speaker, just set: + `#define AUDIO_PIN_ALT A4` or `#define AUDIO_PIN_ALT A5` Do note though that the dac_basic driver is only capable of reproducing one tone per speaker/channel at a time, for more tones simultaneously, try the dac_additive driver. @@ -48,23 +50,25 @@ wiring red to A4 and black to A5 (or the other way round) and add `#define AUDIO ##### Proton-C Example: The Proton-C comes (optionally) with one 'builtin' piezo, which is wired to A4+A5. For this board `config.h` would include these defines: + ```c #define AUDIO_PIN A5 #define AUDIO_PIN_ALT A4 #define AUDIO_PIN_ALT_AS_NEGATIVE ``` - ### DAC (additive) Another option, besides dac_basic (which produces sound through a square-wave), is to use the DAC to do additive wave synthesis. With a number of predefined wave-forms or by providing your own implementation to generate samples on the fly. To use this feature set `AUDIO_DRIVER = dac_additive` in your `rules.mk`, and select in `config.h` EITHER `#define AUDIO_PIN A4` or `#define AUDIO_PIN A5`. The used waveform *defaults* to sine, but others can be selected by adding one of the following defines to `config.h`: -`#define AUDIO_DAC_SAMPLE_WAVEFORM_SINE` -`#define AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE` -`#define AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID` -`#define AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE` + +* `#define AUDIO_DAC_SAMPLE_WAVEFORM_SINE` +* `#define AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE` +* `#define AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID` +* `#define AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE` + Should you rather choose to generate and use your own sample-table with the DAC unit, implement `uint16_t dac_value_generate(void)` with your keyboard - for an example implementation see keyboards/planck/keymaps/synth_sample or keyboards/planck/keymaps/synth_wavetable @@ -73,9 +77,9 @@ if the DAC pins are unavailable (or the MCU has no usable DAC at all, like STM32 Note that there is currently only one speaker/pin supported. set in `rules.mk`: -`AUDIO_DRIVER = pwm_software` and in `config.h` -`#define AUDIO_PIN C13` (can be any pin) -to have the selected pin output a pwm signal, generated from a timer callback which toggles the pin in software. + +`AUDIO_DRIVER = pwm_software` and in `config.h`: +`#define AUDIO_PIN C13` (can be any pin) to have the selected pin output a pwm signal, generated from a timer callback which toggles the pin in software. #### Wiring the usual piezo wiring: red goes to the selected AUDIO_PIN, black goes to ground. From 28c4b3cd0b2a6b1098550e60ee14515122167b79 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Sun, 7 Feb 2021 18:25:16 -0800 Subject: [PATCH 148/153] Add some settings I missed --- docs/audio_driver.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/audio_driver.md b/docs/audio_driver.md index 89e286760e70..8dc71e7e10e9 100644 --- a/docs/audio_driver.md +++ b/docs/audio_driver.md @@ -72,6 +72,13 @@ Additionally, in the board config, you'll want to make changes to enable the DAC #define STM32_GPT_USE_TIM8 TRUE ``` +?> Note: DAC1 (A4) uses TIM6, DAC2 (A5) uses TIM7, and the audio state timer uses TIM8 (configurable). + +You can also change the timer used for the overall audio state by defining the driver. For instance: + +```c +#define AUDIO_STATE_TIMER GPTD9 +``` ### DAC additive :id=dac-additive @@ -171,6 +178,12 @@ On 'larger' STM32s, GPIOv2 or GPIOv3 are used; with them it is also necessary to This driver uses the PWM callbacks from PWMD1 with TIM1_CH1 to toggle the selected AUDIO_PIN in software. During the same callback, with AUDIO_PIN_ALT_AS_NEGATIVE set, the AUDIO_PIN_ALT is toggled inversely to AUDIO_PIN. This is useful for setups that drive a piezo from two pins (instead of one and Gnd). +You can also change the timer used for software PWM by defining the driver. For instance: + +```c +#define AUDIO_STATE_TIMER GPTD8 +``` + ### Testing Notes :id=testing-notes From fa31cadc46994fb5e7b5b3799cf9b17fd3b99136 Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Sun, 7 Feb 2021 20:10:25 -0800 Subject: [PATCH 149/153] Strip AUDIO_DRIVER to parse the name correctly --- common_features.mk | 2 +- docs/config_options.md | 12 ++++++-- .../1upkeyboards/sweet16/v2/proton_c/config.h | 4 +++ keyboards/atomic/keymaps/pvc/config.h | 2 +- keyboards/boston_meetup/2019/config.h | 5 +++- keyboards/c39/keymaps/kuchosauronad0/config.h | 9 ------ keyboards/ckeys/obelus/config.h | 2 +- keyboards/ckeys/thedora/config.h | 3 ++ keyboards/clueboard/2x1800/2018/config.h | 4 +-- keyboards/clueboard/2x1800/2019/config.h | 4 +-- keyboards/clueboard/66/rev4/config.h | 4 +++ keyboards/clueboard/66_hotswap/gen1/config.h | 5 ++++ .../clueboard/66_hotswap/prototype/config.h | 2 +- keyboards/clueboard/california/config.h | 4 +++ keyboards/clueboard/card/config.h | 2 +- keyboards/crkbd/keymaps/gotham/config.h | 2 +- keyboards/ergodash/mini/config.h | 2 +- keyboards/ergodash/rev1/config.h | 2 +- .../evyd13/plain60/keymaps/audio/config.h | 2 +- .../flehrad/bigswitch/keymaps/wanleg/config.h | 2 +- keyboards/hadron/ver3/config.h | 6 +++- keyboards/handwired/aranck/config.h | 2 +- .../5x6_right_trackball/config.h | 2 +- keyboards/handwired/heisenberg/config.h | 2 +- keyboards/handwired/ibm122m/config.h | 6 ++-- keyboards/handwired/xealous/config.h | 3 +- keyboards/helix/pico/config.h | 2 +- keyboards/hp69/config.h | 5 ++-- keyboards/jones/v03/config.h | 4 +-- keyboards/jones/v03_1/config.h | 4 +-- keyboards/keebio/iris/keymaps/blucky/config.h | 4 +-- .../keebio/iris/keymaps/broswen/config.h | 2 +- .../keebio/iris/keymaps/drashna/config.h | 2 +- keyboards/keebio/iris/keymaps/mtdjr/config.h | 2 +- keyboards/keebio/iris/keymaps/pvinis/config.h | 2 +- .../levinson/keymaps/issmirnov/config.h | 2 +- .../quefrency/keymaps/drashna_ms/config.h | 2 +- .../keebio/viterbi/keymaps/drashna/config.h | 2 +- keyboards/keysofkings/twokey/config.h | 30 +++++++++---------- .../knops/mini/keymaps/mverteuil/config.h | 4 +-- keyboards/launchpad/keymaps/drashna/config.h | 2 +- keyboards/lets_split/sockets/config.h | 2 +- keyboards/lfkeyboards/lfk78/config.h | 2 +- keyboards/lfkeyboards/lfk87/config.h | 2 +- keyboards/lfkeyboards/mini1800/config.h | 2 +- keyboards/lfkeyboards/smk65/revb/config.h | 3 +- keyboards/meira/featherble/config.h | 2 +- keyboards/meira/keymaps/grahampheath/config.h | 2 +- keyboards/mitosis/keymaps/datagrok/config.h | 2 +- keyboards/mitosis/keymaps/mjt/config.h | 2 +- keyboards/moonlander/config.h | 4 +++ keyboards/mschwingen/modelm/config.h | 2 +- keyboards/nack/config.h | 14 ++++----- keyboards/nightly_boards/n40_o/config.h | 4 +-- keyboards/nightly_boards/n87/config.h | 2 +- keyboards/nightly_boards/octopad/config.h | 2 +- keyboards/orthodox/keymaps/drashna/config.h | 2 +- keyboards/planck/config.h | 2 +- keyboards/planck/ez/config.h | 5 +++- keyboards/planck/keymaps/dodger/config.h | 2 +- keyboards/planck/light/config.h | 4 +-- keyboards/planck/rev6/config.h | 6 ++-- keyboards/preonic/config.h | 2 +- keyboards/preonic/rev3/config.h | 6 ++-- keyboards/scarletbandana/config.h | 2 +- keyboards/silverbullet44/config.h | 2 +- keyboards/splitkb/zima/config.h | 2 +- keyboards/subatomic/config.h | 2 +- keyboards/tetris/config.h | 2 +- keyboards/vitamins_included/rev1/config.h | 2 +- keyboards/vitamins_included/rev2/config.h | 2 +- keyboards/wilba_tech/wt60_xt/config.h | 2 +- keyboards/yoichiro/lunakey_mini/config.h | 2 +- .../community/numpad_5x6/bjohnson/config.h | 2 -- layouts/community/numpad_5x6/drashna/config.h | 1 - .../community/ortho_4x12/bakingpy/config.h | 2 +- layouts/community/ortho_5x12/drashna/config.h | 2 +- .../ortho_5x14/yet-another-developer/config.h | 2 +- .../community/split_3x6_3/drashna/config.h | 2 +- .../chibios/QMK_PROTON_C/configs/config.h | 7 ----- quantum/audio/audio.h | 30 ------------------- users/yanfali/config.h | 2 +- 82 files changed, 150 insertions(+), 158 deletions(-) diff --git a/common_features.mk b/common_features.mk index 57cc743a59fc..6c793b39cc4b 100644 --- a/common_features.mk +++ b/common_features.mk @@ -66,7 +66,7 @@ ifeq ($(strip $(AUDIO_ENABLE)), yes) SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c SRC += $(QUANTUM_DIR)/process_keycode/process_clicky.c SRC += $(QUANTUM_DIR)/audio/audio.c ## common audio code, hardware agnostic - SRC += $(QUANTUM_DIR)/audio/driver_$(PLATFORM_KEY)_$(AUDIO_DRIVER).c + SRC += $(QUANTUM_DIR)/audio/driver_$(PLATFORM_KEY)_$(strip $(AUDIO_DRIVER)).c SRC += $(QUANTUM_DIR)/audio/voices.c SRC += $(QUANTUM_DIR)/audio/luts.c endif diff --git a/docs/config_options.md b/docs/config_options.md index 9a64b9b3d209..e7ced5834922 100644 --- a/docs/config_options.md +++ b/docs/config_options.md @@ -67,16 +67,22 @@ This is a C header file that is one of the first things included, and will persi * turns on the alternate audio voices (to cycle through) * `#define C4_AUDIO` * enables audio on pin C4 + * Depricated. Use `#define AUDIO_PIN C4` * `#define C5_AUDIO` * enables audio on pin C5 + * Depricated. Use `#define AUDIO_PIN C5` * `#define C6_AUDIO` * enables audio on pin C6 + * Depricated. Use `#define AUDIO_PIN C6` * `#define B5_AUDIO` - * enables audio on pin B5 (duophony is enables if one of B[5-7]\_AUDIO is enabled along with one of C[4-6]\_AUDIO) + * enables audio on pin B5 (duophony is enables if one of B pins is enabled along with one of C pins) + * Depricated. Use `#define AUDIO_PIN B5`, or use `#define AUDIO_PIN_ALT B5` if a `C` pin is enabled with `AUDIO_PIN` * `#define B6_AUDIO` - * enables audio on pin B6 (duophony is enables if one of B[5-7]\_AUDIO is enabled along with one of C[4-6]\_AUDIO) + * enables audio on pin B5 (duophony is enables if one of B pins is enabled along with one of C pins) + * Depricated. Use `#define AUDIO_PIN B6`, or use `#define AUDIO_PIN_ALT B6` if a `C` pin is enabled with `AUDIO_PIN` * `#define B7_AUDIO` - * enables audio on pin B7 (duophony is enables if one of B[5-7]\_AUDIO is enabled along with one of C[4-6]\_AUDIO) + * enables audio on pin B5 (duophony is enables if one of B pins is enabled along with one of C pins) + * Depricated. Use `#define AUDIO_PIN B7`, or use `#define AUDIO_PIN_ALT B7` if a `C` pin is enabled with `AUDIO_PIN` * `#define BACKLIGHT_PIN B7` * pin of the backlight * `#define BACKLIGHT_LEVELS 3` diff --git a/keyboards/1upkeyboards/sweet16/v2/proton_c/config.h b/keyboards/1upkeyboards/sweet16/v2/proton_c/config.h index 30abf28ee339..286af1857f68 100644 --- a/keyboards/1upkeyboards/sweet16/v2/proton_c/config.h +++ b/keyboards/1upkeyboards/sweet16/v2/proton_c/config.h @@ -18,3 +18,7 @@ #define ENCODERS_PAD_A { A2 } #define ENCODERS_PAD_B { A1 } #define ENCODER_RESOLUTION 4 + +#define AUDIO_PIN A5 +#define AUDIO_PIN_ALT A4 +#define AUDIO_PIN_ALT_AS_NEGATIVE diff --git a/keyboards/atomic/keymaps/pvc/config.h b/keyboards/atomic/keymaps/pvc/config.h index 3803a2ccd013..01fa0f43134f 100644 --- a/keyboards/atomic/keymaps/pvc/config.h +++ b/keyboards/atomic/keymaps/pvc/config.h @@ -31,7 +31,7 @@ along with this program. If not, see . #define BACKLIGHT_PIN B7 #define BACKLIGHT_BREATHING -#define C6_AUDIO +#define AUDIO_PIN C6 /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW diff --git a/keyboards/boston_meetup/2019/config.h b/keyboards/boston_meetup/2019/config.h index 3f2a0dd5d609..d9fd93da6e28 100644 --- a/keyboards/boston_meetup/2019/config.h +++ b/keyboards/boston_meetup/2019/config.h @@ -31,7 +31,10 @@ //Audio #undef AUDIO_VOICES -#undef C6_AUDIO +#undef AUDIO_PIN +#define AUDIO_PIN A5 +#define AUDIO_PIN_ALT A4 +#define AUDIO_PIN_ALT_AS_NEGATIVE #ifdef AUDIO_ENABLE #define STARTUP_SONG SONG(ONE_UP_SOUND) diff --git a/keyboards/c39/keymaps/kuchosauronad0/config.h b/keyboards/c39/keymaps/kuchosauronad0/config.h index cf0726e2bb02..d67935a9fd0a 100644 --- a/keyboards/c39/keymaps/kuchosauronad0/config.h +++ b/keyboards/c39/keymaps/kuchosauronad0/config.h @@ -32,12 +32,3 @@ along with this program. If not, see . # define RGB_DI_PIN D0 # define RGBLED_NUM 4 #endif // !RGBLIGHT_ENABLE - -/* -#ifdef AUDIO_ENABLE -# Timer 1: #define B5_AUDIO #define B6_AUDIO #define B7_AUDIO -# Timer 3: #define C4_AUDIO #define C5_AUDIO #define C6_AUDIO -//TODO: only D0 and D1 available -#endif // !AUDIO_ENABLE -*/ - diff --git a/keyboards/ckeys/obelus/config.h b/keyboards/ckeys/obelus/config.h index eaf4811ba738..25bc1db03c1f 100644 --- a/keyboards/ckeys/obelus/config.h +++ b/keyboards/ckeys/obelus/config.h @@ -154,7 +154,7 @@ along with this program. If not, see . #ifdef AUDIO_ENABLE #define AUDIO_VOICES - #define C6_AUDIO + #define AUDIO_PIN C6 #define STARTUP_SONG SONG(STARTUP_SOUND) #endif diff --git a/keyboards/ckeys/thedora/config.h b/keyboards/ckeys/thedora/config.h index 349e33748b54..c7557aa62d6d 100755 --- a/keyboards/ckeys/thedora/config.h +++ b/keyboards/ckeys/thedora/config.h @@ -157,6 +157,9 @@ // NOTE: Must change polyphony_rate to a number higher than 0 in voices.c #define AUDIO_VOICES #define PITCH_STANDARD_A 880.0f +#define AUDIO_PIN A5 +#define AUDIO_PIN_ALT A4 +#define AUDIO_PIN_ALT_AS_NEGATIVE // Mouse keys #define MOUSEKEY_DELAY 0 diff --git a/keyboards/clueboard/2x1800/2018/config.h b/keyboards/clueboard/2x1800/2018/config.h index 40486379eab3..9d5b9b514473 100644 --- a/keyboards/clueboard/2x1800/2018/config.h +++ b/keyboards/clueboard/2x1800/2018/config.h @@ -20,8 +20,8 @@ along with this program. If not, see . #include "config_common.h" /* audio support */ -#define B7_AUDIO -#define C4_AUDIO +#define AUDIO_PIN_ALT B7 +#define AUDIO_PIN C4 #define AUDIO_CLICKY /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ diff --git a/keyboards/clueboard/2x1800/2019/config.h b/keyboards/clueboard/2x1800/2019/config.h index 595dc61081f5..162d41a2e2a0 100644 --- a/keyboards/clueboard/2x1800/2019/config.h +++ b/keyboards/clueboard/2x1800/2019/config.h @@ -27,8 +27,8 @@ along with this program. If not, see . #define ENCODER_RESOLUTION 4 /* audio support */ -#define B7_AUDIO -#define C4_AUDIO +#define AUDIO_PIN_ALT B7 +#define AUDIO_PIN C4 #define AUDIO_CLICKY /* diff --git a/keyboards/clueboard/66/rev4/config.h b/keyboards/clueboard/66/rev4/config.h index c745b5a1101d..2c11cf1ec05f 100644 --- a/keyboards/clueboard/66/rev4/config.h +++ b/keyboards/clueboard/66/rev4/config.h @@ -22,3 +22,7 @@ #define RGBLIGHT_EFFECT_KNIGHT_OFFSET 2 // The led to start at #define RGBLIGHT_EFFECT_KNIGHT_LED_NUM 5 // How many LEDs to travel #define RGBLIGHT_EFFECT_SNAKE_LENGTH 4 // How many LEDs wide to light up + +#define AUDIO_PIN A5 +#define AUDIO_PIN_ALT A4 +#define AUDIO_PIN_ALT_AS_NEGATIVE diff --git a/keyboards/clueboard/66_hotswap/gen1/config.h b/keyboards/clueboard/66_hotswap/gen1/config.h index 1ddcfacf4d6c..5e0682e5a7a8 100644 --- a/keyboards/clueboard/66_hotswap/gen1/config.h +++ b/keyboards/clueboard/66_hotswap/gen1/config.h @@ -108,3 +108,8 @@ #define LED_DRIVER_COUNT 1 #define LED_DRIVER_LED_COUNT 71 + +#define AUDIO_PIN A5 +#define AUDIO_PIN_ALT A4 +#define AUDIO_PIN_ALT_AS_NEGATIVE +n diff --git a/keyboards/clueboard/66_hotswap/prototype/config.h b/keyboards/clueboard/66_hotswap/prototype/config.h index 5c22b927adc3..a1ab703c3408 100644 --- a/keyboards/clueboard/66_hotswap/prototype/config.h +++ b/keyboards/clueboard/66_hotswap/prototype/config.h @@ -3,7 +3,7 @@ /* Speaker configuration */ -#define B7_AUDIO +#define AUDIO_PIN B7 #define NO_MUSIC_MODE #define AUDIO_CLICKY diff --git a/keyboards/clueboard/california/config.h b/keyboards/clueboard/california/config.h index b8c5759db6b6..017f1ddf66de 100644 --- a/keyboards/clueboard/california/config.h +++ b/keyboards/clueboard/california/config.h @@ -1,3 +1,7 @@ #pragma once #include "config_common.h" + +#define AUDIO_PIN A5 +#define AUDIO_PIN_ALT A4 +#define AUDIO_PIN_ALT_AS_NEGATIVE diff --git a/keyboards/clueboard/card/config.h b/keyboards/clueboard/card/config.h index 67ddb5e25cad..a115f5d6cf26 100644 --- a/keyboards/clueboard/card/config.h +++ b/keyboards/clueboard/card/config.h @@ -23,4 +23,4 @@ along with this program. If not, see . #define BACKLIGHT_LEVELS 6 // Enable audio -#define C6_AUDIO +#define AUDIO_PIN C6 diff --git a/keyboards/crkbd/keymaps/gotham/config.h b/keyboards/crkbd/keymaps/gotham/config.h index ed08203aa156..dd58a0fe05d3 100644 --- a/keyboards/crkbd/keymaps/gotham/config.h +++ b/keyboards/crkbd/keymaps/gotham/config.h @@ -15,7 +15,7 @@ #define NO_ACTION_ONESHOT #ifdef AUDIO_ENABLE -# define B5_AUDIO +# define AUDIO_PIN B5 # define NO_MUSIC_MODE # define AUDIO_CLICKY #endif diff --git a/keyboards/ergodash/mini/config.h b/keyboards/ergodash/mini/config.h index 5e16c78544ab..b936e0f54e2a 100644 --- a/keyboards/ergodash/mini/config.h +++ b/keyboards/ergodash/mini/config.h @@ -45,7 +45,7 @@ along with this program. If not, see . /* define if matrix has ghost */ //#define MATRIX_HAS_GHOST -#define C6_AUDIO +#define AUDIO_PIN C6 /* number of backlight levels */ #ifdef BACKLIGHT_ENABLE diff --git a/keyboards/ergodash/rev1/config.h b/keyboards/ergodash/rev1/config.h index 6e25194e4b66..07282cdad287 100644 --- a/keyboards/ergodash/rev1/config.h +++ b/keyboards/ergodash/rev1/config.h @@ -45,7 +45,7 @@ along with this program. If not, see . /* define if matrix has ghost */ //#define MATRIX_HAS_GHOST -#define C6_AUDIO +#define AUDIO_PIN C6 /* number of backlight levels */ #ifdef BACKLIGHT_ENABLE diff --git a/keyboards/evyd13/plain60/keymaps/audio/config.h b/keyboards/evyd13/plain60/keymaps/audio/config.h index 9a43b7fbe346..50309173b409 100644 --- a/keyboards/evyd13/plain60/keymaps/audio/config.h +++ b/keyboards/evyd13/plain60/keymaps/audio/config.h @@ -1,3 +1,3 @@ #pragma once -#define B7_AUDIO +#define AUDIO_PIN B7 diff --git a/keyboards/flehrad/bigswitch/keymaps/wanleg/config.h b/keyboards/flehrad/bigswitch/keymaps/wanleg/config.h index 54abb9a6c17e..bb638ce599b6 100644 --- a/keyboards/flehrad/bigswitch/keymaps/wanleg/config.h +++ b/keyboards/flehrad/bigswitch/keymaps/wanleg/config.h @@ -39,4 +39,4 @@ #define QMK_LED B0 // set audio pin -#define C6_AUDIO +#define AUDIO_PIN C6 diff --git a/keyboards/hadron/ver3/config.h b/keyboards/hadron/ver3/config.h index f76ca40603cf..8c04575eeab2 100644 --- a/keyboards/hadron/ver3/config.h +++ b/keyboards/hadron/ver3/config.h @@ -50,7 +50,11 @@ //Audio #undef AUDIO_VOICES -#undef C6_AUDIO +#undef AUDIO_PIN +#define AUDIO_PIN A5 +#define AUDIO_PIN_ALT A4 +#define AUDIO_PIN_ALT_AS_NEGATIVE + #ifdef AUDIO_ENABLE #define STARTUP_SONG SONG(PLANCK_SOUND) diff --git a/keyboards/handwired/aranck/config.h b/keyboards/handwired/aranck/config.h index 5356feb1ef84..7d0ab25fe423 100644 --- a/keyboards/handwired/aranck/config.h +++ b/keyboards/handwired/aranck/config.h @@ -101,7 +101,7 @@ along with this program. If not, see . /** * Aranck-specific definitions */ -#define B5_AUDIO +#define AUDIO_PIN B5 /** * Aranck-specific definitions END */ diff --git a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/config.h b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/config.h index 6d89314a2ce9..d18f08e40857 100644 --- a/keyboards/handwired/dactyl_manuform/5x6_right_trackball/config.h +++ b/keyboards/handwired/dactyl_manuform/5x6_right_trackball/config.h @@ -61,7 +61,7 @@ along with this program. If not, see . #define BOOTMAGIC_LITE_ROW_RIGHT 6 #define BOOTMAGIC_LITE_COLUMN_RIGHT 5 -#define C6_AUDIO +#define AUDIO_PIN C6 #define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 4095 #define DYNAMIC_KEYMAP_LAYER_COUNT 16 diff --git a/keyboards/handwired/heisenberg/config.h b/keyboards/handwired/heisenberg/config.h index 9fe2ec879ab1..ba35f24aca2f 100644 --- a/keyboards/handwired/heisenberg/config.h +++ b/keyboards/handwired/heisenberg/config.h @@ -101,7 +101,7 @@ along with this program. If not, see . /** * Heisenberg-specific definitions */ -#define B5_AUDIO +#define AUDIO_PIN B5 /** * Heisenberg-specific definitions END */ diff --git a/keyboards/handwired/ibm122m/config.h b/keyboards/handwired/ibm122m/config.h index e0e95d6d3b7d..bd1fdc97dc25 100644 --- a/keyboards/handwired/ibm122m/config.h +++ b/keyboards/handwired/ibm122m/config.h @@ -24,7 +24,7 @@ along with this program. If not, see . #define PRODUCT_ID 0x0000 #define DEVICE_VER 0x0001 #define MANUFACTURER IBM -#define PRODUCT IBM Model M 122 key +#define PRODUCT IBM Model M 122 key /* key matrix size */ #define MATRIX_ROWS 8 @@ -102,8 +102,8 @@ along with this program. If not, see . * */ -#define B6_AUDIO -#define C6_AUDIO +#define AUDIO_PIN_ALT B6 +#define AUDIO_PIN C6 /* control how magic key switches layers */ //#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true diff --git a/keyboards/handwired/xealous/config.h b/keyboards/handwired/xealous/config.h index 251e85d4c122..5c1469b1f012 100644 --- a/keyboards/handwired/xealous/config.h +++ b/keyboards/handwired/xealous/config.h @@ -34,10 +34,9 @@ along with this program. If not, see . #ifdef AUDIO_ENABLE - #define C6_AUDIO + #define AUDIO_PIN C6 #define STARTUP_SONG SONG(STARTUP_SOUND) #define NO_MUSIC_MODE #define TONE_QWERTY SONG(Q__NOTE(_E4)); #define TONE_NUMPAD SONG(Q__NOTE(_D4)); #endif - diff --git a/keyboards/helix/pico/config.h b/keyboards/helix/pico/config.h index 3938db30e6a4..b01fd3a0016c 100644 --- a/keyboards/helix/pico/config.h +++ b/keyboards/helix/pico/config.h @@ -77,7 +77,7 @@ along with this program. If not, see . /* Audio */ #ifdef AUDIO_ENABLE - #define B5_AUDIO + #define AUDIO_PIN B5 #endif /* ws2812 RGB LED */ diff --git a/keyboards/hp69/config.h b/keyboards/hp69/config.h index ca0a9eb47b6e..06dd57145ca8 100644 --- a/keyboards/hp69/config.h +++ b/keyboards/hp69/config.h @@ -48,5 +48,6 @@ along with this program. If not, see . #define RGBLED_NUM 20 #define RGBLIGHT_ANIMATIONS -#define A4_AUDIO -#define A5_AUDIO \ No newline at end of file +#define AUDIO_PIN A5 +#define AUDIO_PIN_ALT A4 +#define AUDIO_PIN_ALT_AS_NEGATIVE diff --git a/keyboards/jones/v03/config.h b/keyboards/jones/v03/config.h index 3683a43dd19f..0ff82e8d37db 100644 --- a/keyboards/jones/v03/config.h +++ b/keyboards/jones/v03/config.h @@ -57,8 +57,8 @@ along with this program. If not, see . /* Audio */ #ifdef AUDIO_ENABLE - #define C6_AUDIO - #define B6_AUDIO // 2nd pin for simultaneous audio. + #define AUDIO_PIN C6 + #define AUDIO_PIN_ALT B6 // 2nd pin for simultaneous audio. #define AUDIO_CLICKY #endif diff --git a/keyboards/jones/v03_1/config.h b/keyboards/jones/v03_1/config.h index a064e5639695..c1d6a577fc49 100644 --- a/keyboards/jones/v03_1/config.h +++ b/keyboards/jones/v03_1/config.h @@ -57,8 +57,8 @@ along with this program. If not, see . /* Audio */ #ifdef AUDIO_ENABLE - #define C6_AUDIO - #define B7_AUDIO // 2nd pin for simultaneous audio. + #define AUDIO_PIN C6 + #define AUDIO_PIN_ALT B7 // 2nd pin for simultaneous audio. #define AUDIO_CLICKY #endif diff --git a/keyboards/keebio/iris/keymaps/blucky/config.h b/keyboards/keebio/iris/keymaps/blucky/config.h index 213445dd3f3d..f187addbd333 100644 --- a/keyboards/keebio/iris/keymaps/blucky/config.h +++ b/keyboards/keebio/iris/keymaps/blucky/config.h @@ -1,5 +1,5 @@ /* -Copyright 2019 Brian Luckenbill +Copyright 2019 Brian Luckenbill 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 @@ -17,7 +17,7 @@ along with this program. If not, see . #pragma once -#define C6_AUDIO +#define AUDIO_PIN C6 #undef RGBLED_NUM #define RGBLED_NUM 12 diff --git a/keyboards/keebio/iris/keymaps/broswen/config.h b/keyboards/keebio/iris/keymaps/broswen/config.h index 19c47780dbff..fcfbfe8cf06e 100644 --- a/keyboards/keebio/iris/keymaps/broswen/config.h +++ b/keyboards/keebio/iris/keymaps/broswen/config.h @@ -32,7 +32,7 @@ along with this program. If not, see . #define RGBLIGHT_HUE_STEP 5 #define RGBLIGHT_SAT_STEP 8 #define RGBLIGHT_VAL_STEP 8 -#define C6_AUDIO +#define AUDIO_PIN C6 #define NO_MUSIC_MODE diff --git a/keyboards/keebio/iris/keymaps/drashna/config.h b/keyboards/keebio/iris/keymaps/drashna/config.h index 63f87b7c4e03..f68166c98f05 100644 --- a/keyboards/keebio/iris/keymaps/drashna/config.h +++ b/keyboards/keebio/iris/keymaps/drashna/config.h @@ -43,7 +43,7 @@ #endif // RGBLIGHT_ENABLE #ifdef AUDIO_ENABLE -# define C6_AUDIO +# define AUDIO_PIN C6 # ifdef RGBLIGHT_ENABLE # ifndef __arm__ # define NO_MUSIC_MODE diff --git a/keyboards/keebio/iris/keymaps/mtdjr/config.h b/keyboards/keebio/iris/keymaps/mtdjr/config.h index 93dc4c211ddc..9adb6d62715f 100644 --- a/keyboards/keebio/iris/keymaps/mtdjr/config.h +++ b/keyboards/keebio/iris/keymaps/mtdjr/config.h @@ -34,7 +34,7 @@ along with this program. If not, see . // #define AUDIO_CLICKY // #define AUDIO_CLICKY_ON -// #define C6_AUDIO +// #define AUDIO_PIN C6 // #define AUDIO_CLICKY_FREQ_RANDOMNESS 0.1f // #define AUDIO_CLICKY_FREQ_MAX 100.0f diff --git a/keyboards/keebio/iris/keymaps/pvinis/config.h b/keyboards/keebio/iris/keymaps/pvinis/config.h index 9574f2a837f5..c2870eba0b94 100644 --- a/keyboards/keebio/iris/keymaps/pvinis/config.h +++ b/keyboards/keebio/iris/keymaps/pvinis/config.h @@ -16,7 +16,7 @@ // Choose pin to use for audio. C6 is the one iris uses. #ifdef AUDIO_ENABLE -# define C6_AUDIO +# define AUDIO_PIN C6 # define STARTUP_SONG SONG(NO_SOUND) // No startup song. #endif diff --git a/keyboards/keebio/levinson/keymaps/issmirnov/config.h b/keyboards/keebio/levinson/keymaps/issmirnov/config.h index 89c2f5ebe82c..2f0fbaf33c6a 100644 --- a/keyboards/keebio/levinson/keymaps/issmirnov/config.h +++ b/keyboards/keebio/levinson/keymaps/issmirnov/config.h @@ -29,6 +29,6 @@ #ifdef AUDIO_ENABLE #define QMK_SPEAKER C6 - #define C6_AUDIO + #define AUDIO_PIN C6 #define NO_MUSIC_MODE // Save 2000 bytes #endif diff --git a/keyboards/keebio/quefrency/keymaps/drashna_ms/config.h b/keyboards/keebio/quefrency/keymaps/drashna_ms/config.h index 089c8cf79e52..80a3cb877e2a 100644 --- a/keyboards/keebio/quefrency/keymaps/drashna_ms/config.h +++ b/keyboards/keebio/quefrency/keymaps/drashna_ms/config.h @@ -35,6 +35,6 @@ along with this program. If not, see . #endif #ifdef AUDIO_ENABLE - #define B7_AUDIO + #define AUDIO_PIN B7 #define AUDIO_CLICKY #endif diff --git a/keyboards/keebio/viterbi/keymaps/drashna/config.h b/keyboards/keebio/viterbi/keymaps/drashna/config.h index 5d7ffa8a1d53..2decb3b3e937 100644 --- a/keyboards/keebio/viterbi/keymaps/drashna/config.h +++ b/keyboards/keebio/viterbi/keymaps/drashna/config.h @@ -34,7 +34,7 @@ #define PRODUCT Drashnas Viterbi Macro Pad #ifdef AUDIO_ENABLE -# define C6_AUDIO +# define AUDIO_PIN C6 # define NO_MUSIC_MODE #endif diff --git a/keyboards/keysofkings/twokey/config.h b/keyboards/keysofkings/twokey/config.h index d7f4c3cf0a64..9b77fa73e243 100755 --- a/keyboards/keysofkings/twokey/config.h +++ b/keyboards/keysofkings/twokey/config.h @@ -1,18 +1,18 @@ /* Copyright 2020 Keys of Kings - * - * 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 2 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 . - */ + * + * 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 2 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 . + */ #pragma once @@ -59,7 +59,7 @@ #define RGBLIGHT_HUE_STEP 4 #define RGBLIGHT_SAT_STEP 4 #define RGBLIGHT_VAL_STEP 4 -#define B6_AUDIO +#define AUDIO_PIN B6 #define AUDIO_CLICKY #endif diff --git a/keyboards/knops/mini/keymaps/mverteuil/config.h b/keyboards/knops/mini/keymaps/mverteuil/config.h index f72145c5a86e..584296cfaada 100644 --- a/keyboards/knops/mini/keymaps/mverteuil/config.h +++ b/keyboards/knops/mini/keymaps/mverteuil/config.h @@ -18,8 +18,8 @@ #if defined(AUDIO_ENABLE) #define AUDIO_CLICKY - #define B5_AUDIO - #define C6_AUDIO + #define AUDIO_PIN_ALT B5 + #define AUDIO_PIN C6 #define STARTUP_SONG SONG(ZELDA_PUZZLE) #define GOODBYE_SONG SONG(COIN_SOUND) #endif diff --git a/keyboards/launchpad/keymaps/drashna/config.h b/keyboards/launchpad/keymaps/drashna/config.h index 212b1da805e0..b14becc25bf5 100644 --- a/keyboards/launchpad/keymaps/drashna/config.h +++ b/keyboards/launchpad/keymaps/drashna/config.h @@ -27,5 +27,5 @@ #define RGBLIGHT_VAL_STEP 17 #define DRIVER_LED_TOTAL RGBLED_NUM -#define B7_AUDIO +#define AUDIO_PIN B7 #define AUDIO_CLICKY diff --git a/keyboards/lets_split/sockets/config.h b/keyboards/lets_split/sockets/config.h index 4315ce24fda5..67fa4b4ccc20 100644 --- a/keyboards/lets_split/sockets/config.h +++ b/keyboards/lets_split/sockets/config.h @@ -61,7 +61,7 @@ along with this program. If not, see . /* Audio settings */ #ifdef AUDIO_ENABLE - #define C6_AUDIO // Define this to enable the buzzer + #define AUDIO_PIN C6 // Define this to enable the buzzer #endif /* diff --git a/keyboards/lfkeyboards/lfk78/config.h b/keyboards/lfkeyboards/lfk78/config.h index 5a855b07c53f..2b0b01d86117 100644 --- a/keyboards/lfkeyboards/lfk78/config.h +++ b/keyboards/lfkeyboards/lfk78/config.h @@ -39,7 +39,7 @@ along with this program. If not, see . #define TAPPING_TERM 200 -#define C6_AUDIO +#define AUDIO_PIN C6 #define AUDIO_VOICES #define RGB_DI_PIN C7 // Have to set it to something to get the ws2812 code to compile diff --git a/keyboards/lfkeyboards/lfk87/config.h b/keyboards/lfkeyboards/lfk87/config.h index 118c135aa1e2..c030590921e1 100644 --- a/keyboards/lfkeyboards/lfk87/config.h +++ b/keyboards/lfkeyboards/lfk87/config.h @@ -50,7 +50,7 @@ along with this program. If not, see . #endif #define AUDIO_VOICES -#define C6_AUDIO +#define AUDIO_PIN C6 #define BACKLIGHT_LEVELS 10 #define BACKLIGHT_PWM_MAP {2, 4, 8, 16, 40, 55, 70, 128, 200, 255} diff --git a/keyboards/lfkeyboards/mini1800/config.h b/keyboards/lfkeyboards/mini1800/config.h index a6cd675ddfb3..b8c0f2b671d2 100644 --- a/keyboards/lfkeyboards/mini1800/config.h +++ b/keyboards/lfkeyboards/mini1800/config.h @@ -37,7 +37,7 @@ along with this program. If not, see . #define RGBLED_NUM 26 // Number of LEDs #define AUDIO_VOICES -#define C6_AUDIO +#define AUDIO_PIN C6 #define BACKLIGHT_LEVELS 10 #define BACKLIGHT_PWM_MAP {2, 4, 8, 16, 40, 55, 70, 128, 200, 255} diff --git a/keyboards/lfkeyboards/smk65/revb/config.h b/keyboards/lfkeyboards/smk65/revb/config.h index 0d4fe40f3587..924a04fd9efc 100644 --- a/keyboards/lfkeyboards/smk65/revb/config.h +++ b/keyboards/lfkeyboards/smk65/revb/config.h @@ -43,8 +43,7 @@ along with this program. If not, see . //RevB only: #define AUDIO_VOICES -#define C6_AUDIO -// #define B5_AUDIO +#define AUDIO_PIN C6 #define BACKLIGHT_LEVELS 8 #define BACKLIGHT_PWM_MAP {8, 16, 40, 55, 70, 128, 200, 255} diff --git a/keyboards/meira/featherble/config.h b/keyboards/meira/featherble/config.h index c6c63556d650..e8db87acbb3a 100644 --- a/keyboards/meira/featherble/config.h +++ b/keyboards/meira/featherble/config.h @@ -37,7 +37,7 @@ along with this program. If not, see . #define UNUSED_PINS #define QMK_SPEAKER B5 -#define B5_AUDIO +#define AUDIO_PIN B5 #define AUDIO_VOICES // #define BACKLIGHT_PIN B7 diff --git a/keyboards/meira/keymaps/grahampheath/config.h b/keyboards/meira/keymaps/grahampheath/config.h index fcc5e4f13681..604f37846156 100644 --- a/keyboards/meira/keymaps/grahampheath/config.h +++ b/keyboards/meira/keymaps/grahampheath/config.h @@ -21,7 +21,7 @@ // place overrides here #define MUSIC_MASK (keycode != KC_NO) -#define C6_AUDIO +#define AUDIO_PIN C6 #ifdef AUDIO_ENABLE #define STARTUP_SONG SONG(PLANCK_SOUND) // #define STARTUP_SONG SONG(NO_SOUND) diff --git a/keyboards/mitosis/keymaps/datagrok/config.h b/keyboards/mitosis/keymaps/datagrok/config.h index 0e82b628b4d2..5f37d27e694b 100644 --- a/keyboards/mitosis/keymaps/datagrok/config.h +++ b/keyboards/mitosis/keymaps/datagrok/config.h @@ -36,7 +36,7 @@ } #define AUDIO_VOICES #define AUDIO_CLICKY -#define C6_AUDIO +#define AUDIO_PIN C6 #endif #endif diff --git a/keyboards/mitosis/keymaps/mjt/config.h b/keyboards/mitosis/keymaps/mjt/config.h index 71adc5a2df72..830cbc9e09d6 100644 --- a/keyboards/mitosis/keymaps/mjt/config.h +++ b/keyboards/mitosis/keymaps/mjt/config.h @@ -15,7 +15,7 @@ #endif #define AUDIO_VOICES -#define C6_AUDIO +#define AUDIO_PIN C6 // fix iPhone power adapter issue #define USB_MAX_POWER_CONSUMPTION 50 diff --git a/keyboards/moonlander/config.h b/keyboards/moonlander/config.h index d1c685280f99..c88feea3d006 100644 --- a/keyboards/moonlander/config.h +++ b/keyboards/moonlander/config.h @@ -101,3 +101,7 @@ # define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 16383 # define DYNAMIC_KEYMAP_LAYER_COUNT 32 #endif + +#define AUDIO_PIN A5 +#define AUDIO_PIN_ALT A4 +#define AUDIO_PIN_ALT_AS_NEGATIVE diff --git a/keyboards/mschwingen/modelm/config.h b/keyboards/mschwingen/modelm/config.h index 07881cd211f9..2b42bb38ed76 100644 --- a/keyboards/mschwingen/modelm/config.h +++ b/keyboards/mschwingen/modelm/config.h @@ -87,5 +87,5 @@ #define RGBLED_NUM 3 // disabled, needs PCB patch. -//#define C6_AUDIO +//#define AUDIO_PIN C6 //#define NO_MUSIC_MODE diff --git a/keyboards/nack/config.h b/keyboards/nack/config.h index 9f0880e38fee..e442a13336f4 100644 --- a/keyboards/nack/config.h +++ b/keyboards/nack/config.h @@ -13,7 +13,7 @@ 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 . -*/ +*/ #pragma once #include "config_common.h" @@ -27,7 +27,7 @@ along with this program. If not, see . #define MATRIX_ROWS 4 #define MATRIX_COLS 13 -#define MATRIX_ROW_PINS { A0, A1, A2, A3 } +#define MATRIX_ROW_PINS { A0, A1, A2, A3 } #define MATRIX_COL_PINS { A6, A7, A8, A9, A10, B0, B1, B2, B6, B7, C13, C14, C15 } #define DIODE_DIRECTION ROW2COL @@ -40,7 +40,7 @@ along with this program. If not, see . #define RGB_DI_PIN B5 #define RGBLED_NUM 52 #define DRIVER_LED_TOTAL RGBLED_NUM - #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 128 // Max brightness of LEDs + #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 128 // Max brightness of LEDs #define RGB_MATRIX_STARTUP_VAL 64 #define RGB_MATRIX_HUE_STEP 10 #define RGB_MATRIX_SAT_STEP 10 @@ -49,11 +49,11 @@ along with this program. If not, see . #ifdef AUDIO_ENABLE #define STARTUP_SONG SONG(NO_SOUND) - #define AUDIO_PIN A4 // Pin of the left speaker - #define AUDIO_PIN_ALT A5 // Pin of the right speaker - /* + #define AUDIO_PIN A5 + #define AUDIO_PIN_ALT A4 + #define AUDIO_PIN_ALT_AS_NEGATIVE + /* * Basically, change this section once pull request 6165 has been merged * https://github.com/qmk/qmk_firmware/pull/6165 */ #endif - diff --git a/keyboards/nightly_boards/n40_o/config.h b/keyboards/nightly_boards/n40_o/config.h index e0bcdbe0114e..a5257cc4946c 100644 --- a/keyboards/nightly_boards/n40_o/config.h +++ b/keyboards/nightly_boards/n40_o/config.h @@ -66,7 +66,7 @@ along with this program. If not, see . /* Audio */ -#define B7_AUDIO +#define AUDIO_PIN B7 #define AUDIO_CLICKY @@ -80,5 +80,3 @@ along with this program. If not, see . #define LOCKING_SUPPORT_ENABLE /* Locking resynchronize hack */ #define LOCKING_RESYNC_ENABLE - - diff --git a/keyboards/nightly_boards/n87/config.h b/keyboards/nightly_boards/n87/config.h index 890276c30500..0315119d8883 100644 --- a/keyboards/nightly_boards/n87/config.h +++ b/keyboards/nightly_boards/n87/config.h @@ -84,7 +84,7 @@ along with this program. If not, see . // #define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255 #endif -#define B7_AUDIO +#define AUDIO_PIN B7 #define AUDIO_CLICKY diff --git a/keyboards/nightly_boards/octopad/config.h b/keyboards/nightly_boards/octopad/config.h index 1477ce93e25c..ee417644d7ed 100644 --- a/keyboards/nightly_boards/octopad/config.h +++ b/keyboards/nightly_boards/octopad/config.h @@ -66,7 +66,7 @@ along with this program. If not, see . /* Audio */ -#define B5_AUDIO +#define AUDIO_PIN B5 #define AUDIO_CLICKY #define NO_MUSIC_MODE diff --git a/keyboards/orthodox/keymaps/drashna/config.h b/keyboards/orthodox/keymaps/drashna/config.h index 585c916404f5..e3a89bce6aa2 100644 --- a/keyboards/orthodox/keymaps/drashna/config.h +++ b/keyboards/orthodox/keymaps/drashna/config.h @@ -50,7 +50,7 @@ along with this program. If not, see . #endif // RGBLIGHT_ENABLE #ifdef AUDIO_ENABLE -# define C6_AUDIO +# define AUDIO_PIN C6 # ifdef RGBLIGHT_ENABLE # define NO_MUSIC_MODE # endif diff --git a/keyboards/planck/config.h b/keyboards/planck/config.h index c8cbd7494a37..f7dce70207fe 100644 --- a/keyboards/planck/config.h +++ b/keyboards/planck/config.h @@ -41,7 +41,7 @@ along with this program. If not, see . #define QMK_SPEAKER C6 #define AUDIO_VOICES -#define C6_AUDIO +#define AUDIO_PIN C6 #define BACKLIGHT_PIN B7 diff --git a/keyboards/planck/ez/config.h b/keyboards/planck/ez/config.h index ecab5d5dcdf2..7f8876496382 100644 --- a/keyboards/planck/ez/config.h +++ b/keyboards/planck/ez/config.h @@ -56,7 +56,10 @@ #define MUSIC_MAP #undef AUDIO_VOICES -#undef C6_AUDIO +#undef AUDIO_PIN +#define AUDIO_PIN A5 +#define AUDIO_PIN_ALT A4 +#define AUDIO_PIN_ALT_AS_NEGATIVE /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ // #define DEBOUNCE 6 diff --git a/keyboards/planck/keymaps/dodger/config.h b/keyboards/planck/keymaps/dodger/config.h index 2f94edb01571..38af37bc0519 100644 --- a/keyboards/planck/keymaps/dodger/config.h +++ b/keyboards/planck/keymaps/dodger/config.h @@ -41,7 +41,7 @@ along with this program. If not, see . #define QMK_SPEAKER C6 #define AUDIO_VOICES -#define C6_AUDIO +#define AUDIO_PIN C6 #define BACKLIGHT_PIN B7 diff --git a/keyboards/planck/light/config.h b/keyboards/planck/light/config.h index c7bc9cb1a381..c570ec7667c0 100644 --- a/keyboards/planck/light/config.h +++ b/keyboards/planck/light/config.h @@ -15,8 +15,8 @@ #define MATRIX_ROW_PINS { B0, E7, F0, F1 } #define MATRIX_COL_PINS { E6, E3, E4, D3, D4, D5, C0, A7, A6, E1, E0, D7 } -#define C6_AUDIO -#define B5_AUDIO +#define AUDIO_PIN C6 +#define AUDIO_PIN_ALT B5 #undef BACKLIGHT_PIN diff --git a/keyboards/planck/rev6/config.h b/keyboards/planck/rev6/config.h index f60b0ec2ef47..055610c699f5 100644 --- a/keyboards/planck/rev6/config.h +++ b/keyboards/planck/rev6/config.h @@ -53,8 +53,10 @@ #define MUSIC_MAP #undef AUDIO_VOICES -// Note: following undef isn't really necessary on STM32, C6_AUDIO is AVR related -#undef C6_AUDIO +#undef AUDIO_PIN +#define AUDIO_PIN A5 +#define AUDIO_PIN_ALT A4 +#define AUDIO_PIN_ALT_AS_NEGATIVE /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ // #define DEBOUNCE 6 diff --git a/keyboards/preonic/config.h b/keyboards/preonic/config.h index c4aa5805dc16..f08be58c68c1 100644 --- a/keyboards/preonic/config.h +++ b/keyboards/preonic/config.h @@ -41,7 +41,7 @@ along with this program. If not, see . #define QMK_SPEAKER C6 #define AUDIO_VOICES -#define C6_AUDIO +#define AUDIO_PIN C6 #define BACKLIGHT_PIN B7 diff --git a/keyboards/preonic/rev3/config.h b/keyboards/preonic/rev3/config.h index 773a9c5fbd59..e8b09e8484f0 100644 --- a/keyboards/preonic/rev3/config.h +++ b/keyboards/preonic/rev3/config.h @@ -40,8 +40,10 @@ #define MUSIC_MAP #undef AUDIO_VOICES -// Note: following undef isn't really necessary on STM32, C6_AUDIO is AVR related -#undef C6_AUDIO +#undef AUDIO_PIN +#define AUDIO_PIN A5 +#define AUDIO_PIN_ALT A4 +#define AUDIO_PIN_ALT_AS_NEGATIVE /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ // #define DEBOUNCE 6 diff --git a/keyboards/scarletbandana/config.h b/keyboards/scarletbandana/config.h index 38a15f676f34..b9c8dd9b0fbf 100644 --- a/keyboards/scarletbandana/config.h +++ b/keyboards/scarletbandana/config.h @@ -45,7 +45,7 @@ along with this program. If not, see . #define QMK_SPEAKER C6 #ifdef AUDIO_ENABLE -#define C6_AUDIO +#define AUDIO_PIN C6 #define STARTUP_SONG SONG(PREONIC_SOUND) // Disable music mode to keep the firmware size down #define NO_MUSIC_MODE diff --git a/keyboards/silverbullet44/config.h b/keyboards/silverbullet44/config.h index dfd5e0aa9464..cd78ef34185d 100644 --- a/keyboards/silverbullet44/config.h +++ b/keyboards/silverbullet44/config.h @@ -111,7 +111,7 @@ along with this program. If not, see . /* Audio */ #ifdef AUDIO_ENABLE - #define B6_AUDIO + #define AUDIO_PIN B6 #define STARTUP_SONG SONG(STARTUP_SOUND) #define AUDIO_CLICKY #define AUDIO_CLICKY_FREQ_RANDOMNESS 1.0f diff --git a/keyboards/splitkb/zima/config.h b/keyboards/splitkb/zima/config.h index b39ef73082bc..fcfa37ff351b 100644 --- a/keyboards/splitkb/zima/config.h +++ b/keyboards/splitkb/zima/config.h @@ -49,7 +49,7 @@ along with this program. If not, see . // #define QMK_ESC_INPUT C6 // #define QMK_SPEAKER B6 -#define B6_AUDIO +#define AUDIO_PIN B6 #define AUDIO_CLICKY #define NO_MUSIC_MODE diff --git a/keyboards/subatomic/config.h b/keyboards/subatomic/config.h index db65287fcf38..b19339ad6cb4 100644 --- a/keyboards/subatomic/config.h +++ b/keyboards/subatomic/config.h @@ -37,7 +37,7 @@ along with this program. If not, see . #define UNUSED_PINS // #define AUDIO_VOICES -// #define C6_AUDIO +// #define AUDIO_PIN C6 #define BACKLIGHT_PIN B7 diff --git a/keyboards/tetris/config.h b/keyboards/tetris/config.h index a38c3a8d4562..1f13f5f16805 100755 --- a/keyboards/tetris/config.h +++ b/keyboards/tetris/config.h @@ -34,7 +34,7 @@ #define NO_ACTION_FUNCTION #ifdef AUDIO_ENABLE - #define B5_AUDIO + #define AUDIO_PIN B5 #define STARTUP_SONG SONG(ONE_UP_SOUND) #define NO_MUSIC_MODE #endif diff --git a/keyboards/vitamins_included/rev1/config.h b/keyboards/vitamins_included/rev1/config.h index ff0c6bcb5be3..e8390aa27bf8 100644 --- a/keyboards/vitamins_included/rev1/config.h +++ b/keyboards/vitamins_included/rev1/config.h @@ -61,7 +61,7 @@ along with this program. If not, see . /* Audio settings */ #ifdef AUDIO_ENABLE - #define C6_AUDIO // Define this to enable the buzzer + #define AUDIO_PIN C6 // Define this to enable the buzzer #endif /* diff --git a/keyboards/vitamins_included/rev2/config.h b/keyboards/vitamins_included/rev2/config.h index ebbbc15eaed5..8bf640f0bb01 100644 --- a/keyboards/vitamins_included/rev2/config.h +++ b/keyboards/vitamins_included/rev2/config.h @@ -61,7 +61,7 @@ along with this program. If not, see . /* Audio settings */ #ifdef AUDIO_ENABLE - #define C6_AUDIO // Define this to enable the buzzer + #define AUDIO_PIN C6 // Define this to enable the buzzer #endif #define QMK_ESC_OUTPUT F1 // usually COL diff --git a/keyboards/wilba_tech/wt60_xt/config.h b/keyboards/wilba_tech/wt60_xt/config.h index 6ddad99df95a..5914e59fd14f 100644 --- a/keyboards/wilba_tech/wt60_xt/config.h +++ b/keyboards/wilba_tech/wt60_xt/config.h @@ -25,7 +25,7 @@ #define MANUFACTURER wilba.tech #define PRODUCT wilba.tech WT60-XT -#define C6_AUDIO +#define AUDIO_PIN C6 #define AUDIO_CLICKY /* key matrix size */ diff --git a/keyboards/yoichiro/lunakey_mini/config.h b/keyboards/yoichiro/lunakey_mini/config.h index 86290cd4e14f..abbecef44336 100644 --- a/keyboards/yoichiro/lunakey_mini/config.h +++ b/keyboards/yoichiro/lunakey_mini/config.h @@ -89,7 +89,7 @@ along with this program. If not, see . #endif /* Audio Support */ -#define C6_AUDIO +#define AUDIO_PIN C6 /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ #define DEBOUNCE 5 diff --git a/layouts/community/numpad_5x6/bjohnson/config.h b/layouts/community/numpad_5x6/bjohnson/config.h index 668450d88da5..6f1c53970036 100644 --- a/layouts/community/numpad_5x6/bjohnson/config.h +++ b/layouts/community/numpad_5x6/bjohnson/config.h @@ -1,7 +1,5 @@ #pragma once -// #define B6_AUDIO - #if defined(RGBLIGHT_ENABLE) && !defined(RGBLED_NUM) #define RGB_DI_PIN B7 #define RGBLED_NUM 13 // Number of LEDs diff --git a/layouts/community/numpad_5x6/drashna/config.h b/layouts/community/numpad_5x6/drashna/config.h index 97c1170d7873..1f485e1939d8 100644 --- a/layouts/community/numpad_5x6/drashna/config.h +++ b/layouts/community/numpad_5x6/drashna/config.h @@ -16,7 +16,6 @@ #pragma once -// #define B6_AUDIO #if defined(RGBLIGHT_ENABLE) && !defined(RGBLED_NUM) # define RGB_DI_PIN B1 diff --git a/layouts/community/ortho_4x12/bakingpy/config.h b/layouts/community/ortho_4x12/bakingpy/config.h index a153adffb6f0..f7d2c24252ee 100644 --- a/layouts/community/ortho_4x12/bakingpy/config.h +++ b/layouts/community/ortho_4x12/bakingpy/config.h @@ -16,5 +16,5 @@ #define RGBLIGHT_VAL_STEP 8 #ifdef AUDIO_ENABLE -#define C6_AUDIO +#define AUDIO_PIN C6 #endif diff --git a/layouts/community/ortho_5x12/drashna/config.h b/layouts/community/ortho_5x12/drashna/config.h index 76bd642a32ce..619b460a7b0a 100644 --- a/layouts/community/ortho_5x12/drashna/config.h +++ b/layouts/community/ortho_5x12/drashna/config.h @@ -33,6 +33,6 @@ # define RGBLIGHT_EFFECT_KNIGHT_OFFSET 3 # define RGBLIGHT_EFFECT_KNIGHT_LED_NUM 14 -# define B7_AUDIO +# define AUDIO_PIN B7 # define NO_MUSIC_MODE #endif diff --git a/layouts/community/ortho_5x14/yet-another-developer/config.h b/layouts/community/ortho_5x14/yet-another-developer/config.h index 7504338fff4c..3f8dbd3c5edc 100644 --- a/layouts/community/ortho_5x14/yet-another-developer/config.h +++ b/layouts/community/ortho_5x14/yet-another-developer/config.h @@ -17,6 +17,6 @@ # define RGBLIGHT_EFFECT_KNIGHT_OFFSET 3 # define RGBLIGHT_EFFECT_KNIGHT_LED_NUM 14 -# define B7_AUDIO +# define AUDIO_PIN B7 # define NO_MUSIC_MODE #endif diff --git a/layouts/community/split_3x6_3/drashna/config.h b/layouts/community/split_3x6_3/drashna/config.h index b9b1d073d66f..17d7b9ec7389 100644 --- a/layouts/community/split_3x6_3/drashna/config.h +++ b/layouts/community/split_3x6_3/drashna/config.h @@ -74,7 +74,7 @@ #endif #ifdef AUDIO_ENABLE -# define B6_AUDIO +# define AUDIO_PIN B6 # define NO_MUSIC_MODE #endif diff --git a/platforms/chibios/QMK_PROTON_C/configs/config.h b/platforms/chibios/QMK_PROTON_C/configs/config.h index 5e29d1fce154..a73f0c0b475a 100644 --- a/platforms/chibios/QMK_PROTON_C/configs/config.h +++ b/platforms/chibios/QMK_PROTON_C/configs/config.h @@ -18,10 +18,3 @@ #ifndef EARLY_INIT_PERFORM_BOOTLOADER_JUMP # define EARLY_INIT_PERFORM_BOOTLOADER_JUMP TRUE #endif - - -#if defined(AUDIO_ENABLE) && defined(AUDIO_DRIVER_DAC) && !defined(AUDIO_PIN) -# define AUDIO_PIN A5 -# define AUDIO_PIN_ALT A4 -# define AUDIO_PIN_ALT_AS_NEGATIVE -#endif diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 6f1dc139d319..56b9158a1a03 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -271,36 +271,6 @@ bool audio_update_state(void); // legacy and back-warts compatibility stuff -// LEGACY defines - TODO: remove and replace these in all keyboards using them -#ifdef A4_AUDIO -# define AUDIO_PIN A4 -#endif -#ifdef A5_AUDIO -# define AUDIO_PIN A5 -#endif -#if !defined(AUDIO_PIN_ALT) -# ifdef B5_AUDIO -# define AUDIO_PIN_ALT B5 -# endif -# ifdef B6_AUDIO -# define AUDIO_PIN_ALT B6 -# endif -# ifdef B7_AUDIO -# define AUDIO_PIN_ALT B7 -# endif -#endif -#if !defined(AUDIO_PIN) -# ifdef C4_AUDIO -# define AUDIO_PIN C4 -# endif -# ifdef C5_AUDIO -# define AUDIO_PIN C5 -# endif -# ifdef C6_AUDIO -# define AUDIO_PIN C6 -# endif -#endif - #define is_audio_on() audio_is_on() #define is_playing_notes() audio_is_playing_melody() #define is_playing_note() audio_is_playing_note() diff --git a/users/yanfali/config.h b/users/yanfali/config.h index 26517a9f64b0..a39e95c9ddec 100644 --- a/users/yanfali/config.h +++ b/users/yanfali/config.h @@ -2,7 +2,7 @@ #ifdef KEYBOARD_evyd13_plain60 -#define B7_AUDIO +#define AUDIO_PIN B7 #ifdef AUDIO_ENABLE #define STARTUP_SONG SONG(GUITAR_SOUND) #endif From cea6cfb42bdbf62fb305c9714150eee657a0e28a Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Tue, 9 Feb 2021 08:50:15 -0800 Subject: [PATCH 150/153] fix depreciated --- docs/config_options.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/config_options.md b/docs/config_options.md index e7ced5834922..aeaaf47aaf4f 100644 --- a/docs/config_options.md +++ b/docs/config_options.md @@ -67,22 +67,22 @@ This is a C header file that is one of the first things included, and will persi * turns on the alternate audio voices (to cycle through) * `#define C4_AUDIO` * enables audio on pin C4 - * Depricated. Use `#define AUDIO_PIN C4` + * Deprecated. Use `#define AUDIO_PIN C4` * `#define C5_AUDIO` * enables audio on pin C5 - * Depricated. Use `#define AUDIO_PIN C5` + * Deprecated. Use `#define AUDIO_PIN C5` * `#define C6_AUDIO` * enables audio on pin C6 - * Depricated. Use `#define AUDIO_PIN C6` + * Deprecated. Use `#define AUDIO_PIN C6` * `#define B5_AUDIO` - * enables audio on pin B5 (duophony is enables if one of B pins is enabled along with one of C pins) - * Depricated. Use `#define AUDIO_PIN B5`, or use `#define AUDIO_PIN_ALT B5` if a `C` pin is enabled with `AUDIO_PIN` + * enables audio on pin B5 (duophony is enabled if one of B pins is enabled along with one of C pins) + * Deprecated. Use `#define AUDIO_PIN B5`, or use `#define AUDIO_PIN_ALT B5` if a `C` pin is enabled with `AUDIO_PIN` * `#define B6_AUDIO` - * enables audio on pin B5 (duophony is enables if one of B pins is enabled along with one of C pins) - * Depricated. Use `#define AUDIO_PIN B6`, or use `#define AUDIO_PIN_ALT B6` if a `C` pin is enabled with `AUDIO_PIN` + * enables audio on pin B5 (duophony is enabled if one of B pins is enabled along with one of C pins) + * Deprecated. Use `#define AUDIO_PIN B6`, or use `#define AUDIO_PIN_ALT B6` if a `C` pin is enabled with `AUDIO_PIN` * `#define B7_AUDIO` - * enables audio on pin B5 (duophony is enables if one of B pins is enabled along with one of C pins) - * Depricated. Use `#define AUDIO_PIN B7`, or use `#define AUDIO_PIN_ALT B7` if a `C` pin is enabled with `AUDIO_PIN` + * enables audio on pin B5 (duophony is enabled if one of B pins is enabled along with one of C pins) + * Deprecated. Use `#define AUDIO_PIN B7`, or use `#define AUDIO_PIN_ALT B7` if a `C` pin is enabled with `AUDIO_PIN` * `#define BACKLIGHT_PIN B7` * pin of the backlight * `#define BACKLIGHT_LEVELS 3` From 76bf2b66cf802e7412718cc4022ea2a45c7eb450 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Tue, 9 Feb 2021 12:08:23 -0800 Subject: [PATCH 151/153] Update util/audio_generate_dac_lut.py Co-authored-by: Jack Humbert --- util/audio_generate_dac_lut.py | 1 - 1 file changed, 1 deletion(-) diff --git a/util/audio_generate_dac_lut.py b/util/audio_generate_dac_lut.py index 6895e5791635..c31ba3d7ee00 100755 --- a/util/audio_generate_dac_lut.py +++ b/util/audio_generate_dac_lut.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 # -# Copyright 2019 Jack Humbert # Copyright 2020 JohSchneider # # This program is free software: you can redistribute it and/or modify From c0f86058e68a78cf066a241fc849179cf76d69ec Mon Sep 17 00:00:00 2001 From: Drashna Jael're Date: Fri, 12 Feb 2021 12:23:13 -0800 Subject: [PATCH 152/153] Fix type in clueboard config --- keyboards/clueboard/66_hotswap/gen1/config.h | 1 - 1 file changed, 1 deletion(-) diff --git a/keyboards/clueboard/66_hotswap/gen1/config.h b/keyboards/clueboard/66_hotswap/gen1/config.h index 5e0682e5a7a8..1471af63dcd0 100644 --- a/keyboards/clueboard/66_hotswap/gen1/config.h +++ b/keyboards/clueboard/66_hotswap/gen1/config.h @@ -112,4 +112,3 @@ #define AUDIO_PIN A5 #define AUDIO_PIN_ALT A4 #define AUDIO_PIN_ALT_AS_NEGATIVE -n From 5cd859c25fa72a0e9f959e2a716952e950fbb161 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Sun, 14 Feb 2021 14:27:44 -0800 Subject: [PATCH 153/153] Apply suggestions from tzarc Co-authored-by: Nick Brassel --- docs/audio_driver.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/audio_driver.md b/docs/audio_driver.md index 8dc71e7e10e9..7cd5a98d9f46 100644 --- a/docs/audio_driver.md +++ b/docs/audio_driver.md @@ -61,14 +61,21 @@ Additionally, in the board config, you'll want to make changes to enable the DAC //halconf.h: #define HAL_USE_DAC TRUE #define HAL_USE_GPT TRUE +#include_next ``` ``` c // mcuconf.h: +#include_next +#undef STM32_DAC_USE_DAC1_CH1 #define STM32_DAC_USE_DAC1_CH1 TRUE +#undef STM32_DAC_USE_DAC1_CH2 #define STM32_DAC_USE_DAC1_CH2 TRUE +#undef STM32_GPT_USE_TIM6 #define STM32_GPT_USE_TIM6 TRUE +#undef STM32_GPT_USE_TIM7 #define STM32_GPT_USE_TIM7 TRUE +#undef STM32_GPT_USE_TIM8 #define STM32_GPT_USE_TIM8 TRUE ``` @@ -90,12 +97,17 @@ Additionally, in the board config, you'll want to make changes to enable the DAC //halconf.h: #define HAL_USE_DAC TRUE #define HAL_USE_GPT TRUE +#include_next ``` ``` c // mcuconf.h: +#include_next +#undef STM32_DAC_USE_DAC1_CH1 #define STM32_DAC_USE_DAC1_CH1 TRUE +#undef STM32_DAC_USE_DAC1_CH2 #define STM32_DAC_USE_DAC1_CH2 TRUE +#undef STM32_GPT_USE_TIM6 #define STM32_GPT_USE_TIM6 TRUE ``` @@ -146,11 +158,15 @@ A configuration example for the STM32F103C8 would be: #define HAL_USE_PWM TRUE #define HAL_USE_PAL TRUE #define HAL_USE_GPT TRUE +#include_next ``` ``` c // mcuconf.h: +#include_next +#undef STM32_PWM_USE_TIM1 #define STM32_PWM_USE_TIM1 TRUE +#undef STM32_GPT_USE_TIM4 #define STM32_GPT_USE_TIM4 TRUE ```