View unanswered posts | View active topics It is currently Sat Oct 25, 2014 4:54 pm






Reply to topic  [ 17 posts ]  Go to page 1, 2  Next
Bug when using random and PlayTone 
Author Message
Rookie

Joined: Sat Aug 09, 2008 7:18 pm
Posts: 17
Post Bug when using random and PlayTone
I've noticed some very strange behavior which is almost certainly a compiler bug. When using PlayTone with a random value my program hard locks. The only way to continue is to remove the batteries from the NXT. This does not occur when I simply give a constant integer value to PlayTone, regardless of whether or not random is used elsewhere prior to PlayTone. I've stepped through in the debugger to see what value random is returning and its a good value, yet the program still hangs on PlayTone if the random value is passed into it.

I wanted to make an arpeggiator for my robot that would play random tones from a specified harmonic and rhythmic pattern ( for instance, randomly play any note in a Cmaj7 chord with a specified rhythm and tempo)


Sun Aug 10, 2008 9:35 pm
Profile
Creator
Creator

Joined: Fri Feb 09, 2007 9:21 am
Posts: 615
Post Re: Bug when using random and PlayTone
This is an error in the "RobotCIntrinsics.c" file. It has three different declarations of the "PlayTone" function. Two of these are related to providing legacy support for Robolab and are not needed for ROBOTC. These functions generate VM opcodes that relate to VMs limited to 256 variables and requiring parameters to be compile time constants.
Code:
intrinsic void PlayTone(compileConst int frequency, compileConst int durationIn10MsecTicks)
                   asm(opcdPlayTone, word(frequency), byte(durationIn10MsecTicks));

intrinsic void PlayTone(const int frequency, compileConst int durationIn10MsecTicks)
                   asm(opcdPlayToneVar, byte(parameterIndex(frequency)), byte(durationIn10MsecTicks));


The file will be fixed in versions 1.41. Meanwhile, you could manually edit the file yourself to remove the "offending" declarations if you want a immediate fix.


Tue Aug 12, 2008 11:50 am
Profile
Rookie

Joined: Sat Aug 09, 2008 7:18 pm
Posts: 17
Post Re: Bug when using random and PlayTone
Thanks! I'll give that a try as soon as I get a chance. If it works out I'll post my arpeggiator code in case anyone else is interested in using it for their robots.


Wed Aug 13, 2008 12:24 am
Profile
Rookie

Joined: Sat Aug 09, 2008 7:18 pm
Posts: 17
Post Re: Bug when using random and PlayTone
Hmm, I commented out those lines and I still have the problem. Does this file get recompiled when I recompile my program from the IDE?


Thu Aug 14, 2008 11:30 pm
Profile
Creator
Creator

Joined: Fri Feb 09, 2007 9:21 am
Posts: 615
Post Re: Bug when using random and PlayTone
Yes. The file ("RobotCIntrinsics.c") gets recompiled if the "modification date" of the file is later than the date/time of the last compile.


Fri Aug 15, 2008 3:21 am
Profile
Creator
Creator

Joined: Fri Feb 09, 2007 9:21 am
Posts: 615
Post Re: Bug when using random and PlayTone
By the way, I've been looking at the sound generation functionality of the NXT and looking to add more flexibility than wav files that would be easy to use. If you have some ideas here that are also memory efficient I'd look at whether it is easy to integrate natively into the firmware. My end target is something that adds a lot more flexibility in terms of 'pleasing sounds' that is also easy to program.


Fri Aug 15, 2008 3:37 am
Profile
Creator
Creator

Joined: Fri Feb 09, 2007 9:21 am
Posts: 615
Post Re: Bug when using random and PlayTone
I just tried the following program with version 1.41 and verified that it worked and didn't crash the brick.

Code:
task main()
{
  while (true)
  {
    PlayTone(random(3000), random(20));
    while (bSoundActive)
    {}
  }
}

I cannot reproduce your problem of locked brick.

Version 1.41 should be posted as pre-release on www.robotc.net in the next day or two.


Fri Aug 15, 2008 3:43 am
Profile
Rookie

Joined: Sat Aug 09, 2008 7:18 pm
Posts: 17
Post Re: Bug when using random and PlayTone
Yeah sorry, I did manage to get it working. I'm looking forward to the next version.


Sat Aug 16, 2008 10:27 pm
Profile
Rookie

Joined: Sat Aug 09, 2008 7:18 pm
Posts: 17
Post Re: Bug when using random and PlayTone
Also, I've got the arpeggiator working pretty well. Basically you can define a chord or scale formula, a rhythmic pattern and set some parameters for note selection and tempo and it plays notes. You can get a lot of interesting sounds out of it, ranging from musical to completely random with a minimal amount of data. If used creatively I think it could really add a lot of personality to a robot. I'd still like to add a lot of features to it, but when I get it a little further along I'll post the code. I think it might be cool to integrate it into the firmware too.


Sat Aug 16, 2008 10:47 pm
Profile
Rookie

Joined: Sat Aug 09, 2008 7:18 pm
Posts: 17
Post Re: Bug when using random and PlayTone
Oh yeah.. I was also wondering about the wav capabilities of the NXT. I am interested in taking advantage of its sound capabilities to the fullest. Is there some kind of tool to create the sound files that the NXT uses? Since it is able to play sounds resembling the human voice, it should also be capable of generating waveforms that sound like synthesizers, like square waves, sawtooth, etc. These sounds could potentially be much more pleasing than the tones generated with PlayTone. If I could combine the arpeggiator with a waveform generator and volume control I could definitely make a lot of cool sounds with a minimal amount of data. Is there any way to access more advanced features of the sound system?


Sat Aug 16, 2008 10:56 pm
Profile
Creator
Creator

Joined: Fri Feb 09, 2007 9:21 am
Posts: 615
Post Re: Bug when using random and PlayTone
The problem with WAV files is that they are way too memory intensive.

First generation WAV files on the NXT supported simple uncompressed RAW PCM samples using operating at 8K Hz. This means 8K bytes per second of WAV. 8KHz is essentially telephone call quality. CD quality music is 44 KHz and 16-bit samples.

Second generation uses a simple 2:1 compression to reduce the memory requirements 50% at nearly the same audio quality.

"Play tone" is much more memory efficient requiring only a few bytes per tone.

MIDI sequencer functionality is not really an option for the NXT. it would be all firmware code of what I think are fairly real-time intensive calculations. Even for a "single MIDI stream" -- I don't know the real term for this.

I also forgot to mention that NXT "Play Tone" only knows how to generate sine waves. MIDI requires square, sawtooth, etc. In fact, I think current generation MIDI synthesizers have separate "WAV" files for each type of instrument -- piano, trumpet, violin, ....

And then you have to worry about decay. The volume goes down over time.

I only know enough about MIDI to have concluded a while back that it wasn't realistic to build a bare bones capability into the NXT.


Sun Aug 17, 2008 10:58 pm
Profile
Rookie

Joined: Sat Aug 09, 2008 7:18 pm
Posts: 17
Post Re: Bug when using random and PlayTone
I was more curious whether or not there could be some more advanced interface to the speaker of the NXT. Currently we can play sounds either by calling PlayTone or PlaySoundFile. I would like a more direct interface into the speaker so that I can generate my own waveforms at runtime using math functions, control the volume level of the waveforms, potentially do some polyphony ( playing multiple notes at once ) by mathematically combining waves of different pitches at runtime. I'm not really looking at doing midi, though the data for midi songs is small and could potentially be worked into a sound system that generates tones on the fly. Modern midi synths do in fact have samples for every instrument and usually for every note. The data for that would be far too much, though it is conceivable that you could store a very small library of wave samples that could be controlled by midi or similar data. Even without midi, the ability to generate procedural waveforms (other than those generated by PlayTone or PlaySoundFile ) would open up a lot of possibilities for sound on the NXT.

My arpeggiator is not intended to be a midi synth, by the way. Basically what it is is a way to generate notes in a controlled random way. In its simplest form, it allows you to define a chord or scale formula and the arpeggiator randomly selects notes from that. I've already provided it with a lot more advanced control features as well. You can define rhythmic patterns and note selection patterns ( for instance, if on beat 2 you only want it to select from a limited number of notes in the chord or scale, you can define that in the pattern). You can set other parameters, such as linearity ( the likelihood that the next note selected will be only one chord or scale tone away from the previous one, making the selected notes sound more melodic ), linear direction change ( the likelihood that the linear direction, ascending or descending will be changed at the time of note selection ), syncopation ( the likelihood of inserting a random rest ), legato ( duration of the note as a fraction of it's rhythmic value on the staff ) and more. Depending on the parameters you give it it can be either completely random or completely controlled. You could set up a pattern that is intended to be completely controlled and then simply swap chord formulas to change chords. This works similarly to how the "styles" on many cheap portable keyboards work. Basically, the style consists of a pattern of notes representing the bassline, keyboard part, drums, etc., but these notes are relative to a root tone and a chord formula, so that when you play a chord on the keys, the keyboard automatically updates all of the accompanying instruments to play the pattern using the new chord formula. In this way you can generate musical accompaniment for an entire song with only slightly more data than would be required for one or two measures of midi. Without polyphony, that has limited applications, but its still kind of cool. To non-musicians this probably all sounds really complicated, and it sort of is. To make it simpler I can provide a bunch of simple templates from which people can generate a variety of sounds.

Just some examples of sounds that I can make with the arpeggiator now. I'll describe them based on what I think they sound like

Slot machine win - to me it sounds like an old slot machine when you win the jackpot. This is simply a major triad played over multiple octaves ascending at a very fast tempo.

Confused - random notes from a whole tone scale played as 8th notes at 120 bpm. Sort of sounds like the robot is thinking and is slightly confused

Wandering - random notes played from a 13th chord as swinging 8th notes at 120 bpm. Sounds like the robot is casually wandering around without a care in the world. I use this for my TableBot ( a bot that wanders around my table top using sonar to detect the edges and avoid falling ). When its wandering it plays the 13th chord, then when it gets to the edge it plays a different, less pleasant sound effect, then it goes back to playing the happy wandering song once it has turned back around and is wandering about the table again.

The soloist - giving the arpeggiator a scale and setting the linearity high and the linear change rate to a low value greater than 0 makes the robot play a melody which is random, yet melodic.

Controlled noise - playing random notes of a chord extremely fast sounds like noise, while retaining a harmonic quality.


To really take advantage of the arpeggiator and the sound effects, I would need some more advanced interface to the speaker than just PlayTone or PlaySoundFile. If I can combine the arpeggiator with waveform generation I think I could make a lot of cool sounds with a very small data set.


Sun Aug 17, 2008 11:50 pm
Profile
Rookie

Joined: Sat Aug 09, 2008 7:18 pm
Posts: 17
Post Re: Bug when using random and PlayTone
Basically what I am saying is that I am interested in contributing to software or firmware which enhances the sound capabilities of the NXT, and I have some ideas about how to do that, but without some more advanced functionality than PlayTone and PlaySoundFile what I can do is really limited. Until then I'll keep working on the arpeggiator until I feel its reached its maximum potential.


Mon Aug 18, 2008 1:34 am
Profile
Creator
Creator

Joined: Fri Feb 09, 2007 9:21 am
Posts: 615
Post Re: Bug when using random and PlayTone
What functionality do you need?

Hee's how the firmware/hardware works.

Firmware generates a very fast bit stream to the speaker using DMA so that there is "minimal" CPU overhead. The "density" of the bit stream (i.e. the percentage of "ones" in the bit stream) indicates the "voltage" level that is applied to the speaker.

The DMA buffer hardware on the NXT allows it to specify 256 bits (8 x 32-bits) at a time to send to the speaker.

For WAV files, the NXT hardware is interrupted for every sample. The sample is 8-bits. The sample value is translated into a 256-bit pattern with the number of ones in the pattern equal to the sample value. This pattern is then output to the speaker. The interrupt rate is set to the sampling rate (normally 8K Hz) of the WAV file. So the NXT is being interrupted every 8 KHz and doing some relatively simply calculations to calculate the bit stream to the speaker.

For tones, a little bit different technique is used. The interrupt rate for the sound hardware is set to twice the frequency of the tone. On every interrupt, the 256-bit DMA buffer is set up with a pattern that approximates half a cycle of a sine wave. It's actually 8 samples of 4-bits; the samples for lowest volume are 0,1,3,3,4,3,3,1 which is the crude approximation of a sine way. The pattern alternates between positive values (above) and negative values (0,-1,-3,-3,-4,-3,-3,-1) to give a full cycle.

The 256-bit maximum DMA buffer size is fixed in the hardware/silicon. And it's double buffered so that the interrupt is used to calculate the next values while the values calculated on the prevous interrupt are played. This is why the approximate sine wave is 8 samples -- it takes 32-bits to create "ones density" for the 4-bit value and 1-bit sign value and 8 x 32 is 256.

The volume level (0 to 4) is used as an appropriate modifier to adjust the calculations.

It's not reasonable to do much more calculations that above. The types of things that are feasible include:
  1. Providing other simple waveforms -- square and sawtooth -- besides the sine wave.
  2. Adding some kind of simple algorithm to modify the volume over time. All within the limit of 2-bit volume.
  3. It might be feasible to generate and mix a couple of simultaneous notes at once using the algorithm for playing WAV files. At every interrupt rather than looking up the next sample for a WAV file, its done by calculation to determine the current "sample" for a note. For multiple notes, the values are added together. The challenge for this is that it should be all fixed point calculations -- floating point is too real time expensive -- and very simple. And no more than about 10 lines of C-code total per sample for the calculations.
  4. Instead of playing a WAV file, provide an interface where user program provides a sample rate and an array of values to output. With/without a continuous looping option. That way, user application could calculate the samples at its leisure without regard to real-time and then have them played back in real-time.
Does any of above seem reasonable for providing more sound functionality?


Mon Aug 18, 2008 8:50 am
Profile
Rookie

Joined: Sat Aug 09, 2008 7:18 pm
Posts: 17
Post Re: Bug when using random and PlayTone
Now we are talking! :D I need a bit to digest all of this. Conceptually it all makes sense to me because I do a lot of recording with both audio and midi, and I have the programming background to understand how it works, but I've not actually done any low level audio programming before. Here are my initial thoughts:

1. Providing other simple waveforms -- square and sawtooth -- besides the sine wave.

This sounds very simple and could be added to extend the functionality of play tone. You said the sine wave sample is 8 samples of 4 bits which represents half of a sine wave. You could have a function called SetToneWaveform which takes a 32 bit value representing half of a waveform. Then you can predefine 32 bit values for square wave, sawtooth, etc., and for the more adventurous, allow us to create our own waveforms, dynamically in real time. This is the beginning of a synthesizer.

2. Adding some kind of simple algorithm to modify the volume over time. All within the limit of 2-bit volume.

If RobotC already has some volume control capability I must have overlooked it. From your post it sounds as though it supports 4 volume levels for PlayTone. If this is already there it's trivial to add volume control over time.

3. It might be feasible to generate and mix a couple of simultaneous notes at once using the algorithm for playing WAV files. At every interrupt rather than looking up the next sample for a WAV file, its done by calculation to determine the current "sample" for a note. For multiple notes, the values are added together. The challenge for this is that it should be all fixed point calculations -- floating point is too real time expensive -- and very simple. And no more than about 10 lines of C-code total per sample for the calculations.

This is the thing that I am really interested in. I would like to have a go at implementing 2,3,or 4 note polyphony by mixing waves together at real time.

4. Instead of playing a WAV file, provide an interface where user program provides a sample rate and an array of values to output. With/without a continuous looping option. That way, user application could calculate the samples at its leisure without regard to real-time and then have them played back in real-time.

This would be awesome. That's exactly what I was hoping for.


Mon Aug 18, 2008 10:38 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 17 posts ]  Go to page 1, 2  Next

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.