Subversion Repositories DIN Is Noise

Rev

Rev 2250 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
* scale_info.cc
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/



#include "scalelist.h"
#include "scale_info.h"
#include "tokenizer.h"
#include "utils.h"
#include "checkbutton.h"
#include "note.h"
#include "settings.h"
#include "ui_list.h"
#include "main.h"
#include "console.h"
#include "log.h"
#include <vector>
#include <string>

extern string user_data_dir;
extern map<string, float> INTERVALS;
extern int NUM_INTERVALS;
extern vector<string> INTERVAL_NAMES;
extern string SCALE;
extern ui_list uis;
extern char BUFFER [];

int scale_info::set_tonic (float f) {
  nearest_note.freq = f;
  western = find_nearest_note (nearest_note.name, nearest_note.freq, nearest_note.distance);

  // snap note
  //
  /*float d2 = nearest_note.distance * nearest_note.distance;
  if (d2 > 1) {
    tonic = f;
  } else {
    if (nearest_note.freq != lastsnapfreq) {
      tonic = nearest_note.freq;
      lastsnapfreq = tonic;
    } else {
      tonic = f;
      lastsnapfreq = 0.0f;
    }
  }*/


  tonic = f;
  lo_tonic = tonic / 2.0f;
  hi_tonic = tonic * 2.0f;
  if (scl) scl->tonic_changed ();
  return 1;
}

int scale_info::load_scale (const string& n) {

  name = n;

  ifstream file ((user_data_dir + name).c_str(), ios::in);
  if (!file) return 0;

  string ignore;
  int nn;
  file >> ignore >> nn >> ignore;
  set_num_notes (nn);
  notes.resize (num_notes);
  for (int i = 0; i < num_notes; ++i) file >> notes[i];

  intervals = INTERVALS;

  if (scl) scl->scale_loaded ();

  return 1;

}

int scale_info::save_scale () {

  string fname (user_data_dir + name);

  ofstream file ((user_data_dir + name).c_str(), ios::out);
  if (!file) return 0;

  file << "num_notes " << num_notes << endl;
  file << "notes ";
  for (int i = 0; i < num_notes; ++i) file << notes[i] << spc;
  file << endl;

  dlog << "+++ saved scale into " + fname + " +++" << endl;

  return 1;

}

void scale_info::update (checkbutton* cb_notes) {
  notes.clear ();
  name.clear ();
  for (int i = 0; i < NUM_INTERVALS; ++i) {
    if (cb_notes[i].state) {
      const string& in = INTERVAL_NAMES[i];
      notes.push_back (in);
      name += in;
    }
  }

  set_num_notes (notes.size ());
  if (scl) scl->scale_changed ();
  SCALE = name;
}

void scale_info::update_settings () {
  sprintf (BUFFER, " nearest note = %s @ %0.3f Hz", nearest_note.name.c_str (), nearest_note.freq);
  uis.settings_scr.ol_nearest_note.option.set_text (BUFFER);
  uis.settings_scr.ol_nearest_note.set_apply_pos ();
  uis.settings_scr.sp_key.set_value (tonic);
  uis.settings_scr.sn_scale_notes.refresh ();
}

void scale_info::set_num_notes (int n) {
  num_notes = n;
  last_note = num_notes - 1;
  second_last_note = last_note - 1;
  num_ranges = last_note;
  last_range = num_ranges - 1;
}