Calculate a specific pitch (outside of a 12-tone equal temperament note)

This commit is contained in:
Kelvin Sherlock 2023-05-28 15:45:13 -04:00
parent 320bcf3dca
commit 18e306e277
2 changed files with 119 additions and 11 deletions

View File

@ -402,11 +402,14 @@ function SampleDisplay(props) {
return rv;
}
function NoteDisplay(props) {
var { osc, note } = props;
const { osc, note } = props;
return PitchDisplay({ osc, pitch: NoteFrequency(note) });
}
function PitchDisplay(props) {
var { osc, pitch } = props;
const wave = 0;
const sr = calc_sr(osc);
const note_frq = NoteFrequency(note);
const f = note_frq / (sr / (1 << 8 + wave));
const f = pitch / (sr / (1 << 8 + wave));
var best_res = 0;
var best_freq = 0;
for (var res = 0; res < 8; ++res) {
@ -504,6 +507,7 @@ var Application = class extends preact.Component {
this._resChange = this.resChange.bind(this);
this._freqChange = this.freqChange.bind(this);
this._noteChange = this.noteChange.bind(this);
this._pitchChange = this.pitchChange.bind(this);
this._durationChange = this.durationChange.bind(this);
this._tabChange = this.tabChange.bind(this);
this._asmChange = this.asmChange.bind(this);
@ -522,7 +526,8 @@ var Application = class extends preact.Component {
shape: 0,
in_freq: 44100,
in_size: 0,
indeterminate: false
indeterminate: false,
pitch: 440
};
}
oscChange(e) {
@ -540,6 +545,15 @@ var Application = class extends preact.Component {
var v = +e.target.value || 0;
this.setState({ res: v });
}
pitchChange(e) {
e.preventDefault();
var v = +e.target.value;
if (v < 0)
v = 0;
if (v > 65535)
v = 65535;
this.setState({ pitch: v });
}
freqChange(e) {
e.preventDefault();
var v = +e.target.value >> 0;
@ -629,6 +643,20 @@ var Application = class extends preact.Component {
wave
}));
}
pitchChildren() {
var { osc, wave, pitch } = this.state;
return /* @__PURE__ */ preact.h(preact.Fragment, null, /* @__PURE__ */ preact.h("div", null, /* @__PURE__ */ preact.h("label", null, "Oscillators"), " ", /* @__PURE__ */ preact.h(Oscillators, {
value: osc,
onChange: this._oscChange
})), /* @__PURE__ */ preact.h("div", null, /* @__PURE__ */ preact.h("label", null, "Pitch"), " ", /* @__PURE__ */ preact.h(Frequency, {
value: pitch,
onChange: this._pitchChange
}), " Hz"), /* @__PURE__ */ preact.h(PitchDisplay, {
osc,
pitch,
wave
}));
}
waveChildren() {
var { assembler, shape } = this.state;
return /* @__PURE__ */ preact.h(preact.Fragment, null, /* @__PURE__ */ preact.h("div", null, /* @__PURE__ */ preact.h("label", null, "Assembler"), " ", /* @__PURE__ */ preact.h(Assembler, {
@ -710,16 +738,20 @@ var Application = class extends preact.Component {
children = this.noteChildren();
break;
case 3:
children = this.waveChildren();
children = this.pitchChildren();
break;
case 4:
children = this.timerChildren();
children = this.waveChildren();
break;
case 5:
children = this.timerChildren();
break;
case 6:
children = this.hyperChildren();
break;
}
var options = ["Sample", "Resample", "Note", "Wave", "Timer", "HyperCard Pitch"].map((o, ix) => {
const Labels = ["Sample", "Resample", "Note", "Pitch", "Wave", "Timer", "HyperCard Pitch"];
var options = Labels.map((o, ix) => {
return /* @__PURE__ */ preact.h("option", {
key: ix,
value: ix

View File

@ -77,6 +77,7 @@ function SampleDisplay(props) {
}
/*
function NoteDisplay(props) {
@ -114,6 +115,48 @@ function NoteDisplay(props) {
);
}
*/
function NoteDisplay(props) {
const { osc, note } = props;
return PitchDisplay({osc: osc, pitch: NoteFrequency(note)});
}
function PitchDisplay(props) {
var { osc, pitch } = props;
const wave = 0; // 256
const sr = calc_sr(osc);
const f = pitch / (sr / (1 << (8 + wave)));
// best_res = 7 - Math.ceil(Math.log2(f)) ?
// best_freq = f * (1 << calc_shift(best_res, 0)) ?
var best_res = 0;
var best_freq = 0;
for (var res = 0; res < 8; ++res) {
const shift = (1 << calc_shift(res, wave));
const tmp = Math.round(f * shift);
if (tmp >= 0x10000) break;
best_res = res;
best_freq = tmp;
}
[best_res, best_freq] = simplify(best_res, best_freq);
return (
<>
<RateDisplay wave={0} osc={osc} freq={best_freq} res={best_res} />
<div>Wave Size: 256</div>
<div>Resolution: {best_res}</div>
<div>Frequency: {best_freq}</div>
</>
);
}
function RateDisplay(props) {
const { osc, wave, freq, res} = props;
@ -254,6 +297,7 @@ export class Application extends preact.Component {
this._resChange = this.resChange.bind(this);
this._freqChange = this.freqChange.bind(this);
this._noteChange = this.noteChange.bind(this);
this._pitchChange = this.pitchChange.bind(this);
this._durationChange = this.durationChange.bind(this);
this._tabChange = this.tabChange.bind(this);
this._asmChange = this.asmChange.bind(this);
@ -267,6 +311,7 @@ export class Application extends preact.Component {
note: C4, assembler: 0, shape: 0,
in_freq: 44100, in_size: 0,
indeterminate: false,
pitch: 440,
};
}
@ -288,6 +333,15 @@ export class Application extends preact.Component {
this.setState( { res: v } );
}
pitchChange(e) {
e.preventDefault();
var v = +e.target.value;
if (v < 0) v = 0;
if (v > 65535) v = 65535;
this.setState( { pitch: v } );
}
freqChange(e) {
e.preventDefault();
var v = +e.target.value >> 0;
@ -393,6 +447,26 @@ export class Application extends preact.Component {
}
pitchChildren() {
var { osc, wave, pitch } = this.state;
return (
<>
<div>
<label>Oscillators</label> <Oscillators value={osc} onChange={this._oscChange} />
</div>
<div>
<label>Pitch</label> <Frequency value={pitch} onChange={this._pitchChange} /> Hz
</div>
<PitchDisplay osc={osc} pitch={pitch} wave={wave} />
</>
);
}
waveChildren() {
var { assembler, shape } = this.state;
@ -500,12 +574,14 @@ export class Application extends preact.Component {
case 0: children = this.sampleChildren(); break;
case 1: children = this.resampleChildren(); break;
case 2: children = this.noteChildren(); break;
case 3: children = this.waveChildren(); break;
case 4: children = this.timerChildren(); break;
case 5: children = this.hyperChildren(); break;
case 3: children = this.pitchChildren(); break;
case 4: children = this.waveChildren(); break;
case 5: children = this.timerChildren(); break;
case 6: children = this.hyperChildren(); break;
}
var options = ["Sample", "Resample", "Note", "Wave", "Timer", "HyperCard Pitch",].map( (o, ix) => {
const Labels = ["Sample", "Resample", "Note", "Pitch", "Wave", "Timer", "HyperCard Pitch"];
var options = Labels.map( (o, ix) => {
return <option key={ix} value={ix}>{o}</option>;
});