In some cases you will run into trouble when you want to use the standard function of Doors to create a traceability for a depth of 2 that is not going into the same direction. To solve this problem the implementation of an own Layout DXL is necessary.
The example below shows the situation with depth 2 and the same Linkmodule in which you can use the standard function to create a Layout DXL column:
The next situation, which is not possible to master with the standard doors function, shows the problem where depth two with two different direction and link module types gives the needed traceability information for the report.
Approach – Ansatz
To get the needed traceability information within a module, you can add a layout dxl column by clicking on the column header of the current selected view in the module and add a layout DXL column. This layout DXL column can iterate through the outgoing modules of the current object, catch all objects that are linked and look for incoming links on it.
Solution – Lösung
//
/*******************************************************************************
* Author: Björn Karpenstein
* Stakeholder: Björn Karpenstein
*
* Subversion
* ===================================================
* $Rev:: $: Revision of last commit
* $Author:: $: Author of last commit
* $Date:: $: Date of last commit
*
* Change Control
* ==============
* n/a
*
* Description
* ===========
* This script gives the traceability over 2 modules with two different diection
* and module types
*******************************************************************************/
string firstLinkModule = "/Product Lifecycle Management/10 Administration/Create";
string secondLinkModule = "/Product Lifecycle Management/10 Administration/Triggers";
Skip dublettenRaus=createString;
pragma encoding,"UTF-8";
pragma runLim, 0;
//Object obj=current;
Link lnk;
Link inLnk;
LinkRef lnkRef;
ModName_ otherMod = null;
for lnk in obj->firstLinkModule do
{
string tmn=fullName target(lnk);
if(!open module tmn)
{
read(tmn,false);
}
Object keypoint = target(lnk);
//display identifier(keypoint) "\n";
if(null keypoint)
{
//display "no link to keypoint";
}
else
{
//display "keypoint : " identifier(keypoint) "";
for lnkRef in keypoint<-secondLinkModule do
{
//display "drin";
otherMod = module (sourceVersion lnkRef);
if (!null otherMod)
{
if ((!isDeleted otherMod) && (null data(sourceVersion lnkRef)))
{
load((sourceVersion lnkRef),false);
}
}
}
for inLnk in keypoint<-secondLinkModule do
{
// Get In-Link Object
Object phase = source inLnk;
if ( isDeleted(phase) || null(phase) ) continue;
string dummy="";
if(!find(dublettenRaus, phase."Object Text" "", dummy))
{
put(dublettenRaus, phase."Object Text" "", phase."Object Text" "");
}
}
}
}
int phaseCounter=0;
// Iteration through the SkipList
for myIterator in dublettenRaus do
{
string keyValue = (string key(dublettenRaus));
string currentObject = null;
if(find(dublettenRaus, keyValue, currentObject))
{
display keyValue;
}
}
delete dublettenRaus;
// Get the current selected module
Module m = current;
// Create first object of module
Object firstObjectInModule = create(m);
Create hierarchically objects
// Create child object of firstObj
Object childObjOfFirst = create below(firstObj);
// Create last Object (this will generate an error
// if the object has no children present
Object lastChildObjOfFirst = create last(firstObj);
// Creates a new object on the same level as firstObj
Object newObjectOnSameLevel = create after(firstObj);
// Select the current Module
Module m = current;
// Get first Object of Module
Object firstObject = first(m);
// Get last Object of Module
Object lastObject = last(m);
Selection on object children and parents (get parent / first / last child)
// Get current selected module (highlighted row in Module)
Object currObj = current
// Get first Child of the Object (which is below currObj -
// i.e. whenn currObj is a Headline)
Object firstChild = first(currObj);
// Get last child of the objects below currObj
Object lastChild = last(currObj);
// Get the parent of currObj
Object parentObject = parent(currObj);
Selection of vertically arranged objects in the module (without considering the object hierarchy)
Object currObj = current;
// Select the previous object independent from the object hierarchy
Object previousObj = previous(lastChild);
// Select the next object independent from the object hierarchy
Object nextObj = next(lastChild);
Selection of siblings of the current object
Object currObj = current;
// Selection of the first sibling in the same hiararchy and hierarchy level
Object firstSibling = first sibling (currObj);
// Selection of the last sibling in the same hiararchy and hierarchy level
Object firstSibling = first sibling (currObj);
Jared Dines macht z.Zt. einen Wettbewerb, bei dem man ein Solo über einen Song-Ausschnitt von ihm spielen soll. Der beste Shredderer erhält als Belohnung 500 $. Ich habe mal Just-For-Fun teilgenommen und hoffe das ich in seinem Video auf dem Channel auftauche :-).
Über das relationale Datenmodell des Enterprise Architects soll die Geometrie von Links auf Diagrammen rekonstruiert werden. Die nötigen Felder sind in den Tiefen der Datenstrukturen aus Tabellen und Attributen in einem Memo-/Freitext-Feld versteckt.
Ich entwickle zur Zeit eine eigene Interpretation des EA-Renderers mit GoJS, wo ich auf das Problem gestoßen bin, dass ich aufgrund der unterschiedlichen Connectorstyles, welche für einen Link auf unterschiedlichen Diagrammen eine andere Geometrie vorweisen kann, den Endpunkt nicht ermitteln kann. Eine Lösung hierzu möchte ich hier ausarbeiten.
Analyse
Relationen
Ein Link/Connector (Tabelle „t_connector„) kann auf mehreren Diagrammen unterschiedliche Darstellungen haben. Die Geometrie des Links auf einem Diagramm wird über das Attribut „Geometry“ der Tabelle „t_diagramlinks“ bestimmt. Das Attribut „Geometry“ ist ein Langtext-/Memo-Feld und wird im folgenden einer Analyse unterzogen, da sich im Internet nur sehr spärlich Informationen über den Aufbau und die Bedeutung des Doppelpunkt-separierten Strings finden.
Die Tabelle „t_diagramlinks“
“ A DiagramLink is an object that holds display information on a connector between two elements in a specific diagram. It includes, for example, the custom points and display appearance. It can be accessed from the Diagram DiagramLinks collection. “
Long Notes: Read/Write The ID of the associated connector.
DiagramID
Long Notes: Read/Write The local ID for the associated diagram.
Geometry
String (Memo-Field) Notes: Read/Write The geometry associated with the current connector in this diagram.
HiddenLabels
Boolean Notes: Indicates if this connector’s labels are hidden on the diagram.
InstanceID
Long Notes: Read only The connector identifier for the current model.
IsHidden
Boolean Notes: Read/Write Indicates if this item is hidden or not.
LineColor
Long Notes: Sets the line color of the connector. Set to -1 to reset to the default color in the model.
LineStyle
Long Notes: Sets the line style of the connector. 1 = Direct 2 = Auto Routing 3 = Custom Line 4 = Tree Vertical 5 = Tree Horizontal 6 = Lateral Vertical 7 = Lateral Horizontal 8 = Orthogonal Square 9 = Orthogonal Rounded
LineWidth
Long Notes: Sets the line width of the connector.
ObjectType
ObjectType Notes: Read only Distinguishes objects referenced through a Dispatch interface.
Path
String Notes: Read/Write The path of the connector in this diagram.
SourceInstanceUID
String Notes: Read only Returns the Unique Identifier of the source object.
SuppressSegment
Boolean Notes: Indicates whether the connector segments are suppressed.
Style
String Notes: Read/Write Additional style information; for example, color or thickness.
TargetInstanceUID
String Notes: Read only Returns the Unique Identifier of the target object.
Der String „Geometry“ wird in MDB Viewer Plus als (MEMO) dargestellt, das MemoFeld kann allerdings rechts eingeblendet werden. Dort tauchen einige weitere versteckte Attribute für die Geometry der Linie auf, welche im nachfolgendem Analysiert werden Die Auswahl des LineStyles für einen Connector, wie oben im Screenshot dargestellt, bestimmt die Darstellung.Die LineStyles werden in der Tabelle [t_diagramlinks] und über Mode={1,2,3} und dem optionalen Zusatz TREE={V,H,OS,OR,LV,LH}:Mode=3 für Mode „3“ gespeichert.
Das Hauptproblem: Das Datenmodell besitzt nicht die Information, an welcher Seite der End-Knoten/das Ziel-Rechteck geschnitten wird. Lediglich über das Attribut t_diagrammlinks.Geometry lässt sich über den CSV-Value „Edge“ die Startseite des Startknotens bestimmen.
Fremdmeinungen einholen – ein Ausflug in die Forenwelt
Ich habe mich aus Gründen der Kollaboration entschieden, die Analysen in Stackoverflow und EA fortzuführen. Hier finden sich die Links zu meinem Beitrag:
Fazit: Obwohl mir kein Forum eine nutzbare Lösung angeboten hat, lohnt es sich sich neue Anregungen zu dem Problem einzuholen
Lösung für das Problem mit der fehlenden Ecke des Zielknoten (Target Edge) – Rechteckschnitt
Im Datenmodell wird die Mouse-Release Position über Geometry EX/EY (Geometry) gespeichert, was allerdings nicht der Schnittpunkt mit dem Rechteck ist.
Mit 4 Geraden lässt sich das Rechteck bestimmen (obgleich natürlich auch Punkte existieren, die nicht auf dem Rechteck liegen).
Seite 1 der Lösung
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Erzeuge eine eigene Link-Klasse für das Routing der Pfeile, die von Hand gezogen wurden
// und über spezielle Attribute in der EAP-Datei definiert werden
// Ruft die Superklasse von go.Link im Konstruktor auf
function MultiNodePathLink() {
go.Link.call(this);
}
go.Diagram.inherit(MultiNodePathLink, go.Link); // Erben von go.Link
// ignores this.routing, this.adjusting, this.corner, this.smoothness, this.curviness
/** @override */
MultiNodePathLink.prototype.computePoints = function () {
// Die this Referenz ist hier ist ein geerbter ein go.Link. der bei Links
var startNode = this.fromNode;
var startNodeX = startNode.location.M; // X-Koordinate vom Startknoten
var startNodeY = startNode.location.N; // Y-Koordinate vom Startknoten
var endNode = this.toNode;
var endNodeX = endNode.location.M; // X-Koordinate vom Startknoten
var endNodeY = endNode.location.N; // Y-Koordinate vom Startknoten
var startNodeData = startNode.data; // Das sind die Daten
var endNodeData = endNode.data; // Das sind die Daten
// Die Link-Daten
var linkProperties = this.data;
//** Das Feld Style in [t_diagramlink] bestimmt die Connector-Darstellung **/
// https://www.capri-soft.de/blog/?p=2904
/*
* 1 = Direct Mode=1
* 2 = Auto Routing Mode=2
* 3 = Custom Line Mode=3
* 4 = Tree Vertical Mode=3;TREE=V
* 5 = Tree Horizontal Mode=3;TREE=H
* 6 = Lateral Vertical Mode=3;TREE=LV
* 7 = Lateral Horizontal Mode=3;TREE=LH
* 8 = Orthogonal Square Mode=3;TREE=OS
* 9 = Orthogonal Rounded Mode=3;TREE=OR
*/
var styleStringArray = linkProperties.style.split(";");
var mode = -1;
var tree = '';
for (var i = 0; i < styleStringArray.length; i++) {
if (styleStringArray[i].trim().indexOf('Mode=') > -1) {
mode = styleStringArray[i].replace('Mode=', '');
}
if (styleStringArray[i].trim().indexOf('TREE=') > -1) {
tree = styleStringArray[i].replace('TREE=', '');
}
}
// In der Tabelle t_diagramlinks in der Freitextspalte "Geometry" wird in einem CSV-String
// gespeichert, wie der Link letztendlich auf dem Diagram gezogen wurde
var geometryString = linkProperties.geometry.split(";");
var sx, sy, ex, ey, edge;
for (var i = 0; i < geometryString.length; i++) {
// SX and SY are relative to the centre of the start object
if (geometryString[i].trim().indexOf('SX=') > -1) sx = geometryString[i].replace('SX=', '');
if (geometryString[i].trim().indexOf('SY=') > -1) sy = geometryString[i].replace('SY=', '');
// EX and EY are relative to the centre of the end object
if (geometryString[i].trim().indexOf('EX=') > -1) ex = geometryString[i].replace('EX=', '');
if (geometryString[i].trim().indexOf('EY=') > -1) ey = geometryString[i].replace('EY=', '');
// EDGE ranges in value from 1-4, with 1=Top, 2=Right, 3=Bottom, 4=Left (Outgoing Point of the Start Object)
if (geometryString[i].trim().indexOf('EDGE=') > -1) edge = geometryString[i].replace('EDGE=', '');
}
// Hier beginnt das Custom-Routing
if (typeof (sx) === "undefined" || typeof (sy) === "undefined" || typeof (ex) === "undefined" || typeof (ey) === "undefined" || typeof (edge) === "undefined") {
return;
}
this.clearPoints();
if (linkProperties.start_object_name == 'System Verification Test Reports' && linkProperties.end_object_name == 'System test specifications') {
var test = 'irrsinn';
}
// Hier werden die Wege definiert für das gecustomizte Link Routing
// Geht der Link nach oben oder unten wird die Y-Koordinate des Startknotens genutzt (Weil Orthogonales Routing)
var startConnX = null;
var startConnY = null;
if (edge == 1) { // Ecke oben
startConnX = Math.abs(startNodeX) + Math.abs((startNode.actualBounds.width / 2) + new Number(sx));
startConnY = Math.abs(startNodeY);
}
else if (edge == 3) { // Ecke unten
startConnX = Math.abs(startNodeX) + Math.abs((startNode.actualBounds.width / 2) + new Number(sx));
startConnY = Math.abs(startNodeY) + new Number(startNode.actualBounds.height);
}
else if (edge == 2) { // Ecke rechts
startConnX = Math.abs(startNodeX) + startNode.actualBounds.width;
startConnY = Math.abs(startNodeY) + Math.abs((startNode.actualBounds.height / 2) - new Number(sy));
}
else if (edge == 4) { // Ecke links
startConnX = new Number(Math.abs(startNodeX));
startConnY = Math.round(startNodeY) + Math.round((startNode.actualBounds.height / 2) - new Number(sy));
}
else {
alert('Die Edge konnte nicht entdeckt werden! Ist der Geometry String in der EAP Datei richtig?');
}
this.addPoint(new go.Point(Math.round(startConnX), Math.round(startConnY)));
// Abfrage: Gibt es einen letzten Path Punkt?
var lastPathPunkt=false;
var lastPathPunktX, lastPathPunktY;
if (mode != 1)
{
// Routing über die Zwischenwege
if (typeof linkProperties.conn_path !== "undefined" && linkProperties.conn_path !== "") {
var splittedArray = linkProperties.conn_path.split(";");
if (splittedArray.length > 1) {
// Hier ist mindestens ein Wert vorhanden da auch der erste mit Semikolon abgeschlossen wird im Path vom EA
for (var i = 0; i < splittedArray.length - 1; i++) {
var einMittelPunkt = splittedArray[i];
var mittelPunktArray = einMittelPunkt.split(":");
this.addPoint(new go.Point(Math.abs(new Number(mittelPunktArray[0])), Math.abs(new Number(mittelPunktArray[1]))))
lastPathPunktX = Math.abs(new Number(mittelPunktArray[0]));
lastPathPunktY = Math.abs(new Number(mittelPunktArray[1]));
lastPathPunkt = true;
}
}
}
}
// Wenn es keinen Pfad gab,muss der letzte Punkt mit dem Startknoten identisch sein
if (lastPathPunkt == false) {
lastPathPunktX = Math.abs(Math.round(startConnX));
lastPathPunktY = Math.abs(Math.round(startConnY));
}
// End-Routing
// Der Endpunkt in EA in Document Coordinates
var endConnX = Math.abs(endNodeX) + Math.abs((endNode.actualBounds.width / 2) + new Number(ex));
var endConnY = Math.abs(endNodeY) + Math.abs((endNode.actualBounds.height / 2) - new Number(ey));
// Spezialfälle bei horizontalen und vertikalen Linien:
if (endConnX == lastPathPunktX) {
// Es liegt eine vertikale Gerade (z.B. von oben nach unten) vor
this.addPoint(new go.Point(Math.round(lastPathPunktX), Math.round(lastPathPunktY)));
this.addPoint(new go.Point(Math.round(endConnX), Math.round(endConnY)));
} else if (endConnY == lastPathPunktY) {
// Es liegt eine horizontale Gerade (z.B. von rechts nach links) vor
this.addPoint(new go.Point(Math.round(lastPathPunktX), Math.round(lastPathPunktY)));
this.addPoint(new go.Point(Math.round(endConnX), Math.round(endConnY)));
} else {
// Es ist keine Gerade sondern ein Gerade, die mit y=m*x+b beschrieben werden kann
// 1.) Gerade zwischen Start- und Endpunkt ermittelnhn
// Ye-Ys
// m = ----- b=Ys-m*Xs oder b=Ye-m*Xe
// Xe-Xs
var m = (endConnY - lastPathPunktY) / (endConnX - lastPathPunktX);
var b = lastPathPunktY - m * lastPathPunktX
// 2.) Ermittlung der horizontalen und vertikalen Geraden des Rechteckes und dem Schnittpunkten
// Die Geraden, die das Rechteck definieren:
var rY1 = endNodeY;
var rY2 = endNodeY + endNode.actualBounds.height;
var rX1 = endNodeX;
var rX2 = endNodeX + endNode.actualBounds.width;
// (rX1, rY1) -zu-> (rX2, rY2)
// Horizontale Geraden:
// y - b
// x = -----
// m
var lengthToPoint = [];
var sX1 = (rY1 - b) / m; // S1(sX1|rY1)
if (sX1 >= rX1 && sX1 <= rX2) {
// Der Schnittpunkt sX1 ist am Rechteck
// Distanz: d=SQRT((y2-y1)^2+(x2-x1)^2)
var dS1 = Math.sqrt(Math.pow(rY1 - lastPathPunktY, 2) + Math.pow(sX1 - lastPathPunktX, 2));
lengthToPoint.push({
"distanz": dS1,
"x": sX1,
"y": rY1
});
}
var sX2 = (rY2 - b) / m; // S2(sX2|rY2)
if (sX2 >= rX1 && sX2 <= rX2) {
// Der Schnittpunkt sX2 ist am Rechteck
// Distanz: d=SQRT((y2-y1)^2+(x2-x1)^2)
var dS2 = Math.sqrt(Math.pow(rY2 - lastPathPunktY, 2) + Math.pow(sX2 - lastPathPunktX, 2));
lengthToPoint.push({
"distanz": dS2,
"x": sX2,
"y": rY2
});
}
// Vertikale Geraden:
//
// y = m*x + b
var sY1 = m * rX1 + b; // S3(rX1|sY1)
if (sY1 >= rY1 && sY1 <= rY2) {
// Der Schnittpunkt sY1 ist am Rechteck
// Distanz: d=SQRT((y2-y1)^2+(x2-x1)^2)
var dS3 = Math.sqrt(Math.pow(sY1 - lastPathPunktY, 2) + Math.pow(rX1 - lastPathPunktX, 2));
lengthToPoint.push({
"distanz": dS3,
"x": rX1,
"y": sY1
});
}
var sY2 = m * rX2 + b; // S4(rX2|sY2)
if (sY2 >= rY1 && sY2 <= rY2) {
// Der Schnittpunkt sY2 ist am Rechteck
// Distanz: d=SQRT((y2-y1)^2+(x2-x1)^2)
var dS4 = Math.sqrt(Math.pow(sY2 - lastPathPunktY, 2) + Math.pow(rX2 - lastPathPunktX, 2));
lengthToPoint.push({
"distanz": dS4,
"x": rX2,
"y": sY2
});
}
// Sortiere alle Punkte nach Distanz - der mit der kleinsten Entfernung isses
lengthToPoint.sort(function (a, b) { return a.distanz - b.distanz });
if (lengthToPoint.length > 0)
{
this.addPoint(new go.Point(Math.round(lengthToPoint[0].x), Math.round(lengthToPoint[0].y)));
}
else
{
this.addPoint(new go.Point(Math.round(lastPathPunktX), Math.round(lastPathPunktY)));
}
}
return true;
};
// end MultiNodePathLink class
Eine halbe Stunde von mir entfernt befindet sich ein beliebtes Ausflugsziel in der Rhön – die Wasserkuppe. In der Skisaison, welche meistens Anfang Januar beginnt, erwischt man oft Tage mit schlechtem Wetter. Wenn man mal einen schönen Tag erwischt ist die Piste leider oft gerammelt voll. Da ich z.Zt. meine betriebliche Elternzeit, welche durch das großzügige Angebot meine Arbeitgebers ermöglicht wird, mit einem freiem Tag in der Woche in Anspruch nehme, konnte ich an diesem Freitag bei fast leerer Piste und Kaiserwetter das folgende Video aufnehmen:
Meine Ski-Abfahrt bei Kaiserwetter auf der Wasserkuppe
Also J.B.O. hatte ja schon eine (mehr oder weniger) genehmigte Cover-Version von „Everybody“ mit dem Titel „Everybody“ auf der Platte, allerdings hatte ich irgendwie einen anderen Text im Ohr….
Und wer könnte dann wohl blöd genug sein den Kalauer in einen Coversong zu packen?
Ergebnis
Lyrics
Ich trink gerade (yeah) Ne Kaltschale Hopfenkaltschale Seid ihr auch so breit Beck's Bier's back alright
Oh mein Gott das Becks ist leer Ich trink zu schnell ich hätt gern mehr eben war die Flasch' noch voll doch es schmeckte viel zu toll
Ist euer Beck's Bier leer? (Yeaaah ) Und ihr möchtet mehr (Yeaaah) Trinkt ihr so schnell ihr könnt (Yeaaah) Denn wenn ihr alles alle trinkt kommt dann der Beck's-Mann und der bringt
Eine Schale (Yeeaaah) Hopfenkaltschale (Yeaaaah) Eine Kaltschale und die macht euch breit Beck's Bier's back alright alright....
Zwischenteil: Jetzt kommt mal her und trinkt mal leer macht euch das Leben nicht so schwer Der Beck's Mann bringt euch immer mehr feiert stets des Beck's Rückkehr
Die wenigsten Musiker machen sich Gedanken über den kommerziellen Plastik-Pop, welcher für die Feiermeute auf Mallorca oder für die Apres-Ski-Macher im Schirm aufbereitet wird. Die Musik gilt als niveaulos und frivol, was die Urlaubsgedanken weg von Moral, Anstand und anderen Pflichten bringen soll.
Ich wollte mal die ganzen Meinungen aus den Foren verifizieren und habe mir wirklich erfolgreiche Ballermann-Hits vorgenommen, angehört und versucht meine persönlichen Schlüsse aus dem Material zu ziehen.
Was macht einen Ballermann-Hit aus? Ist er wirklich so primitiv, wie es manch einer vermutet?
Meine ersten drei Versuche
Wie die meisten Leser jetzt vermuten, benötigt man eine Musiksoftware wie Cubase als DAW mit einigen Software-Instrumenten oder „echten Hardwaresynthesizern“. Ich persönlich nutze ausschließlich Software-Instrumente (VST Instrumente), die ich in meiner DAW eingebunden habe. Die folgenden Softwareinstrumente kommen unter Cubase bei mir zum Einsatz
Groove Agent für den Beat
Presets von Sylenth1 für die Melodien und Euronsynth-Akkorden
Retrologue 2 für das Nachstellen von analogen Synthesizer-Sounds
Samples (Hey! Hou! Wooosh!!! usw…)
Einen Rauschgenerator (weißes Rauschen) für Riser-Sounds (also diese Wind-Woosh-Übergänge zwischen Song-Teilen)
Sidechain-Kompressoren für Bass und Riser-Sounds, damit die Kick möglichst unbelegt/frei und durchsetzungsfähig bleibt (habe ich noch nicht perfektioniert).
Hier meine Ergebnisse:
Platz 3 bei der Teilnahme am Recording.de Ballermann-Contest BSC22. Der Refrain kommt aus meinem „Wellerman Deutsch“-Video von Youtube was mittlerweile 2,6 Mio. Views und 1.000.000 Spotify Streams hat.
Mein Song: „Wenn ich Bier trink, dann bin ich froh“ mit Cubase Arrangement Das Gejubel habe ich von einem Video der Fans der isländischen Nationalmannschaft entnommen
Schonmal ein guter Anfang. BPM und Melodien passen, habe noch keine mehstimmigen Harmonien und keinen Millenial Whoop reingesungen. Die Performance lässt auch noch etwas zu wünschen übrig. Mikrofon: Mit einem SM-57 eingesungen, was ich hinter einem Pop-Schutz hatte
Hier ist noch etwas älterer Versuch mit einem anderem Lied:
Mikrofon: Mal mit den RHODE NT-1 eingesungen
Ein Rezept
Hier hatte einer das folgende Rezept veröffentlicht:
1. Da hätten wir die Geschwindigkeit. Sie ist wie alle Hits an einen bestimmten Herzrythmus des Menschen angelehnt. Und auch eine gewisse Kopfnickfrequenz muss eingehalten werden. Daher ist diese Art typischer Pop immer so um 125-130 bpm angelegt.
2. Dann hätten wir sanfte Instrumente. Was sie machen, ist klassisches Songwriting. Wichtig ist, dass sie nicht experimentell sondern funktionell sind. Bei der Mucke gehts nicht um Sounds, sondern um gefällige Harmonie.
3. Chords & Melodie (kein ACID-Geschranze, TB303-Riffs oder modulares Synthesizer-Gedudel….) Ohne Harmonien gehts mal GARNICH. Und hier dürften die meisten scheitern. Ein Hit schreibt man nicht mal eben einfach so. Hier sind absolut Kenntnisse von Harmonielehre und Melodiekomposition erfordderlich. Wer das nicht beherrscht.. soll Minimal machen.
4. Text Geht er nicht gut über die Lippen, – ist er zu lyrisch – zu verstrickt – zu künstlerisch – zu schicki micki, hat man verloren. Jeder kennt die Texte und das hat mehrere Gründe. Nicht weil sie dumm sind, sondern weil die Wort- und Satzstruktur und die Wortklänge in sich selbst stimmig sind und gut mit Zunge und Zähnen harmonieren.
5. Produktion Ist die Komposition im Kasten muss das ganze auch noch erstklassig klingen. Und zwar ausproduziert und perfekt gemischt. Das ist hier kein Rotz-Rock, sondern Hochglanz-Plastik-Pop.
von Ari (scheint mittlerweile im Forum gesperrt zu sein)
Die folgenden Texte kommen gut an
Frivole bis hin zu obszönen Texten
Verbindung mit ausgelassender Feierei und starkem Alkoholkonsum
Geld egal / keine Kohle / ab ins Dispo / scheiss auf dein Geld usw …
Metaphern über Sonne, Palmen, Strand und Meer auf Mallorca
Je einfacher und absurder der Text, desto höher ist die Wahrscheinlichkeit die feierende Meute damit zu erreichen.
Einsatz von Risern, Swooshes und Reverse-Becken beim Übergang in eine anderen Part (z.B. in die Bridge oder den Refrain)
Durchsetzungsfähige Kick, oft mit Ducking-Bass (gerne Sägezahnbass)
Bass-Drops
Eurodance-Synthesizer die Sägezahn-Akkorde spielen
Döpp Döpp Döpp (oft genutzte Gesangshook, gerne im Chor mit einschlägiger Melodie)
Höre ich mir die „echten“ Ballermann-Hits mal an, stelle ich fest dass da i.d.R. doch mehrere Akkorde als nur C-Dur+Dominante(G)+Subdominante(F) und 120-130 BPM vorhanden sind… faszinierend ist, dass Mickie Krauses „Schatz schenk mir ein Foto“ sogar aus 9 Akkorden (mit Tonartwechsel) besteht. Es handelt sich aber ausschließlich um Dur- und Moll-Akkorde.
In fast jeder modernen Ballermann-Produktion sind die folgenden Elemente zu hören:
Beispiel: Schatzi Schenk mir ein Foto
Gemessen: 140 BPM (also kein 125 – 130 weil Herzschlagrythmus)
Tonart: A Dur / nach Tonartwechsel H Dur Es handelt sich also nicht um C-Dur, wie es oft für Ballermann Hits behauptet wird.
Harmonien
Wenn man sie auf einer Gitarre nachspielt, hören sich die Harmonien fast so an, als seien sie einem spanischem Gitarrenlied entsprungen.
Intro
A, E, D, E
Bridge-Akkord
C#m
Strophe
2x (F#m, E, Hm)
Bridge Refrain (… hast du ein Foto oder hast du ne Nummer dabei)
Tonartwechsel (… die Stühle in den Himmel… [Riser Sound Drums weg und wieder einblenden])
Refrain 2 Halbtöne höher (auf H, F#, E, F#) gesungen mit „La la la lalalala“ – und dann noch 3x normal
Outro
Bleibt auf H-Dur, endet mit Applaus und Gejubel Samples und einer Explosion auf dem letzten Bass-Drum-Hit (evtl. auch mit Bass Drop)
Fürchterlich uninstrumental aber sehr erfolgreich 🙂 . Wer also gerne als Ballermann-Star 300 Tage im Jahr auf der Bühne (oder auf einer Bierkiste) stehen möchte muss als Referenz mind. einen Ballermann-Hit landen. In allen Videos von Mickie akquiriert er haufenweise Frauen damit der frivole Textteil neben der Alkoholverherrlichung zur Geltung kommt
Mickies Produktionen
Ich habe ein YouTube-Video entdeckt, in dem Mickie bei XTREME SOUND in Köln ist:
Mickie bekommt bestimmt Vergünstigungen wenn er Werbung für XTREME SOUND macht 🙂 … er ist aber nur einer von vielen Chartplatzierern die von dieser Firma produziert wurden.
Auf der Website von XTREME SOUND findet man einen ganzen Haufen bekannter und unbekannter Künstler. Im Grunde hat alles den selben Sound/die selbe Lautheit. DJ Ötzi, Möhre, Almklausi u.v.m. stehen auf deren Liste – alles keine namenlosen Künstler.
Ohne die Songs von Xtreme Sound hätten die Deutschen wohl weniger zu feiern, denn das Studio allein steht für etwa dreiviertel aller Stimmungs-Hits.
Tipps der Macher hinter Mickies Hits
Zum Arrangement:
Seine Kompositionen reicht Pfeil mal unaufgefordert bei Tonstudios ein, mal wird er für Auftragsproduktionen für konkrete Künstler angefragt. Im Durchschnitt erreichen Xtreme Sound so Woche für Woche 20 neue Titel, von denen die allermeisten jedoch mangels Aussicht auf Erfolg nicht veröffentlicht werden. Um die 70 Songs produziert das Studio pro Jahr, wobei den Machern mit ihrer jahrelangen Erfahrung und dem Wissen um aktuelle Trends oft die optimale Kombination aus Künstler, Song und Produktion gelingt. Ein Riesenmarkt im nationalen Musikgeschäft. Mit ganz eigenen Regeln.
Zum Text (Nummer 5) – Die Leute müssen sich den Ref. aufs T-Shirt drucken wollen…
„Beim Schlager ist die Melodie wichtiger und die Texte drehen sich mehr um die Themen Partnerschaft und Liebe. Bei Ballermann-Liedern ähneln sich viele Songs und haben einen schnellen Beat. Dafür kommt’s hier mehr auf den Text an.“ Gerade der Refrain muss so sein, dass die Leute sich wiedererkennen und damit identifizieren können. „Am besten ist er so geil, dass sie sich ihn aufs T-Shirt drucken lassen würden“, so Pfeil.
Ballermann-Hits bestehen fast ausschließlich aus Synthesizer-Klängen und Riser-Sounds, haben aber oftmals mehr als nur 3 Akkorde. Das ultimative funktionierende Rezept gibt es nicht. Der Sound und die Texte sind bei vielen Stücken ähnlich, da XTREME SOUND in Köln zwei Drittel der Ballermann-Stars produziert, mixt und mastered.
Mal abgesehen von der Produktion gehört ein natürliches Talent Menschen zu animieren dazu. Wer den Pausenclown in der Schule markiert hat, sollte damit gute Voraussetzungen mitbringen. Wer zusätzlich eine Gleichgültigkeit gegenüber der Tatsache hat, dass er ausschließlich vor betrunkenen Menschen spielen wird und viel harte Arbeit investieren möchte, ist hier richtig – obgleich die Erfolgschancen aufgrund zahlreicher Newcomer nicht besonders hoch sind. Mickie Krause hat z.B. für seine Videos 20 Strandschönheiten aufgegabelt und dazu animiert sich mit ihm zum Affen zu machen :-). Wer eher im stillem Kämmerchen Musik prodziert und Songs writet, wird nicht besonders weit kommen.
„.. auf Mallorca wird darüber entschieden, welche Lieder zum Hit werden…“
Pfeil von XTREME Sound Köln
Zitat aus dem Forum: „Wer woran scheitern möchte, ist jedem selbst überlassen. Fakt ist – diese Musikrichtung ist alles andere als einfach! „
Kennt Ihr noch die Game Boy Version von Super Mario? Richtig das war Super Mario Land! Dieses Spiel hat etliche Stunden meiner Lebenszeit in jungen Jahren verbrannt. War es am Pausenhof nicht damals eine Ehre behaupten zu können, man habe das Spiel bereits durchgezockt? Ich kann mich an die Game Boy Zeiten erinnern, in denen fieberhaft Tipps, Tricks und Geheimnisse für das Durchspielen ausgetauscht wurden.
Super Mario Land Theme – von mir nachgespielt auf dem Keyboard mit Quadrat-Oszillator
Als ich den nachgespielten Theme nun einem Bekannten zeigte, der angab früher auch im Super Mario Rausch gewesen zu sein, kam zunächst die Frage:
„Ist das aus dem Game oder hast du dir das selber ausgedacht?“
Meine erste Vermutung ich hätte den Theme dermaßen unkenntlich nachgespielt, dass ein eingefleischter Super Mario Fan ihn nicht erkennen kann, erwies sich dann Gott-sei-Dank als falsch. Mein Bekannter besaß keinen Game Boy. Er kannte nur den typischen NES-Theme von Super Mario Bros., welcher tausendfach im Internet nachgespielt wurde/wird (von Nintendo Sound Designer „Koji Kondo“). Interessant ist, dass der Theme von Super Mario Land eigens für die Game Boy Version komponiert wurde, auch wenn er nicht direkt für den Quadrat-Ausgang einer Spielekonsole konzipiert ist.
Der Komponist vom Super Mario Land Main Theme ist der Japaner „Hirokazu Tanaka“, welcher zu der Zeit viele Soundtracks für Nintendo verfasst hat, wie z.B. auch die Musik von Tetris. Das Album mit der Original-Musik von ihm findet man hier:
Es handelt sich hierbei um den ersten Titel „MARIO ADVENTURES I (Main BGM #1)„. Da die Stücke aber scheinbar nicht per se für eine Nintendo Konsole entwickelt wurden, dauert es eine Weile bis man ihn wirklich erkennt.