Duvida Cifra de musica

Ola.

Eu estou fazendo um projetinho no qual eu vou fazer tipo um site de musica com cifras e tals(trabalhinho faculdade)

Até ae tudo bem. O meu problema é o seguinte:

Eu gostaria de fazer o processo de mudar o tom da musica, o método para isso eu ja montei, o problema ta em pegar as notas para fazer a mudança.

Exemplo:

eu tenho essa cifra

14 Bis
"A Qualquer Tempo"
Intro (violão/flauta): E F# E F# C#m7 F# B E F# E/B B

E                     F#   E                   F#
A qualquer tempo cantar a qualquer hora nascer
C#m7   F#          B   E C#m7  F#/Bb    E/B
To.....do tempo é tempo pra    gente se ver
C#m7   F#          B   E C#m7  F#/Bb     B
To.....do tempo é tempo pra    gente se ver

Pra quem não entende muiito de musica, eu preciso pegar só aquelas letras maíusculas, que são sa notas, em cima da letra da musica.

A princípio eu estava pensando em jogar a cifra num TextArea e pegar um método que fosse lendo caracter por caracter … mas seria muiito trabalhoso… alguem tem alguma idéia de como fazer isso?

Espero ter sido claro o suficiente x)

Outra forma seria utilizar expressões regulares(regx)!!, com isso vc consegueria pegar as notas, sem ter q percorrer caracter por caracter…

E como funciona isso?

Tem algum exemplo?

Vou dar uma pesquisada sobre isso

Expressão regular é usado quando vc quer localizar padroes, texto, numeros em um texto, vc cria uma expressão (linguagem da expressão regular) para localizar o que vc quer!!
No java vc usa assim ± assim :

String regex = "\s+(A#)\s?";//expressão regular 
Matcher m = Pattern.compile(regex)).matcher("       C#    D   E   F   G  A#  B           ");

					if(m.find()){
						String nota= m.group(1);// pegando o primeiro mas vc pode pecorrer os grupos
if(nota.equals("A#")){
 System.out.println("Lá Sustenido ");
}

					}
				}

No exemplo do codigo acima aqueles caracteres é a espressão regular, que significa isso:

[code]\s+(A#)\s?

\s+ -> indica que o texto a ser buscado deve ter um espaço antes da próxima sequencia
(A#) -> os parentes indicam um grupo. as letras ‘A#’ indicam o que é que estou buscando no texto
\s? - > indica que após o grupo acima pode ter espaço ou não.
\s -> espaço em branco

  • -> define que deve ter pelo menos 1 ou mais ocorrencia do que vem antes do sinal
    ? -> define que deve ter 0(zero) ou mais ocorrencia do que vem antes do sinal
    [/code]

Eu apreendi bastante com este site, mais existem varios: http://www.regular-expressions.info/java.html no inicio é complicado mas depois fica facil e se torna viciante rss
Neste site eu costumo testar a regx no exemplo do site de JS: http://www.regular-expressions.info/javascriptexample.html

Consegui entender maio ou menos…

Mas dai eu teria que fazer um processo desse para cada nota neh?

Não pode acontecer de dar um erro tipo assim:

E     C#m
E vou la na praia...

Tipo… o “E” da primeira linha é a nota… ja o “E” da segunda liha é a da musica… entende ?

Intão depende da sua expressão regular, é possivel vc separar o que vc quizer, só vai depender da sua regex e do texto, se tiver diferença este a frase da musica e as cifras da musica vc consegue seprar na regex…

Mudando a expressão pra isso ^\s?(E)(\s\s)+ a regx não confundiria as frases e o texto, exemplo bem simples só pra exemplo…

Blz… vou dar uma estudada nisso… parece que vai dar certo.

Qualquer coisa eu volto a postar

Depende, tem mais de uma maneira de usar a expressão regular. vc pode fazer uma expressão por nota(Exemplo dado), ou uma para separar todas as notas, ou intão separ o Tom(C D E B …) dos acidentes(m 7, 9, b, #…) da nota … ai cabe como vc quizer fazer…
um exemplo q talvez usaria seria tentar fazer uma regx para identicar as notas obtendo em grupos tudo numa expressão só…

Entãoo…

Eu vou precisar só da nota em si… tipo C ou D#… porque os 7, 9, e etc não mudam com o tom

Ex: Cm7 se eu aumentar vai C#m7… então teoricamente eu preciso só do C

juliocesarss

Segue abaixo um código que pode te ajudar.

[code]import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Partitura {
public static void main(String[] args) {
String musica = "Cm7 F# B E C#m7 F#/Bb E/B ";

	Partitura partitura = new Partitura();
	Map<String, String> dePara = partitura.nivelAToB();
	String musicaAlterada = partitura.mudarMusica(musica, dePara);
	
	System.out.println(musica);
	System.out.println(musicaAlterada);
}

// Método para alterar a música
private String mudarMusica(String musica, Map<String, String> dePara) {
	String musicaAlterada = musica;
	Set<Map.Entry<String, String>> entry = dePara.entrySet();
	for (Map.Entry<String, String> dado : entry) 
		musicaAlterada = musicaAlterada.replaceAll(String.format("( +|^)%s( +)", dado.getKey()), String.format("$1%s$2", dado.getValue()));
	return musicaAlterada;	
}

// Método para carregar o De >>> Para, das notas musicais.
private Map<String, String> nivelAToB() {
	Map<String, String> notas = new HashMap<String, String>();
	notas.put("Cm7", "C#m7");
	notas.put("B", "B#");
	
	return notas;
}

}
[/code]
O método nivelAToB tem como objetivo carregar um de/para das notas, ou seja Cm7 um nível acima é C#m7 e todas as outras regras, neste caso, se o sistema tiver mais de uma alteração de nível, o mesmo pode ser utilizado para carregar outros de/para.
Mas caso seja possível vários níveis, ao invés de fazer tudo em apenas um método é mais interessante criar interface de escala musical, assim cada nível da escala implementa o seu de/para. (mas isto é algo que pode ser feito depois, primeiro vamos tentar fazer da forma mais simples)

O método mudarMusica, vai percorrer o de/para e mudar todas as notas, e no final retornar a música alterada.

Nos testes que realizei funcionou ok, porem não tenho domínio da regra de negócio, então neste caso não sei se vai contemplar todas as regras !!! Para isto é necessário você passar mais detalhes desta “conversão” de níveis e suas particularidades.

Por exemplo fiquei na dúvida se E/B aumentado um nível é E/B#, ou E#/B#, etc etc.
Mas a princípio acredito que este método e com as dicas do pessoal, você já consiga elaborar uma solução, fazendo o loop por toda a musica e mudando a mesma.

Dependendo da regra vai ser necessário mexer nesta expressão regular b%s( +)[/b], que é utilizada pelo método mudarMusica

OBS: O código que mostrei tem algumas coisas que podem ser melhoradas, como é o caso de usar StringBuilder ao invés de String, etc etc… !!! mas neste caso fica estas alterações e melhorias para você fazer.

Att

cara, acho q vc esta indo em uma boa direção

mas acho q seria melhor vc guardar a estrutra da tablatura, ao invés de vc ficar processando texto pra td q é lado

[quote=“Astork”] notas.put("B", "B#"); [/quote]
acredito q a pressa te tirou a atenção, nao existe B#, é C

denovo o B# e ainda por cima o E#, ambos nao existem hehe, mas nesses casos quando se aumenta ou diminui o tom a alteraçao acontece subindo meio tom de E/B# vai para F/C e um tom de de D/F# vai para E/G#

acordes_s [ C, C#, D, D#, E, F, F#, G, G#, A, A#, B ]
acordes_b [ C, Db, D, Eb, E, F, Gb, G, Ab, A, Bb, B ]

Tablatura
{
	List acordes
	[
		Nota Acordes
		{
			int nota
			int posição
		} 
	]

	List linhas
	[
		String linha
	]
}

com essa estrutura (meio confusa, admito), vc pode separar cada as linhas com as letras da musica das linhas com os acordes, isso evitaria essa parafernalia com exporessões regulares, apenas faria um laço pelos acordes mudando o valor de nota, e na hora de imprimir seria o correspondente em acordes_s ou acordes_b

se essa ideia te interessar agente pode desenvolver melhor essa estrutra

flw, t+

Galera… Brigado pela ajuda até aqui… esta me ajudando bastante.

De musicas e notas musicais eu entendo então sei como funciona… e cmo eu disse o método pra aumentar e diminuir o tom eu ja consegui fazer.

O grande X da questão é:

Eu tenho essa musica:

E       C#m       A
Primeira linha da musica bla bla...

E       C#m       A
Segunda linha da musica bla bla...

Eu to jogando isso num TextArea(por enquanto… não sei se isso seria o ideal) para aparecer para o usuário.

Quando ele clicar em + 1 TOM , a muscisa teria que ficar assim:

F#       D#m       B
Primeira linha da musica bla bla...

F#       D#m       B
Segunda linha da musica bla bla...

Só que pra isso eu preciso de algo que me faça capturar exatamente as notas, ja que pro java ali tudo é texto.

A princípio eu pensei em algo que fosse lendo caracter por caracter e comparando se é uma nota ou não… mas seria muiito trabalhoso e não sei se daria certo… queria saber se tem alguma maneira mais simples.

Espero ter sido claro o suficiente

[quote=juliocesarss]Entãoo…

Eu vou precisar só da nota em si… tipo C ou D#… porque os 7, 9, e etc não mudam com o tom

Ex: Cm7 se eu aumentar vai C#m7… então teoricamente eu preciso só do C[/quote]

Se for só pra subir e descer o tom, vc pode separar só a nota como vc disse, porq os outros ñ muda msm!! lembrando q existe algumas regras de meio tom. tipo: E# B# isso é feio, se não errado…

TO ligado… em relação a isso ja ta feito… pra mudar o tom certinhoo… tanto +1 tom quanto + 1/2 Tom.

A minha dificuldade está mesmo em pegar as notas pra aplicar a mudança

[quote=Priuli]Expressão regular é usado quando vc quer localizar padroes, texto, numeros em um texto, vc cria uma expressão (linguagem da expressão regular) para localizar o que vc quer!!
No java vc usa assim ± assim :

String regex = "\s+(A#)\s?";//expressão regular 
Matcher m = Pattern.compile(regex)).matcher("       C#    D   E   F   G  A#  B           ");

					if(m.find()){
						String nota= m.group(1);// pegando o primeiro mas vc pode pecorrer os grupos
if(nota.equals("A#")){
 System.out.println("Lá Sustenido ");
}

					}
				}

No exemplo do codigo acima aqueles caracteres é a espressão regular, que significa isso:

[code]\s+(A#)\s?

\s+ -> indica que o texto a ser buscado deve ter um espaço antes da próxima sequencia
(A#) -> os parentes indicam um grupo. as letras ‘A#’ indicam o que é que estou buscando no texto
\s? - > indica que após o grupo acima pode ter espaço ou não.
\s -> espaço em branco

  • -> define que deve ter pelo menos 1 ou mais ocorrencia do que vem antes do sinal
    ? -> define que deve ter 0(zero) ou mais ocorrencia do que vem antes do sinal
    [/code]

Eu apreendi bastante com este site, mais existem varios: http://www.regular-expressions.info/java.html no inicio é complicado mas depois fica facil e se torna viciante rss
Neste site eu costumo testar a regx no exemplo do site de JS: http://www.regular-expressions.info/javascriptexample.html[/quote]

Muito bom.

O bom do regx é que vc ñ precisa ficar varrendo char… por char… dependendo como for feito até é possivel deixar elegante e diminuir bastante o codigo,. segue a referencia dos comandos para regx para quem estiver estudando http://www.regular-expressions.info/reference.html

isso é fácil de resolver.

Quando o usuário envia a cifra, você estabele um padrão pras notas.

Por ex: Se a nota for C#m, faça o usuário escrever a nota dentro de uma tag que você possa fazer o parse depois, algo como [nota]C#m[/nota].

Como é feito no GUJ, com as tags [*quote], [*code], etc.

Assim, você pode identificar as notas e estilizá-las para mostrar e fazer operações.

Para fazer a operação de mapeamento de tons,

você pode ter isso fixo ou em um algoritmo, já que você terá a nota e poderá substitui-lá por uma de maior ou menor tom.

Para fazer isso pode ser de N jeitos, mas um método simples que eu pensei agora é que a nota seja um Enum, que tenha os métodos aumentarTom e diminuirTom, Tom. Esses métodos retornam uma instância do Enum Nota, representando a nota na sequência esperada.