wysocki Posted June 14, 2016 Share Posted June 14, 2016 I write a lot of music chord sheets for the guys in my band, both from original and cover songs. I start off with just putting it down in a text file with chords on one line and then the lyrics on the next like this: Gm Cm7 F Bb Times are hard You're afraid to pay the fee Eb Ab Bb F/A Eb/G F Eb So you find yourself somebody Who can do the job for free Many times after I write it all out, I'll want to transpose the key up or down a few steps and it's a pain to go through manually and change my chords. I know there are music programs that allow you to enter your music there and they can do the transposing, but I'd like to write a little Autoit script to be able to just take my text file, find the chords, transpose them by an inputted amount, and then allow me to either rewrite the file or just display it onscreen first. Sounded easy, until I tried it! I thought I'd just scan the input file for capital letters and rotate them up or down a few notches. UNLESS they're part of the lyrics. Then what about "#" and "b"? How do I recognize "Adim" as a chord and not part of some lyric? Gets to be a real mess! Has anyone ever ventured into this kind of project? Any tips on how to go about it? Link to comment Share on other sites More sharing options...
iamtheky Posted June 15, 2016 Share Posted June 15, 2016 I suppose if you knew the steps yourself, used only flats (as adding sharps and naturals would make the transposition harder). You could get away with stepping the notes yourself. This probably has many flaws and is really only acceptable as pseudo code: #include <array.au3> $str = "Gm Cm7 F Bb" & @LF & _ "Times are hard You're afraid to pay the fee" & @LF & _ " Eb Ab Bb F Eb F Eb" & @LF & _ "So you find yourself somebody Who can do the job for free" $aStr = stringsplit($str , @LF , 2) for $i = 0 to ubound($aStr) - 1 step 2 $aStr[$i] = stringregexpreplace($aStr[$i] , "\s+" , " ") $aChords = stringsplit(stringstripWS($aStr[$i] , 1) , " " , 2) $aChordTranspose = _Transpose(-2 , $aChords) _ArrayDisplay($aChordTranspose) next Func _Transpose($halfsteps , $array) Local $aNotes = ["Bb" , "B" , "C" , "Db" , "D" , "Eb" , "E" , "F" , "Gb" , "G" , "Ab" , "A" ,"Bb" , "B" , "C" , "Db" , "D" , "Eb" , "E" , "F" , "Gb" , "G" , "Ab" , "A" , "Bb" , "B" , "C" , "Db" , "D" , "Eb" , "E" , "F" , "Gb" , "G" , "Ab" , "A"] For $i = 0 to ubound($array) - 1 $sTarget = stringregexp($array[$i] , "(\Db*)" , 3)[0] $aMatches = _ArrayFindAll($aNotes , $sTarget) $array[$i] = stringreplace($array[$i] , $sTarget , $aNotes[$aMatches[1] + $halfsteps]) Next _ArrayDisplay($array , $halfsteps & " Steps") EndFunc ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__) Link to comment Share on other sites More sharing options...
czardas Posted June 15, 2016 Share Posted June 15, 2016 (edited) This is not too difficult! Make a transposition table with intervals and note names (2D array). Search for the note in your table and read the transposed note name directly from the table. Name 1 2 3 4 <== semitones C C# D Eb E C# D Eb E F Db D Eb E F D Eb E F F# Whether you use sharps or flats is up to you. You could respell the names after transposition anyway. You will probably want to avoid double sharps and double flats. Any problems, then post your attempt. Edit: To transpose down, use (12 - interval). @iamtheky's method is also good, and a bit easier to implement. Edited June 15, 2016 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
mikell Posted June 15, 2016 Share Posted June 15, 2016 @czardas Hehe, not so easy to get exactly the wanted result ... Here is my try... the pattern should be better defined of course #include <Array.au3> $str = "Gm Cm7 F Bb" & @crlf & _ "Times are hard You're afraid to pay the fee" & @crlf & _ " Eb Ab Bb F/A Eb/G F Eb" & @crlf & _ "So you find yourself somebody Who can do the job for free" & @crlf Msgbox(0,"", $str) Msgbox(0,"", _Transpose($str, 2) ) Func _Transpose($song, $step) Local $aNotes = ["Bb" , "B" , "C" , "Db" , "D" , "Eb" , "E" , "F" , "Gb" , "G" , "Ab" , "A"] If $step < 0 Then $step = 12 + $step $pattern = '([A-Z]b?)(?=\s|/|m7?|dim|$)' $tmp = Execute('"' & StringRegExpReplace($song, $pattern, '" & $aNotes[Mod(_ArraySearch($aNotes, "$1")+$step, 12)] & "') & '"') Return $tmp EndFunc czardas 1 Link to comment Share on other sites More sharing options...
mLipok Posted June 15, 2016 Share Posted June 15, 2016 @wysocki I think you would be interested in look here: czardas 1 Signature beginning:* Please remember: "AutoIt"..... * Wondering who uses AutoIt and what it can be used for ? * Forum Rules ** ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Code * for other useful stuff click the following button: Spoiler Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST API * ErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 * My contribution to others projects or UDF based on others projects: * _sql.au3 UDF * POP3.au3 UDF * RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF * SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane * Useful links: * Forum Rules * Forum etiquette * Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * Wiki: * Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX IE Related: * How to use IE.au3 UDF with AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskScheduler * IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related: * How to get reference to PDF object embeded in IE * IE on Windows 11 * I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions * EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *I also encourage you to check awesome @trancexx code: * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuff * OnHungApp handler * Avoid "AutoIt Error" message box in unknown errors * HTML editor * winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/ "Homo sum; humani nil a me alienum puto" - Publius Terentius Afer"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming" , be and \\//_. Anticipating Errors : "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty." Signature last update: 2023-04-24 Link to comment Share on other sites More sharing options...
czardas Posted June 16, 2016 Share Posted June 16, 2016 (edited) I guess I can't keep this from your inquisitive minds any longer. I have some libraries which are totally overkill for this. Actually I have written a lot of stuff but it's still no where near ready for release. Here is a small sample from a few years back. The theory is too difficult to explain, but you might want to research it yourself. To understand this, you also need to understand formulaic chord/scale construction. The last row gives the number of semitones. Actually harmonic construction and transposition are not the same thing, but this covers the full range of note names and musical intervals. It might give you some ideas. A typical chord formula might look like this: p1, mi3, dim5, dim7 (diminished seventh). Func _LoadIntervalMap() Local $aTemp[10][32] = _ [["1","#1","b2","2","bb3","#2","b3","3","b4","#3","4","#4","b5","5","bb6","#5","b6","6","bb7","#6","b7","7","b8","b9","9","#9","b10","b11","11","#11","b13","13"], _ ["C","C#","Db","D","Ebb","D#","Eb","E","Fb","E#","F","F#","Gb","G","Abb","G#","Ab","A","Bbb","A#","Bb","B","Cb","Db","D","D#","Eb","Fb","F","F#","Ab","A"], _ ["D","D#","Eb","E","Fb","E#","F","F#","Gb","Fx","G","G#","Ab","A","Bbb","A#","Bb","B","Cb","B#","C","C#","Db","Eb","E","E#","F","Gb","G","G#","Bb","B"], _ ["E","E#","F","F#","Gb","Fx","G","G#","Ab","Gx","A","A#","Bb","B","Cb","B#","C","C#","Db","Cx","D","D#","Eb","F","F#","Fx","G","Ab","A","A#","C","C#"], _ ["F","F#","Gb","G","Abb","G#","Ab","A","Bbb","A#","Bb","B","Cb","C","Dbb","C#","Db","D","Ebb","D#","Eb","E","Fb","Gb","G","G#","Ab","Bbb","Bb","B","Db","D"], _ ["G","G#","Ab","A","Bbb","A#","Bb","B","Cb","B#","C","C#","Db","D","Ebb","D#","Eb","E","Fb","E#","F","F#","Gb","Ab","A","A#","Bb","Cb","C","C#","Eb","E"], _ ["A","A#","Bb","B","Cb","B#","C","C#","Db","Cx","D","D#","Eb","E","Fb","E#","F","F#","Gb","Fx","G","G#","Ab","Bb","B","B#","C","Db","D","D#","F","F#"], _ ["B","B#","C","C#","Db","Cx","D","D#","Eb","Dx","E","E#","F","F#","Gb","Fx","G","G#","Ab","Gx","A","A#","Bb","C","C#","Cx","D","Eb","E","E#","G","G#"], _ ["p1","aug1","mi2","ma2","dim3","aug2","mi3","ma3","dim4","aug3","p4","aug4","dim5","p5","dim6","aug5","mi6","ma6","dim7","aug6","mi7","ma7","dim8","mi9","ma9","aug9","mi10","dim11","p11","aug11","mi13","ma13"], _ [0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,13,14,15,15,16,17,18,20,21]] Return $aTemp EndFunc NB: To use the 1D array method suggested by others, you might want to use the following simplified (mixed) sequence:C, C#, D, Eb, E, F, F#, G, Ab, A, Bb, B . . . my recommendation! for the 12 chord root names within the octave. The sequence conforms to the most commonly found chord roots. It's not theoretically correct to do this, but it is common practice to ignore such subtleties and also quite a practical solution. Edit: Also this can be used to respell note names (R stands for root): Func _LoadEnharmonicEquivalents() Local $aTemp[8][5] = _ [["R","bb","b","#","x"],["C","Bb","B","Db","D"],["D","C","C#","Eb","E"],["E","D","D#","F","F#"], _ ["F","Eb","E","Gb","G"],["G","F","F#","Ab","A"],["A","G","G#","Bb","B"],["B","A","A#","C","C#"]] Return $aTemp EndFunc @mikell Very nice. Edited June 16, 2016 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
mikell Posted June 16, 2016 Share Posted June 16, 2016 (edited) czardas, Following your recommendation I suggest this #include <Array.au3> $str = "Gm Cm7 F# Bb" & @crlf & _ "Times are hard You're afraid to pay the fee" & @crlf & _ " Eb Ab Bb F/A Eb/G F Eb" & @crlf & _ "So you find yourself somebody Who can do the job for free" & @crlf ;Msgbox(0,"", $str) Msgbox(0,"", _Transpose($str, -2, 1) ) Func _Transpose($song, $step, $mix = 0) If $mix = 0 Then Local $aNotes = ["Bb" , "B" , "C" , "Db" , "D" , "Eb" , "E" , "F" , "Gb" , "G" , "Ab" , "A"] Else Local $aNotes = ["Bb" , "B" , "C" , "C#" , "D" , "Eb" , "E" , "F" , "F#" , "G" , "G#" , "A"] EndIf $pattern = '([A-G][b#]?)(?=\s|/|[45679]|m[45679]?|dim|$)' $tmp = Execute('"' & StringRegExpReplace($song, $pattern, _ '" & $aNotes[Mod(_ArraySearch($aNotes, "$1")+12+$step, 12)] & "') & '"') Return $tmp EndFunc still in the context of the OP's asking "a little Autoit script to be able to just take my text file, find the chords, transpose them by an inputted amount, and then allow me to either rewrite the file or just display it " As you said, the chord transposition is not too difficult by itself, but the text-file-in/text-file-out thing was a pretty tricky challenge BTW your mus++ is ... totally insane, fantastic. Seriously, this deserved a handy user manual and/or a cute gui so the common user could plainly understand and appreciate the power and acuteness of this script Edited June 16, 2016 by mikell czardas 1 Link to comment Share on other sites More sharing options...
czardas Posted June 16, 2016 Share Posted June 16, 2016 That's much more flexible. 1 hour ago, mikell said: the text-file-in/text-file-out thing was a pretty tricky challenge That's why I left that to you. One thing I'm curious about though - you used G# instead of Ab. Actually this is a 50/50 case. You will often see brass instruments tuned to Bb or Eb. Likewise there are a whole range of instruments tuned to keys containing sharps: G major contains F#, and D major contains F# and C#. The notes G# = Ab have an equal likelihood of occurrence. So what you did still fits well with my suggestion. A more theoretical treatment would be overkill for this particular purpose IMO. 2 hours ago, mikell said: your mus++ is ... totally insane, fantastic. I very much appreciate you saying this. Thanks! operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
mikell Posted June 16, 2016 Share Posted June 16, 2016 (edited) 1 hour ago, czardas said: One thing I'm curious about though - you used G# instead of Ab This is not a specific choice ... when I formerly began to learn guitar I got a lot of sheet music using this chord notation, and this habit still remains Anyway my code is mainly for the concept, it allows the OP to easily populate the array according to his particular needs - and also to modify the pattern if I forgot/missed something Edit the pattern should be amended indeed - it produces strange results if the lyrics contain "Eminent, "Amplitude" etc Edited June 16, 2016 by mikell Link to comment Share on other sites More sharing options...
Jfish Posted June 16, 2016 Share Posted June 16, 2016 @czardas - I had not seen your mus++ before. That is the craziest most fantastic thing. I am not a musician - nor do I know how to read music but such a cool script. Great job. czardas 1 Build your own poker game with AutoIt: pokerlogic.au3 | Learn To Program Using FREE Tools with AutoIt Link to comment Share on other sites More sharing options...
czardas Posted June 16, 2016 Share Posted June 16, 2016 (edited) 4 hours ago, mikell said: when I formerly began to learn guitar I got a lot of sheet music using this chord notation It is indeed more typical for guitar music to use more sharps than flats: this has everything to do with tuning and the ease with which the most common chord shapes can be reached by the fingers. Anyway I fear we veer slightly away from the topic, because this was not necessarily a guitar specific question. I tend to get carried away on subjects like this. Edit: I think you need to separate the chords from the lyrics and recombine after transposition. You can't predict the type of nomenclature used for the chord quality and there's a lot of disparity in song sheets - different symbols used etc... It's an outrageous task to try and cover every convention. I wouldn't say it's impossible, but I pity anyone who tries. I gave up this particular idea because some conventions appear to collide. I may look at it again in the future. Edited June 16, 2016 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
mikell Posted June 16, 2016 Share Posted June 16, 2016 (edited) 1 hour ago, czardas said: I think you need to separate the chords from the lyrics and recombine after transposition. This IS the reason why it's tricky Edit In fact I first tried this way (doing something like iamtheky did) but a tiny headache advised me to give it up. I would by far prefer to build a 2-lines regex pattern if necessary Edited June 16, 2016 by mikell Link to comment Share on other sites More sharing options...
iamtheky Posted June 16, 2016 Share Posted June 16, 2016 I think if you write the transposition, you should be able to set the parameters for the sheet music syntax. There are way too many notations, and novice folk like me who screw it up and call F/A something like FaddA, when everyone else is screaming that it already has an A in it. And I'm like, but I'm adding another? ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__) Link to comment Share on other sites More sharing options...
Malkey Posted June 16, 2016 Share Posted June 16, 2016 Here is an interface based on mikell's example. When using this example, a feature or problem found is when "Chord List# 2" and a "Transpose Value" of 0 is selected. There is no "Ab" in "Chord List# 2" to be displayed in the modified text. So, nothing is displayed in the "Modified Text" edit control. expandcollapse popup#include <Array.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <UpDownConstants.au3> #include <StaticConstants.au3> #include <FileConstants.au3> #include <WinAPI.au3> TranspostKeys() Func TranspostKeys() Local $sFileSaveDialog, $tPosS, $id Local $sComboDat, $sTTip Local $aNotes = _ ['Bb,B,C,Db,D,Eb,E,F,Gb,G,Ab,A', _ 'Bb,B,C,C#,D,Eb,E,F,F#,G,Ab,A', _ 'Bb,B,C,C#,D,Eb,E,F,F#,G,G#,A'] For $i = 0 To UBound($aNotes) - 1 $sComboDat &= "Chord List# " & $i & "|" $sTTip &= "Chord List# " & $i & " = " & $aNotes[$i] & @CRLF Next $sComboDat = StringTrimRight($sComboDat, 1) ; Remove trailing "|" ;_ArrayDisplay($aNotes) Local $str = "Gm Cm7 F Bb" & @CRLF & _ "Times are hard You're afraid to pay the fee" & @CRLF & _ " Eb Ab Bb F/A Eb/G F Eb" & @CRLF & _ "So you find yourself somebody Who can do the job for free" & @CRLF Local $hGui = GUICreate("Transpose Keys", 606, 906, -1, -1, $WS_SIZEBOX) GUISetFont(10, 400) Local $idChdLab = GUICtrlCreateLabel("Select Chord List >", 140, 6, 125, 25) Local $idCombo = GUICtrlCreateCombo("Chord List# 0", 260, 3, 130, 25) GUICtrlSetData($idCombo, StringTrimLeft($sComboDat, 14)) Local $idOpen = GUICtrlCreateButton('Open a chord file', 395, 3, 170, 26) GUICtrlCreateLabel("Original Text", 3, 14, 100, 20, -1, $WS_EX_CLIENTEDGE) Local $idOrig = GUICtrlCreateEdit($str, 3, 33, 600, 400) GUICtrlCreateLabel("TransposeValue", 20, 443, 110, 20) Local $idInput = GUICtrlCreateInput("-2", 130, 443, 80, 20) GUICtrlCreateUpdown($idInput, BitOR($UDS_ALIGNRIGHT, $UDS_WRAP, $UDS_NOTHOUSANDS)) Local $idTranspose = GUICtrlCreateButton("Run Transpose", 250, 440, 120, 26) Local $idSave = GUICtrlCreateButton('Save "Modified Text" As', 395, 440, 170, 26) GUICtrlCreateLabel("Modified Text", 3, 467, 100, 20, -1, $WS_EX_CLIENTEDGE) Local $idMod = GUICtrlCreateEdit(_Transpose($str, $aNotes[StringRegExpReplace(GUICtrlRead($idCombo), "\N", "")], GUICtrlRead($idInput)), 3, 486, 600, 400) GUISetState(@SW_SHOW) While 1 ; ------ ToolTip -------- $id = _WinAPI_GetDlgCtrlID(_WinAPI_WindowFromPoint(_WinAPI_GetMousePos())) If $id = $idChdLab Or $id = $idCombo Then ToolTip($sTTip) Else ToolTip("") EndIf ; --- End of ToolTip ----- Sleep(10) Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idOpen Local $sFileOpenDialog = FileOpenDialog("Open a Chord file", "", "Text (*.txt)|All Files (*.*)", $FD_FILEMUSTEXIST) If $sFileOpenDialog <> "" Then GUICtrlSetData($idOrig, FileRead($sFileOpenDialog), "") EndIf Case $idTranspose $iList = StringRegExpReplace(GUICtrlRead($idCombo), "\D", "") GUICtrlSetData($idMod, _Transpose(GUICtrlRead($idOrig), $aNotes[$iList], GUICtrlRead($idInput)), "") Case $idSave $sFileSaveDialog = FileSaveDialog("Choose a filename.", "::{450D8FBA-AD25-11D0-98A8-0800361B1103}", "Text (*.txt)|All Files (*.*)", $FD_PATHMUSTEXIST, "Modified.txt") If $sFileSaveDialog <> "" Then If FileExists($sFileSaveDialog) Then $iMsgB = MsgBox(4, "Replace Existing File", '"' & $sFileSaveDialog & '" aready exists.' & @CRLF & @CRLF & 'Press "Yes" to continue, and, replace the contents of this file.') If $iMsgB = 6 Then FileDelete($sFileSaveDialog) FileWrite($sFileSaveDialog, GUICtrlRead($idMod)) EndIf Else FileWrite($sFileSaveDialog, GUICtrlRead($idMod)) EndIf EndIf EndSwitch WEnd GUIDelete() EndFunc ;==>TranspostKeys Func _Transpose($song, $sNotes, $step) Local $aNotes = StringSplit($sNotes, ",", 2) If $step < 0 Then $step += UBound($aNotes) * (Ceiling(Abs($step) / UBound($aNotes))) Local $pattern = '([A-G][b#]?)(?=\s|/|m[45679]?|dim|$)' Return Execute('"' & StringRegExpReplace($song, $pattern, '" & $aNotes[Mod(_ArraySearch($aNotes, "$1") + $step, UBound($aNotes))] & "') & '"') EndFunc ;==>_Transpose Link to comment Share on other sites More sharing options...
mikell Posted June 17, 2016 Share Posted June 17, 2016 (edited) Malkey, This could easily be fixed by first changing all the chords to flats, then transpose Func _Transpose($song, $sNotes, $step) Local $tmp[5][2] = [["Bb", "A#"], ["Db", "C#"], ["Eb", "D#"], ["Gb", "F#"], ["Ab", "G#"]] For $i = 0 to 4 $song = StringReplace($song, $tmp[$i][1], $tmp[$i][0]) Next Local $aNotesIn = ["Bb", "B", "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A"] Local $aNotesOut = StringSplit($sNotes, ",", 2) If $step < 0 Then $step += 12*(Ceiling(Abs($step)/12)) Local $pattern = '([A-G][b#]?)(?=\s|/|[45679]|m(?=[/\s#\d]|$)|dim|aug|sus|$)' Return Execute('"' & StringRegExpReplace($song, $pattern, '" & $aNotesOut[Mod(_ArraySearch($aNotesIn, "$1")+$step, 12)] & "') & '"') EndFunc ;==>_Transpose Edited June 19, 2016 by mikell added sus in the pattern Link to comment Share on other sites More sharing options...
czardas Posted June 19, 2016 Share Posted June 19, 2016 (edited) @mikell Another common chord type uses 'sus': it should be included. I'm wondering what happened to wysocki, did they get the answer they wanted? Some aspects of my own project are far in advance of many similar commercial music programs on the market, and I am reluctant to give freebies to lazy companies who can't be bothered to employ professional musicians to develop their apps, which seems frequently to be the case. I'm happy to give hints here and there for simple things like this, so please don't get me wrong. One day I'm going to release an amazing program, the likes of which nobody has seen - no hints on that one! Edited June 19, 2016 by czardas mLipok 1 operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
mikell Posted June 19, 2016 Share Posted June 19, 2016 (edited) czardas, Added 'sus' in the pattern I know that my little code (and so Malkey's) is raw and incomplete, as I said it doesn't pretend to be fully comprehensive but it should work in the limits of the requirements defined by the title of the thread Obviously as I'm not a professional musician your comments are welcome, so would be some from wysocki to refine the code to better fit their needs if necessary BTW "no hints on that one" ? you rascal, you make our mouthes water Edited June 19, 2016 by mikell czardas 1 Link to comment Share on other sites More sharing options...
czardas Posted June 19, 2016 Share Posted June 19, 2016 (edited) I wanna see the rest of the lyrics before I commit. Edited June 19, 2016 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
wysocki Posted July 2, 2016 Author Share Posted July 2, 2016 Wow, what great response to this issue! Sorry for not being in the loop here but I was out for a couple weeks vacation just after I started the thread. Oddly, I didn't get any notifs of replies even though it was checked?? I had tried using Band-In-A-Box, entering the whole song with lyrics, then BIAB allows you easily change the key. Problem is that is doesn't print chord+lyric sheets as I wanted so I thought about writing my own transposer. Can't wait to read through all the ideas, thanks all! Especially want to check out mus++, it looks amazing! Link to comment Share on other sites More sharing options...
czardas Posted July 3, 2016 Share Posted July 3, 2016 I wondered what happened. I hope you had a good vacation. Anyway, if you have any problems coding this, please post your attempt. operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now