Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seeded random for scribble.progression()? #102

Open
vinceTheProgrammer opened this issue May 23, 2020 · 2 comments
Open

Seeded random for scribble.progression()? #102

vinceTheProgrammer opened this issue May 23, 2020 · 2 comments
Labels

Comments

@vinceTheProgrammer
Copy link

Hi, this is probably inappropriate to ask here, but can anyone help me use the "seedrandom" package with scribbletune's progression method?

If I understand correctly, and based on my experience with the method so far, scribbletune.progression() returns a random chord progression that follows the rules of music theory.

I want to return a random chord progression that follows the rules of music theory, but I also want to seed it, so I can return the same progression again later.

I tried finding where the Math.random() function is in the index.js of the scribbletune package so I can maybe pass the seeded random function in as a third parameter to replace the Math.random() function within the progression() method, but I wasn't skilled enough to find it xp.

Any help is appreciated. Thanks in advance.

@walmik
Copy link
Collaborator

walmik commented May 24, 2020

Hello @vinceTheProgrammer

Does your usecase need something like this:

const mySeededChord = progression('M', 23424); // e.g. 'I V vi V'

and then later,

const myChordFromSeed = progression('M', 23424);  // continues to return 'I V vi V'

If this is indeed the case, then one possible scenario is to create a map object inside the progression method's closure and if a seed was passed, store the generated chord internally in the map against the provided seed. The next time the request comes for this method with that same seed, then first look up the map and see if that seed exists, if it does, then just return as is without any computing.

A good place to start would be to affect this method https://github.com/scribbletune/scribbletune/blob/master/src/progression.ts#L105-L160

const getProgFactory = ({ T, P, D }: TPD) => {
  const seeds = {};
  return(count: number = 4, seed: number) => {
    if (seeds[seed]) {
      // return early
      return seeds[seed];
    }

    // If seed was not passed, continue executing this method
    // which generates chords in a variable called `chords`

    if (seed) {
      seeds[seed] = chords;
    }

    return chords;
  };
}

This will obviously not be persistent and will only last during each session of using Scribbletune (within the terminal or the browser). To make it persistent we may have to give some more thought and even implement a provision for cleaning up the persisted seeds. For the browser we could use local storage and for the terminal we could use a simple file based persistence.

Lemme know if you re interested in implementing any of this, I can help you get in any or all of these changes as a new feature in Scribbletune!

@vinceTheProgrammer
Copy link
Author

@walmik
Sorry I took so long to respond. Shortly after I made this issue I got frustrated because I was editing progression.ts, utils.ts, etc then trying to run my app immediately after each edit and getting no new results no matter what I changed, so I gave up until just a few hours ago when I decided to give it another go. I realize now I was just being dumb and not realizing that the .ts files are probably just used for compiling the module, but I have no experience compiling node modules, so I decided to just edit scribbletune's index.js file directly. This is the solution I came up with that works perfectly for my use case:

In my app's index file:

const seedrandom = require('seedrandom');
let myrng = seedrandom(seed);
exports.myrng = myrng;

At the top of scribbletune's index file:

const index = require('../../index.js');

At pickOne() and dice():

t.pickOne = function (n) {
        return n.length > 1 ? n[Math.round(index.myrng())] : n[0]
}, t.dice = function () {
        return !!Math.round(index.myrng())
}

I hope you don't mind that the solution I came up with is very specific to my use case and probably won't fit into the main scribbletune module. You wouldn't want me writing code for scribbletune anyway as my code is usually a total mess XD.

@walmik walmik added the feature label Jun 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants