Board logo

标题: [转载代码] 音频可视化效果 [打印本页]

作者: aa77dd@163.com    时间: 2016-10-22 22:06     标题: 音频可视化效果



转自: http://codepen.io/raurir/pen/ZQVrzg

演示地址:

https://a7d.000webhostapp.com/audio-visualiser/index_s_dread_rock.html
  1. <!DOCTYPE html>
  2. <html >
  3.   <head>
  4.     <meta charset="UTF-8">
  5.     <title>Audio Visualiser</title>
  6.     <style>
  7.     body {
  8.         background-color: #000;
  9.     }
  10.     canvas {
  11.         margin: 50px auto;
  12.         display: block;
  13.     }
  14.     </style>
  15.   </head>
  16.   <body>
  17.   </body>
  18. </html>
  19. <script>
  20. (function() {
  21.   var Alien, Aliencon, Analyse, Music, con,
  22.     bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
  23.   Alien = (function() {
  24.     Alien.prototype.grid = null;
  25.     Alien.prototype.cellSize = 30;
  26.     Alien.prototype.numberOfRows = 10;
  27.     Alien.prototype.numberOfColumns = 10;
  28.     Alien.prototype.halfColumns = 0;
  29.     Alien.prototype.colReflected = 0;
  30.     Alien.prototype.ticks = 0;
  31.     Alien.prototype.canvas = null;
  32.     Alien.prototype.drawingContext = null;
  33.     Alien.prototype.canvasWidth = 0;
  34.     Alien.prototype.canvasHeight = 0;
  35.     function Alien() {
  36.       this.step = bind(this.step, this);
  37.       this.getAlien = bind(this.getAlien, this);
  38.       this.halfColumns = this.numberOfColumns / 2;
  39.       this.canvasWidth = this.cellSize * (this.numberOfColumns + 2);
  40.       this.canvasHeight = this.cellSize * (this.numberOfRows + 2);
  41.       this.canvas = document.createElement('canvas');
  42.       this.drawingContext = this.canvas.getContext('2d');
  43.       this.canvas.height = this.canvasWidth;
  44.       this.canvas.width = this.canvasHeight;
  45.       this.canvas.aliens = {
  46.         x: 0,
  47.         y: 0
  48.       };
  49.     }
  50.     Alien.prototype.clearCanvas = function() {
  51.       return this.drawingContext.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
  52.     };
  53.     Alien.prototype.seed = function() {
  54.       var column, k, ref, results, row, seedCell;
  55.       this.grid = [];
  56.       results = [];
  57.       for (row = k = 0, ref = this.numberOfRows; 0 <= ref ? k < ref : k > ref; row = 0 <= ref ? ++k : --k) {
  58.         this.grid[row] = [];
  59.         results.push((function() {
  60.           var n, ref1, results1;
  61.           results1 = [];
  62.           for (column = n = 0, ref1 = this.halfColumns; 0 <= ref1 ? n < ref1 : n > ref1; column = 0 <= ref1 ? ++n : --n) {
  63.             seedCell = this.createSeedCell(column);
  64.             results1.push(this.grid[row][column] = seedCell);
  65.           }
  66.           return results1;
  67.         }).call(this));
  68.       }
  69.       return results;
  70.     };
  71.     Alien.prototype.createSeedCell = function(probability) {
  72.       var chance, cutoff, tobe;
  73.       chance = Math.random();
  74.       cutoff = (probability + 1) / (this.halfColumns + 1);
  75.       tobe = chance < cutoff;
  76.       return tobe;
  77.     };
  78.     Alien.prototype.generateAlien = function() {
  79.       var q, r;
  80.       r = (function(_this) {
  81.         return function(m) {
  82.           return ~~(Math.random() * m + 1);
  83.         };
  84.       })(this);
  85.       q = (function(_this) {
  86.         return function() {
  87.           var a, g, i, j, l;
  88.           l = r(11);
  89.           g = r(5);
  90.           a = [];
  91.           i = 0;
  92.           while (i < l) {
  93.             j = i * g;
  94.             a.push(j);
  95.             if (i) {
  96.               a.unshift(-j);
  97.             }
  98.             i++;
  99.           }
  100.           return a;
  101.         };
  102.       })(this);
  103.       return {
  104.         x: q(),
  105.         y: q()
  106.       };
  107.     };
  108.     Alien.prototype.drawGrid = function(pixels) {
  109.       var b, b1, colourFill, colourLine, column, g, g1, k, n, o, r, r1, ref, ref1, ref2, results, row;
  110.       this.canvas.aliens = this.generateAlien();
  111.       r = ~~(Math.random() * 128 + 64);
  112.       g = ~~(Math.random() * 128 + 64);
  113.       b = ~~(Math.random() * 128 + 64);
  114.       colourLine = "rgba(" + r + ", " + g + ", " + b + ", 1)";
  115.       r1 = ~~(r - Math.random() * 64);
  116.       g1 = ~~(g - Math.random() * 64);
  117.       b1 = ~~(b - Math.random() * 64);
  118.       colourFill = "rgb(" + r1 + ", " + g1 + ", " + b1 + ")";
  119.       for (row = k = 0, ref = this.numberOfRows; 0 <= ref ? k < ref : k > ref; row = 0 <= ref ? ++k : --k) {
  120.         for (column = n = 0, ref1 = this.numberOfColumns; 0 <= ref1 ? n < ref1 : n > ref1; column = 0 <= ref1 ? ++n : --n) {
  121.           this.drawCell(row, column, colourLine, 10);
  122.         }
  123.       }
  124.       results = [];
  125.       for (row = o = 0, ref2 = this.numberOfRows; 0 <= ref2 ? o < ref2 : o > ref2; row = 0 <= ref2 ? ++o : --o) {
  126.         results.push((function() {
  127.           var p, ref3, results1;
  128.           results1 = [];
  129.           for (column = p = 0, ref3 = this.numberOfColumns; 0 <= ref3 ? p < ref3 : p > ref3; column = 0 <= ref3 ? ++p : --p) {
  130.             results1.push(this.drawCell(row, column, colourFill, 0));
  131.           }
  132.           return results1;
  133.         }).call(this));
  134.       }
  135.       return results;
  136.     };
  137.     Alien.prototype.drawCell = function(y, x, fillStyle, strokeWidth) {
  138.       var colReflected, isOn;
  139.       if (x >= this.halfColumns) {
  140.         colReflected = this.numberOfColumns - x - 1;
  141.       } else {
  142.         colReflected = x;
  143.       }
  144.       isOn = this.grid[y][colReflected];
  145.       if (isOn) {
  146.         this.drawingContext.fillStyle = fillStyle;
  147.         return this.drawingContext.fillRect((1 + x) * this.cellSize - strokeWidth, (1 + y) * this.cellSize - strokeWidth, this.cellSize + strokeWidth * 2, this.cellSize + strokeWidth * 2);
  148.       }
  149.     };
  150.     Alien.prototype.getAlien = function() {
  151.       return this.canvas;
  152.     };
  153.     Alien.prototype.step = function() {};
  154.     Alien.prototype.change = function() {
  155.       this.clearCanvas();
  156.       this.seed();
  157.       return this.drawGrid();
  158.     };
  159.     return Alien;
  160.   })();
  161.   window.Alien = Aliencon = console;
  162.   Analyse = (function() {
  163.     Analyse.prototype.waves = null;
  164.     Analyse.prototype.node = null;
  165.     Analyse.prototype.analyser = null;
  166.     Analyse.prototype.audio = null;
  167.     Analyse.prototype.frameBufferSize = Math.pow(2, 11);
  168.     Analyse.prototype.channels = 4;
  169.     Analyse.prototype.bufferSize = 0;
  170.     Analyse.prototype.signal = null;
  171.     Analyse.prototype.fft = null;
  172.     Analyse.prototype.amplitude = 0;
  173.     Analyse.prototype.spectrum = [];
  174.     function Analyse() {
  175.       this.step = bind(this.step, this);
  176.       this.processAudio = bind(this.processAudio, this);
  177.       this.bufferSize = this.frameBufferSize / this.channels;
  178.       this.signal = new Float32Array(this.bufferSize);
  179.       this.fft = new FFT(this.bufferSize, 44100);
  180.       this.newAudioContext();
  181.       // this.loadAudio('https://dl.dropboxusercontent.com/u/729503/Codepen/usee.mp3');
  182.       this.loadAudio('https://cf-media.sndcdn.com/CmhscBlMZl1W.128.mp3?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiKjovL2NmLW1lZGlhLnNuZGNkbi5jb20vQ21oc2NCbE1abDFXLjEyOC5tcDMiLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE0NzcxMzk3MDN9fX1dfQ__&Signature=mCistR~h5En7Nk92Kq~bQIVWaSPmhz-PZ8CMB4OkboW-7Kg6zBGJ3Q5XQ~KDt-uMVYvelxaIZnmoB5rfyELS-ck0hX0WV4RRzHKsJXAAvQjEYES0SSpSueJFh4Vy6Oeh-xuwRK1gApq0S89Oo-km31w3cho4ix10WPcVu0Cgn0P57inrnDEq6NATn3T9iqNI47poxtqZk02VhL5GDr5DnxTvrWy7IqCTlci82LNKZEX1mY6quBP11R8EM7fUDd1BfbgEeZyjiP2IrrXsqpi9q3KDKOZtIIK24Kg2pWJWKzeHZBQu8zc8YQW-eeJYkAWpLDT132jvZ4CE3g1o3zSJow__&Key-Pair-Id=APKAJAGZ7VMH2PFPW6UQ');
  183.       con.log("Analyse constructor", this.signal.length);
  184.     }
  185.     Analyse.prototype.newAudioContext = function() {
  186.       var fok;
  187.       fok = (function(_this) {
  188.         return function(f) {
  189.           return window[f] != null;
  190.         };
  191.       })(this);
  192.       this.waves = false;
  193.       if (fok('AudioContext')) {
  194.         con.log("AudioContext");
  195.         this.waves = new AudioContext();
  196.       } else if (fok('webkitAudioContext')) {
  197.         con.log("webkitAudioContext");
  198.         this.waves = new webkitAudioContext();
  199.       }
  200.       return con.log("waves", this.waves);
  201.     };
  202.     Analyse.prototype.loadAudio = function(url) {
  203.       con.log("loadAudio", url, this.waves);
  204.       if (this.audio) {
  205.         this.audio.remove();
  206.       }
  207.       if (this.node) {
  208.         this.node.disconnect();
  209.       }
  210.       this.audio = new Audio();
  211.       this.audio.crossOrigin = "anonymous";
  212.       this.audio.preload = 'auto';
  213.       this.audio.controls = true;
  214.       document.body.appendChild(this.audio);
  215.       if (this.waves) {
  216.         con.log("waves created");
  217.         this.audio.addEventListener('canplay', (function(_this) {
  218.           return function(e) {
  219.             return _this.setupAudioNodes(e);
  220.           };
  221.         })(this));
  222.       } else {
  223.       }
  224.       return this.audio.src = url;
  225.     };
  226.     Analyse.prototype.setupAudioNodes = function(e) {
  227.       con.log("setupAudioNodes");
  228.       if (this.analyser == null) {
  229.         this.analyser = this.analyser || this.waves.createScriptProcessor(this.bufferSize, 2, 2);
  230.         this.analyser.onaudioprocess = this.processAudio;
  231.         this.node = this.waves.createMediaElementSource(this.audio);
  232.         this.node.connect(this.analyser);
  233.         this.analyser.connect(this.waves.destination);
  234.       }
  235.       return this.audio.play();
  236.     };
  237.     Analyse.prototype.processAudio = function(e) {
  238.       var i, inputArrayL, inputArrayR, k, outputArrayL, outputArrayR, ref;
  239.       inputArrayL = e.inputBuffer.getChannelData(0);
  240.       inputArrayR = e.inputBuffer.getChannelData(1);
  241.       outputArrayL = e.outputBuffer.getChannelData(0);
  242.       outputArrayR = e.outputBuffer.getChannelData(1);
  243.       for (i = k = 0, ref = this.bufferSize; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) {
  244.         outputArrayL[i] = inputArrayL[i];
  245.         outputArrayR[i] = inputArrayR[i];
  246.         this.signal[i] = (inputArrayL[i] + inputArrayR[i]) / 2;
  247.       }
  248.       this.fft.forward(this.signal);
  249.       return this.fftChanged();
  250.     };
  251.     Analyse.prototype.fftChanged = function() {
  252.       var i, k, magSum, ref, specLength;
  253.       specLength = this.fft.spectrum.length;
  254.       magSum = 0;
  255.       for (i = k = 0, ref = specLength; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) {
  256.         magSum += this.fft.spectrum[i];
  257.       }
  258.       return this.amplitude = 100 * magSum / specLength;
  259.     };
  260.     Analyse.prototype.step = function() {
  261.       var bandTotal, currentBand, i, k, ref, results, specLength, totalBands;
  262.       specLength = this.fft.spectrum.length;
  263.       totalBands = specLength / 32;
  264.       this.spectrum = [];
  265.       currentBand = -1;
  266.       results = [];
  267.       for (i = k = 0, ref = specLength; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) {
  268.         if (i % totalBands === 0) {
  269.           bandTotal = 0;
  270.           currentBand++;
  271.         }
  272.         bandTotal += this.fft.spectrum[i];
  273.         if (i % totalBands === totalBands - 1) {
  274.           results.push(this.spectrum[currentBand] = bandTotal);
  275.         } else {
  276.           results.push(void 0);
  277.         }
  278.       }
  279.       return results;
  280.     };
  281.     Analyse.prototype.getAnalysis = function() {
  282.       return {
  283.         spectrum: this.spectrum,
  284.         amplitude: this.amplitude,
  285.         waveform: this.signal
  286.       };
  287.     };
  288.     return Analyse;
  289.   })();
  290.   window.Analyse = Analyse;
  291. //------------------------------------------//
  292. //-------- STUFF FOR AUDIO ANALYSIS --------//
  293. function FourierTransform(bufferSize, sampleRate)
  294. {
  295. this.bufferSize = bufferSize;
  296. this.sampleRate = sampleRate;
  297. this.bandwidth  = bufferSize * sampleRate;
  298. this.spectrum   = new Float32Array(bufferSize/2);
  299. this.real       = new Float32Array(bufferSize);
  300. this.imag       = new Float32Array(bufferSize);
  301. this.peakBand   = 0;
  302. this.peak       = 0;
  303. this.getBandFrequency = function(index)
  304. {
  305. return this.bandwidth * index + this.bandwidth / 2;
  306. };
  307. this.calculateSpectrum = function()
  308. {
  309. var spectrum  = this.spectrum,
  310. real      = this.real,
  311. imag      = this.imag,
  312. bSi       = 2 / this.bufferSize,
  313. rval, ival, mag;
  314. this.peak = this.peakBand = 0;
  315. for (var i = 0, N = bufferSize*0.5; i < N; i++)
  316. {
  317. rval = real[i];
  318. ival = imag[i];
  319. mag = bSi * Math.sqrt(rval * rval + ival * ival);
  320. if (mag > this.peak)
  321. {
  322. this.peakBand = i;
  323. this.peak = mag;
  324. }
  325. spectrum[i] = mag;
  326. }
  327. };
  328. }
  329. function FFT(bufferSize, sampleRate)
  330. {
  331. FourierTransform.call(this, bufferSize, sampleRate);
  332. this.reverseTable = new Uint32Array(bufferSize);
  333. var limit = 1;
  334. var bit = bufferSize >> 1;
  335. var i;
  336. while (limit < bufferSize)
  337. {
  338. for (i = 0; i < limit; i++)
  339. this.reverseTable[i + limit] = this.reverseTable[i] + bit;
  340. limit = limit << 1;
  341. bit = bit >> 1;
  342. }
  343. this.sinTable = new Float32Array(bufferSize);
  344. this.cosTable = new Float32Array(bufferSize);
  345. for (i = 0; i < bufferSize; i++)
  346. {
  347. this.sinTable[i] = Math.sin(-Math.PI/i);
  348. this.cosTable[i] = Math.cos(-Math.PI/i);
  349. }
  350. }
  351. FFT.prototype.forward = function(buffer)
  352. {
  353.   var bufferSize      = this.bufferSize,
  354.       cosTable        = this.cosTable,
  355.       sinTable        = this.sinTable,
  356.       reverseTable    = this.reverseTable,
  357.       real            = this.real,
  358.       imag            = this.imag,
  359.       spectrum        = this.spectrum;
  360. var k = Math.floor(Math.log(bufferSize) / Math.LN2);
  361. if (Math.pow(2, k) !== bufferSize) { throw "Invalid buffer size, must be a power of 2."; }
  362. if (bufferSize !== buffer.length)  { throw "Supplied buffer is not the same size as defined FFT. FFT Size: " + bufferSize + " Buffer Size: " + buffer.length; }
  363. var halfSize = 1,
  364. phaseShiftStepReal,
  365. phaseShiftStepImag,
  366. currentPhaseShiftReal,
  367. currentPhaseShiftImag,
  368. off,
  369. tr,
  370. ti,
  371. tmpReal,
  372. i;
  373. for (i = 0; i < bufferSize; i++)
  374. {
  375. real[i] = buffer[reverseTable[i]];
  376. imag[i] = 0;
  377. }
  378. while (halfSize < bufferSize)
  379. {
  380. phaseShiftStepReal = cosTable[halfSize];
  381. phaseShiftStepImag = sinTable[halfSize];
  382. currentPhaseShiftReal = 1;
  383. currentPhaseShiftImag = 0;
  384. for (var fftStep = 0; fftStep < halfSize; fftStep++)
  385. {
  386. i = fftStep;
  387. while (i < bufferSize)
  388. {
  389. off = i + halfSize;
  390. tr = (currentPhaseShiftReal * real[off]) - (currentPhaseShiftImag * imag[off]);
  391. ti = (currentPhaseShiftReal * imag[off]) + (currentPhaseShiftImag * real[off]);
  392. real[off] = real[i] - tr;
  393. imag[off] = imag[i] - ti;
  394. real[i] += tr;
  395. imag[i] += ti;
  396. i += halfSize << 1;
  397. }
  398. tmpReal = currentPhaseShiftReal;
  399. currentPhaseShiftReal = (tmpReal * phaseShiftStepReal) - (currentPhaseShiftImag * phaseShiftStepImag);
  400. currentPhaseShiftImag = (tmpReal * phaseShiftStepImag) + (currentPhaseShiftImag * phaseShiftStepReal);
  401. }
  402. halfSize = halfSize << 1;
  403. }
  404. return this.calculateSpectrum();
  405. };
  406. window.FFT = FFT;
  407. ;
  408.   con = console;
  409.   Music = (function() {
  410.     Music.prototype.analyser = null;
  411.     Music.prototype.aliendude = null;
  412.     Music.prototype.canvas = null;
  413.     Music.prototype.pixels = null;
  414.     Music.prototype.canvasWidth = 1000;
  415.     Music.prototype.canvasHeight = 500;
  416.     Music.prototype.centreX = 0;
  417.     Music.prototype.centreY = 0;
  418.     Music.prototype.scale = 1;
  419.     Music.prototype.float = 20;
  420.     function Music() {
  421.       this.step = bind(this.step, this);
  422.       con.log("Music constructor");
  423.       this.createCanvas();
  424.       this.analyser = new Analyse(this.pixels, this.centreX, this.centreY);
  425.       this.aliendude = new Alien();
  426.       if (window.requestAnimationFrame) {
  427.         con.log("native requestAnimationFrame");
  428.       } else {
  429.         con.log("creating requestAnimationFrame");
  430.         window.requestAnimationFrame = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame;
  431.       }
  432.       this.step();
  433.     }
  434.     Music.prototype.createCanvas = function() {
  435.       this.centreX = this.canvasWidth / 2;
  436.       this.centreY = this.canvasHeight / 2;
  437.       this.canvas = document.createElement('canvas');
  438.       document.body.appendChild(this.canvas);
  439.       this.pixels = this.canvas.getContext('2d');
  440.       this.canvas.width = this.canvasWidth;
  441.       return this.canvas.height = this.canvasHeight;
  442.     };
  443.     Music.prototype.clearCanvas = function() {
  444.       this.pixels.fillStyle = "rgb(0, 0, 0)";
  445.       return this.pixels.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
  446.     };
  447.     Music.prototype.alienScale = 2;
  448.     Music.prototype.alienRotate = 0.01;
  449.     Music.prototype.step = function() {
  450.       var amplitude, anal, b, bandWidth, c, g, i, img, k, len, len1, level, n, o, p, padding, r, ref, ref1, ref2, ref3, sc, specLength, spectrum, waveform, waveformLength, x, y;
  451.       this.clearCanvas();
  452.       this.analyser.step();
  453.       this.aliendude.step();
  454.       anal = this.analyser.getAnalysis();
  455.       spectrum = anal.spectrum;
  456.       amplitude = anal.amplitude;
  457.       waveform = anal.waveform;
  458.       this.pixels.fillStyle = "rgb(0, 20, 40)";
  459.       this.pixels.fillRect(0, this.canvasHeight, this.canvasWidth, -amplitude * this.canvasHeight);
  460.       specLength = spectrum.length;
  461.       bandWidth = this.canvasWidth / specLength;
  462.       padding = 5;
  463.       for (i = k = 0, ref = specLength; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) {
  464.         c = ~~(i / specLength * 55);
  465.         r = 100;
  466.         g = 200 + c;
  467.         b = 255 - c;
  468.         level = spectrum[i];
  469.         this.pixels.fillStyle = "rgba(" + r + ", " + g + ", " + b + ", 0.5)";
  470.         this.pixels.fillRect(i * bandWidth + padding, this.canvasHeight, bandWidth - padding * 2, -level * this.centreY);
  471.       }
  472.       waveformLength = waveform.length;
  473.       bandWidth = this.canvasWidth / waveformLength;
  474.       this.pixels.beginPath();
  475.       for (i = n = 0, ref1 = waveformLength; 0 <= ref1 ? n < ref1 : n > ref1; i = 0 <= ref1 ? ++n : --n) {
  476.         this.pixels.strokeStyle = '#0fe';
  477.         this.pixels.lineWidth = 1;
  478.         x = i * bandWidth;
  479.         y = this.centreY + waveform[i] * this.centreY;
  480.         if (i === 0) {
  481.           this.pixels.moveTo(x, y);
  482.         } else {
  483.           this.pixels.lineTo(x, y);
  484.         }
  485.       }
  486.       this.pixels.stroke();
  487.       this.float += this.alienRotate;
  488.       this.scale = spectrum[0];
  489.       if (this.scale > this.alienScale * 4) {
  490.         this.aliendude.change();
  491.         this.alienScale = this.scale;
  492.         this.alienRotate = (Math.random() - 0.5) * 0.1;
  493.       } else {
  494.         this.alienScale *= 0.9;
  495.       }
  496.       sc = this.alienScale * 1;
  497.       img = this.aliendude.getAlien();
  498.       this.pixels.save();
  499.       this.pixels.translate(this.centreX, this.centreY);
  500.       this.pixels.rotate(this.float);
  501.       this.pixels.scale(sc, sc);
  502.       this.pixels.translate(-img.width / 2, -img.height / 2);
  503.       ref2 = img.aliens.x;
  504.       for (o = 0, len = ref2.length; o < len; o++) {
  505.         x = ref2[o];
  506.         ref3 = img.aliens.y;
  507.         for (p = 0, len1 = ref3.length; p < len1; p++) {
  508.           y = ref3[p];
  509.           this.pixels.drawImage(img, img.width * x, img.height * y);
  510.         }
  511.       }
  512.       this.pixels.restore();
  513.       return requestAnimationFrame(this.step);
  514.     };
  515.     return Music;
  516.   })();
  517.   window.Music = Music;
  518.   new Music();
  519. }).call(this);
  520. </script>
复制代码

作者: happy886rr    时间: 2016-10-22 22:36

居然是傅里叶变换
作者: 523066680    时间: 2016-10-22 22:49

本帖最后由 523066680 于 2016-10-22 22:59 编辑

要是结合分形想必是极美妙的
我觉得图像方面我可以玩的有趣一些,但是不懂音频解析,所以就当吹吹牛啦。模拟信号处理是不是一定会涉及博里叶变换?

恰巧就在今天看到知乎的一个帖子:有哪些计算机生成的精美图形?
某个回答里介绍了一款强大的音乐可视化插件——MilkDrop
https://www.zhihu.com/question/19935130/answer/127674701
作者: aa77dd@163.com    时间: 2016-10-22 22:57

本帖最后由 aa77dd@163.com 于 2016-10-22 23:01 编辑

回复 3# 523066680

自学过一点高数, 早忘光了, 不懂 傅里叶变换

想起了 N 年前 有增强版的 nullsoft winamp 就自带  MilkDrop  plug-in
作者: 523066680    时间: 2016-10-22 22:58

回复 4# aa77dd@163.com


    准备辞职深造,趁年轻。
作者: aa77dd@163.com    时间: 2016-10-22 23:08

回复 5# 523066680

哈哈, 同意

MilkDrop 源码?
http://forums.winamp.com/showthread.php?t=214971
作者: aa77dd@163.com    时间: 2016-10-22 23:32

回复 3# 523066680

回味经典  含 MilkDrop2 可视化效果插件
http://meggamusic.co.uk/winamp/Winamp_Download.htm

Winamp 所属公司 Nullsoft 的吉祥物是 一只 大羊驼





欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2