recorderjs-rails 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d8041ec3672629dae5b6d6d765c5f185e5e800ef
4
+ data.tar.gz: 51746e2fb3fbd1363c47fd1e9f4fbdd2ee6ecebc
5
+ SHA512:
6
+ metadata.gz: 53e1f69f2e5c35a389373eb4ceef0918a10857c292a4ef77a431ebd48c2dc83c842894822ce1af5e1e2cfa655af1a1151dc29752bd7fc2297cb966ed11e6f290
7
+ data.tar.gz: 537ecce15afc7ea5543d251209d3f80d8504d4a54bddfa853c03d2f528426fc31dcf2597554c4a08a20f7bb2a674d142e7444467df663b39cec877484aca48e3
@@ -0,0 +1 @@
1
+ recorderjs-rails
@@ -0,0 +1 @@
1
+ ruby-2.2.1
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+ ruby "2.2.1"
3
+
4
+ gemspec
5
+
@@ -0,0 +1,8 @@
1
+ recorderjs-rails
2
+ ================
3
+
4
+ A rails plugin for recording/exporting the output of Web Audio API nodes.
5
+
6
+ Source code: [https://github.com/mattdiamond/Recorderjs](https://github.com/mattdiamond/Recorderjs).
7
+
8
+
@@ -0,0 +1 @@
1
+ require 'recorderjs/rails'
@@ -0,0 +1,3 @@
1
+ require 'recorderjs/rails/engine'
2
+ require 'recorderjs/rails/version'
3
+
@@ -0,0 +1,6 @@
1
+ module Recorderjs
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Recorderjs
2
+ module Rails
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
6
+
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/recorderjs/rails/version', __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "recorderjs-rails"
6
+ s.version = Recorderjs::Rails::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["Julien Defrance"]
9
+ s.homepage = "https://github.com/mattdiamond/Recorderjs"
10
+
11
+ s.summary = "Use Recorderjs with Rails 4+"
12
+ s.description = "A plugin for recording/exporting the output of Web Audio API nodes"
13
+
14
+ s.required_rubygems_version = ">= 1.3.6"
15
+
16
+ s.add_dependency "railties", ">= 3.0", "< 5.0"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
20
+ s.require_path = 'lib'
21
+ end
22
+
@@ -0,0 +1,92 @@
1
+ (function(window){
2
+
3
+ var WORKER_PATH = 'recorderWorker.js';
4
+
5
+ var Recorder = function(source, cfg){
6
+ var config = cfg || {};
7
+ var bufferLen = config.bufferLen || 4096;
8
+ var numChannels = config.numChannels || 2;
9
+ this.context = source.context;
10
+ this.node = (this.context.createScriptProcessor ||
11
+ this.context.createJavaScriptNode).call(this.context,
12
+ bufferLen, numChannels, numChannels);
13
+ var worker = new Worker(config.workerPath || WORKER_PATH);
14
+ worker.postMessage({
15
+ command: 'init',
16
+ config: {
17
+ sampleRate: this.context.sampleRate,
18
+ numChannels: numChannels
19
+ }
20
+ });
21
+ var recording = false,
22
+ currCallback;
23
+
24
+ this.node.onaudioprocess = function(e){
25
+ if (!recording) return;
26
+ var buffer = [];
27
+ for (var channel = 0; channel < numChannels; channel++){
28
+ buffer.push(e.inputBuffer.getChannelData(channel));
29
+ }
30
+ worker.postMessage({
31
+ command: 'record',
32
+ buffer: buffer
33
+ });
34
+ }
35
+
36
+ this.configure = function(cfg){
37
+ for (var prop in cfg){
38
+ if (cfg.hasOwnProperty(prop)){
39
+ config[prop] = cfg[prop];
40
+ }
41
+ }
42
+ }
43
+
44
+ this.record = function(){
45
+ recording = true;
46
+ }
47
+
48
+ this.stop = function(){
49
+ recording = false;
50
+ }
51
+
52
+ this.clear = function(){
53
+ worker.postMessage({ command: 'clear' });
54
+ }
55
+
56
+ this.getBuffer = function(cb) {
57
+ currCallback = cb || config.callback;
58
+ worker.postMessage({ command: 'getBuffer' })
59
+ }
60
+
61
+ this.exportWAV = function(cb, type){
62
+ currCallback = cb || config.callback;
63
+ type = type || config.type || 'audio/wav';
64
+ if (!currCallback) throw new Error('Callback not set');
65
+ worker.postMessage({
66
+ command: 'exportWAV',
67
+ type: type
68
+ });
69
+ }
70
+
71
+ worker.onmessage = function(e){
72
+ var blob = e.data;
73
+ currCallback(blob);
74
+ }
75
+
76
+ source.connect(this.node);
77
+ this.node.connect(this.context.destination); //this should not be necessary
78
+ };
79
+
80
+ Recorder.forceDownload = function(blob, filename){
81
+ var url = (window.URL || window.webkitURL).createObjectURL(blob);
82
+ var link = window.document.createElement('a');
83
+ link.href = url;
84
+ link.download = filename || 'output.wav';
85
+ var click = document.createEvent("Event");
86
+ click.initEvent("click", true, true);
87
+ link.dispatchEvent(click);
88
+ }
89
+
90
+ window.Recorder = Recorder;
91
+
92
+ })(window);
@@ -0,0 +1,147 @@
1
+ var recLength = 0,
2
+ recBuffers = [],
3
+ sampleRate,
4
+ numChannels;
5
+
6
+ this.onmessage = function(e){
7
+ switch(e.data.command){
8
+ case 'init':
9
+ init(e.data.config);
10
+ break;
11
+ case 'record':
12
+ record(e.data.buffer);
13
+ break;
14
+ case 'exportWAV':
15
+ exportWAV(e.data.type);
16
+ break;
17
+ case 'getBuffer':
18
+ getBuffer();
19
+ break;
20
+ case 'clear':
21
+ clear();
22
+ break;
23
+ }
24
+ };
25
+
26
+ function init(config){
27
+ sampleRate = config.sampleRate;
28
+ numChannels = config.numChannels;
29
+ initBuffers();
30
+ }
31
+
32
+ function record(inputBuffer){
33
+ for (var channel = 0; channel < numChannels; channel++){
34
+ recBuffers[channel].push(inputBuffer[channel]);
35
+ }
36
+ recLength += inputBuffer[0].length;
37
+ }
38
+
39
+ function exportWAV(type){
40
+ var buffers = [];
41
+ for (var channel = 0; channel < numChannels; channel++){
42
+ buffers.push(mergeBuffers(recBuffers[channel], recLength));
43
+ }
44
+ if (numChannels === 2){
45
+ var interleaved = interleave(buffers[0], buffers[1]);
46
+ } else {
47
+ var interleaved = buffers[0];
48
+ }
49
+ var dataview = encodeWAV(interleaved);
50
+ var audioBlob = new Blob([dataview], { type: type });
51
+
52
+ this.postMessage(audioBlob);
53
+ }
54
+
55
+ function getBuffer(){
56
+ var buffers = [];
57
+ for (var channel = 0; channel < numChannels; channel++){
58
+ buffers.push(mergeBuffers(recBuffers[channel], recLength));
59
+ }
60
+ this.postMessage(buffers);
61
+ }
62
+
63
+ function clear(){
64
+ recLength = 0;
65
+ recBuffers = [];
66
+ initBuffers();
67
+ }
68
+
69
+ function initBuffers(){
70
+ for (var channel = 0; channel < numChannels; channel++){
71
+ recBuffers[channel] = [];
72
+ }
73
+ }
74
+
75
+ function mergeBuffers(recBuffers, recLength){
76
+ var result = new Float32Array(recLength);
77
+ var offset = 0;
78
+ for (var i = 0; i < recBuffers.length; i++){
79
+ result.set(recBuffers[i], offset);
80
+ offset += recBuffers[i].length;
81
+ }
82
+ return result;
83
+ }
84
+
85
+ function interleave(inputL, inputR){
86
+ var length = inputL.length + inputR.length;
87
+ var result = new Float32Array(length);
88
+
89
+ var index = 0,
90
+ inputIndex = 0;
91
+
92
+ while (index < length){
93
+ result[index++] = inputL[inputIndex];
94
+ result[index++] = inputR[inputIndex];
95
+ inputIndex++;
96
+ }
97
+ return result;
98
+ }
99
+
100
+ function floatTo16BitPCM(output, offset, input){
101
+ for (var i = 0; i < input.length; i++, offset+=2){
102
+ var s = Math.max(-1, Math.min(1, input[i]));
103
+ output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
104
+ }
105
+ }
106
+
107
+ function writeString(view, offset, string){
108
+ for (var i = 0; i < string.length; i++){
109
+ view.setUint8(offset + i, string.charCodeAt(i));
110
+ }
111
+ }
112
+
113
+ function encodeWAV(samples){
114
+ var buffer = new ArrayBuffer(44 + samples.length * 2);
115
+ var view = new DataView(buffer);
116
+
117
+ /* RIFF identifier */
118
+ writeString(view, 0, 'RIFF');
119
+ /* RIFF chunk length */
120
+ view.setUint32(4, 36 + samples.length * 2, true);
121
+ /* RIFF type */
122
+ writeString(view, 8, 'WAVE');
123
+ /* format chunk identifier */
124
+ writeString(view, 12, 'fmt ');
125
+ /* format chunk length */
126
+ view.setUint32(16, 16, true);
127
+ /* sample format (raw) */
128
+ view.setUint16(20, 1, true);
129
+ /* channel count */
130
+ view.setUint16(22, numChannels, true);
131
+ /* sample rate */
132
+ view.setUint32(24, sampleRate, true);
133
+ /* byte rate (sample rate * block align) */
134
+ view.setUint32(28, sampleRate * 4, true);
135
+ /* block align (channel count * bytes per sample) */
136
+ view.setUint16(32, numChannels * 2, true);
137
+ /* bits per sample */
138
+ view.setUint16(34, 16, true);
139
+ /* data chunk identifier */
140
+ writeString(view, 36, 'data');
141
+ /* data chunk length */
142
+ view.setUint32(40, samples.length * 2, true);
143
+
144
+ floatTo16BitPCM(view, 44, samples);
145
+
146
+ return view;
147
+ }
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: recorderjs-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Julien Defrance
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: railties
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
33
+ description: A plugin for recording/exporting the output of Web Audio API nodes
34
+ email:
35
+ executables: []
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - ".ruby-gemset"
40
+ - ".ruby-version"
41
+ - Gemfile
42
+ - README.md
43
+ - lib/recorderjs-rails.rb
44
+ - lib/recorderjs/rails.rb
45
+ - lib/recorderjs/rails/engine.rb
46
+ - lib/recorderjs/rails/version.rb
47
+ - recorderjs-rails.gemspec
48
+ - vendor/assets/javascripts/recorder.js
49
+ - vendor/assets/javascripts/recorderWorker.js
50
+ homepage: https://github.com/mattdiamond/Recorderjs
51
+ licenses: []
52
+ metadata: {}
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 1.3.6
67
+ requirements: []
68
+ rubyforge_project:
69
+ rubygems_version: 2.4.5
70
+ signing_key:
71
+ specification_version: 4
72
+ summary: Use Recorderjs with Rails 4+
73
+ test_files: []