programming forums Java Java JSRs Mobile Certification Databases Caching Books Engineering OS Languages Paradigms IDEs Build Tools Frameworks Products This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
Sheriffs:
Saloon Keepers:
Bartenders:

# Major Scale & Sequence Loop

Greenhorn
Posts: 7
Hello, first time posting here!!

I'm trying to figure out how to print the Major Scale of any give note in music. It works as follows: There are 12 notes and each note is assigned a number C = 0, C# = 1, D = 2, D# = 3, E = 4, F = 5, F# = 6, G = 7, G# = 8, A = 9, Bb = 10, B = 11. After picking a random note, say F, the idea is to add the following sequence to move through the scale: 0, +2, +2, +1, +2, +2, +2, +1. So, with F being 5, we move through the scale as 5, 7, 9, 10, 0, 2, 4, 5. The theory is unimportant but, as you can see, the sequence loops back on itself, rather than continue past 11. This is where I'm stuck, though. I'm not clear on how to loop my numbers around in code. I'll show my attempt here:

For the sake of simplicity I haven't shown the entire script of 'if' statements, but you get the idea.

0, 2, 4 (For C)
5, 7, 9 (For F)
10 (For Bb)

The last line demonstrates the problem, as I need it read as 10, 0, 2.
I've tried different approaches, but wanted to convey the basic problem with this post. Can anyone help? Many thanks.

Sheriff
Posts: 4293
127
Welcome to the Ranch, Daniel.

How about trying a modulo function?

Daniel Witheridge
Greenhorn
Posts: 7
Thanks for responding. I've been looking around at examples on modulos & I've tried implementing it into my code, as follows.

The numbers I'm getting are a bit...odd. Should I be working the modulo into the 'for' loop, or am I on the right track? Apologies for the confusion here, as I've only really started Java as of today!!

Ranch Hand
Posts: 104
1
You can use a header to read notes from an array. You'll also use a header count to learn the header's position. As you read from the note array, the count will increase or decease accordingly.

If the header count exceeding 11th position, then the counter will set the head back to position zero.

There are many solutions, but I think this would be one of the easiest one to implement.

Marshal
Posts: 56610
172
That does sound a good idea. Search for a circular array and find out how it works. I think you will find that Quazi Irfan has described a circular array but not by that name.

Alternatively consider a circular linked list where the final node (B) links back to the first one (C).

Ranch Hand
Posts: 55
You can remove the second condition of the if statement and print using the mod operator.

Greenhorn
Posts: 17
You can try using collections to do the hard work.

Daniel Witheridge
Greenhorn
Posts: 7
Sorry for the delay, here. A lot of this is new to me and my mind is in a bit of a whirlwind on the approach.

James Harte: Your code prints out 'exactly' what I'm looking for, but in the context of the problem I won't be able to make use of import java.util.ArrayList;. Instead, I'll have to call my own function in the main method.

Knute/ Irfan/ Ritchie/ King: You'll have to forgive my ignorance, but a lot of the theory is going right over my head. I've checked for circular arrays online, but it's still very confusing to me. Maybe if I begin again with a more simple example of just looping around a circular array that only increments by 1? The following sample of code isn't correct, but it's the closest example of an answer I can give based on what I think I know so far:

Any help is greatly appreciated.

Many thanks.

Campbell Ritchie
Marshal
Posts: 56610
172
Beware of long lines; I have broken them by changing the // comments to /* comments */
I think you are going round in circles, and I think you need to start again. Turn your computer off. Consider the following three arrays:-Write the top array down on paper and against it write the offsets from C. You will find the offsets exactly the same as the array indices.

Now start from a particular note, say F which you have already decided is offset 5. Repeatedly add the elements of a scale to it, then take the remainder when divided by 12. you should now be able to see how to use the remainder operator. You also see that you go up to the end of the array and then go back round to its beginning. If you go on long enough you end up going round in circles, which is why it is called a circular array.

Try the following two Unicode escapes: \u266d = ♭ \u266f = ♯

If you have a descending scale you wouldn't be able to use remainder; you would have to add 12 if the number goes negative. Otherwise you get negative remainders.
Now what are you going to do when you are in B♭minor and need D♭ instead of C♯ ?

Campbell Ritchie
Marshal
Posts: 56610
172
Darryl Burke contacted me to point out there is a simple example of a circular array on another forum.

Campbell Ritchie
Marshal
Posts: 56610
172
Actually, I don&apost think there is actually an array in that example.

Daniel Witheridge
Greenhorn
Posts: 7
Ok, I'm still confused so I'll try something different here.
What if instead of a circular array, I had all the note sequences pre-written into a 2x2 array and call them that way...?

The problem now is that I don't know how to call a specific line. Can anyone help?

Bartender
Posts: 3271
82
Some time ago I was messing around with a problem and wrote a CircularLinkedList class. Don't know if it will help, it may be a bit of an overkill for what you need, but here's the code in case you can use it.
To be honest I can't remember if I even fully tested this code but at a quick glance it looks ok.

To use it for your purposes: Create a CircularLinkedList object sized at the number of notes and add the notes in order. Then use get(i) to get the appropriate note (get will silently handle the wrapping).

Knute Snortum
Sheriff
Posts: 4293
127
Daniel Witheridge wrote:The problem now is that I don't know how to call a specific line. Can anyone help?

By "call a specific line" do you mean how do you know what's Bb or C, etc.? You could use a Map with the scale name as the key and the array index as the value.

Daniel Witheridge
Greenhorn
Posts: 7
Tony: Oh, jeez! I've only just started Java as of this week, but that looks light years ahead of what I'm capable of. Thanks for responding Tony, but I'm still struggling with basic concepts as it is and this is like handing a child the complete works of Shakespeare!!

Knute Sortum: If I can just break away for a moment to follow up on my previous post. I have tried a different approach with defining the arrays, to get around lumping them into 1 single set as follows:

Regarding the original question, if I wanted to call one of these note sequences from a starting function taking an argument whose number represents one of the note array positions, how would I do this? What I mean is, similar to how I defined the 'scale function' to take the initial numbers in the 1st post and 'then' called and printed the relevant note arrays in the 'majorScaleOf function' that followed.

I hope that makes sense...

*Edit*: I just saw your new post following this one, after the fact. Would my new approach be better, or should I stick with that last method you were responding to...?

Knute Snortum
Sheriff
Posts: 4293
127
However you setup an array of arrays will be fine, but if you use the same index in the outer array (like you're doing) you don't need a Map to point to the outer array.

However, are enharmonic notes going to be a problem? Or will you convert them into the correct index before the call?

Tony Docherty
Bartender
Posts: 3271
82
Daniel Witheridge wrote:Tony: Oh, jeez! I've only just started Java as of this week, but that looks light years ahead of what I'm capable of. Thanks for responding Tony, but I'm still struggling with basic concepts as it is and this is like handing a child the complete works of Shakespeare!!

Sorry I hadn't realised you'd only just started Java, I just saw the earlier posts where someone was suggesting using a circular array.

Daniel Witheridge
Greenhorn
Posts: 7
Thanks for responding, Knute. I'll double check that as I go. I have a feeling my first attempt was probably the closest, as I have yet to encounter anything to do with circular arrays in the material I'm following. For the purpose of this exercise it may be a bit like trying to heat a cup of tea with a hadron collider.

Campbell Ritchie
Marshal
Posts: 56610
172
No, my approach was the closest: work it all out on paper first, with a pencil and eraser. That latter is very important because you will have to destroy the evidence correct your errors.

When you have something working on paper, remembering taht I have supplied you with an array of note names, then you can convert it to code.

Daniel Witheridge
Greenhorn
Posts: 7
Ok. Thank you for sticking with me.

Campbell Ritchie
Marshal
Posts: 56610
172
Show us what you wrote on the paper.