Refactored recording storage from two arrays for pitch period and note length to struct with pitch index and length using bit fields so that MAXNOTES can be increased to 0xA2.

This commit is contained in:
Jonathan Chan 2018-03-23 23:55:58 -07:00
parent ea2d661bb6
commit 6e85ff2d17
1 changed files with 48 additions and 46 deletions

View File

@ -2,54 +2,57 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#define c 3822 #define MIDC 3822
#define dflat 3608 #define DFLAT 3608
#define d 3405 #define D 3405
#define eflat 3214 #define EFLAT 3214
#define e 3034 #define E 3034
#define f 2863 #define F 2863
#define gflat 2703 #define GFLAT 2703
#define g 2551 #define G 2551
#define aflat 2408 #define AFLAT 2408
#define a 2273 #define A 2273
#define bflat 2145 #define BFLAT 2145
#define b 2025 #define B 2025
#define cc 1911 #define TENC 1911
#define n 0 #define NONE 0
#define LED1 BIT0 #define LED1 BIT0
#define BUTTON BIT3 #define BUTTON BIT3
#define OUTPUT BIT6 #define OUTPUT BIT6
// constants used for unit conversions in timer interrupt
// CSINT should be 256^2 / 10 000 = 65 536 / 10 000 = 6 // CSINT should be 256^2 / 10 000 = 65 536 / 10 000 = 6
// USINT should be 60 000 // USINT should be 60 000
#define CSUS 10000 // microseconds (us) in a centisecond (cs) #define CSUS 10000 // microseconds (us) in a centisecond (cs)
#define CSINT 6 // centiseconds storable in int of microseconds #define CSINT 6 // centiseconds storable in int of microseconds
#define USINT 60000 // CSINT in microseconds #define USINT 60000 // CSINT in microseconds
#define MAXNOTES 0x4D // not enough RAM to allocate any more to rec, len :( #define MAXNOTES 0xA2 // 162 (not enough RAM to allocate any more to rec)
// max length of note is 0xFFFF centiseconds = approx. 10 minutes // pitch is index of scale array
unsigned int rec[MAXNOTES]; // notes recorded // max length of note is 0xFFF = approx. 41 seconds
unsigned int len[MAXNOTES]; // length of each note in centiseconds typedef struct {
unsigned int pitch : 4;
unsigned int length : 12;
} Note;
unsigned int scale[16] = {
NONE, MIDC, DFLAT, D, EFLAT, E, F,
GFLAT, G, AFLAT, A, BFLAT, B, TENC,
NONE, NONE // should not be used
};
Note rec[MAXNOTES];
volatile bool recording = true; volatile bool recording = true;
volatile unsigned int notes = 1; volatile unsigned int notes = 1;
volatile unsigned int us = 0; volatile unsigned int us = 0;
volatile unsigned int cs = 0; volatile unsigned int cs = 0;
unsigned int scale[16] = { void play(unsigned int pitch) {
n, c, dflat, d, eflat, e, f, gflat, g, aflat, a, bflat, b, cc, n, n if (pitch != 0) {
}; CCR0 = scale[pitch];
CCR1 = scale[pitch] / 2; // max volume
unsigned int whole[8] = {
c, d, e, f, g, a, b, cc
};
void play(unsigned int note) {
if (note != n) {
CCR0 = note;
CCR1 = 250;
} else { } else {
CCR0 = 0xFFFF; // cannot count to 0; set to max CCR0 = 0xFFFF; // cannot count to 0; set to max
CCR1 = 0; CCR1 = 0;
@ -58,34 +61,34 @@ void play(unsigned int note) {
void playback() { void playback() {
for (unsigned int i = 0; i < notes; i++) { for (unsigned int i = 0; i < notes; i++) {
play(rec[i]); play(rec[i].pitch);
for (unsigned int j = 0; j < len[i]; j++) { for (unsigned int j = 0; j < rec[i].length; j++) {
__delay_cycles(CSUS); __delay_cycles(CSUS);
} }
} }
} }
void save_length(unsigned int position) { void save_length(unsigned int position) {
len[position] = cs + (us + TAR)/CSUS; rec[position].length = cs + (us + TAR)/CSUS;
cs = us = TAR = 0; // reset all counts cs = us = TAR = 0; // reset all counts
} }
void end_record() { void end_record() {
P1OUT &= ~LED1; recording = false;
TACCTL0 &= ~CCIE; P1OUT &= ~LED1;
play(n); TACCTL0 &= ~CCIE;
play(0);
} }
void record() { void record() {
unsigned int note;
TAR = 0; TAR = 0;
P1OUT |= LED1; P1OUT |= LED1;
while (recording && notes < MAXNOTES) { while (recording && notes < MAXNOTES) {
note = scale[P2IN & 0xF]; unsigned int pitch = P2IN & 0xF;
if (note != rec[notes - 1]) { if (pitch != rec[notes - 1].pitch) {
save_length(notes - 1); save_length(notes - 1);
rec[notes] = note; rec[notes].pitch = pitch;
play(note); play(pitch);
notes++; notes++;
} }
__delay_cycles(1000); __delay_cycles(1000);
@ -139,9 +142,8 @@ __interrupt void port1_isr(void)
{ {
if (recording) { if (recording) {
save_length(notes); save_length(notes);
recording = false;
end_record(); end_record();
} }
playback(); playback();
P1IFG &= ~BUTTON; // set interrupt flag to 0 P1IFG &= ~BUTTON; // set interrupt flag to 0
} }