Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Записка_к_курсачу

.pdf
Скачиваний:
10
Добавлен:
11.05.2015
Размер:
1.12 Mб
Скачать

Рисунок 5.6 - Страница с плеером

При нажатии на картинку нужной песни начинается загрузка файла, о чѐм уведомляет подсказка в правом углу. По завершении загрузки подсказка уведомит, что файл загружен и готов к воспроизведению.

Когда начинается воспроизведение, пользователь в реальном времени может видеть визуализированный вариант песниспектр частот, описывающих еѐ(рис 5.7)

21

Рисунок 5.7 - Воспроизведение

22

ЗАКЛЮЧЕНИЕ

Вкурсовом проекте проведен анализ и даны прогнозы развития web audio api. Разработано программное средство, демонстрирующее возможности данной технологии. Данная программа предоставляет возможность ознакомиться с web audio, а также может служить хранилищем медиафайлов.

Впроцессе работы над курсовым проектом я познакомился с функциями web audio. Более глубоко усвоил написание прототипов на javascript.

23

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

[1]O’Reilly, Р. Javascript: подробное руководство(the definitive guide) / O’Reilly - СПб.: Питер, 2004. - 928 с.

[2]Википедия [Электронный ресурс]. - Электронные данные. - Режим доступа: http://ru.wikipedia.org/wiki/

[3]Флэнаган, Д. Язык программирования Ruby / Д. Флэнаган,Ю. Мацумото. - Питер, 2011.

[4]Шаблон проектирования ActiveRecord [Электронный ресурс]. - Электронные данные. - Режим доступа: ttps://github.com/rails/rails/tree/master/activerecord

[5]Краткая экскурсия по языку Ruby - СПб.: Питер, 2007. - 196 с. - ISBN 5- 469-01291-3.

[6]Yukihiro Matsumoto. Ruby in a Nutshell - Sebastopol, CA: O’Reilly, 2002.

-ISBN 0-596-00214-9.

[7]Фицджеральд М. Изучаем Ruby (Learning Ruby) - 1-е изд. - СПб.: BHV-

СПб, 2008. - 336 с. - ISBN 978-5-9775-0225-2

[8]The Ruby Way - 2-е изд. - М.: ДМК Пресс, 2007. - 688 с. - ISBN 0-672- 32884-4.

[9]Тейт Б., Хиббс К. Ruby on Rails. Быстрая веб-разработка - СПб.: BHVПетербург, 2008. - 224 с.

[10]StackOverflow [Электронный ресурс]. - Электронные данные. - Режим

доступа: http://stackoverflow.com/

24

ПРИЛОЖЕНИЕ A Исходный код программы

source 'https://rubygems.org' gem 'rails', '4.0.3'

gem 'sass-rails', '~> 4.0.0' gem 'uglifier', '>= 1.3.0'

gem 'coffee-rails', '~> 4.0.0' gem 'haml'

gem 'devise' gem 'mysql2'

gem 'jquery-rails' gem 'turbolinks'

gem 'jbuilder', '~> 1.2' gem 'bootstrap-sass'

gem 'bootstrap-slider-rails' gem 'pg'

gem 'font-awesome-rails' gem 'paperclip', "~> 3.5.3"

gem 'rails_12factor', group: :production gem 'simple_form'

gem 'remotipart' group :development do

gem 'pry'

gem 'proxylocal'

gem 'better_errors'

end

group :doc do

gem 'sdoc', require: false

end

class Song < ActiveRecord::Base belongs_to :user

validates :title, presence: true has_attached_file :track

validates_attachment_content_type :track,

:content_type => ['application/ogg','audio/mp3', 'application/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/ogg'],

:file_name => { :matches => [/mp3|ogg\Z/]} do_not_validate_attachment_file_type :track

end

class User < ActiveRecord::Base

#Include default devise modules. Others available are:

#:confirmable, :lockable, :timeoutable and :omniauthable has_many :songs

devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable

end

25

class AudioController < ApplicationController def index

@song = Song.new

@songs = current_user.songs; end

def create

@song = Song.new(song_params) @song.user = current_user respond_to do |format|

if @song.save format.js

end end

end

private

def song_params

params.require(:song).permit(:title, :performer, :track) end

end

class StaticController < ApplicationController def index

end end

BloudAudiotools::Application.routes.draw do get "static/index"

devise_for :users

root 'static#index'

resources :audio, only: [:index, :create]

#Example of regular route:

#get 'products/:id' => 'catalog#view'

#Example of named route that can be invoked with purchase_url(id: product.id)

#get 'products/:id/purchase' => 'catalog#purchase', as: :purchase

end

function bloudPiano() { this.sampleRate = 44100; this.mNumNotes = 32 + 12*2;

this.noteSamples = new Array(this.mNumNotes); this.noteLen = 1*this.sampleRate;

this.buffer = null; this.octave = 0; this.volume = 100; var self = this; $(".slider").slider({

26

'min': "0", 'max': "100", 'value': "100", 'step': "2",

'orientation': 'horizontal' }).on('slide', function(ev) {

self.volume = ev.value;

})

this.formulaArea = document.getElementById("formulas"); this.mAudioContext = null;

this.mCanvasGraph = null;

this.mCanvasGraph = document.getElementById("graph"); this.mCanvasPiano = document.getElementById("piano");

if( window.AudioContext ) { this.mAudioContext = new AudioContext(); } if( this.mAudioContext==null ) {

if( window.webkitAudioContext ) { this.mAudioContext = new webkitAudioContext();

}

}

if( this.mAudioContext==null ) {

alert("your browser doesn't support AudioContext, update it") return;

}

this.buffer = new Array( 8 ); this.mActiveNote = new Array( 8 ); for( j=0; j<8; j++ )

{

this.buffer[j] = this.mAudioContext.createBuffer( 1, this.noteLen, this.sampleRate );

this.mActiveNote[j] = { mNote:666, mTo:0.0 };

}

for( j=0; j<this.mNumNotes; j++ )

{

this.noteSamples[j] = new Float32Array(this.noteLen);

}

this.mId = 0;

this.formulaArea.value = "y = sin(w*t)*exp(-5*t);"; this.newSound();

}

bloudPiano.prototype.newSound = function()

{

var self = this;

var message = "Done";

var formula = this.formulaArea.value; try

{

var musPattern = new String(formula);

musPattern = musPattern.replace( /sin/gi, "Math.sin" ); musPattern = musPattern.replace( /cos/gi, "Math.cos" ); musPattern = musPattern.replace( /tan/gi, "Math.tan" ); musPattern = musPattern.replace( /asin/gi, "Math.asin" ); musPattern = musPattern.replace( /acos/gi, "Math.acos" );

27

musPattern = musPattern.replace( /exp/gi, "Math.exp" ); musPattern = musPattern.replace( /pow/gi, "Math.pow" ); musPattern = musPattern.replace( /sqrt/gi, "Math.sqrt" ); musPattern = musPattern.replace( /log/gi, "Math.log" ); musPattern = musPattern.replace( /abs/gi, "Math.abs" ); musPattern = musPattern.replace( /min/gi, "Math.min" ); musPattern = musPattern.replace( /max/gi, "Math.max" ); musPattern = musPattern.replace( /round/gi, "Math.round" ); musPattern = musPattern.replace( /floor/gi, "Math.floor" ); musPattern = musPattern.replace( /ceil/gi, "Math.ceil" ); musPattern = musPattern.replace( /random/gi, "Math.random" );

var func = new Function( "w", "num", "buf", "var isr = 1.0/44100.0; for( i=0; i<num; i++ ) { var t = i*isr; var y=0.0; " + musPattern + "; buf[i] = y; }" );

var noteIndex = 0;

function calcFrequencies() {

if(noteIndex >= self.mNumNotes) return;

var f = 440.0*Math.pow( 2.0, (noteIndex-12-9)/12.0 ); var w = 2.0*Math.PI*f; func(w,self.noteLen,self.noteSamples[noteIndex]); noteIndex = noteIndex + 1;

calcFrequencies();

}

noteIndex = 0; calcFrequencies();

this.drawGraph();

}

catch(e) { message = e;

}

console.log(message);

}

bloudPiano.prototype.playNote = function( note ) { var id = this.mId;

note += this.octave*12;

this.mId = (this.mId+1) % 8;

var dbuf = this.buffer[id].getChannelData(0); var num = this.noteLen;

var sbuf = this.noteSamples[note]; for( i=0; i<num; i++ )

{

dbuf[i] = sbuf[i];

}

var gainNode = this.mAudioContext.createGain(); gainNode.connect(this.mAudioContext.destination); gainNode.gain.value = 0.5 * this.volume/100.0;

var node = this.mAudioContext.createBufferSource();

28

node.buffer = this.buffer[id]; gainNode.gain.value = 0.5 * this.volume/100.0; gainNode.connect(this.mAudioContext.destination); node.connect(gainNode);

node.state = node.noteOn; node.start(0);

this.mActiveNote[id].mNote = note; this.mActiveNote[id].mTo = new Date().getTime();

}

bloudPiano.prototype.drawGraph = function() { var ctx = this.mCanvasGraph.getContext('2d');

var xres = this.mCanvasGraph.width; var yres = this.mCanvasGraph.height;

ctx.fillStyle = '#202020'; ctx.fillRect(0, 0, xres, yres);

ctx.strokeStyle = '#596DFF'; ctx.lineWidth = 1;

ctx.beginPath();

for(var

i = 0; i < this.noteLen; i++) {

 

var x

= xres*i/this.noteLen;

 

var y

= this.noteSamples[0][i];

 

var j

= yres*(0.5+0.5*y);

 

ctx.lineTo(x, j);

 

}

 

 

ctx.stroke();

 

ctx.closePath();

 

}

 

 

bloudPiano.prototype.setVolume = function()

 

{

 

 

var v =

document.getElementById("myVolume").value;

 

if( v<

0 ) { v= 0; document.getElementById("myVolume").value =

0; }

if( v>100 ) { v=100; document.getElementById("myVolume").value = 100; } this.volume = v;

}

$(document).ready(function(){ var piano = null;

if (document.querySelector("#graph")) initPiano();

})

function initPiano() { piano = new bloudPiano();

window.onkeydown = function(ev)

{

if(piano ==null)

piano = new bloudPiano();

29

var note = 666;

 

 

//-----------------------------------

 

 

 

if(

ev.keyCode==90

)

note= 0; // C 0

if(

ev.keyCode==83

)

note= 1; // C#0

if(

ev.keyCode==88

)

note= 2; // D 0

if(

ev.keyCode==68

)

note= 3; // D#0

if(

ev.keyCode==67

)

note= 4; // E 0

if(

ev.keyCode==86

)

note= 5; // F 0

if(

ev.keyCode==71

)

note= 6; // F#0

if(

ev.keyCode==66

)

note= 7; // G 0

if(

ev.keyCode==72

)

note= 8; // G#0

if(

ev.keyCode==78

)

note= 9; // A 0

if(

ev.keyCode==74

)

note=10; // A#0

if(

ev.keyCode==77

)

note=11; // B 0

//-----------------------------------

 

 

 

if(

ev.keyCode==81

)

note=12; // C 1

if(

ev.keyCode==50

)

note=13; // C#1

if(

ev.keyCode==87

)

note=14; // D 1

if(

ev.keyCode==51

)

note=15; // D#1

if(

ev.keyCode==69

)

note=16; // E 1

if(

ev.keyCode==82

)

note=17; // F 1

if(

ev.keyCode==53

)

note=18; // F#1

if(

ev.keyCode==84

)

note=19; // G 1

if(

ev.keyCode==54

)

note=20; // G#1

if(

ev.keyCode==89

)

note=21; // A 1

if(

ev.keyCode==55

)

note=22; // A#1

if(

ev.keyCode==85

)

note=23; // B 1

//-----------------------------------

 

 

 

if( ev.keyCode==73 )

 

note=24; // C 2

if(

ev.keyCode==57

)

note=25; // C#2

if( ev.keyCode==79 )

 

note=26; // D 2

if(

ev.keyCode==48

)

note=27; // D#2

if( ev.keyCode==80 )

 

note=28; // E 2

if(

ev.keyCode==219 )

note=29; // F 2

if(

ev.keyCode==187 )

note=30; // F#2

if(

ev.keyCode==221 )

note=31; // G 2

//-----------------------------------

 

 

 

if( note==666 ) return;

 

piano.playNote( note

);

 

}

}

BLoudPlayer = (function (){ BLoudPlayer = function() {

var self = this;

this.context = new AudioContext(); this.destination = this.context.destination; this.buffer = null;

this.state = "idle"; this.setupGraphics(); this.setupAudioNodes();

Array.prototype.forEach.call(document.querySelectorAll('.audiofile'),

function(e){

e.addEventListener('click', function(){

30