/flash/src/js/audio.js

http://echo-nest-remix.googlecode.com/ · JavaScript · 184 lines · 157 code · 23 blank · 4 comment · 15 complexity · 25839d3a494d82e25ac126db23b0526d MD5 · raw file

  1. function AudioAnalysis(analysis) {
  2. extend(this, analysis);
  3. var duration = this.metadata.duration;
  4. if (this.sections) {
  5. this.sections = AudioQuantumList.fromSections(this.sections);
  6. this.sections.analysis = this;
  7. }
  8. if (this.bars) {
  9. this.bars = AudioQuantumList.fromEvents('bar', this.bars, duration);
  10. this.bars.analysis = this;
  11. }
  12. if (this.beats) {
  13. this.beats = AudioQuantumList.fromEvents('beat', this.beats, duration);
  14. this.beats.analysis = this;
  15. }
  16. if (this.tatums) {
  17. this.tatums = AudioQuantumList.fromEvents('tatum', this.tatums, duration);
  18. this.tatums.analysis = this;
  19. }
  20. if (this.segments) {
  21. this.segments = AudioQuantumList.fromSegments(this.segments);
  22. this.segments.analysis = this;
  23. }
  24. }
  25. function AudioQuantum() {
  26. this.start = 0;
  27. this.end = 0;
  28. this.duration = 0;
  29. }
  30. extend(AudioQuantum.prototype, {
  31. setDuration: function(duration) {
  32. this.duration = duration;
  33. this.end = this.start + duration;
  34. },
  35. setEnd: function(end) {
  36. this.end = end;
  37. this.duration = this.end - this.start;
  38. },
  39. parent: function() {
  40. // TODO handle error
  41. var uppers = this.container.analysis[AudioQuantum.parentAttributes[this.container.kind]];
  42. return uppers.that(selection.overlap(this))[0];
  43. },
  44. children: function() {
  45. // TODO handle error
  46. var downers = this.container.analysis[AudioQuantum.childrenAttributes[this.container.kind]];
  47. return downers.that(selection.areContainedBy(this));
  48. },
  49. group: function() {
  50. var parent = this.parent();
  51. if (parent) {
  52. return parent.children();
  53. }
  54. else {
  55. return this.container;
  56. }
  57. },
  58. localContext: function() {
  59. var group = this.group();
  60. return [group.indexOf(this), group.length];
  61. }
  62. });
  63. extend(AudioQuantum, {
  64. parentAttributes: {
  65. bar: 'sections',
  66. beat: 'bars',
  67. tatum: 'beats'
  68. },
  69. childrenAttributes: {
  70. section: 'bars',
  71. bar: 'beats',
  72. beat: 'tatums'
  73. }
  74. });
  75. function AudioQuantumList(kind) {
  76. var array = extend([], AudioQuantumList.Methods);
  77. array.kind = kind;
  78. return array;
  79. }
  80. AudioQuantumList.Methods = {
  81. that: function(filter) {
  82. var result = new AudioQuantumList(this.kind);
  83. for (var i = 0; i < this.length; i++) {
  84. var aq = this[i];
  85. if (filter(aq)) {
  86. result.push(aq);
  87. }
  88. }
  89. return result;
  90. },
  91. orderedBy: function(fn, descending) {
  92. var result = new AudioQuantumList(this.kind);
  93. result.push.apply(result, this);
  94. result.sort(function(a, b) {
  95. var aa = fn(a);
  96. var bb = fn(b);
  97. if (aa > bb) {
  98. return 1;
  99. }
  100. if (aa < bb) {
  101. return -1;
  102. }
  103. return 0;
  104. });
  105. // TODO
  106. if (descending) {
  107. result.reverse();
  108. }
  109. return result;
  110. }
  111. };
  112. extend(AudioQuantumList, {
  113. fromEvents: function(kind, events, duration) {
  114. var aqs = new AudioQuantumList(kind);
  115. var previousAq = new AudioQuantum();
  116. previousAq.start = 0;
  117. for (var i = 0; i < events.length; i++) {
  118. var event = events[i];
  119. var aq = new AudioQuantum();
  120. aq.start = aq.value = event.value;
  121. aq.confidence = event.confidence;
  122. aq.container = aqs;
  123. aqs.push(aq);
  124. previousAq.setEnd(aq.start);
  125. previousAq = aq;
  126. }
  127. // TODO audio.py duplicates the duration of the second-to-last event
  128. previousAq.setEnd(duration);
  129. return aqs;
  130. },
  131. fromSections: function(sections) {
  132. var aqs = new AudioQuantumList('section');
  133. for (var i = 0; i < sections.length; i++) {
  134. var section = sections[i];
  135. var aq = new AudioQuantum();
  136. aq.start = section.start;
  137. aq.setDuration(section.duration);
  138. aq.container = aqs;
  139. aqs.push(aq);
  140. }
  141. return aqs;
  142. },
  143. fromSegments: function(segments) {
  144. var aqs = new AudioQuantumList('segment');
  145. for (var i = 0; i < segments.length; i++) {
  146. var segment = segments[i];
  147. var aq = new AudioQuantum();
  148. aq.start = aq.value = segment.start;
  149. aq.setDuration(segment.duration);
  150. aq.pitches = segment.pitches;
  151. aq.timbre = segment.timbre;
  152. aq.loudnessBegin = segment.startLoudness;
  153. aq.loudnessMax = segment.maxLoudness;
  154. aq.timeLoudnessMax = segment.maxLoudnessTimeOffset;
  155. aq.loudnessEnd = segment.endLoudness;
  156. aq.container = aqs;
  157. aqs.push(aq);
  158. }
  159. return aqs;
  160. }
  161. });