Skip to content

Commit

Permalink
Moved all "humanoid" built-in FlexFX sounds and test-codes to a new M…
Browse files Browse the repository at this point in the history
…oody extension
  • Loading branch information
GrandpaBond committed Jul 27, 2023
1 parent bf6a4d9 commit f747e16
Show file tree
Hide file tree
Showing 3 changed files with 1 addition and 450 deletions.
21 changes: 0 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,6 @@ The ``|music:Music|`` category has a ``||music:micro:bit(V2)||`` section with bl
These let you build some amazing sounds, but sometimes you need something more complex.
``|flexFX:FlexFX|`` sounds are *re-usable* objects that can stitch together up to three sound-expressions.
They use **play-settings**, which means you can play them at different pitch, volume, or duration.
## Built-in Sounds
### Simple Sounds
These are FlexFX sounds that can be played very simply using the **emit** block:
```block
flexFX.emit(2)
```
Expanding this block, you can specify the play-settings to be used (with duration in ms):
```block
flexFX.emit(5,400,100,5000);
```
### Behaviours
Currently the built-in sounds are mostly expressive humanoid sounds, so there is a set of **behaviour** blocks
that perform several repetitions of a FlexFX sound, with their play-settings slightly randomised to give
a more natural effect. The results will change with every performance.
```block
flexFX.giggle();
```
These blocks can also be expanded to control the number of repeats, the volume, and the overall duration (in ms).
```block
flexFX.whistle(30,200,12000);
```

## Anatomy of a FlexFX
The basic idea is that a FlexFX is built from one, two or three **parts**.
Expand Down
356 changes: 1 addition & 355 deletions flexFX.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,29 +74,6 @@ enum Effect {
//% block="Warble"
WARBLE = SoundExpressionEffect.Warble
}
// provide enum for UI drop-down to select built-in flexFX samples
enum MoodSound {
//% block="Tweet"
TWEET = 1,
//% block="Laugh"
LAUGH = 2,
//% block="Snore"
SNORE = 3,
//% block="Doo"
DOO = 4,
//% block="Eh?"
QUERY = 5,
//% block="Uh-oh"
UHOH = 6,
//% block="Moan"
MOAN = 7,
//% block="Duh!"
DUH = 8,
//% block="Waah"
WAAH = 9,
//% block="Growl"
GROWL = 10
}
/**
* Tools for creating composite sound-effects (of class FlexFX) that can be performed with
* dynamically-specified pitch, volume and duration. Provides a built-in set of samples.
Expand Down Expand Up @@ -463,335 +440,4 @@ namespace flexFX {
1.0 - (timePercentA - timeGapPercent) / 100);

}
// ---Create Built-in FlexFXs----

/*
Short-hand definitions are laid out as follows:
<name> <%Freq,%vol> at start of PartA
<PartA wave-style> <%Freq,%vol> at end of PartA & start of PartB (if used)
<PartB wave-style> <%Freq,%vol> at end of PartB & start of PartC (if used)
<PartC wave-style> <%Freq,%vol> at end of PartC (if used)
The right-hand column shows the timing breakdown
*/

/*
TWEET 80% 45%
SIN LOG NONE 100% 100% | 100%
*/
createFlexFX(MoodSound.TWEET.toString(), 80, 45,
Wave.SINE, Attack.FAST, Effect.NONE, 100, 100);

/*
LAUGH 70% 40%
SAW LOG NONE 100% 100% | 10%
SQU LIN NONE 70% 75% | 90%
*/
create2PartFlexFX(MoodSound.LAUGH.toString(), 70, 40,
Wave.SAWTOOTH, Attack.FAST, Effect.NONE, 100, 100,
Wave.SQUARE, Attack.SLOW, Effect.NONE, 70, 75, 90);

/*
SNORE 3508 10%
NOI VIB LIN 715 100% | 50%
NOI VIB LIN 5008 0% | 50%
NOTE: The noise-generator is highly sensitive to the chosen frequency-trajectory, and these strange values have been experimentally derived.
By always invoking Snore.performUsing() with (freq=1), these literal frequencies will get used as specified here!
*/
create2PartFlexFX(MoodSound.SNORE.toString(), 3508, 10,
Wave.NOISE, Attack.SLOW, Effect.VIBRATO, 715, 100,
Wave.NOISE, Attack.SLOW, Effect.VIBRATO, 5008, 0, 50);

/*
DOO 300% 80%
SAW LOG NONE 100% 90% | 5%
SQU LIN NONE 100% 70% | 95%
*/
create2PartFlexFX(MoodSound.DOO.toString(), 300, 80,
Wave.SAWTOOTH, Attack.FAST, Effect.NONE, 100, 90,
Wave.SQUARE, Attack.SLOW, Effect.NONE, 100, 70, 5);

/*
QUERY 110% 20%
SQU LIN NONE 100% 100% | 20%
SQU CUR NONE 150% 30% | 80%
*/
create2PartFlexFX(MoodSound.QUERY.toString(), 110, 20,
Wave.SQUARE, Attack.SLOW, Effect.NONE, 100, 100,
Wave.SQUARE, Attack.MEDIUM, Effect.NONE, 150, 30, 20);

/*
UHOH 110% 40%
SAW LOG NONE 120% 100% | 20%
SILENCE | 20%
95% 100%
SQU LIN NONE 85% 75% | 60%
*/
createDoubleFlexFX(MoodSound.UHOH.toString(),
110, 40, Wave.SAWTOOTH, Attack.FAST, Effect.NONE, 120, 100,
95, 100, Wave.SQUARE, Attack.SLOW, Effect.NONE, 85, 75,
20, 20);

/*
MOAN 120% 60%
TRI CUR NONE 100% 100% | 60%
TRI CUR NONE 95% 80% | 30%
TRI LIN NONE 115% 55% | 10%
*/
create3PartFlexFX(MoodSound.MOAN.toString(), 120, 60,
Wave.TRIANGLE, Attack.MEDIUM, Effect.NONE, 100, 100,
Wave.TRIANGLE, Attack.MEDIUM, Effect.NONE, 95, 80,
Wave.TRIANGLE, Attack.SLOW, Effect.NONE, 115, 55, 60, 30);

/*
DUH 100% 60%
SQU LIN NONE 95% 100% | 10%
SQU LIN NONE 110% 80% | 25%
SQU LIN NONE 66% 40% | 65%
*/
create3PartFlexFX(MoodSound.DUH.toString(), 100, 60,
Wave.SQUARE, Attack.SLOW, Effect.NONE, 95, 100,
Wave.SQUARE, Attack.SLOW, Effect.NONE, 110, 80,
Wave.SQUARE, Attack.SLOW, Effect.NONE, 66, 40, 10, 25);

/*
WAAH 100% 10%
SAW CUR NONE 140% 100% | 70%
SAW LIN NONE 110% 60% | 20%
SAW LIN NONE 30% 5% | 10%
*/
create3PartFlexFX(MoodSound.WAAH.toString(), 100, 10,
Wave.SAWTOOTH, Attack.MEDIUM, Effect.NONE, 140, 100,
Wave.SAWTOOTH, Attack.SLOW, Effect.NONE, 110, 60,
Wave.SAWTOOTH, Attack.SLOW, Effect.NONE, 30, 5, 70, 20);

/*
GROWL 30% 50%
SAW LOG NONE 100% 80% | 60%
SAW LIN NONE 90% 100% | 15%
SAW LIN NONE 30% 75% | 15%
*/
create3PartFlexFX(MoodSound.GROWL.toString(), 30, 50,
Wave.SAWTOOTH, Attack.FAST, Effect.NONE, 100, 80,
Wave.SAWTOOTH, Attack.SLOW, Effect.NONE, 90, 100,
Wave.SAWTOOTH, Attack.SLOW, Effect.NONE, 30, 75, 60, 15);

// *** SIMPLE UI BLOCKS ***

/**
Emit a built-in FlexFX Sound
*/
//% block="emit $builtIn ||at pitch $pitch with strength $strength for $duration ms"
//% expandableArgumentMode="toggle"
//% inlineInputMode=inline
//% pitch.min=100 pitch.max=800 pitch.defl=300
//% strength.min=0 strength.max=255 strength.defl=180
//% duration.min=50 duration.max=9999 duration.defl=800
//% weight=300
export function emit(builtIn: MoodSound, pitch = 300, strength = 180, duration = 800) {
// select builtin target...
let target: FlexFX = flexFXList.find(i => i.id === builtIn.toString());
if (target != null) {
target.performUsing(pitch, strength, duration);
}
}

/**
Hum randomly for a while...
*/
//% block="hum || $repeat times with strength $strength over $duration ms"
//% expandableArgumentMode="toggle"
//% repeat.min=1 repeat.max=100 repeat.defl=10
//% strength.min=0 strength.max=255 strength.defl=180
//% duration.min=1 duration.max=9999 duration.defl=2000
//% weight=250
export function hum(repeat = 12, strength = 180, duration = 4000) {
quiet = false;
let ave = duration / repeat;
let gap = 0.2 * ave;
let skip = true;
for (let index = 0; index < repeat; index++) {
let span = randint(0.7 * ave, 1.4 * ave);
let pitch = randint(200, 400);
if ((span > ave) || (skip)) {
// mostly "Dum"...
performFlexFX(MoodSound.DOO.toString(), pitch, strength, span);
basic.pause(gap);
skip = false;
} else {
// .. with occasional short, higher-pitched "Di" (unrepeated)
performFlexFX(MoodSound.DOO.toString(), 1.33 * pitch, strength, 0.3 * ave);
basic.pause(gap / 2);
skip = true;
}
}
quiet = true;
}

/**
Complain randomly for a while...
*/
//% block="grumble || $repeat times with strength $strength over $duration ms"
//% expandableArgumentMode="toggle"
//% repeat.min=1 repeat.max=100 repeat.defl=5
//% strength.min=0 strength.max=255 strength.defl=250
//% duration.min=1 duration.max=9999 duration.defl=3000
//% weight=245
export function grumble(repeat = 5, strength = 180, duration = 4000) {
quiet = false;
let ave = duration / repeat;
let gap = 0.2 * ave;
for (let index = 0; index < repeat; index++) {
let span = randint(0.4 * ave, 1.8 * ave);
if (span > 0.8 * ave) {
performFlexFX(MoodSound.DUH.toString(), randint(150, 300), strength, 0.5 * span);
} else {
performFlexFX(MoodSound.UHOH.toString(), randint(100, 200), 1.2 * strength, 2 * span);
}
pause(gap);
}
quiet = true;
}

/**
Giggle for a bit...
*/
//% block="giggle || $repeat times with strength $strength over $duration ms"
//% expandableArgumentMode="toggle"
//% repeat.min=1 repeat.max=100 repeat.defl=12
//% strength.min=0 strength.max=255 strength.defl=200
//% duration.min=1 duration.max=9999 duration.defl=4000
//% weight=240
export function giggle(repeat = 10, strength = 200, duration = 2000) {
quiet = false;
let ave = duration / repeat;
let gap = 0.2 * ave;
let pitch = randint(350, 700);
for (let index = 0; index < repeat; index++) {
let span = randint(0.4 * ave, 1.8 * ave);
performFlexFX(MoodSound.LAUGH.toString(), pitch, strength, span);
pitch = 0.95 * pitch;
basic.pause(gap);
}
quiet = true;
}


/**
Whistle a happy tune...
*/
//% block="whistle || $repeat times with strength $strength over $duration ms"
//% expandableArgumentMode="toggle"
//% repeat.min=1 repeat.max=100 repeat.defl=8
//% strength.min=0 strength.max=255 strength.defl=180
//% duration.min=1 duration.max=9999 duration.defl=2500
//% weight=235
export function whistle(repeat = 12, strength = 180, duration = 2500) {
quiet = false;
let ave = duration / repeat;
let gap = 0.2 * ave;
for (let index = 0; index < repeat; index++) {
let span = randint(0.4 * ave, 1.8 * ave);
performFlexFX(MoodSound.TWEET.toString(), randint(800, 2000), strength, span);
basic.pause(gap);
}
quiet = true;
}


/**
Sleep rather noisily...
*/
//% block="snore || $repeat times with strength $strength over $duration ms"
//% expandableArgumentMode="toggle"
//% repeat.min=1 repeat.max=100 repeat.defl=8
//% strength.min=0 strength.max=255 strength.defl=150
//% duration.min=1 duration.max=9999 duration.defl=5000
//% weight=230
export function snore(repeat = 6, strength = 150, duration = 10000) {
quiet = false;
let ave = duration / repeat;
for (let index = 0; index < repeat; index++) {
let span = randint(0.9 * ave, 1.1 * ave);
performFlexFX(MoodSound.SNORE.toString(), 1, 80, 0.3 * span);
pause(0.1 * ave);
performFlexFX(MoodSound.SNORE.toString(), 1, 150, 0.4 * span);
pause(0.3 * ave);
}
quiet = true;
}


/**
Be just a bit frightened...
*/
//% block="whimper || $repeat times with strength $strength over $duration ms"
//% expandableArgumentMode="toggle"
//% repeat.min=1 repeat.max=100 repeat.defl=10
//% strength.min=0 strength.max=255 strength.defl=100
//% duration.min=1 duration.max=9999 duration.defl=4000
//% weight=225
export function whimper(repeat = 8, strength = 150, duration = 5000) {
if (quiet) {
quiet = false;
let ave = duration / repeat;
let gap = 0.5 * ave;
for (let index = 0; index < repeat; index++) {
performFlexFX(MoodSound.MOAN.toString(), randint(350, 550), strength, randint(0.4 * ave, 1.4 * ave));
basic.pause(gap);
}
quiet = true;
}
}

/**
Be really sad...
*/
//% block="cry || $repeat times with strength $strength over $duration ms"
//% expandableArgumentMode="toggle"
//% repeat.min=1 repeat.max=100 repeat.defl=8
//% strength.min=0 strength.max=255 strength.defl=200
//% duration.min=1 duration.max=9999 duration.defl=3000
//% weight=220
export function cry(repeat = 8, strength = 200, duration = 3500) {
if (quiet) {
quiet = false;
let ave = duration / repeat;
let gap = 0.3 * ave;
for (let index = 0; index < repeat; index++) {
let span = randint(0.5 * ave, 1.2 * ave);
if (span > ave) {
performFlexFX(MoodSound.MOAN.toString(), randint(350, 550), 1.25 * strength, 0.7 * span);
} else {
performFlexFX(MoodSound.WAAH.toString(), randint(350, 450), 0.25 * strength, 1.3 * span);
}
basic.pause(gap);
}
quiet = true;
}
}

/**
Be a bit angry...
*/
//% block="shout || $repeat times with strength $strength over $duration ms"
//% expandableArgumentMode="toggle"
//% repeat.min=1 repeat.max=100 repeat.defl=5
//% strength.min=0 strength.max=255 strength.defl=250
//% duration.min=1 duration.max=9999 duration.defl=2500
//% weight=215
export function shout(repeat = 5, strength = 250, duration = 2500) {
if (quiet) {
quiet = false;
let ave = duration / repeat;
let gap = 0.3 * ave;
for (let index = 0; index < repeat; index++) {
performFlexFX(MoodSound.GROWL.toString(), randint(320, 450), strength, randint(0.5 * ave, 1.3 * ave));
basic.pause(gap);
}
quiet = true;
}
}
}

}
Loading

0 comments on commit f747e16

Please sign in to comment.