ui sound player functional
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 450 B |
Binary file not shown.
|
After Width: | Height: | Size: 538 B |
@@ -1,110 +0,0 @@
|
||||
package funkin.editors.charter;
|
||||
|
||||
import flixel.util.FlxColor;
|
||||
import funkin.backend.system.Conductor;
|
||||
import openfl.geom.Rectangle;
|
||||
import openfl.media.Sound;
|
||||
import flixel.system.FlxSound;
|
||||
import lime.media.AudioBuffer;
|
||||
import flixel.FlxSprite;
|
||||
|
||||
class CharterWaveForms extends FlxTypedGroup<WaveformSprite> {
|
||||
public var sound:FlxSound;
|
||||
public var strumLineID:Int = 0;
|
||||
|
||||
public function new(sound:FlxSound) {
|
||||
this.sound = sound;
|
||||
super();
|
||||
|
||||
for (measure in 0...Std.int(Conductor.getMeasuresLength())) {
|
||||
var waveFormMeasure:WaveformSprite = new WaveformSprite(0, (40 * Conductor.getMeasureLength()) * measure, sound, 40 * 4, Std.int(40 * Conductor.getMeasureLength()));
|
||||
waveFormMeasure.generateFlixel(
|
||||
Conductor.getTimeForStep(measure * Conductor.getMeasureLength()),
|
||||
Conductor.getTimeForStep((measure+1) * Conductor.getMeasureLength())
|
||||
);
|
||||
trace(
|
||||
Conductor.getTimeForStep(measure * Conductor.getMeasureLength()),
|
||||
Conductor.getTimeForStep((measure+1) * Conductor.getMeasureLength())
|
||||
);
|
||||
add(waveFormMeasure);
|
||||
}
|
||||
}
|
||||
|
||||
public override function update(elapsed:Float) {
|
||||
for (mem in members) mem.x = strumLineID * 40 * 4;
|
||||
super.update(elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
class WaveformSprite extends FlxSprite {
|
||||
public var buffer:AudioBuffer;
|
||||
public var sound:Sound;
|
||||
public var peak:Float = 0;
|
||||
public var valid:Bool = true;
|
||||
|
||||
public override function destroy() {
|
||||
super.destroy();
|
||||
if (buffer != null) {
|
||||
buffer.data.buffer = null;
|
||||
buffer.dispose();
|
||||
}
|
||||
}
|
||||
public function new(x:Float, y:Float, buffer:Dynamic, w:Int, h:Int) {
|
||||
super(x,y);
|
||||
this.buffer = null;
|
||||
if (Std.isOfType(buffer, FlxSound)) {
|
||||
@:privateAccess
|
||||
this.buffer = cast(buffer, FlxSound)._sound.__buffer;
|
||||
@:privateAccess
|
||||
this.sound = cast(buffer, FlxSound)._sound;
|
||||
} else if (Std.isOfType(buffer, Sound)) {
|
||||
@:privateAccess
|
||||
this.buffer = cast(buffer, Sound).__buffer;
|
||||
this.sound = cast(buffer, Sound);
|
||||
} else if (Std.isOfType(buffer, AudioBuffer)) {
|
||||
@:privateAccess
|
||||
this.buffer = cast(buffer, AudioBuffer);
|
||||
} else {
|
||||
valid = false;
|
||||
return;
|
||||
}
|
||||
peak = Math.pow(2, buffer.bitsPerSample-1)-1; // max positive value of a bitsPerSample bits integer
|
||||
makeGraphic(w, h, FlxColor.WHITE); // transparent
|
||||
}
|
||||
|
||||
public function generate(startPos:Int, endPos:Int) {
|
||||
if (!valid) return;
|
||||
startPos -= startPos % buffer.bitsPerSample;
|
||||
endPos -= endPos % buffer.bitsPerSample;
|
||||
pixels.lock();
|
||||
pixels.fillRect(new Rectangle(0, 0, pixels.width, pixels.height), 0);
|
||||
var diff = endPos - startPos;
|
||||
var diffRange = Math.floor(diff / pixels.height);
|
||||
for(y in 0...pixels.height) {
|
||||
var d = Math.floor(diff * (y / pixels.height));
|
||||
d -= d % buffer.bitsPerSample;
|
||||
var pos = startPos + d;
|
||||
var max:Int = 0;
|
||||
for(i in 0...Math.floor(diffRange / buffer.bitsPerSample)) {
|
||||
var thing = buffer.data.buffer.get(pos + (i * buffer.bitsPerSample)) | (buffer.data.buffer.get(pos + (i * buffer.bitsPerSample) + 1) << 8);
|
||||
if (thing > 256 * 128)
|
||||
thing -= 256 * 256;
|
||||
if (max < thing) max = thing;
|
||||
}
|
||||
var thing = max;
|
||||
var w = (thing) / pixels.width;
|
||||
pixels.fillRect(new Rectangle((pixels.width / 2) - (w / 2), y, w, 1), FlxColor.RED);
|
||||
}
|
||||
pixels.unlock();
|
||||
}
|
||||
|
||||
public function generateFlixel(startPos:Float, endPos:Float) {
|
||||
if (!valid) return;
|
||||
var rateFrequency = (1 / buffer.sampleRate);
|
||||
var multiplicator = 1 / rateFrequency; // 1 hz/s
|
||||
multiplicator *= buffer.bitsPerSample;
|
||||
multiplicator -= multiplicator % buffer.bitsPerSample;
|
||||
|
||||
generate(Math.floor(startPos * multiplicator / 4000 / buffer.bitsPerSample) * buffer.bitsPerSample, Math.floor(endPos * multiplicator / 4000 / buffer.bitsPerSample) * buffer.bitsPerSample);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import funkin.backend.chart.ChartData;
|
||||
import haxe.io.Bytes;
|
||||
|
||||
typedef SongCreationData = {
|
||||
var song:ChartData;
|
||||
var meta:ChartMetaData;
|
||||
var instBytes:Bytes;
|
||||
var voicesBytes:Bytes;
|
||||
}
|
||||
@@ -81,16 +81,16 @@ class SongCreationScreen extends UISubstateWindow {
|
||||
addLabelOn(needsVoicesCheckbox, "Needs Voices");
|
||||
needsVoicesCheckbox.y += 6; needsVoicesCheckbox.x += 4;
|
||||
|
||||
instExplorer = new UIFileExplorer(songNameTextBox.x, songNameTextBox.y + 32 + 36, #if html5 "mp3" #else "ogg" #end, function (res) {
|
||||
var audioPlayer:UIAudioPlayer = new UIAudioPlayer(instExplorer.x + 16, instExplorer.y + 8, res);
|
||||
instExplorer = new UIFileExplorer(songNameTextBox.x, songNameTextBox.y + 32 + 36, Paths.SOUND_EXT, function (res) {
|
||||
var audioPlayer:UIAudioPlayer = new UIAudioPlayer(instExplorer.x + 8, instExplorer.y + 8, res);
|
||||
instExplorer.members.push(audioPlayer);
|
||||
instExplorer.uiElement = audioPlayer;
|
||||
});
|
||||
songDataGroup.add(instExplorer);
|
||||
addLabelOn(instExplorer, "Inst Audio File");
|
||||
|
||||
voicesExplorer = new UIFileExplorer(instExplorer.x + 320 + 26, instExplorer.y, #if html5 "mp3" #else "ogg" #end, function (res) {
|
||||
var audioPlayer:UIAudioPlayer = new UIAudioPlayer(voicesExplorer.x + 16, voicesExplorer.y + 8, res);
|
||||
voicesExplorer = new UIFileExplorer(instExplorer.x + 320 + 26, instExplorer.y, Paths.SOUND_EXT, function (res) {
|
||||
var audioPlayer:UIAudioPlayer = new UIAudioPlayer(voicesExplorer.x + 8, voicesExplorer.y + 8, res);
|
||||
voicesExplorer.members.push(audioPlayer);
|
||||
voicesExplorer.uiElement = audioPlayer;
|
||||
});
|
||||
|
||||
@@ -1,39 +1,91 @@
|
||||
package funkin.editors.ui;
|
||||
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.ui.FlxBar;
|
||||
import openfl.geom.Rectangle;
|
||||
import flixel.sound.FlxSound;
|
||||
import haxe.io.Bytes;
|
||||
import lime.media.AudioBuffer;
|
||||
import openfl.media.Sound;
|
||||
import flixel.util.FlxStringUtil;
|
||||
|
||||
using flixel.util.FlxSpriteUtil;
|
||||
|
||||
class UIAudioPlayer extends UIButton {
|
||||
public var sound:FlxSound;
|
||||
public var bytes:Bytes;
|
||||
|
||||
public var playingSprite:FlxSprite;
|
||||
public var timeBar:FlxBar;
|
||||
public var timeText:UIText;
|
||||
|
||||
public var timeBarSpr:UISprite; // VISUAL FEEDBACK !11!11!
|
||||
|
||||
public function new(x:Float, y:Float, bytes:Bytes) {
|
||||
sound = FlxG.sound.load(Sound.fromAudioBuffer(AudioBuffer.fromBytes(bytes)));
|
||||
|
||||
super(x, y, "", function () {
|
||||
if (sound.playing) sound.pause();
|
||||
else sound.play();
|
||||
}, 58 - 18, 58 - 18);
|
||||
else sound.play(false, sound.time);
|
||||
}, 58 - 16, 58 - 16);
|
||||
trace(x,y);
|
||||
|
||||
playingSprite = new FlxSprite(x + ((58 - 18)/2) - 8, y + ((58 - 18)/2) - 8).loadGraphic(Paths.image('editors/charter/audio-buttons'), true, 16, 16);
|
||||
playingSprite = new FlxSprite(x + ((58 - 16)/2) - 8, y + ((58 - 16)/2) - 8).loadGraphic(Paths.image('editors/charter/audio-buttons'), true, 16, 16);
|
||||
playingSprite.animation.add("paused", [0]);
|
||||
playingSprite.animation.add("playing", [1]);
|
||||
playingSprite.antialiasing = false;
|
||||
playingSprite.updateHitbox();
|
||||
members.push(playingSprite);
|
||||
|
||||
timeText = new UIText(x + bWidth + 8, y + 4, 0, "", 12);
|
||||
timeText.alignment = RIGHT;
|
||||
members.push(timeText);
|
||||
|
||||
timeBar = new FlxBar(x + bWidth + 8, y + (58 - 16) - ((58 - 16)/3) - 4, LEFT_TO_RIGHT, 202, Std.int((58 - 16)/3), sound, "time", 0, sound.length);
|
||||
timeBar.createImageBar(Paths.image('editors/charter/audio-time-empty'), Paths.image('editors/charter/audio-time-full'));
|
||||
timeBar.numDivisions = timeBar.barWidth;
|
||||
members.push(timeBar);
|
||||
|
||||
timeBarSpr = cast new UISprite(timeBar.x, timeBar.y).makeGraphic(timeBar.barWidth, timeBar.barHeight, 0xFFFFFF);
|
||||
timeBarSpr.alpha = 0;
|
||||
members.push(timeBarSpr);
|
||||
}
|
||||
|
||||
public var dragging:Bool = false;
|
||||
public var wasPlaying:Bool = false;
|
||||
|
||||
public override function update(elapsed:Float) {
|
||||
super.update(elapsed);
|
||||
|
||||
if (sound != null)
|
||||
if (sound != null) {
|
||||
playingSprite.animation.play(sound.playing ? "playing" : "paused");
|
||||
timeText.text = '${FlxStringUtil.formatTime(sound.time/1000, true)} / ${FlxStringUtil.formatTime(sound.length/1000)}';
|
||||
}
|
||||
|
||||
var mousePos = FlxG.mouse.getScreenPosition(__lastDrawCameras[0], FlxPoint.get());
|
||||
var spritePos:FlxPoint = timeBar.getScreenPosition(FlxPoint.get(), __lastDrawCameras[0]);
|
||||
|
||||
if (((mousePos.x > (spritePos.x)) && (mousePos.x < (spritePos.x) + timeBar.barWidth))
|
||||
&& ((mousePos.y > (spritePos.y)) && (mousePos.y < (spritePos.y) + timeBar.barHeight))) {
|
||||
timeBarSpr.cursor = BUTTON;
|
||||
timeBarSpr.alpha = 0.3;
|
||||
if (FlxG.mouse.justPressed) {
|
||||
dragging = true;
|
||||
wasPlaying = sound.playing;
|
||||
}
|
||||
|
||||
if (FlxG.mouse.pressed && dragging) {
|
||||
if (sound.playing) sound.pause();
|
||||
sound.time = FlxMath.remapToRange(mousePos.x - spritePos.x, 0, timeBar.barWidth, 0, sound.length);
|
||||
}
|
||||
} else {
|
||||
timeBarSpr.cursor = ARROW;
|
||||
timeBarSpr.alpha = 0;
|
||||
}
|
||||
|
||||
if (FlxG.mouse.released && dragging && wasPlaying) {
|
||||
sound.play(dragging = wasPlaying = false, sound.time);
|
||||
}
|
||||
}
|
||||
|
||||
public override function destroy() {
|
||||
|
||||
@@ -29,14 +29,14 @@ class UIFileExplorer extends UISliceSprite {
|
||||
if (this.onFile != null) this.onFile(file);
|
||||
});
|
||||
fileDialog.open(fileType);
|
||||
}, 320 - 16, 58 - 18);
|
||||
}, 320 - 16, 58 - 16);
|
||||
members.push(uploadButton);
|
||||
|
||||
uploadIcon = new FlxSprite(uploadButton.x + (uploadButton.bWidth / 2) - 8, uploadButton.y + ((58-18)/2) - 8).loadGraphic(Paths.image('editors/charter/upload-button'));
|
||||
uploadIcon = new FlxSprite(uploadButton.x + (uploadButton.bWidth / 2) - 8, uploadButton.y + ((58-16)/2) - 8).loadGraphic(Paths.image('editors/charter/upload-button'));
|
||||
uploadIcon.antialiasing = false;
|
||||
uploadButton.members.push(uploadIcon);
|
||||
|
||||
deleteButton = new UIButton(x + 320 - (58 - 18) - 16, y + 8, "", function () {
|
||||
deleteButton = new UIButton(x + 320 - (58 - 16) - 8, y + 8, "", function () {
|
||||
if (uiElement != null) {
|
||||
members.remove(uiElement);
|
||||
uiElement.destroy();
|
||||
@@ -46,11 +46,11 @@ class UIFileExplorer extends UISliceSprite {
|
||||
MemoryUtil.clearMajor();
|
||||
|
||||
deleteButton.visible = deleteButton.selectable = deleteIcon.visible = !(uploadButton.visible = uploadButton.selectable = true);
|
||||
}, 58 - 18, 58 - 18);
|
||||
}, 58 - 16, 58 - 16);
|
||||
deleteButton.color = 0xFFFF0000;
|
||||
members.push(deleteButton);
|
||||
|
||||
deleteIcon = new FlxSprite(deleteButton.x + ((58 - 18)/2) - 8, deleteButton.y + ((58 - 18)/2) - 8).loadGraphic(Paths.image('editors/character/delete-button'));
|
||||
deleteIcon = new FlxSprite(deleteButton.x + ((58 - 16)/2) - 8, deleteButton.y + ((58 - 16)/2) - 8).loadGraphic(Paths.image('editors/character/delete-button'));
|
||||
deleteIcon.antialiasing = false;
|
||||
members.push(deleteIcon);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user