login

online now

We have 115 guests and no members online

search

 
Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1

TOPIC: Integrating Tweaker regs arrays into Arduino

Integrating Tweaker regs arrays into Arduino 5 years 7 months ago #274

Hello,

I am looking for an example of how I can integrate the output I get from clicking the "regs" button on Tweaker into my Arduino UNO. I have been creating a sound with the UI and now I simply want to upload it into my Arduino and test how this works.

The regs array that I get looks like this:

ubyte regs[]={1,0,0,0,0,233,0,0,127,0,0,0,0,240,241,1,133,110,18,131,0,0,0,0,10,0,6,0,8,29,54,14,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,9,0,255,0,0,215,0,0,127,0,0,0,0,240,241,1,133,84,149,11,0,0,0,0,242,0,0,0,0,144,144,12,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,109,1,8,118,0,0,127,0,1,0,0,242,0};

To include this sound, am I supposed to declare this as a variable at the start of my code, in the setup or in the main loop of my Arduino sketch? And how can I trigger this sound, say for two seconds? I assume triggering is via the s->setWaveform type commands but I'm not sure.

Please let me know this C/C++ code is meant to be handled in the Arduino IDE—a small example would be ideal, I can take it from there.

Thanks,

Carlos
Last Edit: 5 years 7 months ago by administrator.
The administrator has disabled public write access.

Re: Integrating Tweaker regs arrays into Arduino 5 years 7 months ago #275

Hi Carlos, thanks for the question. The register array that is produced from Tweaker can be loaded into the registers on the Babblebot IC using the writeRegister() function.

The syntax of this function ( as per reference manual ) is :

void writeRegister ( GSRegister regIdx , ubyte value , ubyte mask )

So, you can write a function like this:
void loadPreset()
{
  ubyte regs[]={1,0,0,0,0,233,0,0,127,0,0,0,0,240,241,1,133,110,18,131,0,0,0,0,10,0,6,0,8,29,54,14,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,9,0,255,0,0,215,0,0,127,0,0,0,0,240,241,1,133,84,149,11,0,0,0,0,242,0,0,0,0,144,144,12,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,109,1,8,118,0,0,127,0,1,0,0,242,0};

  for ( int regIdx = 0; regIdx < sizeof(regs); regIdx++ ) {
    writeRegister ( regIdx , regs [ regIdx ] , 0xff );
  }
}

So when this function is called, it will load the registers and produce the sound as heard int tweaker. Depending on how you have set it up, it may terminate on its own or run continuously as it does in the Tweaker program. If it runs continuously and you want to stop the sound output, you can set the master volume to 0. This has the advantage that you can set the master volume back up to start the sound playing again.

Let me know if you need additional help and keep the good questions coming.
The administrator has disabled public write access.

Re: Integrating Tweaker regs arrays into Arduino 5 years 7 months ago #276

Thank you for sharing that—I understand what your explanation is supposed to do, but I still have some confusion as to when I should load the preset sound and initialize synth mode.
Also, I am getting an error when loadPreset() is called — apparently regIdx is being converted from int to GSRegister (as specified in the writeRegister function). The full errors are:

GS_Sound_Preset_Test.cpp: In function 'void loadPreset()':
GS_Sound_Preset_Test:46: error: invalid conversion from 'int' to 'GSRegister'
GS_Sound_Preset_Test:46: error: initializing argument 1 of 'void writeRegister(GSRegister, ubyte, ubyte)'

I am attaching the Arduino code so you see how I'm doing this so far—maybe I forgot to include something else.
#include <GinSing.h>                                 // interface header file

GinSing  GS;                                         // create the class library from which all methods and data are accessed
GinSingSynth *s;                                     // our global pointer to the synth mode interface ( set up after initialization )

#define rcvPin  4                                    // this is the pin used for receiving    ( can be either 4 or 12 )
#define sndPin  3                                    // this is the pin used for transmitting ( can be either 3 or 11 ) 
#define ovfPin  2                                    // this is the pin used for overflow control ( can be either 2 or 10 )

// ---------------------------------------------------------------------------------------------------------------------------------------------

void setup ()
{
  GS.begin ( rcvPin , sndPin , ovfPin );             // start the device (required)
  
  s = GS.getSynth();                                 // get the synth mode interface
  s->begin ();                                       // enter synth mode

  GS.end();                                          // end the device

}

void loop() {
  
  s = GS.getSynth();                                 // get the synth mode interface
  s->begin ();                                       // enter synth mode
  
  loadPreset();                                     // load the preset sound

  
}

void writeRegister ( GSRegister regIdx , ubyte value , ubyte mask ) {} // function to write registers to the IC


void loadPreset() // upload the preset values from Tweaker to write to the register
{
  ubyte regs[]={1,0,0,0,0,233,0,0,127,0,0,0,0,240,241,1,133,110,18,131,0,0,0,0,10,0,6,0,8,29,54,14,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,9,0,255,0,0,215,0,0,127,0,0,0,0,240,241,1,133,84,149,11,0,0,0,0,242,0,0,0,0,144,144,12,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,109,1,8,118,0,0,127,0,1,0,0,242,0};

  for ( int regIdx = 0; regIdx < sizeof(regs); regIdx++ ) {
    writeRegister ( regIdx , regs [ regIdx ] , 0xff );
  }
}
The administrator has disabled public write access.

Re: Integrating Tweaker regs arrays into Arduino 5 years 7 months ago #277

The way to think about the modes ( preset, voice, synth, poly ) is that they have specific functions to set the Babblebot registers that make it do certain things. If you look at the source code for the library functions, you can see that all they do is set specific registers to perform groups of actions. If you are setting the registers yourself, you are bypassing those functions and talking directly to the Babblebot. This is perfectly fine, and just means that you probably won't need to use any of these modes if you want to set the registers.

In my example code I did forget to cast the regIdx veriable to a GSRegister. You can do this simply by:
 for ( int regIdx = 0; regIdx < sizeof(regs); regIdx++ ) {
    writeRegister ( (GSRegister) regIdx , regs [ regIdx ] , 0xff );
  }

Most of the variables uses in the GinSing library have their own variable types to avoid potential misuse, but since the the register index represents a value from zero to 144 this will be fine.

Also note that in your code the writeRegister() delcaration should not be part of your source code; I provided it as an example of how to call the function. Another thing that seems odd in your example is that you are calling GSSynth::begin() repeatedly, which is probably not what you want. Here is a typical application that might use the register sets:

#include <GinSing.h>                                 // interface header file

GinSing  GS;                                         // create the class library

#define rcvPin  4                                    // receiving ( 4 or 12 )
#define sndPin  3                                    // xmit pin ( 3 or 11 ) 
#define ovfPin  2                                    // overflow ( 2 or 10 )

// --------------------------------------------------------------------------------
// setup - this is called once when the Arduino powers up
//
// all we need to do here is start up the board
// --------------------------------------------------------------------------------

void setup ()
{
  GS.begin ( rcvPin , sndPin , ovfPin );             // start the device (required)

  loadPreset1();                                     // start preset sound
}

// --------------------------------------------------------------------------------
// looop - this is called over and over again as quickly as the Arduino can run
//
// since this gets called repeatedly, we only need to test for the condition where
// we would do something based on input or output - for example if an input goes
// high we might load a new register preset (sound)
// ---------------------------------------------------------------------------------

void loop() {
}


// ---------------------------------------------------------------------------------
//  loadPreset1 -- this will load up the sound registers with a preset configuration
//
// each time this is called, it will transmit data to the Babblebot IC that will
// set the state registers. It only needs to be called when we want to change the
// sound output of GinSing board
// ---------------------------------------------------------------------------------

void loadPreset1()
{
  ubyte regs[]={1,0,0,0,0,233,0,0,127,0,0,0,0,240,241,1,133,110,18,131,0,0,0,0,10,0,6,0,8,29,54,14,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,9,0,255,0,0,215,0,0,127,0,0,0,0,240,241,1,133,84,149,11,0,0,0,0,242,0,0,0,0,144,144,12,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,109,1,8,118,0,0,127,0,1,0,0,242,0};

  for ( int regIdx = 0; regIdx < sizeof(regs); regIdx++ ) {
    writeRegister ( (GSRegister)  regIdx , regs [ regIdx ] , 0xff );
  }
}
The administrator has disabled public write access.

Re: Integrating Tweaker regs arrays into Arduino 5 years 7 months ago #282

Thanks for making these points. I understand now that if I am going to be using writeRegister and other IC level commands that I should not be using the mode commands, right? Are they completely incompatible or can you still combine them in your Arduino code?

The reason I ask is because I am still stuck—even though now the code compiles (the casting as GSRegister works, but I also had to the GS. prefix to writeRegister for it to be a recognized library call). It seams to load fine into the Arduino but I can't get the sound to play at all.

I tried to set amplitude levels by using GS.sendCommand ( WriteOneByte , MasterAmplitude , 127 ) and it did not work.

Then I tried a different approach using getMaster():
GinSingMaster *m = GS.getMaster();
m->setMasterAmplitudeVal ( 127 );

And it still didn't work.

I'm kind of giving up on this approach to sound design. I really wanted an easier workflow using Tweaker to output an easy to use Arduino ready code and it is not easy at all. Maybe you can post a tutorial soon to share the knowledge on how to make this workflow possible. Or if there's a tutorial already, can you point me to it?

For now I'm going back to using the GS.getSynth() mode and its library—but this is going to be much more time consuming I think.

Just for reference, here's where I ended with the code.

Thanks for your help,

Carlos
#include <GinSing.h>                                 // interface header file

GinSing  GS;                                         // create the class library

#define rcvPin  4                                    // receiving ( 4 or 12 )
#define sndPin  3                                    // xmit pin ( 3 or 11 ) 
#define ovfPin  2                                    // overflow ( 2 or 10 )

// --------------------------------------------------------------------------------
// setup - this is called once when the Arduino powers up
//
// all we need to do here is start up the board
// --------------------------------------------------------------------------------

void setup ()
{
  GS.begin ( rcvPin , sndPin , ovfPin );             // start the device (required)

  loadPreset1();                                     // start preset sound
}

// --------------------------------------------------------------------------------
// looop - this is called over and over again as quickly as the Arduino can run
//
// since this gets called repeatedly, we only need to test for the condition where
// we would do something based on input or output - for example if an input goes
// high we might load a new register preset (sound)
// ---------------------------------------------------------------------------------

void loop() {
}


// ---------------------------------------------------------------------------------
//  loadPreset1 -- this will load up the sound registers with a preset configuration
//
// each time this is called, it will transmit data to the Babblebot IC that will
// set the state registers. It only needs to be called when we want to change the
// sound output of GinSing board
// ---------------------------------------------------------------------------------

void loadPreset1()
{
  
ubyte regs[]={1,0,0,0,0,131,0,0,127,0,0,0,0,240,241,1,133,110,18,131,0,0,0,0,10,0,6,0,8,29,54,14,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,9,0,255,0,0,129,0,0,127,0,0,0,0,240,241,1,133,84,149,11,0,0,0,0,242,0,0,0,0,144,144,12,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,109,1,8,118,0,0,127,0,253,0,0,0,0};
  
  for ( int regIdx = 0; regIdx < sizeof(regs); regIdx++ ) {
    GS.writeRegister ( (GSRegister)  regIdx , regs [ regIdx ] , 0xff );
  }
  
// I tried this and it didn't work-------  
//  GinSingMaster *m = GS.getMaster();             // get master interface
//  m->setMasterAmplitudeVal ( 127 );               // set global output to 50%

// Then, I tried this and it also doesn't work-------  
//  GS.sendCommand ( WriteOneByte ,        // send command to write 1 byte                 
//  MasterAmplitude ,                      // write to the master amp register                 
//  127 );                                 // write a value of 127 ( 50% )
  

  
}

The administrator has disabled public write access.

Re: Integrating Tweaker regs arrays into Arduino 5 years 7 months ago #283

Good suggestion Carlos - I will begin working on a Tweaker -> Arduino guide today. If you can hang on for a day or two I should be able provide a good working example for you.
The administrator has disabled public write access.

Re: Integrating Tweaker regs arrays into Arduino 5 years 7 months ago #284

That would be great! In the meantime, I'm working on it using GS.getsynth() mode and it's all working fine for now. I have a sketch that checks some differents sensors, and I need to play different sounds based on some conditions detected. Like so:

-if conditionA is true then play soundA for 1 second
-if conditionB is true then play soundB for 1 second

and so forth, you get the point...
I'd like to tell you more about the project actually, I think you'll like to see what we're doing with your awesome GinSings!

Thanks,

Carlos
The administrator has disabled public write access.

Re: Integrating Tweaker regs arrays into Arduino 5 years 7 months ago #285

Hey Carlos, some good news - I was able to load your preset using the code included below. This was a great suggestion, because it actually highlights a bug that I found in the GinSing library code, which means that the reason it did not work was not your fault, but mine.

Because this bug was found in the library, I have provided a workaround file that you can put into your library to fix the issue. I will release a new version of the software with the fix in within the next few days, but this will hopefully fix the issue that you have. The file that had the bug was in GinSing.cpp, which you can find in your Sketchbook location ( Arduino -> Preferences -> Sketchbook Location ). If you go to that folder you will see a folder called "libraries", and in that folder you will find another called "GinSing". If you replace the file called "GinSing.cpp" with the file attached here, you should see that the code below will work. I will incorporate both of these into a tutorial page as you suggest next.

Thanks again for your help in finding this issue - I'm surprised nobody else has not come across this in the most recent revision.



File Attachment:

File Name: GinSing.cpp
File Size: 14 KB




Here is the sample program that I have confirmed works. This is much like the previous example, except that I also added code that will mute the output while the registers get loaded to avoid hearing the sound output change individually as the registers load one at a time:
// -----------------------------------------------------------------------------------------------------------
// tweakset - a sample program to load tweaker output into your Arduino project
// -----------------------------------------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------------------------------------

#include <GinSing.h>                                                // interface headder file
GinSing       GS;                                                   // create the class library

#define rcvPin  4                                                   // recieve pin  ( can be either 4 or 12 )
#define sndPin  3                                                   // transmit pin ( can be either 3 or 11 ) 
#define ovfPin  2                                                   // overflow pin ( can be either 2 or 10 )

                       
// -----------------------------------------------------------------------------------------------------------
//  setup - system entry point for intialization ( called automatically on bootup )
// -----------------------------------------------------------------------------------------------------------

void setup ()
{
    
  GS.begin ( rcvPin , sndPin , ovfPin );                            // start the device
  
  speakIntro();                                                     // start up with a quick voice intro
  
  loadRegisterSet();                                                // load a sample register set
 
}

// -----------------------------------------------------------------------------------------------------------
// shutdown -- system exit point ( called locally )
// -----------------------------------------------------------------------------------------------------------

void shutdown()
{
  GS.end();                                                        // shutown the device
}


// -----------------------------------------------------------------------------------------------------------
// loop -- continuous update point ( called automatically after initialization )
// -----------------------------------------------------------------------------------------------------------

void loop (){}


// -----------------------------------------------------------------------------------------------------------
// speakIntro -- a simple voice command
// -----------------------------------------------------------------------------------------------------------

void speakIntro()
{
  GinSingVoice *v = GS.getVoice();                                  // get the voice mode class interface
  
   v->begin();                                                      // enter voice mode
   v->setNote ( C_2 );                                              // set voice pitch

   GSAllophone welcome[] = {_IE , _A , _M ,                         // define what will be spoken
                             _BENDDN , _J, _I , _NE , _SE ,         // this phrase is I am GinSing
                            _PITCHDN , _I , _PITCHDN , _NGE ,       // with pitch and bend
                            _PA0 , _ENDPHRASE };                    // use _ENDPHRASE to end phrase
                            
    v->speak ( welcome );                                           // speak the phrase
    
    delay ( v->getMillis ( welcome ) + 500 );                       // wait for speaking to finish
}


// -----------------------------------------------------------------------------------------------------------
// loadRegisterSet -- load a  set of registers obtained from the Tweaker program
// -----------------------------------------------------------------------------------------------------------

void loadRegisterSet()
{
  
  
  // this line is produced from the tweaker program - you can replace it with your own to duplicate sounds
  
    ubyte regs[]={1,104,0,0,0,0,0,0,127,0,0,0,0,240,241,1,128,255,0,9,91,0,47,0,126,126,27,0,12,144,144,
                 12,138,0,2,0,2,0,1,0,106,106,239,0,12,144,144,12,136,0,204,1,204,1,3,0,69,69,155,0,12,144,
                 144,12,0,0,0,0,0,0,0,0,127,0,0,0,0,240,241,1,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,
                 0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,0,0,0,0,0,0,0,0,0,0,0,144,144,12,128,0,109,1,8,118,
                 0,0,127,0,24,49,12,0,0};
                 
  
  // reset the system to a default state
 
   GS.reset();
   
   
   // set the master amplitude to zero to mute the output until registers are all loaded

   GS.writeRegister ( MasterAmplitude , 0x0  , 0xff );


   // load the registers into the chip

   for ( int regIdx = 0; regIdx < sizeof ( regs ); regIdx++ ) {
     
       if ( regIdx != MasterAmplitude ) 
         GS.writeRegister ( ( GSRegister )  regIdx , regs [ regIdx ]  , 0xff );

  }
  
  
  // set the actual master amplitude to hear the loaded values
  
   GS.writeRegister ( MasterAmplitude , regs [ MasterAmplitude ]  , 0xff );

}
Last Edit: 5 years 7 months ago by administrator.
The administrator has disabled public write access.
The following user(s) said Thank You: med44

Re: Integrating Tweaker regs arrays into Arduino 5 years 7 months ago #286

I would suggest the simplest way of having a sound play for one second would be to set the ADSR envelope to have a total duration of one second, and then simply trigger the sound when needed. If the sound is required to play sooner than one second, it will retrigger, which I presume would be OK. So for example, you might set ADSR like:
synth->setEnvelope ( OSC_ALL , AT_2MS , 1.0f , DR_2MS , 1.0f , DR_1500MS , 0.0f );

and then in your code:
if ( conditionA ) {
  synth->selectBank ( BANK_A );
  synth->trigger ( OSC_1 );
}

if ( conditionB ) {
  synth->selectBank ( BANK_A );
  synth->trigger ( OSC_2 );

This would trigger DCOs 1 and 2 on bank A, although you can change as it best fits what you have set up for the sounds.

Oh, and please let me know what you are doing on your project - I like to feature projects on the main page...
The administrator has disabled public write access.

Re: Integrating Tweaker regs arrays into Arduino 5 years 7 months ago #287

You rock! This is exactly what I needed, and now it will be much easier to tweak sounds with the Tweaker UI and just update the registers via this.

I'm glad I was able to help you iron out a little bug too!
And you should definitely post a tutorial on this topic. I also have a strong suggestion for you: perhaps in a future update to the Tweaker UI you can add extra function to export an Arduino sketch that includes this code you wrote as well as the regs values already—that way the user simply needs to upload the sketch to Arduino and done.

BTW, our project is this: plantincity.com
We have a series of Arduinos & GinSings monitoring environmental data and making the plants sing based on how they're doing, sort of!

We have a gallery show opening on Nov. 15th. I'll keep you posted with info.

Thanks,

Carlos
The administrator has disabled public write access.
The following user(s) said Thank You: administrator

Re: Integrating Tweaker regs arrays into Arduino 5 years 7 months ago #293

Great looking project - Its really cool that you are getting good press as well. If you need any additional help feel free to hit the forum.

I have also posted the bug fix in official releases ( 4.1 ) in the downloads section.
The administrator has disabled public write access.
  • Page:
  • 1
Time to create page: 0.276 seconds