# Copyright (C) 2002-2004 gregoire HUBERT.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Author : gregoire HUBERT
#
# XML_node.objet
#
# This object is an XML node representation
#
# /- name (string)
# xml_node --- attributes (array)
# \- children (array) or value (string)
class xml_node {
var $name;
var $attributes = array();
var $children = array();
var $value = "";
function xml_node($name,$attributes,$children=array(),$value="") {
$this->name = $name;
if (is_array($attributes)) {
$this->attributes = $attributes;
}
$this->children = $children;
$this->value = $value;
}
}
# Copyright (C) 2003-2004 gregoire HUBERT.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Author : gregoire HUBERT
#
# xml_tree class
#
# This object parses an XML stream and offers a tree composed by xml_nodes
#
class xml_tree {
var $xml_stream;
var $current_node;
var $root_node;
var $index;
var $value;
function xml_tree() {
$this->root_node = new xml_node("__ROOT_NODE",array());
$this->current_node = $this->root_node;
}
function add_tree($xml_stream) {
# Managing the parser
$this->xml_stream = $xml_stream;
$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
xml_parser_set_option($xml_parser,XML_OPTION_SKIP_WHITE,1);
if (!xml_parse_into_struct($xml_parser,$this->xml_stream,$this->value,$this->index)) {
xml_parser_free($xml_parser);
die("XML Parse error");
}
xml_parser_free($xml_parser);
# Now, $this->value and $this->index are informed, we can use the get_node methode.
$tab_result = $this->get_node(0,count($this->value) - 1);
$this->root_node->children[] = $tab_result[0];
$this->current_node = $this->root_node;
}
function get_node($index_start,$index_stop) {
#echo " \n";
#echo "GET-NODE($index_start,$index_stop) \n";
# What we are going to return is an array of xml_nodes
$return_tab = array();
# depth is only here to check if everything is all right
$tab_node = $this->value[$index_start];
$depth = $tab_node["level"]-1;
# Now we have to be sure we do not forget a single node
for ($index = $index_start;$index <= $index_stop;$index++) {
#echo "\$index = $index ";
# get the current node
$tab_node = $this->value[$index];
# what type of node is it ?
switch($tab_node["type"]) {
case "complete" :
# Depth integrity check
if ($tab_node["level"] != $depth+1) {
die("ERREUR # contrainte d'intégrité au noeud complet $index, niveau $depth + 1 au lieu de ".$tab_node["level"]);
}
#echo "Noeud complet trouvé position $index TAG ".$tab_node["tag"]." \n";
# Easy one, no children to manage, only a value...
$return_tab[] = new xml_node($tab_node["tag"],$tab_node["attributes"],"",$tab_node["value"]);
break;
case "open" :
# Depth integrity check
if ($tab_node["level"] != $depth +1 ) {
die("ERREUR # contrainte d'intégrité au noeud ouvert $index, niveau $depth au lieu de ".$tab_node["level"]);
}
# Open tag, we re-use this methode to return its children
# Where is the correspondong close tag ?
$node_index = $this->index[$tab_node["tag"]];
$flipped_node_index = array_flip($node_index);
#echo "This ".$tab_node["tag"]." is at coords ".$flipped_node_index[$index]." ";
$i=1;
do {
$next_index = $node_index[$flipped_node_index[$index] + $i++];
$next_tag=$this->value[$next_index];
}
while ($next_tag["level"]!=$tab_node["level"]);
#echo "Ouverture de noeud détectée pos $index TAG ".$tab_node["tag"]." \n Parcours jusqu au $next_index \n";
# good, we can now instanciate our node
$return_tab[] = new xml_node($tab_node["tag"],$tab_node["attributes"],$this->get_node($index+1,$next_index),"");
# As we called the get_node methode, we are sure that nodes have been parsed to the corresponding close tag
$index = $next_index;
break;
case "close" :
# Depth integrity check
if ($tab_node["level"] != $depth ){
die("ERREUR # contrainte d'intégrité au noeud fermé $index, niveau $depth au lieu de ".$tab_node["level"]);
}
#echo "Fermeture de noeud detectée pos $index TAG ".$tab_node["tag"]."
\n";
# This ugly thing is useless because reaching a close tag means that $index==$index_stop but who knows ? =)
# it will be skipped soon
$index = $index_stop;
break;
default:
die("Erreur de type de TAG non déterminé :'".$tab_node["type"]."'");
}
}
# We are out ... returns the array with collected children...
return ($return_tab);
}
# this function browse the xml tree and set the current node to the selected node
function give_node($path) {
if ($path[0]=="/") {
$current_node=$this->root_node;
$path=substr($path,1);
#echo "ABSOLUTE PATH GIVEN=$path ";
}
else {
$current_node = $this->current_node;
}
#echo "PATH GIVEN=$path ";
$tab_path = split("/",$path);
foreach ($tab_path as $node_expr) {
#echo "STUDYING EXPR='$node_expr' ";
$node = $current_node;
$expr_tab = split("\?",$node_expr);
$node_name = $expr_tab[0];
$attr_tab = 0;
if (count($expr_tab)>1) {
##echo "TROUVE AU MOINS UNE CONDITION SUR LES ATTRIBUTS... ";
$attr_expr_tab=split(",",$expr_tab[1]);
$attr_tab=array();
foreach($attr_expr_tab as $attr_expr) {
$attr_split_expr=split("=",$attr_expr);
$attr_tab[$attr_split_expr[0]]=$attr_split_expr[1];
}
}
$last=0;
foreach ($node->children as $children) {
#echo "COMPARING WITH '$children->name' ";
if ($children->name == $node_name) {
##echo "TROUVE NOEUD CORRESPONDANT $node_name ";
if (is_array($attr_tab)) {
$node_attributes = $children->attributes;
foreach ($attr_tab as $key=>$value) {
if ($node_attributes[$key] == $value) {
#echo "ATTRIBUTE & CHANGE CURRENT NODE TO ".$children->name." ";
$current_node = $children;
$last = 1;
}
}
}
else {
##echo "CHILD=".$children->name." ";
#echo "CHANGE CURRENT NODE TO ".$children->name." ";
$current_node = $children;
$last=1;
}
}
if ($last) {
break;
}
}
if (!$last) {
#echo "PATH ERROR $node_name ";
#die("MMmmmh It seems that this file is not a DIA XML format...sorry...");
return 0;
}
}
return $current_node;
}
function browse_tree($path) {
$node = $this->give_node($path);
if (is_object($node)) {
$this->current_node = $node;
return 1;
}
return 0;
}
# this method dumps an html representation of the xml tree
function xml_show($node = "",$level=0,$last=0) {
if ($node=="") {
$node=$this->root_node;
}
if (!is_object($node)) {
die("ERROR : node is not an object");
}
$line="";
for($i=1;$i<=$level;$i++) {
if ((i==$level-1) and ($last)) {
$line.=" ";
}
else {
$line.=" |";
}
if ($i==$level) {
$line.="`-";
}
}
$line.=$node->name;
#echo $line;
$line.="".count($node->children)."";
if (count($node->children)==1) {
$line.=" (".$node->value.") \n";
echo "$line";
}
else {
$line.=" \n";
echo "$line";
$i=1;
foreach($node->children as $children) {
if ($i==count($node->children)) {
$this->xml_show($children,$level+1,1);
}
else {
$this->xml_show($children,$level+1);
}
$i++;
}
}
}
#END_CLASS
}
SILENT OPERA (FRA) - Reflections (2014)

Label : Massacre Records
Sortie du Scud : 21 février 2014
Pays : France
Genre : Gothic Death Metal symphonique
Type : Album
Playtime : 9 Titres - 53 Mins
A l'heure où j'écris ces quelques lignes, il attend sagement. Il est officiellement sorti de sa cage depuis une dizaine d'heures, et pour être franc, le monde extérieur n'en semble pas pour autant troublé. Peut-être que ce n'est qu'une question de timing, car "il", c'est ce premier album de SILENT OPERA, et on peut dire qu'il se sera fait attendre. Depuis quatre ans et un EP du nom d'Act One, on patiente pour savoir si enfin, ces français sauront rivaliser au cœur d'une scène où la pureté se transforme vite en guimauve, où les bons sentiments côtoient rapidement l'indigence. Le Metal à chanteuse. Mais quelle expression moyenâgeuse et sexiste ! Car SILENT OPERA, en réalité, a beaucoup plus à proposer que le joli minois et la voix cristalline de Laure Laborde, rompant ainsi avec les attentes misogynes et creuvardes de ceux qui pensent que le Metal, quand il est symphonique, se caractérise principalement par les beaux nénés de Simone Simons.
Désolé de vous décevoir les mecs, mais Laure a un petit ami (du moins dans le groupe), et il s'appelle Steven Schriver. Ce duo vocal est d'ailleurs aux premières loges de SILENT OPERA, se répondant du tac au tac, comme dans une épreuve de "Tournez Manège". Les braillements font écho au lyrisme, à la finesse et inversement. A tel point que rapidement, on occulte un peu les brillants arrangements qui font de "Nightmare Circus" une compo très avantageuse. Ces derniers ne passent néanmoins pas leur temps dans l'ombre et on pourra largement avoir le temps de savourer la musicalité des claviers de "Fight Or Drift". A l'instar des Suisses de TROPHALLAXY, SILENT OPERA abat la carte d'un chaud-froid identitaire. Ainsi, deux univers se percutent, se lient, sans pour autant se limiter au cliché du chant masculin VS chant féminin. Quand le Death Metal mélodique croise sur son chemin le Gothic Metal symphonique, c'est exactement ce type de bataille qu'ils livrent ! Jouissif, mais que jusqu'à un certain point. Car après être passé par le stade de l'étonnement, de la jubilation peut-être, de l'admiration surement, il n'est pas illégitime non plus de considérer Reflections comme un album résolument correct mais qui peine à trouver une virtuosité sur le long terme. Les morceaux brillent par épisodes successifs, sans vraiment trouver leur continuité. J'ai par exemple été frappé par "Chronicles Of An Infinite Sadness", qui a une drôle de façon de vouloir casser le rythme. Il ne s'y passe peut-être rien musicalement parlant, mais pire que ça, les émotions provoquées sont assez confuses, et il faudra toute la force de frappe d'"Inner Museum" pour évacuer cette frustration. On peut interpréter ce choix de diverses manières selon les sensibilités, et la mienne me laisse croire qu'à ce niveau, SILENT OPERA manque encore un peu de bouteille. Je ne pense pas mentir en affirmant que ces français n'ont pas encore cette réputation établie qui justifierait à elle seule les tourments palpables d'une telle création. Ceci étant, gravite aussi tout autour une constellation de poésie, d'orchestrations, de légèreté et de romantisme qu'il serait déplacé d'occulter.
Cette œuvre plaira assurément aux amateurs du genre, qui aimeraient parfois que leurs poulains soient plus virils ou plus pondérés. Cette diversité, cette intensité, c'est la grande force de Reflections. Une force qui parlera d'une voix suave à ceux qui voudront se laisser tenter par les grands débuts (on peut le dire, même si SILENT OPERA a déjà 7 ans d'âge) de ces français qui, assurément, ont réalisé là un très beau travail, au raffinement incontestable. Mais quelque part, il faut aimer à parts égales le thé et la bière pour s'en accommoder.
Ajouté : Lundi 25 Août 2014 Chroniqueur : Stef. Score :     Lien en relation: Silent Opera Website Hits: 8348
|