hypercard/rsoundsample relative pitch calculation
This commit is contained in:
parent
5774cc586f
commit
06fe50de8c
|
@ -49,7 +49,7 @@ var NoteInput = class extends preact.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
var { onChange, value } = this.props;
|
var { onChange, value, disabled } = this.props;
|
||||||
var notes = _notes.map((x, ix) => {
|
var notes = _notes.map((x, ix) => {
|
||||||
return /* @__PURE__ */ preact.h("option", {
|
return /* @__PURE__ */ preact.h("option", {
|
||||||
key: ix,
|
key: ix,
|
||||||
|
@ -66,10 +66,12 @@ var NoteInput = class extends preact.Component {
|
||||||
var [note, octave] = split_value(value);
|
var [note, octave] = split_value(value);
|
||||||
return /* @__PURE__ */ preact.h(preact.Fragment, null, /* @__PURE__ */ preact.h("select", {
|
return /* @__PURE__ */ preact.h(preact.Fragment, null, /* @__PURE__ */ preact.h("select", {
|
||||||
onChange: this._noteChange,
|
onChange: this._noteChange,
|
||||||
value: note
|
value: note,
|
||||||
|
disabled
|
||||||
}, notes), " ", /* @__PURE__ */ preact.h("select", {
|
}, notes), " ", /* @__PURE__ */ preact.h("select", {
|
||||||
onChange: this._octaveChange,
|
onChange: this._octaveChange,
|
||||||
value: octave
|
value: octave,
|
||||||
|
disabled
|
||||||
}, octaves), " ", NoteFrequency(value).toFixed(2), " Hz");
|
}, octaves), " ", NoteFrequency(value).toFixed(2), " Hz");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -173,8 +175,7 @@ function Oscillators(props) {
|
||||||
}, i2, " \u2013 ", x2);
|
}, i2, " \u2013 ", x2);
|
||||||
});
|
});
|
||||||
return /* @__PURE__ */ preact.h("select", {
|
return /* @__PURE__ */ preact.h("select", {
|
||||||
value: props.value,
|
...props
|
||||||
onChange: props.onChange
|
|
||||||
}, options);
|
}, options);
|
||||||
}
|
}
|
||||||
function WaveSize(props) {
|
function WaveSize(props) {
|
||||||
|
@ -236,8 +237,15 @@ function WaveShape(props) {
|
||||||
...props
|
...props
|
||||||
}, options);
|
}, options);
|
||||||
}
|
}
|
||||||
|
function CheckBox(props) {
|
||||||
|
return /* @__PURE__ */ preact.h("input", {
|
||||||
|
type: "checkbox",
|
||||||
|
...props
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// src/application.jsx
|
// src/application.jsx
|
||||||
|
var C4 = 4 * 12;
|
||||||
function nmultiply(x) {
|
function nmultiply(x) {
|
||||||
if (x == 0)
|
if (x == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -309,6 +317,13 @@ function ResampleDisplay(props) {
|
||||||
shift: best_shift
|
shift: best_shift
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
function HyperDisplay(props) {
|
||||||
|
var { pitch, freq } = props;
|
||||||
|
const r = freq * 261.63 / (26320 * pitch);
|
||||||
|
const offset = Math.round(3072 * Math.log2(r));
|
||||||
|
const relative = offset < 0 ? -offset + 32768 : offset;
|
||||||
|
return /* @__PURE__ */ preact.h("div", null, "Relative: ", relative);
|
||||||
|
}
|
||||||
var Application = class extends preact.Component {
|
var Application = class extends preact.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -322,17 +337,19 @@ var Application = class extends preact.Component {
|
||||||
this._shapeChange = this.shapeChange.bind(this);
|
this._shapeChange = this.shapeChange.bind(this);
|
||||||
this._inFreqChange = this.inFreqChange.bind(this);
|
this._inFreqChange = this.inFreqChange.bind(this);
|
||||||
this._inSizeChange = this.inSizeChange.bind(this);
|
this._inSizeChange = this.inSizeChange.bind(this);
|
||||||
|
this._indeterminateChange = this.indeterminateChange.bind(this);
|
||||||
this.state = {
|
this.state = {
|
||||||
osc: 32,
|
osc: 32,
|
||||||
wave: 0,
|
wave: 0,
|
||||||
res: 0,
|
res: 0,
|
||||||
freq: 512,
|
freq: 512,
|
||||||
tab: 0,
|
tab: 0,
|
||||||
note: 4 * 12,
|
note: C4,
|
||||||
assembler: 0,
|
assembler: 0,
|
||||||
shape: 0,
|
shape: 0,
|
||||||
in_freq: 44100,
|
in_freq: 44100,
|
||||||
in_size: 0
|
in_size: 0,
|
||||||
|
indeterminate: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
oscChange(e) {
|
oscChange(e) {
|
||||||
|
@ -391,6 +408,11 @@ var Application = class extends preact.Component {
|
||||||
var v = +e.target.value;
|
var v = +e.target.value;
|
||||||
this.setState({ shape: v });
|
this.setState({ shape: v });
|
||||||
}
|
}
|
||||||
|
indeterminateChange(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var v = !!e.target.checked;
|
||||||
|
this.setState({ indeterminate: v });
|
||||||
|
}
|
||||||
sampleChildren() {
|
sampleChildren() {
|
||||||
var { osc, wave, res, freq } = this.state;
|
var { osc, wave, res, freq } = this.state;
|
||||||
var shift = calc_shift(res, wave);
|
var shift = calc_shift(res, wave);
|
||||||
|
@ -455,6 +477,30 @@ var Application = class extends preact.Component {
|
||||||
freq: in_freq
|
freq: in_freq
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
hyperChildren() {
|
||||||
|
var { in_freq, note, indeterminate } = this.state;
|
||||||
|
if (indeterminate)
|
||||||
|
note = C4;
|
||||||
|
return /* @__PURE__ */ preact.h(preact.Fragment, null, /* @__PURE__ */ preact.h("div", null, /* @__PURE__ */ preact.h("label", null, "Oscillators"), " ", /* @__PURE__ */ preact.h(Oscillators, {
|
||||||
|
value: 32,
|
||||||
|
disabled: true
|
||||||
|
})), /* @__PURE__ */ preact.h("div", null, /* @__PURE__ */ preact.h("label", null, "In Frequency"), " ", /* @__PURE__ */ preact.h(Frequency, {
|
||||||
|
value: in_freq,
|
||||||
|
onChange: this._inFreqChange
|
||||||
|
})), /* @__PURE__ */ preact.h("div", null, /* @__PURE__ */ preact.h("label", null, "Indeterminate"), /* @__PURE__ */ preact.h(CheckBox, {
|
||||||
|
checked: indeterminate,
|
||||||
|
onChange: this._indeterminateChange
|
||||||
|
})), /* @__PURE__ */ preact.h("div", {
|
||||||
|
style: indeterminate ? { display: "none" } : ""
|
||||||
|
}, /* @__PURE__ */ preact.h("label", null, "Pitch"), " ", /* @__PURE__ */ preact.h(NoteInput, {
|
||||||
|
value: note,
|
||||||
|
onChange: this._noteChange,
|
||||||
|
disabled: indeterminate
|
||||||
|
})), /* @__PURE__ */ preact.h(HyperDisplay, {
|
||||||
|
freq: in_freq,
|
||||||
|
pitch: NoteFrequency(note)
|
||||||
|
}));
|
||||||
|
}
|
||||||
render() {
|
render() {
|
||||||
var { osc, wave, res, freq, tab } = this.state;
|
var { osc, wave, res, freq, tab } = this.state;
|
||||||
var children;
|
var children;
|
||||||
|
@ -471,8 +517,11 @@ var Application = class extends preact.Component {
|
||||||
case 3:
|
case 3:
|
||||||
children = this.waveChildren();
|
children = this.waveChildren();
|
||||||
break;
|
break;
|
||||||
|
case 4:
|
||||||
|
children = this.hyperChildren();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
var options = ["Sample", "Resample", "Note", "Wave"].map((o, ix) => {
|
var options = ["Sample", "Resample", "Note", "Wave", "HyperCard Pitch"].map((o, ix) => {
|
||||||
return /* @__PURE__ */ preact.h("option", {
|
return /* @__PURE__ */ preact.h("option", {
|
||||||
key: ix,
|
key: ix,
|
||||||
value: ix
|
value: ix
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
import { calc_sr, calc_shift, log2 } from './utils';
|
import { calc_sr, calc_shift, log2 } from './utils';
|
||||||
|
|
||||||
import { NoteInput, NoteFrequency } from './note_input';
|
import { NoteInput, NoteFrequency } from './note_input';
|
||||||
import { RadioGroup } from './radio_group';
|
|
||||||
import { WaveData } from './wave_data';
|
import { WaveData } from './wave_data';
|
||||||
|
|
||||||
import { Oscillators, WaveSize, Resolution, Frequency, Assembler, WaveShape } from './input';
|
import { Oscillators, WaveSize, Resolution, Frequency, Assembler, WaveShape, CheckBox } from './input';
|
||||||
|
|
||||||
|
|
||||||
|
const C4 = 4*12;
|
||||||
|
|
||||||
|
|
||||||
function nmultiply(x) {
|
function nmultiply(x) {
|
||||||
|
@ -141,6 +141,25 @@ function ResampleDisplay(props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function HyperDisplay(props) {
|
||||||
|
|
||||||
|
var { pitch, freq } = props;
|
||||||
|
|
||||||
|
// 26_320 = SR w/ 32 oscillators.
|
||||||
|
// 261.63 = C4
|
||||||
|
// 3072 = 12 * 256 (12 = octave)
|
||||||
|
|
||||||
|
const r = (freq * 261.63 )/ (26_320 * pitch);
|
||||||
|
|
||||||
|
const offset = Math.round(3072 * Math.log2(r));
|
||||||
|
|
||||||
|
const relative = offset < 0 ? -offset + 0x8000 : offset;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>Relative: {relative}</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// oscillators generate addresses, not samples.
|
// oscillators generate addresses, not samples.
|
||||||
// accumulator is 24-bit.
|
// accumulator is 24-bit.
|
||||||
// frequency is 16-bit.
|
// frequency is 16-bit.
|
||||||
|
@ -162,11 +181,13 @@ export class Application extends preact.Component {
|
||||||
this._shapeChange = this.shapeChange.bind(this);
|
this._shapeChange = this.shapeChange.bind(this);
|
||||||
this._inFreqChange = this.inFreqChange.bind(this);
|
this._inFreqChange = this.inFreqChange.bind(this);
|
||||||
this._inSizeChange = this.inSizeChange.bind(this);
|
this._inSizeChange = this.inSizeChange.bind(this);
|
||||||
|
this._indeterminateChange = this.indeterminateChange.bind(this);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
osc: 32, wave: 0, res: 0, freq: 512, tab: 0,
|
osc: 32, wave: 0, res: 0, freq: 512, tab: 0,
|
||||||
note: 4*12, assembler: 0, shape: 0,
|
note: C4, assembler: 0, shape: 0,
|
||||||
in_freq: 44100, in_size: 0,
|
in_freq: 44100, in_size: 0,
|
||||||
|
indeterminate: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,6 +255,12 @@ export class Application extends preact.Component {
|
||||||
this.setState({ shape: v});
|
this.setState({ shape: v});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
indeterminateChange(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var v = !!e.target.checked;
|
||||||
|
this.setState({ indeterminate: v });
|
||||||
|
}
|
||||||
|
|
||||||
sampleChildren() {
|
sampleChildren() {
|
||||||
|
|
||||||
var { osc, wave, res, freq } = this.state;
|
var { osc, wave, res, freq } = this.state;
|
||||||
|
@ -321,6 +348,41 @@ export class Application extends preact.Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hyperChildren() {
|
||||||
|
|
||||||
|
var { in_freq, note, indeterminate } = this.state;
|
||||||
|
|
||||||
|
|
||||||
|
if (indeterminate) note = C4;
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label>Oscillators</label> <Oscillators value={32} disabled={true} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label>In Frequency</label> <Frequency value={in_freq} onChange={this._inFreqChange} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label>Indeterminate</label>
|
||||||
|
<CheckBox checked={indeterminate} onChange={ this._indeterminateChange } />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={indeterminate ? { display: "none" } : ""}>
|
||||||
|
<label>Pitch</label> <NoteInput value={note} onChange={this._noteChange}
|
||||||
|
disabled={indeterminate} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<HyperDisplay freq={in_freq} pitch={NoteFrequency(note)} />
|
||||||
|
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
|
@ -334,9 +396,10 @@ export class Application extends preact.Component {
|
||||||
case 1: children = this.resampleChildren(); break;
|
case 1: children = this.resampleChildren(); break;
|
||||||
case 2: children = this.noteChildren(); break;
|
case 2: children = this.noteChildren(); break;
|
||||||
case 3: children = this.waveChildren(); break;
|
case 3: children = this.waveChildren(); break;
|
||||||
|
case 4: children = this.hyperChildren(); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var options = ["Sample", "Resample", "Note", "Wave"].map( (o, ix) => {
|
var options = ["Sample", "Resample", "Note", "Wave", "HyperCard Pitch"].map( (o, ix) => {
|
||||||
return <option key={ix} value={ix}>{o}</option>;
|
return <option key={ix} value={ix}>{o}</option>;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ export function Oscillators(props) {
|
||||||
// for (var i = 1; i < 33; ++i) {
|
// for (var i = 1; i < 33; ++i) {
|
||||||
// options.push(<option value={i} key={i}>{i}</option>);
|
// options.push(<option value={i} key={i}>{i}</option>);
|
||||||
// }
|
// }
|
||||||
return <select value={props.value} onChange={props.onChange}>{options}</select>;
|
return <select {...props}>{options}</select>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function WaveSize(props) {
|
export function WaveSize(props) {
|
||||||
|
@ -65,3 +65,7 @@ export function WaveShape(props) {
|
||||||
|
|
||||||
return <select {...props}>{options}</select>;
|
return <select {...props}>{options}</select>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function CheckBox(props) {
|
||||||
|
return <input type="checkbox" {...props} />
|
||||||
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ export class NoteInput extends preact.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
var { onChange, value } = this.props;
|
var { onChange, value, disabled } = this.props;
|
||||||
|
|
||||||
var notes = _notes.map( (x, ix) => {
|
var notes = _notes.map( (x, ix) => {
|
||||||
return <option key={ix} value={ix}>{x}</option>;
|
return <option key={ix} value={ix}>{x}</option>;
|
||||||
|
@ -78,9 +78,9 @@ export class NoteInput extends preact.Component {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<select onChange={this._noteChange} value={note}>{notes}</select>
|
<select onChange={this._noteChange} value={note} disabled={disabled}>{notes}</select>
|
||||||
{ ' ' }
|
{ ' ' }
|
||||||
<select onChange={this._octaveChange} value={octave}>{octaves}</select>
|
<select onChange={this._octaveChange} value={octave} disabled={disabled}>{octaves}</select>
|
||||||
{ ' ' }
|
{ ' ' }
|
||||||
{ NoteFrequency(value).toFixed(2) } Hz
|
{ NoteFrequency(value).toFixed(2) } Hz
|
||||||
</>);
|
</>);
|
||||||
|
|
Loading…
Reference in New Issue