diff --git a/PlayWallCore/src/de/tobias/playpad/audio/Peakable.java b/PlayWallCore/src/de/tobias/playpad/audio/Peakable.java
new file mode 100644
index 0000000000000000000000000000000000000000..29f41ebc7f6ec0c0f2f756600773662934e7526d
--- /dev/null
+++ b/PlayWallCore/src/de/tobias/playpad/audio/Peakable.java
@@ -0,0 +1,16 @@
+package de.tobias.playpad.audio;
+
+import javafx.beans.property.DoubleProperty;
+
+public interface Peakable {
+
+	public enum Channel {
+
+		LEFT,
+		RIGHT;
+	}
+	
+	public DoubleProperty audioLevelProperty(Channel channel);
+	
+	public double getAudioLevel(Channel channel);
+}
diff --git a/PlayWallNative/.classpath b/PlayWallNative/.classpath
new file mode 100644
index 0000000000000000000000000000000000000000..7d03288488cf3143f0a6a22231d22bac9bde9d1b
--- /dev/null
+++ b/PlayWallNative/.classpath
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="test"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/PlayWallCore"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/libUtils"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/PlayWallNative/.gitignore b/PlayWallNative/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..ae3c1726048cd06b9a143e0376ed46dd9b9a8d53
--- /dev/null
+++ b/PlayWallNative/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/PlayWallNative/.project b/PlayWallNative/.project
new file mode 100644
index 0000000000000000000000000000000000000000..68507fdf0080728bcd1335ddb47c9170aeb3a493
--- /dev/null
+++ b/PlayWallNative/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>PlayWallNative</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/PlayWallNative/.settings/org.eclipse.jdt.core.prefs b/PlayWallNative/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..3a21537071bf4118b9e1ee864cb4bc258aa48211
--- /dev/null
+++ b/PlayWallNative/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/PlayWallNative/libNativeAudio.dylib b/PlayWallNative/libNativeAudio.dylib
new file mode 100644
index 0000000000000000000000000000000000000000..14afa4716652379483939e006f1d32ba3adde6bb
Binary files /dev/null and b/PlayWallNative/libNativeAudio.dylib differ
diff --git a/PlayWallNative/src/de/tobias/playpad/NativeAudio.java b/PlayWallNative/src/de/tobias/playpad/NativeAudio.java
new file mode 100644
index 0000000000000000000000000000000000000000..cee1d7277008783ef91cb119ce8b389791e4540e
--- /dev/null
+++ b/PlayWallNative/src/de/tobias/playpad/NativeAudio.java
@@ -0,0 +1,58 @@
+package de.tobias.playpad;
+
+public class NativeAudio {
+
+	public static native void initialize();
+	
+	public static native void play(int id);
+
+	public static native void pause(int id);
+
+	public static native void stop(int id);
+
+	public static native void setLoop(int id, boolean loop);
+
+	public static native double getVolume(int id);
+
+	public static native void setVolume(int id, double volume);
+
+	public static native boolean load(int id, String path);
+
+	public static native void dispose(int id);
+
+	public static native double getDuration(int id);
+
+	public static native double getPosition(int id);
+	
+	public static void onPeakMeter(int id, float left, float right) {
+		if (delegate != null) {
+			delegate.onPeakMeter(id, left, right);
+		}
+	}
+
+	public static void onPositionChanged(int id, double position) {
+		if (delegate != null) {
+			delegate.onPositionChanged(id, position);
+		}
+	}
+	
+	public static void onFinish(int id) {
+		if (delegate != null) {
+			delegate.onFinish(id);
+		}
+	}
+
+	private static NativeAudioDelegate delegate;
+
+	public static void setDelegate(NativeAudioDelegate delegate) {
+		NativeAudio.delegate = delegate;
+	}
+
+	public interface NativeAudioDelegate {
+		public void onFinish(int id);
+		
+		public void onPeakMeter(int id, float left, float right);
+		
+		public void onPositionChanged(int id, double position);
+	}
+}
diff --git a/PlayWallNative/src/de/tobias/playpad/NativeAudioMacHandler.java b/PlayWallNative/src/de/tobias/playpad/NativeAudioMacHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..066831def36afb550506bafaa2629c9e6e8f39dd
--- /dev/null
+++ b/PlayWallNative/src/de/tobias/playpad/NativeAudioMacHandler.java
@@ -0,0 +1,135 @@
+package de.tobias.playpad;
+
+import java.nio.file.Path;
+
+import de.tobias.playpad.audio.AudioHandler;
+import de.tobias.playpad.audio.Peakable;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.utils.util.Worker;
+import javafx.application.Platform;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ReadOnlyObjectProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.util.Duration;
+
+public class NativeAudioMacHandler extends AudioHandler implements Peakable {
+
+	private static int counter = 0;
+
+	private final int id;
+	ObjectProperty<Duration> positionProperty;
+	private ObjectProperty<Duration> durationProperty;
+	private boolean isLoaded;
+
+	private DoubleProperty leftPeak;
+	private DoubleProperty rightPeak;
+
+	public NativeAudioMacHandler(PadContent content) {
+		super(content);
+
+		id = counter++;
+		positionProperty = new SimpleObjectProperty<>();
+		durationProperty = new SimpleObjectProperty<>();
+
+		leftPeak = new SimpleDoubleProperty();
+		rightPeak = new SimpleDoubleProperty();
+	}
+
+	protected int getId() {
+		return id;
+	}
+
+	@Override
+	public void play() {
+		NativeAudio.setLoop(id, getContent().getPad().getPadSettings().isLoop());
+		NativeAudio.play(id);
+	}
+
+	@Override
+	public void pause() {
+		NativeAudio.pause(id);
+	}
+
+	@Override
+	public void stop() {
+		NativeAudio.stop(id);
+	}
+
+	@Override
+	public Duration getPosition() {
+		return positionProperty.get();
+	}
+
+	@Override
+	public ReadOnlyObjectProperty<Duration> positionProperty() {
+		return positionProperty;
+	}
+
+	@Override
+	public Duration getDuration() {
+		return durationProperty.get();
+	}
+
+	@Override
+	public ReadOnlyObjectProperty<Duration> durationProperty() {
+		return durationProperty;
+	}
+
+	@Override
+	public void setVolume(double volume) {
+		NativeAudio.setVolume(id, volume);
+
+	}
+
+	@Override
+	public boolean isMediaLoaded() {
+		return isLoaded;
+	}
+
+	@Override
+	public void loadMedia(Path[] paths) {
+		Platform.runLater(() ->
+		{
+			if (getContent().getPad().isPadVisible()) {
+				getContent().getPad().getController().getView().showBusyView(true);
+			}
+		});
+		Worker.runLater(() ->
+		{
+			isLoaded = NativeAudio.load(id, paths[0].toString());
+			if (isLoaded) {
+				Platform.runLater(() ->
+				{
+					durationProperty.set(Duration.seconds(NativeAudio.getDuration(id)));
+					getContent().getPad().setStatus(PadStatus.READY);
+					if (getContent().getPad().isPadVisible()) {
+						getContent().getPad().getController().getView().showBusyView(false);
+					}
+				});
+			}
+		});
+	}
+
+	@Override
+	public void unloadMedia() {
+		NativeAudio.dispose(id);
+	}
+
+	@Override
+	public DoubleProperty audioLevelProperty(Channel channel) {
+		if (channel == Channel.LEFT) {
+			return leftPeak;
+		} else if (channel == Channel.RIGHT) {
+			return rightPeak;
+		}
+		return null;
+	}
+
+	@Override
+	public double getAudioLevel(Channel channel) {
+		return audioLevelProperty(channel).get();
+	}
+}
diff --git a/PlayWallNative/src/de/tobias/playpad/NativeAudioMacHandlerConnect.java b/PlayWallNative/src/de/tobias/playpad/NativeAudioMacHandlerConnect.java
new file mode 100644
index 0000000000000000000000000000000000000000..66245637d4cd9adcaee4cab2710107f6fa924809
--- /dev/null
+++ b/PlayWallNative/src/de/tobias/playpad/NativeAudioMacHandlerConnect.java
@@ -0,0 +1,78 @@
+package de.tobias.playpad;
+
+import java.util.HashMap;
+
+import de.tobias.playpad.NativeAudio.NativeAudioDelegate;
+import de.tobias.playpad.audio.AudioCapability;
+import de.tobias.playpad.audio.AudioHandler;
+import de.tobias.playpad.audio.AudioHandlerConnect;
+import de.tobias.playpad.audio.Peakable.Channel;
+import de.tobias.playpad.pad.PadStatus;
+import de.tobias.playpad.pad.conntent.PadContent;
+import de.tobias.playpad.viewcontroller.AudioHandlerViewController;
+import javafx.util.Duration;
+
+public class NativeAudioMacHandlerConnect extends AudioHandlerConnect implements NativeAudioDelegate {
+
+	private static final HashMap<Integer, NativeAudioMacHandler> handlers = new HashMap<>();
+
+	public NativeAudioMacHandlerConnect() {
+		NativeAudio.initialize();
+		NativeAudio.setDelegate(this);
+	}
+
+	@Override
+	public AudioHandler createAudioHandler(PadContent content) {
+		NativeAudioMacHandler nativeAudioMacHandler = new NativeAudioMacHandler(content);
+		handlers.put(nativeAudioMacHandler.getId(), nativeAudioMacHandler);
+		return nativeAudioMacHandler;
+	}
+
+	@Override
+	public AudioHandlerViewController getAudioHandlerSettingsViewController() {
+		return null;
+	}
+
+	@Override
+	public String getType() {
+		return "Native";
+	}
+
+	@Override
+	public void onFinish(int id) {
+		NativeAudioMacHandler nativeAudioMacHandler = handlers.get(id);
+		if (nativeAudioMacHandler != null) {
+			PadContent content = nativeAudioMacHandler.getContent();
+			if (content != null) {
+				content.getPad().setStatus(PadStatus.STOP);
+			}
+		}
+	}
+	
+	@Override
+	public void onPositionChanged(int id, double position) {
+		NativeAudioMacHandler nativeAudioMacHandler = handlers.get(id);
+		if (nativeAudioMacHandler != null) {
+			nativeAudioMacHandler.positionProperty.set(Duration.seconds(position));
+		}
+	}
+	
+	@Override
+	public void onPeakMeter(int id, float left, float right) {
+		NativeAudioMacHandler nativeAudioMacHandler = handlers.get(id);
+		if (nativeAudioMacHandler != null) {
+			nativeAudioMacHandler.audioLevelProperty(Channel.LEFT).set(left);
+			nativeAudioMacHandler.audioLevelProperty(Channel.RIGHT).set(right);
+		}
+	}
+
+	@Override
+	public boolean isFeatureAvaiable(AudioCapability audioCapability) {
+		return false;
+	}
+
+	@Override
+	public AudioHandlerViewController getAudioFeatureSettings(AudioCapability audioCapablility) {
+		return null;
+	}
+}
diff --git a/PlayWallNative/src/de/tobias/playpad/Waveform.java b/PlayWallNative/src/de/tobias/playpad/Waveform.java
new file mode 100644
index 0000000000000000000000000000000000000000..f01873a01df7c0f3e1eb998941e3bd73b63519f6
--- /dev/null
+++ b/PlayWallNative/src/de/tobias/playpad/Waveform.java
@@ -0,0 +1,7 @@
+package de.tobias.playpad;
+
+public class Waveform {
+
+	public static native float[] createWaveform(String path);
+
+}
diff --git a/PlayWallNative/src/de/tobias/playpad/view/WaveformView.java b/PlayWallNative/src/de/tobias/playpad/view/WaveformView.java
new file mode 100644
index 0000000000000000000000000000000000000000..25029d49df5806ebd6ac9bbeba23d7941aeb091c
--- /dev/null
+++ b/PlayWallNative/src/de/tobias/playpad/view/WaveformView.java
@@ -0,0 +1,39 @@
+package de.tobias.playpad.view;
+
+import javafx.scene.paint.Color;
+import javafx.scene.shape.LineTo;
+import javafx.scene.shape.MoveTo;
+import javafx.scene.shape.Path;
+
+public class WaveformView extends Path {
+
+	public WaveformView(float[] data) {
+		getElements().add(new MoveTo(0, 0));
+
+		double width2 = data.length / 1200.0;
+		int width = data.length / 10000;
+		System.out.println(data.length);
+		System.out.println(width);
+
+		int i = 0;
+		for (i = 0; i < data.length; i += width) {
+			if (i < data.length) {
+				LineTo lineTo = new LineTo(i / width2, data[i] * 50.0);
+				MoveTo moveTo = new MoveTo(i / width2, data[i] * 50.0);
+
+				getElements().addAll(lineTo, moveTo);
+			}
+		}
+		for (; i >= 0; i -= width) {
+			if (i >= 0 && i < data.length) {
+				LineTo lineTo = new LineTo(i / width2, -data[i] * 50.0);
+				MoveTo moveTo = new MoveTo(i / width2, -data[i] * 50.0);
+
+				getElements().addAll(lineTo, moveTo);
+			}
+		}
+		getElements().add(new LineTo(0, 0));
+		getElements().add(new MoveTo(0, 0));
+		setFill(Color.BLACK);
+	}
+}
diff --git a/PlayWallNative/src/de_tobias_playpad_NativeAudio.h b/PlayWallNative/src/de_tobias_playpad_NativeAudio.h
new file mode 100644
index 0000000000000000000000000000000000000000..4bd710308b879f953bd90b3e96a9aa1ec1e2ef92
--- /dev/null
+++ b/PlayWallNative/src/de_tobias_playpad_NativeAudio.h
@@ -0,0 +1,85 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class de_tobias_playpad_NativeAudio */
+
+#ifndef _Included_de_tobias_playpad_NativeAudio
+#define _Included_de_tobias_playpad_NativeAudio
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    play
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_de_tobias_playpad_NativeAudio_play
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    pause
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_de_tobias_playpad_NativeAudio_pause
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    stop
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_de_tobias_playpad_NativeAudio_stop
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    getVolume
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL Java_de_tobias_playpad_NativeAudio_getVolume
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    setVolume
+ * Signature: (ID)V
+ */
+JNIEXPORT void JNICALL Java_de_tobias_playpad_NativeAudio_setVolume
+  (JNIEnv *, jclass, jint, jdouble);
+
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    load
+ * Signature: (ILjava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_de_tobias_playpad_NativeAudio_load
+  (JNIEnv *, jclass, jint, jstring);
+
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    dispose
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_de_tobias_playpad_NativeAudio_dispose
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    getDuration
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL Java_de_tobias_playpad_NativeAudio_getDuration
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     de_tobias_playpad_NativeAudio
+ * Method:    getPosition
+ * Signature: (I)D
+ */
+JNIEXPORT jdouble JNICALL Java_de_tobias_playpad_NativeAudio_getPosition
+  (JNIEnv *, jclass, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/PlayWallNative/src/de_tobias_playpad_Waveform.h b/PlayWallNative/src/de_tobias_playpad_Waveform.h
new file mode 100644
index 0000000000000000000000000000000000000000..9d0e45dcb853ff654b6c6e50ca73a8d9fc6ac183
--- /dev/null
+++ b/PlayWallNative/src/de_tobias_playpad_Waveform.h
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class de_tobias_playpad_Waveform */
+
+#ifndef _Included_de_tobias_playpad_Waveform
+#define _Included_de_tobias_playpad_Waveform
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     de_tobias_playpad_Waveform
+ * Method:    initialize
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_de_tobias_playpad_Waveform_initialize
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     de_tobias_playpad_Waveform
+ * Method:    createWaveform
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_de_tobias_playpad_Waveform_createWaveform
+  (JNIEnv *, jclass, jstring);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/PlayWallNative/test/de/tobias/playpad/NativeAudioTest.java b/PlayWallNative/test/de/tobias/playpad/NativeAudioTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0fe58a6cf60fba757ed8d1a7938d11149af87b5c
--- /dev/null
+++ b/PlayWallNative/test/de/tobias/playpad/NativeAudioTest.java
@@ -0,0 +1,20 @@
+package de.tobias.playpad;
+
+public class NativeAudioTest {
+	
+	public static void main(String[] args) {
+		System.load("/Users/tobias/Documents/Programmieren/Java/git/PlayWall/PlayWallNative/libNativeAudio.dylib");
+
+		NativeAudio.load(0, "/Users/tobias/Downloads/03%20Hymn%20For%20The%20Weekend.mp3.wav");
+		System.out.println(NativeAudio.getDuration(0));
+		NativeAudio.play(0);
+		
+		while (true) {
+			try {
+				Thread.sleep(100);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+}
diff --git a/PlayWallNative/test/de/tobias/playpad/WaveformTest.java b/PlayWallNative/test/de/tobias/playpad/WaveformTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..704d8b6eb7971ccaf75343790d49ffb86f45199f
--- /dev/null
+++ b/PlayWallNative/test/de/tobias/playpad/WaveformTest.java
@@ -0,0 +1,38 @@
+package de.tobias.playpad;
+
+import de.tobias.playpad.view.WaveformView;
+import javafx.application.Application;
+import javafx.scene.Scene;
+import javafx.scene.image.ImageView;
+import javafx.scene.image.WritableImage;
+import javafx.scene.layout.VBox;
+import javafx.stage.Stage;
+
+public class WaveformTest extends Application {
+
+	public static void main(String[] args) {
+		System.load("/Users/tobias/Documents/Programmieren/Java/git/PlayWall/PlayWallNative/libNativeAudio.dylib");
+
+		launch(args);
+	}
+
+	@Override
+	public void start(Stage primaryStage) throws Exception {
+		float[] data = Waveform.createWaveform("/Users/tobias/Music/iTunes/iTunes Media/Music/Coldplay/Mylo Xyloto/04 Charlie Brown.mp3");
+		float[] data2 = Waveform.createWaveform("/Users/tobias/Downloads/TNT-Loop.wav");
+		WaveformView view = new WaveformView(data);
+		WaveformView view2 = new WaveformView(data2);
+
+		WritableImage image = new WritableImage(1200, 150);
+		view.snapshot(null, image);
+		WritableImage image2 = new WritableImage(1200, 150);
+		view2.snapshot(null, image2);
+
+		VBox root = new VBox(new ImageView(image), new ImageView(image2));
+		Scene scene = new Scene(root);
+
+		primaryStage.setScene(scene);
+		primaryStage.show();
+	}
+
+}