preview outputs should be stereo

This commit is contained in:
Jade Rowland 2023-11-23 12:43:51 -05:00
parent e419733716
commit 3fd5fdf1ee
4 changed files with 40 additions and 29 deletions

View File

@ -381,18 +381,18 @@ const generic_params = [
*/
['coarse'],
// /**
// * Allows you to set the output channels on the interface
// *
// * @name channels
// * @synonyms ch
// *
// * @param {!Float32Array} channels Array<int>
// * @example
// * note("e a d b g").channels([2, 3]).room(1)
// *
// */
// ['channels', 'ch'],
/**
* Allows you to set the output channels on the interface
*
* @name channels
* @synonyms ch
*
* @param {number | Pattern} channels pattern the output channels
* @example
* note("e a d b g").channels("2:3").room(1)
*
*/
['channels', 'ch'],
['phaserrate', 'phasr'], // superdirt only
@ -1390,13 +1390,13 @@ controls.ds = register('ds', (ds, pat) => {
return pat.set({ decay, sustain });
});
controls.ch = register(['channels', 'ch'], (channels, pat) => {
channels = !Array.isArray(channels) ? [channels] : channels;
// controls.ch = register(['channels', 'ch'], (channels, pat) => {
// channels = !Array.isArray(channels) ? [channels] : channels;
// channels = channels.map(reify).map((channelPat) => {
// // How do I return the current value of the channel pattern here?
// });
return pat.set({ channels });
});
// // channels = channels.map(reify).map((channelPat) => {
// // // How do I return the current value of the channel pattern here?
// // });
// return pat.set({ channels });
// });
export default controls;

View File

@ -23,6 +23,13 @@ export function registerSound(key, onTrigger, data = {}) {
export function getSound(s) {
return soundMap.get()[s];
}
// sounds with only one active channel will get upmixed to two, stereo sounds should remain unaffected
// There might be a better way to do this
export const upMixToStereo = (ctx, node) => {
const stereo = new StereoPannerNode(ctx);
node.connect(stereo);
return stereo;
};
export const resetLoadedSounds = () => soundMap.set({});
@ -117,14 +124,16 @@ const maxfeedback = 0.98;
const connectToOutputs = (input, channels = [0, 1]) => {
const outputs = getDestinations(channels);
const ctx = getAudioContext();
const center = new StereoPannerNode(ctx);
input.connect(center);
//This upmix can be avoided if correct channel counts are set throughout the app,
//could theoretically support surround sound audio files if that work was done
const stereo = upMixToStereo(ctx, input);
const splitter = new ChannelSplitterNode(ctx, {
numberOfOutputs: input.channelCount,
numberOfOutputs: stereo.channelCount,
});
center.connect(splitter);
stereo.connect(splitter);
outputs.forEach((output, i) => {
splitter.connect(output, i % input.channelCount, 0);
splitter.connect(output, i % stereo.channelCount, 0);
});
};
@ -334,6 +343,8 @@ export const superdough = async (value, deadline, hapDuration) => {
compressorRelease,
} = value;
channels = Array.isArray(channels) ? channels : [channels];
gain *= velocity; // legacy fix for velocity
let toDisconnect = []; // audio nodes that will be disconnected when the source has ended
const onended = () => {

View File

@ -71,8 +71,7 @@ export function waveformN(partials, type) {
const real = new Float32Array(partials + 1);
const imag = new Float32Array(partials + 1);
const ac = getAudioContext();
const osc = ac.createOscillator();
const osc = new OscillatorNode(ac, { channelCount: 1, channelCountMode: 'explicit' });
const terms = {
sawtooth: (n) => [0, -1 / n],
square: (n) => [0, n % 2 === 0 ? 0 : 1 / n],
@ -125,7 +124,8 @@ export function getOscillator(
let o;
// If no partials are given, use stock waveforms
if (!partials || s === 'sine') {
o = getAudioContext().createOscillator();
o = new OscillatorNode(ac, { channelCount: 1, channelCountMode: 'explicit' });
console.log(o);
o.type = s || 'triangle';
}
// generate custom waveform if partials are given

View File

@ -7,7 +7,7 @@ import React, { useMemo, useCallback, useLayoutEffect, useRef, useState } from '
import { Reference } from './Reference';
import { themes } from './themes.mjs';
import { useSettings, settingsMap, setActiveFooter, defaultSettings } from '../settings.mjs';
import { getAudioContext, soundMap } from '@strudel.cycles/webaudio';
import { getAudioContext, soundMap, upMixToStereo } from '@strudel.cycles/webaudio';
import { useStore } from '@nanostores/react';
import { FilesTab } from './FilesTab';
@ -271,7 +271,7 @@ function SoundsTab() {
const onended = () => trigRef.current?.node?.disconnect();
trigRef.current = Promise.resolve(onTrigger(time, params, onended));
trigRef.current.then((ref) => {
ref?.node.connect(ctx.destination);
upMixToStereo(ctx, ref?.node).connect(ctx.destination);
});
}}
>