I have the need for a FUNCTION:

Transpose($Song, $direction)

The logic I need is pretty straight forward, but I am having a hard time replicating it using PHP functions. I will try to break it down to it's simplest form:

I have a field that has several lines of text. Chords and Song Lyrics.

The "Chord" lines begin with an asterisk "*" (first character) and end with the line break. These are the strings I want to parse. Lines with NO asterisk at the beginning are ignored.

Based on 3 arrays of NOTES, I want SUBSTITUTE the text (based on exact text character patterns - just NOTES not the chord type) of the lines in my field that start with an asterisk "*".

original_chord_array = A, A#, B, C, C#, D, D#, E, F, F#, G, G#
transpose_up_array = A#, B, C, C#, D, D#, E, F, F#, G, G#, A
transpose_down_array = G#, A, A#, B, C, C#, D, D#, E, F, F#, G

It is important that it only effects EXACT strings. Notes will always be capitalized and chord types will be lower case. Maybe we can use that characteristic to better identify what to change. Here are some examples of chords:

A
Asus7
Csus add9
Dmaj7
F#m7
G#
C#dim no3

When I transpose UP these chords, just the NOTE should change:

A#
A#sus7
C#sus add9
D#maj7
Gm7
A
Ddim no3

When I transpose DOWN these chords, just the NOTE should change:

G#
G#sus7
Bsus add9
C#maj7
Fm7
G
Cdim no3

Hopefully this break down is clear and someone will bail me out ;-)

Thanks again for the feedback.

Member Avatar for diafol

OK, should be straightforward. You need to set up a multidimensional array - or you can stick with your 3 arrays. However, it may be useful to place all the sharps first. This means that your replacement function will search for these first. If a match is made - you replace and then move on to the next part of the string. If you replaced with the 'normal' note, you'd end up incorrectly replacing a sharp note.

$trans = array(
  'actual' = array("A#","C#"...),
  'up' = array("B","D"...),
  'down' = array("A","C"...)
);

You can use a preg_replace() function - although regex is still beyond me after all these years! So if you want to use that, look it up or perhaps a kind soul on this forum could give you a hand.

My own solution would be to:

This is pseudocode/procedure:

1. explode the string into lines (using the line break as a delimiter)
2. for each line - if it begins with a * - throw it into your transpose function **
3. implode the lines back into a full string

**I'm unsure if you have more than one note/key/chord/whatever in one line.

If just one chord
For each line: loop through the 'actual' and search for a match - if found - replace and exit the loop. Your substring search will need to be case sensitive.

If many chords in one line:
Explode the line using the 'space' as a delimiter - now loop over the bits and then implode back into a line.

Perhaps I've over-egged it?!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.