better music support

This commit is contained in:
Peli de Halleux 2016-03-14 08:32:02 -07:00
parent 53c3b22c1c
commit 4cd222ec82
4 changed files with 36 additions and 8 deletions

View File

@ -158,12 +158,17 @@ namespace music {
return name; return name;
} }
function init() {
if (beatsPerMinute <= 0) beatsPerMinute = 120;
}
/** /**
* Returns the duration of a beat in milli-seconds * Returns the duration of a beat in milli-seconds
*/ */
//% help=/functions/beat weight=49 //% help=/functions/beat weight=49
//% blockId=device_beat block="%fraction|beat" //% blockId=device_beat block="%fraction|beat"
export function beat(fraction : BeatFraction = BeatFraction.Whole): number { export function beat(fraction : BeatFraction = BeatFraction.Whole): number {
init();
let beat = 60000 / beatsPerMinute; let beat = 60000 / beatsPerMinute;
if (fraction == BeatFraction.Whole) return beat; if (fraction == BeatFraction.Whole) return beat;
else if (fraction == BeatFraction.Half) return beat / 2; else if (fraction == BeatFraction.Half) return beat / 2;
@ -178,6 +183,7 @@ namespace music {
//% help=/functions/tempo weight=40 //% help=/functions/tempo weight=40
//% blockId=device_tempo block="tempo (bpm)" blockGap=8 //% blockId=device_tempo block="tempo (bpm)" blockGap=8
export function tempo(): number { export function tempo(): number {
init();
return beatsPerMinute; return beatsPerMinute;
} }
@ -188,7 +194,7 @@ namespace music {
//% help=/functions/tempo weight=39 //% help=/functions/tempo weight=39
//% blockId=device_change_tempo block="change tempo by (bpm)|%value" blockGap=8 //% blockId=device_change_tempo block="change tempo by (bpm)|%value" blockGap=8
export function changeTempoBy(bpm: number): void { export function changeTempoBy(bpm: number): void {
setTempo(beatsPerMinute + bpm); setTempo(beat(BeatFraction.Whole) + bpm);
} }
/** /**
@ -198,6 +204,7 @@ namespace music {
//% help=/functions/tempo weight=38 //% help=/functions/tempo weight=38
//% blockId=device_set_tempo block="set tempo to (bpm)|%value" //% blockId=device_set_tempo block="set tempo to (bpm)|%value"
export function setTempo(bpm: number): void { export function setTempo(bpm: number): void {
init();
if (bpm > 0) { if (bpm > 0) {
beatsPerMinute = Math.max(1, bpm); beatsPerMinute = Math.max(1, bpm);
} }

View File

@ -322,6 +322,8 @@ namespace ks.rt.micro_bit {
export function setAnalogPeriodUs(pin: Pin, micros:number) { export function setAnalogPeriodUs(pin: Pin, micros:number) {
pin.mode = PinMode.Analog | PinMode.Output; pin.mode = PinMode.Analog | PinMode.Output;
pin.period = micros;
board().updateView();
} }
export function servoWritePin(pin: Pin, value: number) { export function servoWritePin(pin: Pin, value: number) {
@ -385,16 +387,33 @@ namespace ks.rt.micro_bit {
} }
export function enablePitch(pin: Pin) { export function enablePitch(pin: Pin) {
pin.mode = PinMode.Analog | PinMode.Output; pin.mode = PinMode.Analog | PinMode.Output | PinMode.Pitch;
} }
export function pitch(frequency: number, ms: number) { export function pitch(frequency: number, ms: number) {
// update analog output
let pin = board().pins.filter(pin => !!pin && (pin.mode & PinMode.Pitch) != 0)[0] || board().pins[0];
if (frequency <= 0) {
pin.value = 0;
pin.period = 0;
} else {
pin.value = 512;
pin.period = 1000000/frequency;
}
board().updateView();
let cb = getResume(); let cb = getResume();
AudioContextManager.tone(frequency, 1); AudioContextManager.tone(frequency, 1);
setTimeout(() => { if (ms <= 0) cb();
if (ms > 0) AudioContextManager.stop(); else {
cb() setTimeout(() => {
}, ms); AudioContextManager.stop();
pin.value = 0;
pin.period = 0;
board().updateView();
cb()
}, ms);
}
} }

View File

@ -219,7 +219,7 @@ namespace ks.rt.micro_bit {
let v = ''; let v = '';
if (pin.mode & PinMode.Analog) { if (pin.mode & PinMode.Analog) {
v = Math.floor(100 - (pin.value || 0) / 1023 * 100) + '%'; v = Math.floor(100 - (pin.value || 0) / 1023 * 100) + '%';
if(text) text.textContent = (pin.value || 0) + ""; if(text) text.textContent = (pin.period ? "~" : "") + (pin.value || 0) + "";
} }
else if (pin.mode & PinMode.Digital) { else if (pin.mode & PinMode.Digital) {
v = pin.value > 0 ? '0%' : '100%'; v = pin.value > 0 ? '0%' : '100%';

View File

@ -14,13 +14,15 @@ namespace ks.rt.micro_bit {
Analog = 0x0002, Analog = 0x0002,
Input = 0x0004, Input = 0x0004,
Output = 0x0008, Output = 0x0008,
Touch = 0x0010 Touch = 0x0010,
Pitch = 0x0020
} }
export class Pin { export class Pin {
constructor(public id: number) { } constructor(public id: number) { }
touched = false; touched = false;
value = 0; value = 0;
period = 0;
mode = PinMode.Unused; mode = PinMode.Unused;
isTouched(): boolean { isTouched(): boolean {