Problema reproduzindo exemplo do Farnell

Problema reproduzindo exemplo do Farnell

por Brian Vasconcelos -
Número de respostas: 4

Boa tarde, estava lendo os capítulos do livro do Farnell sobre o Pd e estou tendo problemas tentando reproduzir um dos exemplos.

Trata-se do seqüenciador exposto na figura 3.9. Clicando manualmente na mensagem o valor é reiniciado com 0 como esperado, mas nunca quando a caixa de mensagem recebe um bang do programa no inlet.

No arquivo anexo segue há uma versão minha que imprime o valor da variável float numa caixa de número e há um bang entre duas mensagens, apenas para demonstrar que de fato a caixa de mensagem está sendo acionada mas que o valor da variável não é alterado. Logo abaixo está uma reprodução(creio exata)  do diagrama do livro do Farnell, para quem não quiser procurar no livro ou checar se errei em alguma ligação/caixa.

Também baixei o tarball com os exemplos do livro mas não encontrei esse em particular para comparar.

Em resposta à Brian Vasconcelos

Re: Problema reproduzindo exemplo do Farnell

por Marcelo Queiroz -

Olá, Brian!

Muito legal que você já tenha começado a fuçar o material do site!!
Muito chato que tão rápido você tenha esbarrado em um erro do Farnell!! sorriso
Não se preocupe, não é culpa sua... vou explicar o que aconteceu e tentar me fazer entender... para quem ainda não começou a mexer com o Pd talvez o melhor seja pular esta mensagem e pensar nessas coisas apenas quando a dúvida efetivamente aparecer.

O problema está na saída do objeto "f 0", que é aquela variável usada como contador. Jamais num programa bem escrito ele deveria ter duas saídas... nesse patch, ele tem uma saída que vai para o incrementador "+ 1" e outra que vai para o "select". Nesses casos, a linguagem define que os fluxos de informação devem ser processados na ordem em que foram criados, que não por acaso é a ordem em que as conexões aparecem no arquivo .pd. Ao copiar o patch do livro, você conectou primeiro a corda que ia para o "select" e depois a que ia para o "+ 1", o que faz o mecanismo de reset do contador parar de funcionar! Mas repito, a culpa não é sua, é do Farnell... sorriso

Para ilustrar este ponto, coloquei em anexo o seu patch, sendo que apaguei apenas aquelas duas conexões e as recriei na ordem em que elas deveriam ser acionadas (primeiro "+ 1", depois "select"). Note que agora o patch funciona. É interessante pensar em porque a outra ordem não funcionava: o valor do contador ia primeiro pro "select", que quando recebe "3" redireciona o fluxo para o "reset" que armazena "0" na variável, e *depois* disso chega (atrasada) aquela mensagem com valor "3" no objeto "+ 1", que manda "4" para a variável que armazena o contador, desfazendo o mecanismo de reset.

E por que eu insisto que a culpa é do Farnell? Porque a versão correta e a versão errada são visualmente idênticas! Para resolver esse tipo de ambiguidade, existe um objeto chamado "trigger", que força uma determinada serialização quando um objeto se conecta a vários outros. No mesmo patch eu coloquei a versão com trigger. A convenção é que o trigger "dispara" as cópias da direita para a esquerda, então primeiro o número é incrementado, e só depois ele vai para o select e eventualmente dispara o mecanismo de reset.

Talvez eu tenha sido meio "caxias" quando disse que jamais um programa deveria ter duas cordinhas saindo de uma mesma caixinha. Várias vezes isso é totalmente inofensivo, particularmente em situações que não envolvem loops ou retro-alimentações. Mas usar "trigger" é sempre o melhor meio de não gerar patches visualmente ambíguos, e ter que ficar caçando bugs que não parecem fazer sentido nenhum.

Abraço,

Marcelo


Em resposta à Marcelo Queiroz

Re: Problema reproduzindo exemplo do Farnell

por Antonio Deusany de Carvalho Junior -

A ordem na qual as ligações são feitas fica salva no arquivo, logo pode ser vista abrindo o arquivo .pd com um editor de texto qualquer. Como a ordem é importante neste caso e não pode ser vista facilmente, realmente a melhor solução é o uso do "trigger". A seguir eu coloquei as linhas dos dois arquivos que estão em ordem diferente, só para ilustrar o fato.

Versão Brian:
....
#X connect 11 0 12 1;
#X connect 12 0 3 0;
#X connect 12 0 2 0;
#X connect 12 0 9 0;
....
#X connect 21 0 22 1;
#X connect 22 0 16 0;
#X connect 22 0 15 0;

Versão Marcelo:
....
#X connect 11 0 12 1;
#X connect 12 0 9 0;
#X connect 12 0 2 0;
#X connect 12 0 3 0;
...
#X connect 21 0 22 1;
#X connect 22 0 15 0;
#X connect 22 0 16 0;

Para mais informações sobre o formato PD:
http://puredata.info/docs/developer/PdFileFormat

= )
DJ

Em resposta à Antonio Deusany de Carvalho Junior

Re: Problema reproduzindo exemplo do Farnell

por Brian Vasconcelos -

Obrigado pelas respostas.

Cheguei a considerar que o problema era de ordem de execução e até a tentar utilizar um trigger, mas sempre esperando que o problema fosse com os fluxos do objeto + 1 e da mensagem 0 indo parar no mesmo inlet do f 0, não cheguei a considerar que o problema surgisse nos fluxos que saem do f 0. Ficarei mais atento a esses casos e darei uma olhada na documentação do formato,  já que parece que nesses casos o erro fica mais explícito nesse texto meio críptico do que no patch. boca aberta

Em resposta à Brian Vasconcelos

Re: Problema reproduzindo exemplo do Farnell

por Marcelo Queiroz -

Se me permitem expressar uma opinião pessoal, entender o formato do arquivo .pd está bem longe de ser uma necessidade introdutória. Isso vai ser de interesse principalmente de quem escreve geradores automáticos de patches Pd em outras linguagens, ou quando se quer escrever um objeto external em C que fica alterando a estrutura de um patch Pd (conectando ou desconectando objetos fora da interface gráfica do Pd). Essas são situações para lá de avançadas... sorriso

O ponto que eu gostaria de deixar claro, e pro qual aquele exemplo do Farnell cai como uma luva, é esse: se o correto funcionamento do um patch depende da ordem de criação das conexões na interface gráfica, então esse não é um bom patch, ou pra ser mais explícito, esse patch está *errado*, mesmo quando conectamos as caixas na ordem certa e o programa "funciona". A inspeção visual do patch na sua forma gráfica é o modo de leitura "normal" de um patch, e ela deve ser suficiente para entendermos o funcionamento dele (sem acesso à representação de baixo nível no arquivo .pd). Sempre que essa premissa falha, é porque perdemos alguma(s) excelente(s) oportunidade(s) de usarmos "triggers".

Bom domingo e até amanhã, nosso primeiro dia de aula! sorriso

Marcelo