captbaritone / webamp

Winamp 2 reimplemented for the browser
https://webamp.org
MIT License
9.72k stars 641 forks source link

Add the simple visualizer #4

Closed captbaritone closed 9 years ago

captbaritone commented 9 years ago

Looks like it could be built using this: https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode

lostsource commented 9 years ago

That should be the way to go. I had made something similar for this http://flairplayer.com

captbaritone commented 9 years ago

@lostsource Excellent. Any code to share, or interest in making another PR?

captbaritone commented 9 years ago

@Cqoicebordel shared this great article, which looks highly relevant: https://developer.tizen.org/fr/documentation/articles/advanced-web-audio-api-usage

captbaritone commented 9 years ago

Here is another resource. An example: http://webaudioapi.com/samples/visualizer/

PAEz commented 9 years ago

Screw that, add Milkdrop..... https://github.com/gattis/milkshake http://butterchurn.neocities.org/ http://www.nihilogic.dk/labs/juicydrop/ - Down at the mo ...and theres others. I dont seem to be able to find the latest one.

idleberg commented 9 years ago

There's also a version of AVS implemented in JS: Webvs

PAEz commented 9 years ago

Never seen that Webvs is sweet, thanks. Now if I could just get the editor to work ;)

captbaritone commented 9 years ago

Working on this.

idleberg commented 9 years ago

Let me point out there's a HTML5 clone of the AVS Editor, as well as several others. To convert AVS to Webvs, you can use this online tool. A look at its code might be helpful when creating custom editors.

captbaritone commented 9 years ago

After an entire morning of Googling I think I may have found a solution which allows us to read local files using the Web Audio API. We will probably have to sacrifice letting people load files from a url, but I think that's a worthwhile tradeoff for getting all the advantages of the Web Audio Api (panning, EQ, visualizer, volume that might work on iOS...).

http://stackoverflow.com/questions/24057133/javascript-readasarraybuffer-returns-empty-array-buffer/24076562#24076562

I'm working on refactoring media.js to use this approach.

captbaritone commented 9 years ago

I have a proof of concept for the sine wave visualization working. You can check it out on this branch. https://github.com/captbaritone/winamp2-js/tree/visualizer

It doesn't look right yet, but it's responding to the music, and the code is actually pretty simple. Plenty of work still to be done.

screen shot 2014-11-17 at 12 02 14 am

You can try it here: http://rawgit.com/captbaritone/winamp2-js/visualizer/index.html

PAEz commented 9 years ago

Sweet, really makes a difference. That visual looks sharp but when I tried it in Chrome the line was a faded grey, so I wondered why.... First, you havent set the width and height of the canvas. You set the css which describes how to display it but doesnt actually set the width and height of the canvas. You need to add width and height to the canvas tag in the html or set it in js. If you dont then Chrome seems to default to 150x300 which means its going to get shrunk alot. Second....this one is awkward for me to explain, so just check the second link ;) http://stackoverflow.com/questions/4938346/canvas-width-and-height-in-html5 http://stackoverflow.com/questions/13593527/canvas-make-the-line-thicker Its still not perfect really, but meh. Still got some debug stuff in there incase its useful...

/* Use Canvas to recreate the simple Winamp visualizer */
Visualizer = {
    do :
    true,
    init: function(canvasNode) {
        this.canvas = canvasNode;
        this.canvasCtx = this.canvas.getContext("2d");
        this.canvasCtx.translate(1, 1); //  http://stackoverflow.com/questions/13593527/canvas-make-the-line-thicker
        // set in the html, coz when I do it here the line still comes out faded?????
        // this.canvas.width=156;
  //       this.canvas.height=36;
        this.width = this.canvas.width;
        this.height = this.canvas.height;
        return this;
    },

    visualize: function(bufferLength, dataArray) {
        function avg() {
            var avg = 0;
            var count = 0;
            for (var l = lastIndex; l < index + 1; l++) {
                if (Visualizer.do)console.debug(l)
                avg += dataArray[l];
                count++;
            }
            var v = avg / count;
            return h * v / 128;
        }
        this.canvasCtx.clearRect(-2, -2, this.width + 2, this.height + 2); // +/- is just there to deal with offset, meh if its right or not ;)

        this.canvasCtx.lineWidth = 2; // 2 because were shrinking the canvas by 2
        this.canvasCtx.strokeStyle = 'rgba(255, 255, 255,1)';

        this.canvasCtx.beginPath();

        var sliceWidth = bufferLength / this.width * 1;
        var h = this.height / 2;

        this.canvasCtx.moveTo(-2, h);
        var index = 0;
        var lastIndex = 0;
        for (var i = 0, iEnd = this.width * 1; i < iEnd; i += 2) {
            index = i * sliceWidth | 0;
            this.canvasCtx.lineTo(i, avg());
            lastIndex = index + 1;
            // if (this.done) console.debug(i, y, v, sliceWidth, i * sliceWidth, dataArray.length)
        }
        lastIndex = index + 1;
            index = i * sliceWidth | 0;

        // this.canvasCtx.lineTo(this.width, h * dataArray[dataArray.length - 1] / 128.0);
        this.canvasCtx.lineTo(this.width, avg());

        this.do = false;

        this.canvasCtx.stroke();
    }
}
captbaritone commented 9 years ago

@PAEz Nice! This helps a lot. I've merged these changes into the branch. They are live on the link above.

I still feel like the amplitude of the wave is rather sedate compared to the native version. Any idea why that might be?

captbaritone commented 9 years ago

I amend my last complaint about the amplitude of the wave. I was testing with Bach. Testing with dubstep now, and the amplitude looks fine :)

PAEz commented 9 years ago

Ya left in the do, that was just for debugging. ;)

The look of the wave is different from winamp by my eyes. The browser version has anti aliasing and winamp doesnt. Now the codes been changed you could just paint a square/pixel at the location instead of drawing lines, this should remove the anti aliasing and be closer to winamp Id rekn....to tired to try right now ;) Totally agree that the amplitudes are different. Ive been playing a techno trak side by side and winamp DOES get higher/lower waves. But this is being done right by the looks of it so Id wonder if winamp is getting the wave different...would love to know what it is....maybe its normalizing the volume or just amping it a bit. And a smaller thing, I think the browser version might have a higher frame rate and thatd change the look of it.

OH, and thanks for the props in the commit....I love getting my name on things ;) But its never necessary.

captbaritone commented 9 years ago

I think getting the non-antialiased like would probably help it look more like the real app. Do we have enough data points that we could just write the pixels?

Looking at the Viscolor.txt documentation, I think there are two colors supplied for drawing the line. Maybe it does some primitive anti-aliasing?

It occurred to me that the native app may not scale the Y axis linearly. Maybe that could account for the amplitude difference? I wish we could see the source code ;)

captbaritone commented 9 years ago

Also, we have an issue where the oscilloscope line is one pixel too short. It's stopping one pixel before the end of the canvas. Perhaps this is due to having to print on the .5 points of the grid?

PAEz commented 9 years ago

I took some screenshots and yeah the last pixel is grey...grrrrr. Didnt notice coz its pretty much impossible for me to notice when its not zoomed in and it goes away when you do zoom in so its the resizing or something. I think that could be fixed rather easily, Im just too tired right now to fuss. Ill install a magnifier or something tomorrow so I can notice these things better, the one that comes with windows wasnt much help. Also noticed that its rather different to winamp in that its one pixel too far to the left and 2 pixels too far the right. And Im not 100% on what you mean by "Do we have enough data points that we could just write the pixels?", but Im pretty sure the answer is yes.

eq I took this screen shot to figure out what that second colour is and its those red dots, so thats what the second colour is for. What gets me is the fact that the wave isnt one colour!!!! What the hell is the rules?!?!?!

captbaritone commented 9 years ago

Rows 18 to 22 pertain to the oscilloscope colors. They function in the same fashion as the Spectrum Analyzer. Row 18 controls the colors that is displayed at the troughs and the row 22 is the color that is displayed at the crest. Each row between 18 and 22 sets a different level of the whole wave.

-- http://wiki.winamp.com/wiki/Editing_the_Configuration_Files#Configuration_File_.7C_VisColor.txt

I'm not sure I completely understand, but we could try tweaking those colors to see what it does.

captbaritone commented 9 years ago

I've merged my oscilloscope functionality into master. I'm going to close this issue and create smaller ones to address the problems we noticed, and the work that is still left to be done.