recorderjs-rails 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []