block = receiveReadOnly(); | block = receiveReadOnly(); | ||||
if (!block) return; | if (!block) return; | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
switch (state) { | switch (state) { | ||||
case 0: | case 0: | ||||
blocklist[0] = block; | blocklist[0] = block; |
count++; | count++; | ||||
return; | return; | ||||
} | } | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
uint32_t *p = (uint32_t *)(block->data); | uint32_t *p = (uint32_t *)(block->data); | ||||
uint32_t *end = p + AUDIO_BLOCK_SAMPLES/2; | uint32_t *end = p + AUDIO_BLOCK_SAMPLES/2; | ||||
int64_t sum = accum; | int64_t sum = accum; |
#include "analyze_tonedetect.h" | #include "analyze_tonedetect.h" | ||||
#include "utility/dspinst.h" | #include "utility/dspinst.h" | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
static inline int32_t multiply_32x32_rshift30(int32_t a, int32_t b) __attribute__((always_inline)); | static inline int32_t multiply_32x32_rshift30(int32_t a, int32_t b) __attribute__((always_inline)); | ||||
static inline int32_t multiply_32x32_rshift30(int32_t a, int32_t b) | static inline int32_t multiply_32x32_rshift30(int32_t a, int32_t b) |
//unsigned int n = read(CHIP_ID); | //unsigned int n = read(CHIP_ID); | ||||
//Serial.println(n, HEX); | //Serial.println(n, HEX); | ||||
write(CHIP_ANA_POWER, 0x4060); // VDDD is externally driven with 1.8V | |||||
int r = write(CHIP_ANA_POWER, 0x4060); // VDDD is externally driven with 1.8V | |||||
if (!r) return false; | |||||
write(CHIP_LINREG_CTRL, 0x006C); // VDDA & VDDIO both over 3.1V | write(CHIP_LINREG_CTRL, 0x006C); // VDDA & VDDIO both over 3.1V | ||||
write(CHIP_REF_CTRL, 0x01F2); // VAG=1.575, normal ramp, +12.5% bias current | write(CHIP_REF_CTRL, 0x01F2); // VAG=1.575, normal ramp, +12.5% bias current | ||||
write(CHIP_LINE_OUT_CTRL, 0x0F22); // LO_VAGCNTRL=1.65V, OUT_CURRENT=0.54mA | write(CHIP_LINE_OUT_CTRL, 0x0F22); // LO_VAGCNTRL=1.65V, OUT_CURRENT=0.54mA |
void AudioEffectFreeverb::update() | void AudioEffectFreeverb::update() | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
const audio_block_t *block; | const audio_block_t *block; | ||||
audio_block_t *outblock; | audio_block_t *outblock; | ||||
int i; | int i; | ||||
void AudioEffectFreeverbStereo::update() | void AudioEffectFreeverbStereo::update() | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
const audio_block_t *block; | const audio_block_t *block; | ||||
audio_block_t *outblockL; | audio_block_t *outblockL; | ||||
audio_block_t *outblockR; | audio_block_t *outblockR; |
if (blockb) release(blockb); // of the blocks is NULL then it's trouble anyway | if (blockb) release(blockb); // of the blocks is NULL then it's trouble anyway | ||||
return; | return; | ||||
} | } | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
pa = (uint32_t *)(blocka->data); | pa = (uint32_t *)(blocka->data); | ||||
pb = (uint32_t *)(blockb->data); | pb = (uint32_t *)(blockb->data); | ||||
end = pa + AUDIO_BLOCK_SAMPLES/2; | end = pa + AUDIO_BLOCK_SAMPLES/2; |
void AudioEffectMultiply::update(void) | void AudioEffectMultiply::update(void) | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
audio_block_t *blocka, *blockb; | audio_block_t *blocka, *blockb; | ||||
uint32_t *pa, *pb, *end; | uint32_t *pa, *pb, *end; | ||||
uint32_t a12, a34; //, a56, a78; | uint32_t a12, a34; //, a56, a78; |
// Audio data converted from WAV file by wav2sketch | // Audio data converted from WAV file by wav2sketch | ||||
#include "AudioSampleCashregister.h" | #include "AudioSampleCashregister.h" | ||||
#include <Arduino.h> | |||||
// Converted from cashregister.wav, using 22050 Hz, u-law encoding | // Converted from cashregister.wav, using 22050 Hz, u-law encoding | ||||
PROGMEM | |||||
const unsigned int AudioSampleCashregister[5809] = { | const unsigned int AudioSampleCashregister[5809] = { | ||||
0x02005AB4,0x82060707,0x03010301,0x08038287,0x81820200,0x09120407,0x15091108,0x02080611, | 0x02005AB4,0x82060707,0x03010301,0x08038287,0x81820200,0x09120407,0x15091108,0x02080611, | ||||
0x0D050D11,0x8008150C,0x93810480,0x000D8890,0x0A060406,0x06000681,0x80828702,0x89928405, | 0x0D050D11,0x8008150C,0x93810480,0x000D8890,0x0A060406,0x06000681,0x80828702,0x89928405, |
// Audio data converted from WAV file by wav2sketch | // Audio data converted from WAV file by wav2sketch | ||||
#include "AudioSampleGong.h" | #include "AudioSampleGong.h" | ||||
#include <Arduino.h> | |||||
// Converted from gong.wav, using 11025 Hz, u-law encoding | // Converted from gong.wav, using 11025 Hz, u-law encoding | ||||
PROGMEM | |||||
const unsigned int AudioSampleGong[27633] = { | const unsigned int AudioSampleGong[27633] = { | ||||
0x0301AFA4,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, | 0x0301AFA4,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, | ||||
0x00000000,0x00000000,0x00000000,0x00000000,0x00008000,0x00000000,0x00000000,0x80800000, | 0x00000000,0x00000000,0x00000000,0x00000000,0x00008000,0x00000000,0x00000000,0x80800000, |
// Audio data converted from WAV file by wav2sketch | // Audio data converted from WAV file by wav2sketch | ||||
#include "AudioSampleHihat.h" | #include "AudioSampleHihat.h" | ||||
#include <Arduino.h> | |||||
// Converted from hihat.wav, using 44100 Hz, u-law encoding | // Converted from hihat.wav, using 44100 Hz, u-law encoding | ||||
PROGMEM | |||||
const unsigned int AudioSampleHihat[5953] = { | const unsigned int AudioSampleHihat[5953] = { | ||||
0x01005CB1,0x77766877,0xEAEC2195,0xE0737099,0x82807B70,0x88909012,0x8B822303,0x8C04180B, | 0x01005CB1,0x77766877,0xEAEC2195,0xE0737099,0x82807B70,0x88909012,0x8B822303,0x8C04180B, | ||||
0x090B9207,0x878EA413,0x1EB09F15,0x0B9B2122,0xA09E0094,0x51B2B980,0xD1485CCA,0xDACCBF48, | 0x090B9207,0x878EA413,0x1EB09F15,0x0B9B2122,0xA09E0094,0x51B2B980,0xD1485CCA,0xDACCBF48, |
// Audio data converted from WAV file by wav2sketch | // Audio data converted from WAV file by wav2sketch | ||||
#include "AudioSampleKick.h" | #include "AudioSampleKick.h" | ||||
#include <Arduino.h> | |||||
// Converted from kick.wav, using 22050 Hz, 16 bit PCM encoding | // Converted from kick.wav, using 22050 Hz, 16 bit PCM encoding | ||||
PROGMEM | |||||
const unsigned int AudioSampleKick[2561] = { | const unsigned int AudioSampleKick[2561] = { | ||||
0x820013EC,0xFFDC0027,0xFF710095,0x038DFF4C,0xFBA10105,0x0037FB6E,0x09D2011A,0x007504CA, | 0x820013EC,0xFFDC0027,0xFF710095,0x038DFF4C,0xFBA10105,0x0037FB6E,0x09D2011A,0x007504CA, | ||||
0x024BF6BF,0xF77B0AFF,0xFB72F723,0xEF3DEBAD,0x0F7009D6,0x09DD1736,0xF26EFA3E,0x0D7002FB, | 0x024BF6BF,0xF77B0AFF,0xFB72F723,0xEF3DEBAD,0x0F7009D6,0x09DD1736,0xF26EFA3E,0x0D7002FB, |
// Audio data converted from WAV file by wav2sketch | // Audio data converted from WAV file by wav2sketch | ||||
#include "AudioSampleSnare.h" | #include "AudioSampleSnare.h" | ||||
#include <Arduino.h> | |||||
// Converted from snare.wav, using 22050 Hz, u-law encoding | // Converted from snare.wav, using 22050 Hz, u-law encoding | ||||
PROGMEM | |||||
const unsigned int AudioSampleSnare[2817] = { | const unsigned int AudioSampleSnare[2817] = { | ||||
0x02002BD3,0x65636656,0x6B6A6B67,0x7071706F,0x43637171,0x29ABBA23,0x3137474C,0x3A4A544D, | 0x02002BD3,0x65636656,0x6B6A6B67,0x7071706F,0x43637171,0x29ABBA23,0x3137474C,0x3A4A544D, | ||||
0x30C1542C,0xE14F6360,0xEDDCE2E6,0xEEF1F4F4,0xEEEDEAEA,0x3745A2E2,0xE7E6DAC8,0xC7C3C3DA, | 0x30C1542C,0xE14F6360,0xEDDCE2E6,0xEEF1F4F4,0xEEEDEAEA,0x3745A2E2,0xE7E6DAC8,0xC7C3C3DA, |
// Audio data converted from WAV file by wav2sketch | // Audio data converted from WAV file by wav2sketch | ||||
#include "AudioSampleTomtom.h" | #include "AudioSampleTomtom.h" | ||||
#include <Arduino.h> | |||||
// Converted from tomtom.wav, using 11025 Hz, 16 bit PCM encoding | // Converted from tomtom.wav, using 11025 Hz, 16 bit PCM encoding | ||||
PROGMEM | |||||
const unsigned int AudioSampleTomtom[3489] = { | const unsigned int AudioSampleTomtom[3489] = { | ||||
0x83001B3C,0xFC0EFF8B,0xFB40FD97,0x045BFB30,0xEABCEAD6,0x04C2F8B3,0x002B0733,0xFB1C0879, | 0x83001B3C,0xFC0EFF8B,0xFB40FD97,0x045BFB30,0xEABCEAD6,0x04C2F8B3,0x002B0733,0xFB1C0879, | ||||
0xE9CCED7A,0xEC2AEC4D,0xF7D8EF09,0xF6EC0EE6,0x15A4F3A6,0xFAD81B95,0xF591F001,0x0A3FFF14, | 0xE9CCED7A,0xEC2AEC4D,0xF7D8EF09,0xF6EC0EE6,0x15A4F3A6,0xFAD81B95,0xF591F001,0x0A3FFF14, |
// Playtune bytestream for file "william_tell_overture.mid" created by MIDITONES V1.6 on Sat Sep 6 16:56:56 2014 | // Playtune bytestream for file "william_tell_overture.mid" created by MIDITONES V1.6 on Sat Sep 6 16:56:56 2014 | ||||
// command line: ./miditones -t16 -v william_tell_overture | // command line: ./miditones -t16 -v william_tell_overture | ||||
#ifdef __AVR__ | |||||
#include <avr/pgmspace.h> | |||||
#else | |||||
#define PROGMEM | |||||
#endif | |||||
#include <Arduino.h> | |||||
const unsigned char PROGMEM score [] = { | const unsigned char PROGMEM score [] = { | ||||
0x90,72,127, 0x91,72,107, 0x92,72,127, 0x93,72,127, 0x94,72,127, 1,169, 0x80, 0x81, 0x82, 0x83, | 0x90,72,127, 0x91,72,107, 0x92,72,127, 0x93,72,127, 0x94,72,127, 1,169, 0x80, 0x81, 0x82, 0x83, | ||||
0x84, 0,183, 0x90,72,127, 0x91,72,107, 0x92,72,127, 0x93,72,127, 0x94,72,127, 0,41, 0x80, | 0x84, 0,183, 0x90,72,127, 0x91,72,107, 0x92,72,127, 0x93,72,127, 0x94,72,127, 0,41, 0x80, |
#include "Flute_100kbyte_samples.h" | #include "Flute_100kbyte_samples.h" | ||||
PROGMEM | |||||
static const uint32_t sample_0_Flute_100kbyte_FluteD4[7936] = { | static const uint32_t sample_0_Flute_100kbyte_FluteD4[7936] = { | ||||
0xfbfffc4b,0xfba4fbac,0xfbbffbb2,0xfc00fbdc,0xfc3afc16,0xfcb8fc57,0xfcf9fcf3,0xfc87fcad, | 0xfbfffc4b,0xfba4fbac,0xfbbffbb2,0xfc00fbdc,0xfc3afc16,0xfcb8fc57,0xfcf9fcf3,0xfc87fcad, | ||||
0xfcabfc77,0xfd8cfd0c,0xfe7dfe0c,0xff24fee0,0xffc4ff61,0x006a002d,0x002d004c,0xffe90000, | 0xfcabfc77,0xfd8cfd0c,0xfe7dfe0c,0xff24fee0,0xffc4ff61,0x006a002d,0x002d004c,0xffe90000, | ||||
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, | 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, | ||||
}; | }; | ||||
PROGMEM | |||||
static const uint32_t sample_1_Flute_100kbyte_FluteE5[9472] = { | static const uint32_t sample_1_Flute_100kbyte_FluteE5[9472] = { | ||||
0x03f00410,0x03f003c0,0x04500410,0x04500460,0x04200410,0x03800400,0x02f00320,0x01900230, | 0x03f00410,0x03f003c0,0x04500410,0x04500460,0x04200410,0x03800400,0x02f00320,0x01900230, | ||||
0x005000c0,0xff30ffb0,0xff70ff40,0xfe10fe90,0xfd70fde0,0xfc70fcc0,0xfc30fc00,0xfc40fca0, | 0x005000c0,0xff30ffb0,0xff70ff40,0xfe10fe90,0xfd70fde0,0xfc70fcc0,0xfc30fc00,0xfc40fca0, | ||||
0x00000000,0x00000000, | 0x00000000,0x00000000, | ||||
}; | }; | ||||
PROGMEM | |||||
static const uint32_t sample_2_Flute_100kbyte_FluteE6[7936] = { | static const uint32_t sample_2_Flute_100kbyte_FluteE6[7936] = { | ||||
0x01b003e0,0x02e00250,0x01300150,0x003000f0,0x01400180,0xffc0fed0,0xff600100,0x0080ffc0, | 0x01b003e0,0x02e00250,0x01300150,0x003000f0,0x01400180,0xffc0fed0,0xff600100,0x0080ffc0, | ||||
0xffd0feb0,0xff500130,0x0070feb0,0xfed00060,0x00d0ffc0,0xff10ff50,0xff500030,0x0080ff60, | 0xffd0feb0,0xff500130,0x0070feb0,0xfed00060,0x00d0ffc0,0xff10ff50,0xff500030,0x0080ff60, | ||||
static const uint8_t Flute_100kbyte_ranges[] = {68, 83, 127, }; | static const uint8_t Flute_100kbyte_ranges[] = {68, 83, 127, }; | ||||
const AudioSynthWavetable::instrument_data Flute_100kbyte = {3, Flute_100kbyte_ranges, Flute_100kbyte_samples }; | const AudioSynthWavetable::instrument_data Flute_100kbyte = {3, Flute_100kbyte_ranges, Flute_100kbyte_samples }; | ||||
#include "MutedTrumpet_samples.h" | #include "MutedTrumpet_samples.h" | ||||
PROGMEM | |||||
static const uint32_t sample_0_MutedTrumpet_HRMMUTED4[8192] = { | static const uint32_t sample_0_MutedTrumpet_HRMMUTED4[8192] = { | ||||
0xffdaffd4,0xffdeffdd,0xffe4ffe1,0xffe2ffe5,0xffd0ffda,0xffbfffc7,0xffb8ffb9,0xffb8ffb9, | 0xffdaffd4,0xffdeffdd,0xffe4ffe1,0xffe2ffe5,0xffd0ffda,0xffbfffc7,0xffb8ffb9,0xffb8ffb9, | ||||
0xffb1ffb3,0xffaeffb1,0xffabffaa,0xffb1ffaf,0xffacffb0,0xffa2ffa7,0xffa3ffa0,0xffa9ffa7, | 0xffb1ffb3,0xffaeffb1,0xffabffaa,0xffb1ffaf,0xffacffb0,0xffa2ffa7,0xffa3ffa0,0xffa9ffa7, | ||||
0x00000000,0x00000000,0x00000000,0x00000000, | 0x00000000,0x00000000,0x00000000,0x00000000, | ||||
}; | }; | ||||
PROGMEM | |||||
static const uint32_t sample_1_MutedTrumpet_HRMMUTEC5[6912] = { | static const uint32_t sample_1_MutedTrumpet_HRMMUTEC5[6912] = { | ||||
0x00000000,0xfffeffff,0x0000ffff,0xffff0000,0xfffffffe,0xffffffff,0xfffdfffe,0xfffdfffd, | 0x00000000,0xfffeffff,0x0000ffff,0xffff0000,0xfffffffe,0xffffffff,0xfffdfffe,0xfffdfffd, | ||||
0xfffbfffc,0xfff9fff9,0xfffbfffa,0xfffbfffb,0xfffafffb,0xfffafff9,0xfffbfffb,0xfff8fff9, | 0xfffbfffc,0xfff9fff9,0xfffbfffa,0xfffbfffb,0xfffafffb,0xfffafff9,0xfffbfffb,0xfff8fff9, | ||||
0x00000000,0x00000000,0x00000000,0x00000000, | 0x00000000,0x00000000,0x00000000,0x00000000, | ||||
}; | }; | ||||
PROGMEM | |||||
static const uint32_t sample_2_MutedTrumpet_HRMMUTEC6[4608] = { | static const uint32_t sample_2_MutedTrumpet_HRMMUTEC6[4608] = { | ||||
0xff89ff87,0xff85ff8a,0xff7cff7f,0xff7bff7b,0xff79ff7a,0xff74ff77,0xff73ff72,0xff7cff78, | 0xff89ff87,0xff85ff8a,0xff7cff7f,0xff7bff7b,0xff79ff7a,0xff74ff77,0xff73ff72,0xff7cff78, | ||||
0xff82ff80,0xff85ff83,0xff8bff88,0xff8eff8d,0xff90ff90,0xff8cff8f,0xff87ff89,0xff7eff83, | 0xff82ff80,0xff85ff83,0xff8bff88,0xff8eff8d,0xff90ff90,0xff8cff8f,0xff87ff89,0xff7eff83, | ||||
static const uint8_t MutedTrumpet_ranges[] = {71, 82, 127, }; | static const uint8_t MutedTrumpet_ranges[] = {71, 82, 127, }; | ||||
const AudioSynthWavetable::instrument_data MutedTrumpet = {3, MutedTrumpet_ranges, MutedTrumpet_samples }; | const AudioSynthWavetable::instrument_data MutedTrumpet = {3, MutedTrumpet_ranges, MutedTrumpet_samples }; | ||||
// Playtune bytestream for file "..\..\Downloads\Good Midi\Overworld.mid" created by MIDITONES V1.14 on Sun Mar 5 00:09:03 2017 | // Playtune bytestream for file "..\..\Downloads\Good Midi\Overworld.mid" created by MIDITONES V1.14 on Sun Mar 5 00:09:03 2017 | ||||
// command line: miditones.exe -t16 -v -i ..\..\Downloads\Good Midi\Overworld | |||||
#ifdef __AVR__ | |||||
#include <avr/pgmspace.h> | |||||
#else | |||||
#define PROGMEM | |||||
#endif | |||||
#include <Arduino.h> | |||||
const unsigned char PROGMEM score [] = { | const unsigned char PROGMEM score [] = { | ||||
0xC0,48, 0x90,66,127, 0xC1,48, 0x91,62,127, 0xC2,48, 0x92,38,127, 0xC3,48, 0x93,38,127, 0,222, 0x92,45,127, 0,222, | 0xC0,48, 0x90,66,127, 0xC1,48, 0x91,62,127, 0xC2,48, 0x92,38,127, 0xC3,48, 0x93,38,127, 0,222, 0x92,45,127, 0,222, | ||||
0x92,50,127, 0,222, 0x92,38,127, 0x93,52,127, 1,188, 0x93,50,127, 0,222, 0x93,50,127, 0,222, 0x92,33,127, | 0x92,50,127, 0,222, 0x92,38,127, 0x93,52,127, 1,188, 0x93,50,127, 0,222, 0x93,50,127, 0,222, 0x92,33,127, |
}, | }, | ||||
}; | }; | ||||
PROGMEM | |||||
const uint32_t sample_0_Pizzicato_PizzViolinE3[2944] = { | const uint32_t sample_0_Pizzicato_PizzViolinE3[2944] = { | ||||
0xffeeffbc,0x03230104,0x062004f3,0x0d4f07cb,0x1c351736,0x16ae18bd,0x1cad1a19,0x1ed81ede, | 0xffeeffbc,0x03230104,0x062004f3,0x0d4f07cb,0x1c351736,0x16ae18bd,0x1cad1a19,0x1ed81ede, | ||||
0x1a1b1b79,0x1ea61c1e,0x11081a2f,0x074a0a00,0x034305c7,0x012e02b7,0xf781fc58,0xf5d7f770, | 0x1a1b1b79,0x1ea61c1e,0x11081a2f,0x074a0a00,0x034305c7,0x012e02b7,0xf781fc58,0xf5d7f770, | ||||
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, | 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, | ||||
}; | }; | ||||
PROGMEM | |||||
const uint32_t sample_1_Pizzicato_PizzViolinC4[2304] = { | const uint32_t sample_1_Pizzicato_PizzViolinC4[2304] = { | ||||
0x02770000,0x0b55063e,0x109c0f35,0x0d690fda,0x088109dd,0xfea10525,0xea5bf55e,0xec27e61c, | 0x02770000,0x0b55063e,0x109c0f35,0x0d690fda,0x088109dd,0xfea10525,0xea5bf55e,0xec27e61c, | ||||
0xf843f547,0xebc1f337,0xeb4be81f,0xf9dcf398,0xf90ffa32,0xfe29faae,0x043a0215,0xf9d20247, | 0xf843f547,0xebc1f337,0xeb4be81f,0xf9dcf398,0xf90ffa32,0xfe29faae,0x043a0215,0xf9d20247, | ||||
}; | }; | ||||
PROGMEM | |||||
const uint32_t sample_2_Pizzicato_PizzViolinE5[768] = { | const uint32_t sample_2_Pizzicato_PizzViolinE5[768] = { | ||||
0x00330000,0x0c1e0957,0x100c0a13,0xefb7085e,0xef13e447,0x25e11a69,0x23032238,0xc02ed183, | 0x00330000,0x0c1e0957,0x100c0a13,0xefb7085e,0xef13e447,0x25e11a69,0x23032238,0xc02ed183, | ||||
0xe93ddc07,0x0e2f1cb4,0x0a35fcfa,0xe333f478,0xee61d669,0x14351329,0x34ef33f1,0xd8cee3ff, | 0xe93ddc07,0x0e2f1cb4,0x0a35fcfa,0xe333f478,0xee61d669,0x14351329,0x34ef33f1,0xd8cee3ff, | ||||
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, | 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, | ||||
}; | }; | ||||
PROGMEM | |||||
const uint32_t sample_3_Pizzicato_PizzViolinE5[768] = { | const uint32_t sample_3_Pizzicato_PizzViolinE5[768] = { | ||||
0x00330000,0x0c1e0957,0x100c0a13,0xefb7085e,0xef13e447,0x25e11a69,0x23032238,0xc02ed183, | 0x00330000,0x0c1e0957,0x100c0a13,0xefb7085e,0xef13e447,0x25e11a69,0x23032238,0xc02ed183, | ||||
0xe93ddc07,0x0e2f1cb4,0x0a35fcfa,0xe333f478,0xee61d669,0x14351329,0x34ef33f1,0xd8cee3ff, | 0xe93ddc07,0x0e2f1cb4,0x0a35fcfa,0xe333f478,0xee61d669,0x14351329,0x34ef33f1,0xd8cee3ff, |
}, | }, | ||||
}; | }; | ||||
PROGMEM | |||||
const uint32_t sample_0_Viola_ViolinBb2[768] = { | const uint32_t sample_0_Viola_ViolinBb2[768] = { | ||||
0x00c00062,0x01d00177,0x00d901a3,0xfd26ff1b,0xfbfffc14,0xfcc2fc94,0xfbf4fc33,0xfdbcfca6, | 0x00c00062,0x01d00177,0x00d901a3,0xfd26ff1b,0xfbfffc14,0xfcc2fc94,0xfbf4fc33,0xfdbcfca6, | ||||
0xfe03fe3f,0xfe96fddc,0x035100ee,0x035d0423,0x002c01be,0x00e00025,0x002f0108,0xff46ff54, | 0xfe03fe3f,0xfe96fddc,0x035100ee,0x035d0423,0x002c01be,0x00e00025,0x002f0108,0xff46ff54, | ||||
0x00000000,0x00000000, | 0x00000000,0x00000000, | ||||
}; | }; | ||||
PROGMEM | |||||
const uint32_t sample_1_Viola_ViolinD3[896] = { | const uint32_t sample_1_Viola_ViolinD3[896] = { | ||||
0xf22af42c,0xf477f50d,0x02bbf927,0x0e000a05,0x143e1088,0x15ac15b8,0x11f914ba,0x12870f75, | 0xf22af42c,0xf477f50d,0x02bbf927,0x0e000a05,0x143e1088,0x15ac15b8,0x11f914ba,0x12870f75, | ||||
0x17fa1743,0x0d0c1332,0x07180989,0xfdef036b,0xfc75f893,0x0a50048f,0x0761093c,0x0e180a9b, | 0x17fa1743,0x0d0c1332,0x07180989,0xfdef036b,0xfc75f893,0x0a50048f,0x0761093c,0x0e180a9b, | ||||
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, | 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, | ||||
}; | }; | ||||
PROGMEM | |||||
const uint32_t sample_2_Viola_ViolinG3[768] = { | const uint32_t sample_2_Viola_ViolinG3[768] = { | ||||
0xff4afeb7,0xfeb0fed3,0xff55ff4a,0xffbeff92,0xffd9fff0,0x000f0001,0xfff0000b,0x00750031, | 0xff4afeb7,0xfeb0fed3,0xff55ff4a,0xffbeff92,0xffd9fff0,0x000f0001,0xfff0000b,0x00750031, | ||||
0x00be00e0,0x017f009a,0x020e01c7,0x025d024c,0x031002b9,0x036e02ec,0x038e0306,0x03420271, | 0x00be00e0,0x017f009a,0x020e01c7,0x025d024c,0x031002b9,0x036e02ec,0x038e0306,0x03420271, | ||||
0xed98fa3f,0x0000dd29,0x00000000,0x00000000,0x00000000, | 0xed98fa3f,0x0000dd29,0x00000000,0x00000000,0x00000000, | ||||
}; | }; | ||||
PROGMEM | |||||
const uint32_t sample_3_Viola_ViolinC4[768] = { | const uint32_t sample_3_Viola_ViolinC4[768] = { | ||||
0x02720224,0x01790179,0x015b010f,0x023001a2,0x02dc0298,0x01d50280,0x00970141,0x011300f4, | 0x02720224,0x01790179,0x015b010f,0x023001a2,0x02dc0298,0x01d50280,0x00970141,0x011300f4, | ||||
0x00be00f3,0xffe3002b,0xffbdffdf,0x00560035,0x007900af,0xffd30046,0xff02fef0,0xfed0feb6, | 0x00be00f3,0xffe3002b,0xffbdffdf,0x00560035,0x007900af,0xffd30046,0xff02fef0,0xfed0feb6, | ||||
}; | }; | ||||
PROGMEM | |||||
const uint32_t sample_4_Viola_ViolinGb4[768] = { | const uint32_t sample_4_Viola_ViolinGb4[768] = { | ||||
0x0014001b,0x00150027,0x00390028,0x00450027,0x00120028,0x001b0022,0xffecfffe,0xffe6ffe0, | 0x0014001b,0x00150027,0x00390028,0x00450027,0x00120028,0x001b0022,0xffecfffe,0xffe6ffe0, | ||||
0xffeefffd,0x00370014,0x0093fff8,0xff980066,0x02d90135,0xf8f6052d,0xf60cf32b,0xfefdf844, | 0xffeefffd,0x00370014,0x0093fff8,0xff980066,0x02d90135,0xf8f6052d,0xf60cf32b,0xfefdf844, | ||||
0x00000000,0x00000000,0x00000000,0x00000000, | 0x00000000,0x00000000,0x00000000,0x00000000, | ||||
}; | }; | ||||
PROGMEM | |||||
const uint32_t sample_5_Viola_ViolinC5[640] = { | const uint32_t sample_5_Viola_ViolinC5[640] = { | ||||
0x01eafdb7,0xf3c6fadb,0xf8bef4e7,0x0c1aff72,0x15b51664,0x12ce16b5,0x0f101140,0x0b890d0a, | 0x01eafdb7,0xf3c6fadb,0xf8bef4e7,0x0c1aff72,0x15b51664,0x12ce16b5,0x0f101140,0x0b890d0a, | ||||
0x0aaa0be0,0x1905125c,0x2b9824a1,0x14a51f92,0xe92efcc9,0xe20ae403,0xde50e318,0xd902def2, | 0x0aaa0be0,0x1905125c,0x2b9824a1,0x14a51f92,0xe92efcc9,0xe20ae403,0xde50e318,0xd902def2, | ||||
0x1659239f,0x13282024,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, | 0x1659239f,0x13282024,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, | ||||
}; | }; | ||||
PROGMEM | |||||
const uint32_t sample_6_Viola_ViolinEb5[768] = { | const uint32_t sample_6_Viola_ViolinEb5[768] = { | ||||
0xff93feb8,0xfde4fb64,0xfe2dfc67,0x12fafe5e,0x120d13e5,0x00ca05cc,0x076307c9,0x0f5f06b9, | 0xff93feb8,0xfde4fb64,0xfe2dfc67,0x12fafe5e,0x120d13e5,0x00ca05cc,0x076307c9,0x0f5f06b9, | ||||
0x08080e4a,0x0f820d05,0x1c4813ad,0x0f4413f8,0xf9d10825,0xef44ec7d,0xeda5ec23,0xe7b9ed75, | 0x08080e4a,0x0f820d05,0x1c4813ad,0x0f4413f8,0xf9d10825,0xef44ec7d,0xeda5ec23,0xe7b9ed75, | ||||
0x00000000,0x00000000, | 0x00000000,0x00000000, | ||||
}; | }; | ||||
PROGMEM | |||||
const uint32_t sample_7_Viola_ViolinEb6[512] = { | const uint32_t sample_7_Viola_ViolinEb6[512] = { | ||||
0xfde7ff2e,0xffebfcf6,0x09180f77,0x066b0250,0x07fe09b7,0x12670b88,0xfd950d9b,0xf116f10d, | 0xfde7ff2e,0xffebfcf6,0x09180f77,0x066b0250,0x07fe09b7,0x12670b88,0xfd950d9b,0xf116f10d, | ||||
0xe96aef60,0xf60fe23f,0x129212e1,0xf943fe40,0xf013f48b,0xf7b2f480,0x000afda7,0x0d25014e, | 0xe96aef60,0xf60fe23f,0x129212e1,0xf943fe40,0xf013f48b,0xf7b2f480,0x000afda7,0x0d25014e, |
#include "WT_Trumpet_samples.h" | #include "WT_Trumpet_samples.h" | ||||
PROGMEM | |||||
static const uint32_t sample_0_WT_Trumpet_trum04[10112] = { | static const uint32_t sample_0_WT_Trumpet_trum04[10112] = { | ||||
0xff9cff8f,0xffceffa9,0xfff90000,0xffd7ffe9,0xffbcffb2,0xff72ffa4,0xffc4ff9e,0xffbcffb2, | 0xff9cff8f,0xffceffa9,0xfff90000,0xffd7ffe9,0xffbcffb2,0xff72ffa4,0xffc4ff9e,0xffbcffb2, | ||||
0xffdcffca,0x006a001e,0x012600c2,0x01620159,0x01430152,0x014e014d,0x0118013c,0x00b100e5, | 0xffdcffca,0x006a001e,0x012600c2,0x01620159,0x01430152,0x014e014d,0x0118013c,0x00b100e5, | ||||
0x07f2f8b2,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, | 0x07f2f8b2,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, | ||||
}; | }; | ||||
PROGMEM | |||||
static const uint32_t sample_1_WT_Trumpet_trum09[9728] = { | static const uint32_t sample_1_WT_Trumpet_trum09[9728] = { | ||||
0x0f1f0a8f,0x15811318,0x0d67137e,0xfeec05c4,0xf883fa6c,0xf8c9f836,0xfb84fa14,0xfe46fceb, | 0x0f1f0a8f,0x15811318,0x0d67137e,0xfeec05c4,0xf883fa6c,0xf8c9f836,0xfb84fa14,0xfe46fceb, | ||||
0xfeb1fee5,0xfe30fe62,0xfd05fdc9,0xfc17fc35,0xfbcafc52,0xf9c7fac5,0xf77af88a,0xf6e0f6d9, | 0xfeb1fee5,0xfe30fe62,0xfd05fdc9,0xfc17fc35,0xfbcafc52,0xf9c7fac5,0xf77af88a,0xf6e0f6d9, | ||||
static const uint8_t WT_Trumpet_ranges[] = {70, 127, }; | static const uint8_t WT_Trumpet_ranges[] = {70, 127, }; | ||||
const AudioSynthWavetable::instrument_data WT_Trumpet = {2, WT_Trumpet_ranges, WT_Trumpet_samples }; | const AudioSynthWavetable::instrument_data WT_Trumpet = {2, WT_Trumpet_ranges, WT_Trumpet_samples }; | ||||
#include "filter_biquad.h" | #include "filter_biquad.h" | ||||
#include "utility/dspinst.h" | #include "utility/dspinst.h" | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
void AudioFilterBiquad::update(void) | void AudioFilterBiquad::update(void) | ||||
{ | { |
// no audible difference. | // no audible difference. | ||||
//#define IMPROVE_EXPONENTIAL_ACCURACY | //#define IMPROVE_EXPONENTIAL_ACCURACY | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
void AudioFilterStateVariable::update_fixed(const int16_t *in, | void AudioFilterStateVariable::update_fixed(const int16_t *in, | ||||
int16_t *lp, int16_t *bp, int16_t *hp) | int16_t *lp, int16_t *bp, int16_t *hp) |
* THE SOFTWARE. | * THE SOFTWARE. | ||||
*/ | */ | ||||
#if !defined(__IMXRT1052__) && !defined(__IMXRT1062__) | |||||
#include <Arduino.h> | #include <Arduino.h> | ||||
#include "input_adc.h" | #include "input_adc.h" | ||||
#include "utility/pdb.h" | #include "utility/pdb.h" | ||||
transmit(out_left); | transmit(out_left); | ||||
release(out_left); | release(out_left); | ||||
} | } | ||||
#endif |
* THE SOFTWARE. | * THE SOFTWARE. | ||||
*/ | */ | ||||
#if !defined(__IMXRT1052__) && !defined(__IMXRT1062__) | |||||
#include <Arduino.h> | #include <Arduino.h> | ||||
#include "input_i2s.h" | #include "input_i2s.h" | ||||
#include "output_i2s.h" | #include "output_i2s.h" | ||||
I2S0_TCSR |= I2S_TCSR_TE | I2S_TCSR_BCE; // TX clock enable, because sync'd to TX | I2S0_TCSR |= I2S_TCSR_TE | I2S_TCSR_BCE; // TX clock enable, because sync'd to TX | ||||
dma.attachInterrupt(isr); | dma.attachInterrupt(isr); | ||||
} | } | ||||
#endif |
* THE SOFTWARE. | * THE SOFTWARE. | ||||
*/ | */ | ||||
#if !defined(__IMXRT1052__) && !defined(__IMXRT1062__) | |||||
#include <Arduino.h> | #include <Arduino.h> | ||||
#include "input_pdm.h" | #include "input_pdm.h" | ||||
#include "utility/dspinst.h" | #include "utility/dspinst.h" | ||||
print "\n};\n"; | print "\n};\n"; | ||||
print "// max=$max, min=$min\n"; | print "// max=$max, min=$min\n"; | ||||
*/ | */ | ||||
#endif |
/* Teensyduino Audio Memcpy | /* Teensyduino Audio Memcpy | ||||
* Copyright (c) 2016 Frank Bösing | |||||
* Copyright (c) 2016, 2017, 2018, 2019 Frank Bösing | |||||
* | * | ||||
* Permission is hereby granted, free of charge, to any person obtaining | * Permission is hereby granted, free of charge, to any person obtaining | ||||
* a copy of this software and associated documentation files (the | * a copy of this software and associated documentation files (the | ||||
* SOFTWARE. | * SOFTWARE. | ||||
*/ | */ | ||||
#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) | |||||
#if defined (__ARM_ARCH_7EM__) | |||||
#include <AudioStream.h> | #include <AudioStream.h> | ||||
.cpu cortex-m4 | .cpu cortex-m4 | ||||
.syntax unified | .syntax unified | ||||
.thumb | .thumb | ||||
.text | .text | ||||
.align 2 | |||||
/* void memcpy_tointerleave(short *dst, short *srcL, short *srcR); */ | /* void memcpy_tointerleave(short *dst, short *srcL, short *srcR); */ | ||||
.global memcpy_tointerleaveLR | .global memcpy_tointerleaveLR |
#include "mixer.h" | #include "mixer.h" | ||||
#include "utility/dspinst.h" | #include "utility/dspinst.h" | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
#define MULTI_UNITYGAIN 65536 | #define MULTI_UNITYGAIN 65536 | ||||
static void applyGain(int16_t *data, int32_t mult) | static void applyGain(int16_t *data, int32_t mult) |
class AudioMixer4 : public AudioStream | class AudioMixer4 : public AudioStream | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
public: | public: | ||||
AudioMixer4(void) : AudioStream(4, inputQueueArray) { | AudioMixer4(void) : AudioStream(4, inputQueueArray) { | ||||
for (int i=0; i<4; i++) multiplier[i] = 65536; | for (int i=0; i<4; i++) multiplier[i] = 65536; |
#endif | #endif | ||||
} | } | ||||
#elif defined(KINETISL) | |||||
void AudioOutputADAT::update(void) | |||||
{ | |||||
audio_block_t *block; | |||||
block = receiveReadOnly(0); // input 0 = ch1 channel | |||||
if (block) release(block); | |||||
block = receiveReadOnly(1); // input 1 = ch2 channel | |||||
if (block) release(block); | |||||
block = receiveReadOnly(2); // input 2 = ch3 channel | |||||
if (block) release(block); | |||||
block = receiveReadOnly(3); // input 3 = ch4 channel | |||||
if (block) release(block); | |||||
block = receiveReadOnly(4); // input 4 = ch5 channel | |||||
if (block) release(block); | |||||
block = receiveReadOnly(5); // input 5 = ch6 channel | |||||
if (block) release(block); | |||||
block = receiveReadOnly(6); // input 6 = ch7 channel | |||||
if (block) release(block); | |||||
block = receiveReadOnly(7); // input 7 = ch8 channel | |||||
if (block) release(block); | |||||
} | |||||
#endif | |||||
/* | /* | ||||
https://forum.pjrc.com/threads/38753-Discussion-about-a-simple-way-to-change-the-sample-rate | https://forum.pjrc.com/threads/38753-Discussion-about-a-simple-way-to-change-the-sample-rate | ||||
} | } | ||||
} | } | ||||
} | } | ||||
#elif defined(KINETISL) | |||||
void AudioOutputADAT::update(void) | |||||
{ | |||||
audio_block_t *block; | |||||
block = receiveReadOnly(0); // input 0 = ch1 channel | |||||
if (block) release(block); | |||||
block = receiveReadOnly(1); // input 1 = ch2 channel | |||||
if (block) release(block); | |||||
block = receiveReadOnly(2); // input 2 = ch3 channel | |||||
if (block) release(block); | |||||
block = receiveReadOnly(3); // input 3 = ch4 channel | |||||
if (block) release(block); | |||||
block = receiveReadOnly(4); // input 4 = ch5 channel | |||||
if (block) release(block); | |||||
block = receiveReadOnly(5); // input 5 = ch6 channel | |||||
if (block) release(block); | |||||
block = receiveReadOnly(6); // input 6 = ch7 channel | |||||
if (block) release(block); | |||||
block = receiveReadOnly(7); // input 7 = ch8 channel | |||||
if (block) release(block); | |||||
} | |||||
#endif | |||||
uint16_t AudioOutputI2S::block_left_offset = 0; | uint16_t AudioOutputI2S::block_left_offset = 0; | ||||
uint16_t AudioOutputI2S::block_right_offset = 0; | uint16_t AudioOutputI2S::block_right_offset = 0; | ||||
bool AudioOutputI2S::update_responsibility = false; | bool AudioOutputI2S::update_responsibility = false; | ||||
DMAMEM static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES]; | |||||
static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES]; | |||||
DMAChannel AudioOutputI2S::dma(false); | DMAChannel AudioOutputI2S::dma(false); | ||||
#if defined(__IMXRT1052__) || defined(__IMXRT1062__) | |||||
#define SAI1 | |||||
//#define SAI2 | |||||
//TODO: Copy these to imrtx.h: | |||||
#define CCM_ANALOG_PLL_AUDIO_LOCK ((uint32_t)(1<<31)) | |||||
#define I2S_TCR2_BCP ((uint32_t)1<<25) | |||||
#define I2S_RCR2_BCP ((uint32_t)1<<25) | |||||
#define I2S_TCR4_FCONT ((uint32_t)1<<28) // FIFO Continue on Error | |||||
#define I2S_RCR4_FCONT ((uint32_t)1<<28) // FIFO Continue on Error | |||||
#define I2S_TCR4_FSP ((uint32_t)1<< 1) | |||||
#define I2S_RCR4_FSP ((uint32_t)1<< 1) | |||||
typedef struct | |||||
{ | |||||
uint32_t CSR; | |||||
uint32_t CR1,CR2,CR3,CR4,CR5; | |||||
union { | |||||
uint32_t DR[8]; | |||||
uint16_t DR16[16]; | |||||
}; | |||||
uint32_t FR[8]; | |||||
uint32_t MR; | |||||
} I2S_PORT; | |||||
typedef struct | |||||
{ | |||||
uint32_t VERID; | |||||
uint32_t PARAM; | |||||
I2S_PORT TX; | |||||
uint32_t unused[9]; | |||||
I2S_PORT RX; | |||||
} I2S_STRUCT; | |||||
//TODO: This should probaly be in a common file | |||||
PROGMEM | |||||
void set_audioClock(int nfact, int32_t nmult, uint32_t ndiv) // sets PLL4 | |||||
{ | |||||
if (CCM_ANALOG_PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_ENABLE) return; | |||||
CCM_ANALOG_PLL_AUDIO = 0; | |||||
//CCM_ANALOG_PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_BYPASS; | |||||
CCM_ANALOG_PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE | |||||
| CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2) // 0: 1/4; 1: 1/2; 0: 1/1 | |||||
| CCM_ANALOG_PLL_AUDIO_DIV_SELECT(nfact); | |||||
CCM_ANALOG_PLL_AUDIO_NUM = nmult & CCM_ANALOG_PLL_AUDIO_NUM_MASK; | |||||
CCM_ANALOG_PLL_AUDIO_DENOM = ndiv & CCM_ANALOG_PLL_AUDIO_DENOM_MASK; | |||||
while (!(CCM_ANALOG_PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_LOCK)) {}; //Wait for pll-lock | |||||
const int div_post_pll = 1; // other values: 2,4 | |||||
CCM_ANALOG_MISC2 &= ~(CCM_ANALOG_MISC2_DIV_MSB | CCM_ANALOG_MISC2_DIV_LSB); | |||||
if(div_post_pll>1) CCM_ANALOG_MISC2 |= CCM_ANALOG_MISC2_DIV_LSB; | |||||
if(div_post_pll>3) CCM_ANALOG_MISC2 |= CCM_ANALOG_MISC2_DIV_MSB; | |||||
} | |||||
I2S_STRUCT *i2s; | |||||
void sai_rxConfig(int nbits, int nw, int sync) | |||||
{ | |||||
i2s->RX.MR = 0; | |||||
i2s->RX.CSR = 0; | |||||
i2s->RX.CR1 = I2S_RCR1_RFW(1); | |||||
i2s->RX.CR2 = I2S_RCR2_SYNC(sync) | I2S_RCR2_BCP // sync=0; rx is async; | |||||
| (I2S_RCR2_BCD | I2S_RCR2_DIV((1)) | I2S_RCR2_MSEL(1)); | |||||
i2s->RX.CR3 = I2S_RCR3_RCE; | |||||
i2s->RX.CR4 = I2S_RCR4_FRSZ((nw-1)) | I2S_RCR4_SYWD((nbits-1)) | I2S_RCR4_MF | I2S_RCR4_FSE | I2S_RCR4_FSP | I2S_RCR4_FSD; | |||||
i2s->RX.CR5 = I2S_RCR5_WNW((nbits-1)) | I2S_RCR5_W0W((nbits-1)) | I2S_RCR5_FBT((nbits-1)); | |||||
} | |||||
void sai_txConfig(int nbits, int nw, int sync) | |||||
{ | |||||
i2s->TX.MR = 0; | |||||
i2s->TX.CSR = 0; | |||||
i2s->TX.CR1 = I2S_TCR1_RFW(1); | |||||
i2s->TX.CR2 = I2S_TCR2_SYNC(sync) | I2S_TCR2_BCP // sync=0; tx is async; | |||||
| (I2S_TCR2_BCD | I2S_TCR2_DIV((1)) | I2S_TCR2_MSEL(1)); | |||||
i2s->TX.CR3 = I2S_TCR3_TCE; | |||||
i2s->TX.CR4 = I2S_TCR4_FRSZ((nw-1)) | I2S_TCR4_SYWD((nbits-1)) | I2S_TCR4_MF | I2S_TCR4_FSD | I2S_TCR4_FSE | I2S_TCR4_FSP; | |||||
i2s->TX.CR5 = I2S_TCR5_WNW((nbits-1)) | I2S_TCR5_W0W((nbits-1)) | I2S_TCR5_FBT((nbits-1)); | |||||
} | |||||
void AudioOutputI2S::begin(void) | |||||
{ | |||||
dma.begin(true); // Allocate the DMA channel first | |||||
block_left_1st = NULL; | |||||
block_right_1st = NULL; | |||||
//Pins: | |||||
#if defined(SAI1) | |||||
CORE_PIN23_CONFIG = 3; //1:MCLK | |||||
CORE_PIN21_CONFIG = 3; //1:RX_BCLK | |||||
CORE_PIN20_CONFIG = 3; //1:RX_SYNC | |||||
CORE_PIN7_CONFIG = 3; //1:RX_DATA0 | |||||
CORE_PIN6_CONFIG = 3; //1:TX_DATA0 | |||||
#elif defined(SAI2) | |||||
CORE_PIN5_CONFIG = 2; //2:MCLK | |||||
CORE_PIN4_CONFIG = 2; //2:TX_BCLK | |||||
CORE_PIN3_CONFIG = 2; //2:TX_SYNC | |||||
CORE_PIN2_CONFIG = 2; //2:TX_DATA0 | |||||
CORE_PIN33_CONFIG = 2; //2:RX_DATA0 | |||||
#endif | |||||
//PLL: | |||||
int fs = AUDIO_SAMPLE_RATE_EXACT; | |||||
// PLL between 27*24 = 648MHz und 54*24=1296MHz | |||||
int n1 = 4; //SAI prescaler 4 => (n1*n2) = multiple of 4 | |||||
int n2 = 1 + (24000000 * 27) / (fs * 256 * n1); | |||||
double C = ((double)fs * 256 * n1 * n2) / 24000000; | |||||
int c0 = C; | |||||
int c2 = 10000; | |||||
int c1 = C * c2 - (c0 * c2); | |||||
set_audioClock(c0, c1, c2); | |||||
//int nch = 1;// number of channels | |||||
int nw = 2; // words / channel | |||||
int nbits = 32;// bits / word | |||||
//SAI PG 2735 | |||||
#if defined(SAI1) | |||||
CCM_CCGR5 |= CCM_CCGR5_SAI1(CCM_CCGR_ON); | |||||
// clear SAI1_CLK register locations | |||||
CCM_CSCMR1 = (CCM_CSCMR1 & ~(CCM_CSCMR1_SAI1_CLK_SEL_MASK)) | |||||
| CCM_CSCMR1_SAI1_CLK_SEL(2); // &0x03 // (0,1,2): PLL3PFD0, PLL5, PLL4 | |||||
CCM_CS1CDR = (CCM_CS1CDR & ~(CCM_CS1CDR_SAI1_CLK_PRED_MASK | CCM_CS1CDR_SAI1_CLK_PODF_MASK)) | |||||
| CCM_CS1CDR_SAI1_CLK_PRED(n1-1) // &0x07 | |||||
| CCM_CS1CDR_SAI1_CLK_PODF(n2-1); // &0x3f | |||||
IOMUXC_GPR_GPR1 = (IOMUXC_GPR_GPR1 & ~(IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL_MASK)) | |||||
| (IOMUXC_GPR_GPR1_SAI1_MCLK_DIR | IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL(0)); //Select MCLK | |||||
i2s = ((I2S_STRUCT *)0x40384000); | |||||
sai_rxConfig(nbits, nw, 0); | |||||
sai_txConfig(nbits, nw, 1); | |||||
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_SAI1_TX); | |||||
#elif defined(SAI2) | |||||
CCM_CCGR5 |= CCM_CCGR5_SAI2(CCM_CCGR_ON); | |||||
CCM_CSCMR1 = (CCM_CSCMR1 & ~(CCM_CSCMR1_SAI2_CLK_SEL_MASK)) | |||||
| CCM_CSCMR1_SAI2_CLK_SEL(2); // &0x03 // (0,1,2): PLL3PFD0, PLL5, PLL4, | |||||
CCM_CS2CDR = (CCM_CS2CDR & ~(CCM_CS2CDR_SAI2_CLK_PRED_MASK | CCM_CS2CDR_SAI2_CLK_PODF_MASK)) | |||||
| CCM_CS2CDR_SAI2_CLK_PRED(n1-1) | CCM_CS2CDR_SAI2_CLK_PODF(n2-1); | |||||
IOMUXC_GPR_GPR1 = (IOMUXC_GPR_GPR1 & ~(IOMUXC_GPR_GPR1_SAI2_MCLK3_SEL_MASK)) | |||||
| (IOMUXC_GPR_GPR1_SAI2_MCLK_DIR | IOMUXC_GPR_GPR1_SAI2_MCLK3_SEL(0)); //Select MCLK | |||||
i2s = ((I2S_STRUCT *)0x40388000); | |||||
sai_rxConfig(nbits, nw, 1); | |||||
sai_txConfig(nbits, nw, 0); | |||||
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_SAI2_TX); | |||||
#endif | |||||
dma.TCD->SADDR = i2s_tx_buffer; | |||||
dma.TCD->SOFF = 2; | |||||
dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); | |||||
dma.TCD->NBYTES_MLNO = 2; | |||||
dma.TCD->SLAST = -sizeof(i2s_tx_buffer); | |||||
dma.TCD->DOFF = 0; | |||||
dma.TCD->CITER_ELINKNO = sizeof(i2s_tx_buffer) / 2; | |||||
dma.TCD->DLASTSGA = 0; | |||||
dma.TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2; | |||||
dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; | |||||
dma.TCD->DADDR = (void *)&i2s->TX.DR16[1]; | |||||
update_responsibility = update_setup(); | |||||
dma.attachInterrupt(isr); | |||||
i2s->RX.CSR |= I2S_RCSR_FRDE | I2S_RCSR_FR | I2S_RCSR_RE | I2S_RCSR_BCE; | |||||
i2s->TX.CSR |= I2S_TCSR_FRDE | I2S_TCSR_FR | I2S_TCSR_TE | I2S_TCSR_BCE; | |||||
dma.enable(); | |||||
} | |||||
#endif | |||||
#if defined(KINETISK) | |||||
void AudioOutputI2S::begin(void) | void AudioOutputI2S::begin(void) | ||||
{ | { | ||||
dma.begin(true); // Allocate the DMA channel first | dma.begin(true); // Allocate the DMA channel first | ||||
config_i2s(); | config_i2s(); | ||||
CORE_PIN22_CONFIG = PORT_PCR_MUX(6); // pin 22, PTC1, I2S0_TXD0 | CORE_PIN22_CONFIG = PORT_PCR_MUX(6); // pin 22, PTC1, I2S0_TXD0 | ||||
#if defined(KINETISK) | |||||
dma.TCD->SADDR = i2s_tx_buffer; | dma.TCD->SADDR = i2s_tx_buffer; | ||||
dma.TCD->SOFF = 2; | dma.TCD->SOFF = 2; | ||||
dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); | dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); | ||||
dma.TCD->DLASTSGA = 0; | dma.TCD->DLASTSGA = 0; | ||||
dma.TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2; | dma.TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2; | ||||
dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; | dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; | ||||
#endif | |||||
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_TX); | dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_TX); | ||||
update_responsibility = update_setup(); | update_responsibility = update_setup(); | ||||
dma.enable(); | dma.enable(); | ||||
I2S0_TCSR = I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE; | I2S0_TCSR = I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE; | ||||
dma.attachInterrupt(isr); | dma.attachInterrupt(isr); | ||||
} | } | ||||
#endif | |||||
void AudioOutputI2S::isr(void) | void AudioOutputI2S::isr(void) | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined(KINETISK) || defined(__IMXRT1052__) || defined(__IMXRT1062__) | |||||
int16_t *dest; | int16_t *dest; | ||||
audio_block_t *blockL, *blockR; | audio_block_t *blockL, *blockR; | ||||
uint32_t saddr, offsetL, offsetR; | uint32_t saddr, offsetL, offsetR; | ||||
} | } | ||||
} | } | ||||
#if defined(KINETISK) || defined(KINETISL) | |||||
// MCLK needs to be 48e6 / 1088 * 256 = 11.29411765 MHz -> 44.117647 kHz sample rate | // MCLK needs to be 48e6 / 1088 * 256 = 11.29411765 MHz -> 44.117647 kHz sample rate | ||||
// | // | ||||
#if F_CPU == 96000000 || F_CPU == 48000000 || F_CPU == 24000000 | #if F_CPU == 96000000 || F_CPU == 48000000 || F_CPU == 24000000 | ||||
CORE_PIN9_CONFIG = PORT_PCR_MUX(6); // pin 9, PTC3, I2S0_TX_BCLK | CORE_PIN9_CONFIG = PORT_PCR_MUX(6); // pin 9, PTC3, I2S0_TX_BCLK | ||||
CORE_PIN11_CONFIG = PORT_PCR_MUX(6); // pin 11, PTC6, I2S0_MCLK | CORE_PIN11_CONFIG = PORT_PCR_MUX(6); // pin 11, PTC6, I2S0_MCLK | ||||
} | } | ||||
#endif |
//Adapted to PT8211, Frank Bösing, Ben-Rheinland | //Adapted to PT8211, Frank Bösing, Ben-Rheinland | ||||
#if !defined(__IMXRT1052__) && !defined(__IMXRT1062__) | |||||
#include <Arduino.h> | #include <Arduino.h> | ||||
#include "output_pt8211.h" | #include "output_pt8211.h" | ||||
#include "memcpy_audio.h" | #include "memcpy_audio.h" | ||||
CORE_PIN11_CONFIG = PORT_PCR_MUX(6); // pin 11, PTC6, I2S0_MCLK | CORE_PIN11_CONFIG = PORT_PCR_MUX(6); // pin 11, PTC6, I2S0_MCLK | ||||
#endif | #endif | ||||
} | } | ||||
#endif |
// compute (a - b) / c | // compute (a - b) / c | ||||
// handling 32 bit interger overflow at every step | // handling 32 bit interger overflow at every step | ||||
// without resorting to slow 64 bit math | // without resorting to slow 64 bit math | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
static inline int32_t substract_int32_then_divide_int32(int32_t a, int32_t b, int32_t c) __attribute__((always_inline, unused)); | static inline int32_t substract_int32_then_divide_int32(int32_t a, int32_t b, int32_t c) __attribute__((always_inline, unused)); | ||||
static inline int32_t substract_int32_then_divide_int32(int32_t a, int32_t b, int32_t c) | static inline int32_t substract_int32_then_divide_int32(int32_t a, int32_t b, int32_t c) | ||||
{ | { |
#include "utility/dspinst.h" | #include "utility/dspinst.h" | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
void AudioSynthWaveformPWM::update(void) | void AudioSynthWaveformPWM::update(void) | ||||
{ | { |
scale = (ph >> 8) & 0xFFFF; | scale = (ph >> 8) & 0xFFFF; | ||||
val2 *= scale; | val2 *= scale; | ||||
val1 *= 0x10000 - scale; | val1 *= 0x10000 - scale; | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
block->data[i] = multiply_32x32_rshift32(val1 + val2, magnitude); | block->data[i] = multiply_32x32_rshift32(val1 + val2, magnitude); | ||||
#elif defined(KINETISL) | #elif defined(KINETISL) | ||||
block->data[i] = (((val1 + val2) >> 16) * magnitude) >> 16; | block->data[i] = (((val1 + val2) >> 16) * magnitude) >> 16; | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
// High accuracy 11th order Taylor Series Approximation | // High accuracy 11th order Taylor Series Approximation | ||||
// input is 0 to 0xFFFFFFFF, representing 0 to 360 degree phase | // input is 0 to 0xFFFFFFFF, representing 0 to 360 degree phase | ||||
// output is 32 bit signed integer, top 25 bits should be very good | // output is 32 bit signed integer, top 25 bits should be very good | ||||
void AudioSynthWaveformSineHires::update(void) | void AudioSynthWaveformSineHires::update(void) | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
audio_block_t *msw, *lsw; | audio_block_t *msw, *lsw; | ||||
uint32_t i, ph, inc; | uint32_t i, ph, inc; | ||||
int32_t val; | int32_t val; | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
void AudioSynthWaveformSineModulated::update(void) | void AudioSynthWaveformSineModulated::update(void) | ||||
{ | { |
end = p + AUDIO_BLOCK_SAMPLES/2; | end = p + AUDIO_BLOCK_SAMPLES/2; | ||||
lo = seed; | lo = seed; | ||||
do { | do { | ||||
#if defined(KINETISK) | |||||
#if defined(__ARM_ARCH_7EM__) | |||||
hi = multiply_16bx16t(16807, lo); // 16807 * (lo >> 16) | hi = multiply_16bx16t(16807, lo); // 16807 * (lo >> 16) | ||||
lo = 16807 * (lo & 0xFFFF); | lo = 16807 * (lo & 0xFFFF); | ||||
lo += (hi & 0x7FFF) << 16; | lo += (hi & 0x7FFF) << 16; |
static inline int32_t signed_saturate_rshift(int32_t val, int bits, int rshift) __attribute__((always_inline, unused)); | static inline int32_t signed_saturate_rshift(int32_t val, int bits, int rshift) __attribute__((always_inline, unused)); | ||||
static inline int32_t signed_saturate_rshift(int32_t val, int bits, int rshift) | static inline int32_t signed_saturate_rshift(int32_t val, int bits, int rshift) | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined (__ARM_ARCH_7EM__) | |||||
int32_t out; | int32_t out; | ||||
asm volatile("ssat %0, %1, %2, asr %3" : "=r" (out) : "I" (bits), "r" (val), "I" (rshift)); | asm volatile("ssat %0, %1, %2, asr %3" : "=r" (out) : "I" (bits), "r" (val), "I" (rshift)); | ||||
return out; | return out; | ||||
static inline int16_t saturate16(int32_t val) __attribute__((always_inline, unused)); | static inline int16_t saturate16(int32_t val) __attribute__((always_inline, unused)); | ||||
static inline int16_t saturate16(int32_t val) | static inline int16_t saturate16(int32_t val) | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined (__ARM_ARCH_7EM__) | |||||
int16_t out; | int16_t out; | ||||
int32_t tmp; | int32_t tmp; | ||||
asm volatile("ssat %0, %1, %2" : "=r" (tmp) : "I" (16), "r" (val) ); | asm volatile("ssat %0, %1, %2" : "=r" (tmp) : "I" (16), "r" (val) ); | ||||
static inline int32_t signed_multiply_32x16b(int32_t a, uint32_t b) __attribute__((always_inline, unused)); | static inline int32_t signed_multiply_32x16b(int32_t a, uint32_t b) __attribute__((always_inline, unused)); | ||||
static inline int32_t signed_multiply_32x16b(int32_t a, uint32_t b) | static inline int32_t signed_multiply_32x16b(int32_t a, uint32_t b) | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined (__ARM_ARCH_7EM__) | |||||
int32_t out; | int32_t out; | ||||
asm volatile("smulwb %0, %1, %2" : "=r" (out) : "r" (a), "r" (b)); | asm volatile("smulwb %0, %1, %2" : "=r" (out) : "r" (a), "r" (b)); | ||||
return out; | return out; | ||||
static inline int32_t signed_multiply_32x16t(int32_t a, uint32_t b) __attribute__((always_inline, unused)); | static inline int32_t signed_multiply_32x16t(int32_t a, uint32_t b) __attribute__((always_inline, unused)); | ||||
static inline int32_t signed_multiply_32x16t(int32_t a, uint32_t b) | static inline int32_t signed_multiply_32x16t(int32_t a, uint32_t b) | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined (__ARM_ARCH_7EM__) | |||||
int32_t out; | int32_t out; | ||||
asm volatile("smulwt %0, %1, %2" : "=r" (out) : "r" (a), "r" (b)); | asm volatile("smulwt %0, %1, %2" : "=r" (out) : "r" (a), "r" (b)); | ||||
return out; | return out; | ||||
static inline int32_t multiply_32x32_rshift32(int32_t a, int32_t b) __attribute__((always_inline, unused)); | static inline int32_t multiply_32x32_rshift32(int32_t a, int32_t b) __attribute__((always_inline, unused)); | ||||
static inline int32_t multiply_32x32_rshift32(int32_t a, int32_t b) | static inline int32_t multiply_32x32_rshift32(int32_t a, int32_t b) | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined (__ARM_ARCH_7EM__) | |||||
int32_t out; | int32_t out; | ||||
asm volatile("smmul %0, %1, %2" : "=r" (out) : "r" (a), "r" (b)); | asm volatile("smmul %0, %1, %2" : "=r" (out) : "r" (a), "r" (b)); | ||||
return out; | return out; | ||||
static inline int32_t multiply_32x32_rshift32_rounded(int32_t a, int32_t b) __attribute__((always_inline, unused)); | static inline int32_t multiply_32x32_rshift32_rounded(int32_t a, int32_t b) __attribute__((always_inline, unused)); | ||||
static inline int32_t multiply_32x32_rshift32_rounded(int32_t a, int32_t b) | static inline int32_t multiply_32x32_rshift32_rounded(int32_t a, int32_t b) | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined (__ARM_ARCH_7EM__) | |||||
int32_t out; | int32_t out; | ||||
asm volatile("smmulr %0, %1, %2" : "=r" (out) : "r" (a), "r" (b)); | asm volatile("smmulr %0, %1, %2" : "=r" (out) : "r" (a), "r" (b)); | ||||
return out; | return out; | ||||
static inline int32_t multiply_accumulate_32x32_rshift32_rounded(int32_t sum, int32_t a, int32_t b) __attribute__((always_inline, unused)); | static inline int32_t multiply_accumulate_32x32_rshift32_rounded(int32_t sum, int32_t a, int32_t b) __attribute__((always_inline, unused)); | ||||
static inline int32_t multiply_accumulate_32x32_rshift32_rounded(int32_t sum, int32_t a, int32_t b) | static inline int32_t multiply_accumulate_32x32_rshift32_rounded(int32_t sum, int32_t a, int32_t b) | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined (__ARM_ARCH_7EM__) | |||||
int32_t out; | int32_t out; | ||||
asm volatile("smmlar %0, %2, %3, %1" : "=r" (out) : "r" (sum), "r" (a), "r" (b)); | asm volatile("smmlar %0, %2, %3, %1" : "=r" (out) : "r" (sum), "r" (a), "r" (b)); | ||||
return out; | return out; | ||||
static inline int32_t multiply_subtract_32x32_rshift32_rounded(int32_t sum, int32_t a, int32_t b) __attribute__((always_inline, unused)); | static inline int32_t multiply_subtract_32x32_rshift32_rounded(int32_t sum, int32_t a, int32_t b) __attribute__((always_inline, unused)); | ||||
static inline int32_t multiply_subtract_32x32_rshift32_rounded(int32_t sum, int32_t a, int32_t b) | static inline int32_t multiply_subtract_32x32_rshift32_rounded(int32_t sum, int32_t a, int32_t b) | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined (__ARM_ARCH_7EM__) | |||||
int32_t out; | int32_t out; | ||||
asm volatile("smmlsr %0, %2, %3, %1" : "=r" (out) : "r" (sum), "r" (a), "r" (b)); | asm volatile("smmlsr %0, %2, %3, %1" : "=r" (out) : "r" (sum), "r" (a), "r" (b)); | ||||
return out; | return out; | ||||
static inline uint32_t pack_16t_16t(int32_t a, int32_t b) __attribute__((always_inline, unused)); | static inline uint32_t pack_16t_16t(int32_t a, int32_t b) __attribute__((always_inline, unused)); | ||||
static inline uint32_t pack_16t_16t(int32_t a, int32_t b) | static inline uint32_t pack_16t_16t(int32_t a, int32_t b) | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined (__ARM_ARCH_7EM__) | |||||
int32_t out; | int32_t out; | ||||
asm volatile("pkhtb %0, %1, %2, asr #16" : "=r" (out) : "r" (a), "r" (b)); | asm volatile("pkhtb %0, %1, %2, asr #16" : "=r" (out) : "r" (a), "r" (b)); | ||||
return out; | return out; | ||||
static inline uint32_t pack_16t_16b(int32_t a, int32_t b) __attribute__((always_inline, unused)); | static inline uint32_t pack_16t_16b(int32_t a, int32_t b) __attribute__((always_inline, unused)); | ||||
static inline uint32_t pack_16t_16b(int32_t a, int32_t b) | static inline uint32_t pack_16t_16b(int32_t a, int32_t b) | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined (__ARM_ARCH_7EM__) | |||||
int32_t out; | int32_t out; | ||||
asm volatile("pkhtb %0, %1, %2" : "=r" (out) : "r" (a), "r" (b)); | asm volatile("pkhtb %0, %1, %2" : "=r" (out) : "r" (a), "r" (b)); | ||||
return out; | return out; | ||||
static inline uint32_t pack_16b_16b(int32_t a, int32_t b) __attribute__((always_inline, unused)); | static inline uint32_t pack_16b_16b(int32_t a, int32_t b) __attribute__((always_inline, unused)); | ||||
static inline uint32_t pack_16b_16b(int32_t a, int32_t b) | static inline uint32_t pack_16b_16b(int32_t a, int32_t b) | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
#if defined (__ARM_ARCH_7EM__) | |||||
int32_t out; | int32_t out; | ||||
asm volatile("pkhbt %0, %1, %2, lsl #16" : "=r" (out) : "r" (b), "r" (a)); | asm volatile("pkhbt %0, %1, %2, lsl #16" : "=r" (out) : "r" (b), "r" (a)); | ||||
return out; | return out; |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
* THE SOFTWARE. | * THE SOFTWARE. | ||||
*/ | */ | ||||
#if !defined(__IMXRT1052__) && !defined(__IMXRT1062__) | |||||
#ifndef pdb_h_ | #ifndef pdb_h_ | ||||
#define pdb_h_ | #define pdb_h_ | ||||
#endif | #endif | ||||
#endif | #endif | ||||
#endif |