An object, which itself contains an array of objects

Hi,

I'm trying to create an object, which itself contains an array of p5.Oscillator objects, but I can't get the code to work the way I want it to. I would like to be able to have a separate methods for playing the sound, changing the frequency, etc... but I can't seem to access p5.Oscillator's methods outside of the function in which I fill the 'this.harmonic' array with instances of the p5.Oscillator object. I keep getting the error: Cannot read property 'start' of undefined.

I'm probably going about this the complete wrong way, but I've posted my code below. Any ideas on what i'm doing wrong?

function Wavetable(theFreq, theAmp, theMaxHarmonics) {
    this.freq = theFreq;
    this.amp = theAmp;
    this.maxHarmonics = theMaxHarmonics;
    this.harmonic = []

    this.init = function() {    
           for(var i = 1; i <= this.maxHarmonics; i++) {
            this.harmonic[i] = new p5.Oscillator();
            this.harmonic[i].setType('sine');
            this.harmonic[i].freq(this.freq * (i+1));
            this.harmonic[i].amp(this.amp / (i+1));
            // this.harmonic[i].start(); // <- This works fine
        }
    };

    this.play = function() {
        for(var i = 0; i < this.harmonic.length; i++) {
            this.harmonic[i].start();  // <- This gives an error: "Cannot read property 'start' of undefined"
        }
     }; 

}

Answers

  • edited June 2017 Answer ✓

    The 1st index's value for an array is 0. However in your loop below, you start that w/ 1 instead: #-o
    for(var i = 1; i <= this.maxHarmonics; i++) { -> for (let i = 0; i < this.maxHarmonics; ++i) {

    BtW, for containers, it's better to name them w/ a plural or collective name: *-:)
    this.harmonic = [] -> this.harmonics = [];

  • edited June 2017 Answer ✓

    And for a joyous OOP experience in JS, nothing's better than to use class constructor blocks: ~O)
    https://developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor

    // forum.Processing.org/two/discussion/23269/
    // an-object-which-itself-contains-an-array-of-objects#Item_2
    
    // GoToLoop (2017-Jun-30)
    
    class Wavetable {
      static get TYPE() {
        delete this.TYPE;
        return this.TYPE = 'sine';
      }
    
      constructor(freq = 440, amp = 1.0, qty = 1) {
        this.freq = freq, this.amp = amp, this.qty = qty;
        this.harmonics = Array(qty);
        this.init();
      }
    
      init(i = 0) {
        const { freq: f, amp: a, qty: q } = this, t = Wavetable.TYPE;
        while (i < q)  (this.harmonics[i++] = new p5.Oscillator(f*i, t)).amp(a/i);
      }
    
      playAll() {
        for (const h of this.harmonics)  h.start();
      }
    }
    
  • Thanks! God, dunno how I didn't catch that - guess it's been a while since I coded in a text based language. Cheers for the info on the use of class constructor blocks in js as well, it does look like a much more eloquent way of doing it - I'll make sure to give that read..

Sign In or Register to comment.