VERD SAM: Hola, tothom. Benvingut al nostre seminari. El meu nom és Sam. HUGH Zabriskie: Sóc Hugh. VERD SAM: I anem a parlar avui sobre JavaScript i l'API de Web Àudio. Només per començar, aquest és un esquema de la nostra agenda per al seminari. Anem a començar parlant de per les que ha d'estar interessat en la web API Audio, per què és JavaScript l'idioma que necessita per a això, i després parlar de JavaScript essentials-- així com, Pots caminar a través d'alguns fonaments de la llengua, i després parlar de la API d'àudio a un nivell alt. Llavors, Hugh parlarà sobre alguns de les etapes de producció d'àudio i després una demostració d'aquest impressionant seqüenciador projecte que va construir i li mostrarà el codi. I després, tindrem temps per preguntes al final de la gent que són aquí viure. HUGH Zabriskie: Cool. VERD SAM: Cool. HUGH Zabriskie: Cool. Vaig a fer còpies de seguretat. SAM VERD: Així que, primer el primer. Així que una de les grans coses sobre el Web API Audio és que no hi ha posada en marxa és necessari. Ve integrat en la majoria dels navegadors moderns, incloent Chrome, Edge, en el seu conjunt manat de altres-- tots els que grans porcions de la gent està utilitzant avui en dia. Així que no s'ha configurat, a part d'aconseguir just un servidor web en marxa, per tu per començar a treballar en el seu projecte, la qual cosa és genial. Li recomanem bastant en gran mesura de que es té en compte utilitzant Chrome per Desenvolupament web JavaScript, només perquè el seu desenvolupador eines són molt forts. Com a exemple de just el que volem dir dient obre el teu Javascript console-- si vas a Chrome i ens fixem en qualsevol pàgina web, i et vas anar clic Inspeccionar element, i després anar a aquest petit desplegable aquí i fa clic a la consola, veuràs el que obre veu una molt semblant a un símbol del sistema que podria veure en el teu Mac, oa la ID. I així, podem Tipus mana aquí, com Clar, i altres comandaments per l'estil. Podem crear variables, com veurem més endavant en JavaScript. I així que qualsevol cosa que podem fer en JavaScript, podem fer-ho amb la consola, i això és una forma súper pràctic per començar a jugar amb les API i sentir-se còmode amb JavaScript dreta del pal. Sense posada en marxa requereix, que és realment agradable. Fresc. Impressionant. Així que només una cosa més per afegir. Si vostè té alguna preguntes-- hi molts de vostès que no són aquí viuen, no dubteu a enviar per correu electrònic nosaltres-- aquests són les nostres adreces de correu electrònic. Si té alguna pregunta no vol demanar-nos, com, oh Tinc un error en el meu codi, o alguna cosa això és una mica més específic, potser a Google en primer lloc. Hi ha un munt de grans recursos sobre l'API d'àudio web per aquí. És realment bé documentat i està sent utilitzat per un munt de gent a la indústria i les persones que són simplement la construcció de coses divertides per a ells mateixos. Així que ha d'haver un munt dels recursos que hi ha. Impressionant. Fresc, així que per què la web API d'àudio? Aquest diagrama és una mica d'una evolució de la forma so en la web ha crescut amb el temps. BGSound era com l'etiqueta HTML original que Internet Explorer fa servir per donar suport. Només es va permetre sons bastant bàsiques, la funcionalitat no era molt robusta, i no es podia fer seqüenciació complicat, o controlar quan el so va començar i es va aturar molt robusta. Per tant, no era particularment ben desenvolupat. Després, després que, Flash va arribar along-- que, Estic segur que vostès estan familiaritzats amb Flash-- potser no com funciona, però vostè ha vist sens dubte. Has d'actualitzar flash Plug-in, tot aquest tipus de coses, i que sens dubte va ampliar la gamma de funcionalitat que estava disponible. Però el que l'usuari instal·li un plug-in és, sens dubte Un inconvenient de incloent Flash en la seva aplicació, no? Perquè llavors vostè és depenent de la usuari anar i trobar aquest plug-in, i probablement s'encengui apagat per aquest pas addicional que han de prendre per utilitzar l'aplicació. I llavors podria haver-hi una actualització que vaig a trencar tota l'aplicació, i que acaba sent un malson per al desenvolupador, també. Així que va ser una barricada. I després, després d'això va venir al llarg, l'etiqueta d'àudio HTML, que és una característica de més modern que HTML-- sens dubte va permetre moltes més coses, però fins i tot les coses que podrien fer Hi havia una mica limitat sol com a resultat de les coses que HTML era capaç. Així que quan el codi JavaScript API, l'API Web Àudio, es va convertir en un estàndard practicar en tots els navegadors, que realment ampliat el conjunt de les oportunitats per als desenvolupadors per aconseguir realment a l'edifici coses interessants per a la web. Durant molt temps no tenien estat eines molt robustes per a aplicacions d'àudio natiu, com-- tothom sap GarageBand, i després, òbviament, hi ha més àudio barrejant aplicacions professionals, i aquest tipus de coses. Però no hi havia un molt bo Cloud-- no Núvol, sí, suposo Plataforma web Cloud-- que permetria als desenvolupadors a construir aplicacions per a les persones fer la mescla d'àudio. I com ell li mostrarà més endavant, la Web API Audio permet realment de gran abast coses succeeixi realment, simplement, la qual cosa és molt bo. Així que aquesta és la instrucció de per què hauria de veure la resta del seminari, bàsicament. I ara, vaig a parlar de alguns elements bàsics simplement JavaScript-- de la llengua, de manera que podem estar a la mateixa pàgina quan parlem de la API una mica més tard. Fresc. Per tant, aquest és un resum. Vaig oblidar que era aquí. Sí. HUGH Zabriskie: Hi ha dos tobogans aquí. VERD SAM: Aquest és el resum d'algunes de les limitacions dels altres mètodes d'unió, d'edat. I llavors ara, tenim aquestes coses. Fresc. Impressionant. Per tant, elements essencials de JavaScript. El primer és el primer, hi ha una diferència prou significativa en JavaScript front en una llenguatge com C, en la forma que es creen variables. Així que en C, que estem acostumats a tenir per escriure les nostres variables, oi? I no em refereixo a tipus com escrigui, vull dir el tipus com ells assignar un significat type-- com, 1 int, float, un char. En C, estàvem molt acostumats a haver de crear una variable i després s'adhereixen a aquest tipus per al temps sencer que fem servir aquesta variable. I això no és necessàriament pitjor, però és probablement més difícil d'utilitzar. Una de les característiques interessants de JavaScript és que les variables són el que s'anomena "dinàmicament mecanografiat", que vol dir que jo puc crear una variable que la sintaxi, varX és igual a 5, per exemple. Això crea originalment un nombre enter variable-- just sota la campana somewhere-- però pot canviar aquesta variable per referir-se a una cadena sense fer res per l'estil crear una nova variable. No necessito de preocupar sobre el tipus de canvi. JavaScript sap que el tipus de canviat, i això passa de forma dinàmica. Per tant, hi ha beneficis i desavantatges al fet que, com qualsevol persona que ha treballat en JavaScript durant un temps podria saber. Hi ha moments en què vostè pot ser accidental canviar el tipus d'una variable i No manegi aquest tipus de canvi, i llavors el teu Javascript pot crash-- o una excepció ser fet fora, ja que tindrà la tipus incorrecte quan s'espera un tipus. Fresc. Així, scoping-- que és com, si recordar les primeres setmanes al curs, fa referència a una variable de forma visible és i en quina àrea del codi. Tot això es veu molt similar a la forma en què es veu en C. Així que les variables estan en l'àmbit general dins de claus dins d'una funció, i després també hi ha les variables a nivell global amb àmbit que tracti: si escrius una variable fora d'una funció, serà visible en tot el text. Una diferència entre JavaScript i C, en particular, és que si es declara un mundial qualsevol variable en un arxiu de text és visible en qualsevol funció dins d'aquest arxiu de text. Això és correcte, no? HUGH Zabriskie: Sí. VERD SAM: Així que és també una mica mica estrany en comparació amb C, on sempre havia de tenir la nostra definicions de variables per sobre dels llocs que es van utilitzar. Això no és una regla que s'aplica més, així, una mica diferent. I de nou només per emfatitzar, global davant variables-- locals molt similar a C. Vostè podria tenir dues variables amb el mateix nom, i tenen un dels seus noms es remeden per una variable local si un d'ells era global. Així tipus, similar de problemes que alguns de vostès poden haver topat en alguna del seu problema s'estableix fins al moment. Fresc, així que això és variables. Control de flux, és a dir, com, -si else-- stuff-- lògic i bucles. Així que per començar, això és el que if-else declaracions semblen en JavaScript. La col·locació de les diverses coses en les línies no és important. Aquesta és només una de les convencions per la forma en codi d'estructura que. Igual que a C, tenim una "si," una declaració parèntesi. Això no és el que volia fer. Ho he tornat a fer. HUGH Zabriskie: Tractant de sortir? SAM VERD: No, estic tractant d'apropar la imatge. No importa. Així doncs, tenim una declaració "if" i tenim una condició dins d'ella que avalua a vertader o fals, i que determina si o no entrem en aquest bloc de codi. I de la mateixa manera, tenim una cosa, si i una persona, igual que estem acostumats a C. També ha de ser bastant còmode la dreta del pal amb bucles, perquè també es veuen molt semblant a C sembla. Però et donaràs compte de nou que tenen, en lloc de int inicialitzacions, tenim inicialitzacions var. I suposo que tens tenir cura de fer Segur que no canviï el valor d'I a partir d'un int a una cadena, per exemple, pel fet que va provocar un comportament estrany pot ser que no esperar. Però això ha de ser bastant familiar, també. Així que aquí és on les coses comencen a aconseguir una mica boig en JavaScript per a algú que va des d'un fons de C. Hi ha funcions en JavaScript, i no hi ha una manera per declarar una funció que es veu tipus de similar a C, i després hi ha un altre que es veu una mica diferent. La primera versió, que podem veure aquí, és una espècie de C-com, si diem, aquesta és una funció, donar-li un nom, donar el nombre d'arguments, i després el contingut de la funció anar dins d'aquestes claus. Anem a veure un exemple de arguments en només un segon. Mentre que a la línia següent, veiem, oh, aquí hi ha una variable anomenada "myFunction" i som iguals a aquest function-- cosa-- genèric que no sembla tenir res a fer. La raó per la qual és diferent que C és que JavaScript és el que s'anomena un llenguatge funcional, o té elements funcionals, el que significa que les funcions són en realitat valors. I això vol dir que podem establir una variable per igualar una funció i després passar aquesta funció voltant, passar-ho com a argument, fer tot tipus de coses així amb les funcions. Una altra cosa a note-- funcions s'escriuen amb un cert nombre d'arguments. Anem a veure un exemple d'una funció amb un argument en la següent diapositiva. Però JavaScript no ho farà gritarte si intenta utilitzar una funció amb el nombre incorrecte d'arguments. Simplement va a fer el seu millor esforç per fer fer, el que significa que si es passa, es crida a una funció que espera un discussió amb cap argument, tot el que passarà és que va a fer el seu millor moment per tractar d'executar aquest codi, i si s'executa amb el temps en una excepció o un error, que va a llançar aquesta excepció i només seguir going-- que és només una de les formes que funciona JavaScript. Sí. AUDIÈNCIA: Què passa si hi ha massa arguments? VERD Carter: Així que la pregunta era, què passa si hi ha massa arguments? I la resposta és que JavaScript serà just ignorar els que estan després dels quals espera. Es tractarà d'executar la funció cridar com si era només els dos primers. Oi? HUGH Zabriskie: Això és correcte, sí. De la mateixa manera, si hi ha són molt pocs arguments, només tipus de dóna nul·la a tots els arguments que no té cap valor per. SAM VERD: Què es pot ser realment útil, si vull escriure una funció que pren uns arguments numèrics variables. Podeu establir valors per defecte en la definició de la funció, i es pot ignorar el fet que l'entrada no hi és. Així que vull parlar una mica més sobre aquesta última bala punt, que és les funcions són valors. Aquest és un exemple que és un lucinant mica si vostè acaba de llegir, i no creu sobre el que està passant per un segon. Per tant, donem una ullada just en la primera línia aquí. Tenim aquesta variable, f1, que diem és una funció que fa això. I el contingut de la funció es console.log ('hola'). Vostè pot pensar en console.log com el Equivalent JavaScript de printf. Llavors, què passarà és que, si ens executar aquest codi en el nostre navegador, que va a imprimir una cadena. Puc demostrar que. AUDIÈNCIA: Per registre, però, fa que vol dir que sigui que s'està gravant en algun lloc? VERD SAM: Sí. Així que et vaig a mostrar el que ha de passar. Per tant el dubte era, què significa log? HUGH Zabriskie: Així console.log és com printf de C. SAM VERD: Així console.log és com printf, pel que si tinc aquest console.log ('hola'), i jo dic a això, la cadena "hola" s'imprimeix a la consola. Aquesta és la consola. És com printf, on imprimeix a terme estàndard. I veurem en un minut, però això és en realitat es fa referència a l'objecte de la consola, i trucar a un mètode en aquest objecte. Això farà més sentit en un minut quan ens arribar a parlar de objectes en JavaScript, però jo pensava que anava a esmentar això. HUGH Zabriskie: Estem utilitzat en el C, dreta- escrivim generalment un gran programa en principal per fer qualsevol cosa. Però el que és fresc en JavaScript que és tenir aquest tipus d'intèrpret que carreres en temps real, de manera que pren simplement línia per línia, que només pot interpretar que a l'acte. I no perd de vista les coses que s'han executat abans, pel que és una eina molt útil per utilitzar console.log, o la consola, en general, per només jugar voltant amb JavaScript. VERD Carter: Així que tornar a aquest exemple-- la segona línia de codi aquí és bastant al·lucinant al meu cap. La primera vegada que llegeixo això, era com, què està passant? Així que el que està succeint és a dir, aquest declaració de la funció, diu, Tinc una funció anomenada f2 que està esperant un argument, f, i després es diu a això funció, f, que se li passa com a argument ni per si mateix amb arguments. Per tant, que podria haver estat confús. Si entenem això com f2 f1 presa com a argument, i després dins de f2, f aconsegueix called-- els mitjans que aquesta línia de codi, després d'aquestes dues línies de codi, dóna com a resultat "hola" que s'està imprimint a la consola. El fet que podem passar funcions voltant com a valors acaba sent un dels més potents funcions de JavaScript com un llenguatge de programació. Fora de tota la coses increïbles que pot fer, així com una característica de la llengua en termes de la forma que fa les coses fàcils programar i permet per les coses que no són particularment ben adaptat al web, programació funcional i funcional aspectes de programació de JavaScript és un dels més conceptes de gran abast que existeix en JavaScript-- si vostè em pregunta. Fresc. Per tant, el següent. A més de ser funcional, també hi ha elements de JavaScript que són orientada a objectes, que és un dels molt paraules de moda populars en ciències de la computació. Programació orientada a objectes és una dada popular. JavaScript té una versió que, on crec que tot valor és també un objecte, el que significa que tots els objectes envolta a alguns nombre de valors. Així que per a valors que són simples, com un nombre sencer, com varX és igual a 5, aquest objecte simplement envolta que un valor. Però també podem imaginar una situació where-- podem pensar en situacions en C on volíem fer alguna cosa amb estructures, per exemple, que envolta diversos valors junts i marques És realment fàcil de passar les coses. Va ser llavors quan un objecte està en JavaScript. És important recordar quan dic que els objectes embolicats alguns nombre de valors junts, que les funcions són també valors, el que significa que les funcions poden També estar dins d'un objecte de JavaScript. I la raó per la qual és important és que, mentre que sovint pensar en trucar a un mètode en un objecte que és d'un terme popular d'altres llenguatges orientats a objectes populars, Una de les diferències és que aquí tot el que és un mètode en JavaScript és un valor emmagatzemat a l'interior d'un objecte que realitza alguna Action-- possiblement usant els altres valors que estan dins de d'aquest objecte, però no necessàriament. Així que vostè pot imaginar una situació, Suposo que en una mica d'una manera boja, on va cridar un mètode d'una objecte en un altre objecte, per exemple. Així que és una mica covard d'aquesta manera. I també es pot canviar els mètodes que estan vinculats a un objecte mitjançant l'assignació d'un mètode que nova funció, que és també bastant diferent d'altres llenguatges orientats a objectes, on una vegada que declarem un objecte i crear instàncies d'ella, no podem canviar els mètodes que són associat amb aquest objecte més. Així que això és bastant diferent. Fresc. Així que aquí està un exemple, en primer lloc, d'un objecte en l'acció. Això és el que s'anomena un objecte genèric, que vol dir que no té cap en particular nom, no té una classe, que és només una mica d'embolcall de valors. I la forma en què es veu és que tenim aquest parell exterior de arrissat es prepara aquí d'indicar a JavaScript i dir, es tracta d'un objecte. Els valors dins d'ella són cada un dels valors a l'interior l'objecte que ha de ser embolicat junts. I dins d'aquest objecte, llavors tenim parells de valors clau, on la clau es refereix al nom del valor a l'interior de l'objecte, i l'altre side-- enfront de la aquí-- de còlon és el valor real que han de ser emmagatzemats. Així que veure aquí que tenim una clau anomenada fn amb valor sam, seguit d'una coma, dient a la següent entrada. A continuació, una clau anomenada ln, amb un valor de verd, seguit d'una coma, seguit de "imprimir" que va a tenir un valor de la funció que va a fer aquesta línia de codi. Anem a fer un pas enrere i desempacar el que està passant aquí. Així que això és una mica complicat, i estem veient una cosa nova per primera vegada. La paraula "this" és el nou que estem veient aquí, i el que això fa és a dir, es refereix a l'actual objectar en el seu abast, no? Així que quan diem, això assenyala el final de nou a tot aquest objeto-- quan fem this.fn, anirem tot el camí de tornada a aquest objecte, aneu al valor fn i obtenir sam, estireu-lo fins al final esquena, enganxar-lo aquí, i després seguir endavant. AUDIÈNCIA: Així que amb la recuperació, és que fet pel paràmetre definició? VERD Carter: tant el dubte era, és el recuperació de fet perquè del paràmetre definició? Sí, absolutament. ¿Què passarà aquí és, aquest punt diu que el codi JavaScript, OK, m'estic posant una mica de valor d'aquest objecte de mi mateix. I llavors va a buscar una entrada anomenada fn, i si el troba, que tornarà que value-- així, és sam. Però també podria haver escrit cosa que no es defineix aquí, i després ho faria només tornar undefined-- que és una cosa que pot JavaScript fer, que pot tenir beneficis, però és també- si vostè comet un error tipogràfic, pot donar lloc a errors estranys. Així que només vaig a tractar de trobar el que li dius a trobar i no va a queixar-se si no el troba. Simplement dirà, no ho vaig fer trobar-lo, i després seguir endavant. Pel que seria indefinit, més blanc, més el cognom. Sí. I llavors podem veure que si llavors podria baixar i access-- i anomenem tf.print () amb parèntesis. Es va a trucar a aquesta impressió funció sense arguments, no? Però si acabem de dir tf.print () punt i coma, sense els parèntesis, tot el que hauria fet és tirar la funció del valor, però en realitat no el va cridar. Fresc. HUGH Zabriskie: En cas de fem un objecte? VERD SAM: És clar, farem això. Així que em puc moure aquest exemple a la consola. Podem imaginar que tinc un objecte. Així que això és un simple objecte. Aquest és un objecte que conté dos valors amb dues claus, dos valors clau parells. Així que llavors puc accedir al valor emmagatzemat dins d'aquest objecte fent x.x1, per exemple, i em dóna 1 volta. De la mateixa manera, x.x2, aconseguir aquest valor de nou. I ara el realment interessant és, que pugui realment afegir alguna cosa a aquest objecte després que jo he creat. Així que vostè pot imaginar, anem dir que tinc una funció. HUGH Zabriskie: Vostè haver de fer Maj-Enter. VERD SAM: Oh, això és molest. Què no li agrada? Oh. Aquí anem. Fresc. Així que he creat aquesta funció, f, que va a anar a la corrent objecte i this.x1 impressió. Així que si em dic per f sí, res va a succeir, oi, perquè no hi ha x1 camp en l'objecte que s'està referint a. Però, si jo dic, x.f = f, i després em cridar x.f (), em vaig a tornar 1. Aquesta funció f és ara associat amb l'objecte x, que té una clau anomenada x1 associat amb el valor 1, així que quan ens diem this.x1, és va a trobar el que està buscant i ser capaç d'imprimir un valor fora. Així que això és només un exemple del tipus de les coses boges que pot fer amb els objectes en JavaScript. Així que va ser la versió versió genèrica, significat que hem creat un objecte utilitzant aquest parèntesi notació cotilla notation--, rather-- i això és molt útil si només volem una instància d'un objecte en particular, però ¿I si volem tenir més d'un de la mateixa classe? I la resposta a aquesta pregunta és, hi ha coses anomenat classes en JavaScript també. Podem crear una funció que fa algun tipus d'inicialització per a un objecte estrany, i diríem, com, la meva class-- el que el nom del objeto-- reutilitzable és igual a la funció que el configura. Així que el que això seria equivalent que és la creació d'un objecte que seria com, claudàtor, str, còlon, això és una cadena, punt i coma, claudàtor. Aquest seria el genèric objecte inicialitzem, amb l'única diferència de ser al següents línies vam crear un prototip, que significa que és una clau per defecte que afegim al nostre objecte que té el valor indicat aquí. El que significa que, quan creo un nou instància d'aquest objecte MiClase, que hi haurà pre-construït a l'interior de és un valor anomenat str i un altre valor myPrint trucada, que és serà una funció. Impressionant. Gran. Així que l'últim que es dir de JavaScript és que és molt útil per a la qual s'anomenen operacions asíncrones. Mitjans asíncrona és que nosaltres pot esperar que alguna operació per completar abans de passar , Però seguir endavant mentre esperem i després fer que alguna cosa succeeixi en el futur. I el que vull dir amb això és que vostè pot imaginar una situació en què envia una sol·licitud a algun lloc web en qualsevol lloc, i que va a que li enviï de tornada alguna gran part de les dades, no? I l'usuari podria esperar en el Mentrestant perquè això succeeixi, i res podria ser passant en aquest moment. Però això no és un gran disseny, no? No vol que la pàgina web es congeli. Què passa si l'usuari desitja feu clic a un menú desplegable? No és un gran patró de disseny. En canvi, en el fons el que JavaScript no es diu, OK, realitzar aquesta operació de forma asíncrona. Així com, esperar en el fons, i després, quan es realitza l'operació, truqui a la devolució de trucada function-- trucar a alguna funció, Feu una mica de Action-- per assenyalar que el operació que estàvem esperant per acabar S'ha acabat. I la raó que és súper poderosa és, podem fer alguna cosa, passar un argument, fer alguna cosa, i després esperar perquè alguna cosa succeeixi. Després, una vegada que alguna cosa completa, podem trucar a una devolució de trucada. Això és molt útil, ja que permet nosaltres fem les coses amb Web API Audio, per exemple, com una càrrega arxiu d'àudio des d'un servidor remot sense haver d'esperar a que el arxiu d'àudio que va a carregar, la qual cosa seria realment dolent per a l'experiència de l'usuari. Fresc. Darrera parella observa sobre depuració, ja que aquest és una cosa que hauràs de fer com a part del seu projecte, garantit. Vaig esmentar la consola JavaScript. És una característica molt útil de tots els navegadors moderns, I realment convidem a obtenir còmode usant la consola, si vols ser bo en JavaScript. És súper útil per depuració, però també és molt útil per calcular com utilitzar una API. Permet la realitat fàcil experimentació sense haver d'escriure alguna codi i, a continuació, compilar-lo. No ha de fer tots aquests passos. Vostè pot escriure una mica de codi en una línia, i després obtenir informació immediata sobre si aquesta línia de codi worked-- molt pràctic. I també, només una note-- tècnica la consola de JavaScript és un exemple d'un REPL-- així que això és R-E-P-L, REPL, que significa llegir, avaluar, llaç d'impressió. Vas a escriure algunes coses en, va llegir el que ha escrit en, que va a avaluar, i que va a imprimir el de sortida, i després es va a començar de nou. Això li permet anar ràpidament a cercles iteració, que és realment genial. Suposo última veritable note-- aquest és la veritable darrera nota, si. Com podem realment utilitzem JavaScript? Així que primer, podem importar usant una etiqueta de script a la part superior o inferior d'un HTML file-- en qualsevol lloc dins d'un arxiu HTML, realment. I dins d'una etiqueta de script, hi ha dos sub-maneres d'importació JavaScript. El primer és per tenir una arxiu JavaScript diferent que importem íntegrament, o per tenir una àrea de codi com a guió per començar, i després script de barra invertida a fi. I llavors només escrivim JavaScript dins de l'arxiu HTML. Aquestes són les dues maneres. No es pot tenir dins d'HTML. AUDIÈNCIA: És un de millor que l'altre? VERD SAM: La pregunta era, és un de millor que l'altre. Així que, sí, com una pràctica estil de codificació, i també és com una pràctica de disseny. Hi ha dues raons per què podria ser millor. La primera és, que fa que el seu codi d'una molt més llegible si tot el codi HTML està en un sol lloc, tots els de la seva CSS està en un altre lloc, tot el teu Javascript es troba en un tercer lloc. Oi? Crec que ja hauríem d'haver parlat al respecte en les Categorías-- com CSS-- el que és-- i va sovint en un altre arxiu. Així, el mateix tipus de concepte aquí. També pot imaginar que JavaScript seria ser reutilitzat en més d'una Pàgina HTML, o potser una gran nombre de pàgines HTML, i que ha de JavaScript refactorizado en un arxiu que es pot importar en més d'un lloc permet que el codi sigui manera més fàcil de mantenir. Es pot imaginar fer-ne un canviar el JavaScript i haver de canviar- en 100 arxius diferents. I en comptes podem simplement canviar- en un, que és molt més potent. He respost a la seva pregunta? Fresc. També podem escriure a la consola, com hem esmentat abans. I un cop més, una última note-- Web Audio està construït, vostè no ha de carregar res. Fresc. Hi ha alguna pregunta, ¿té qualsevol més preguntes sobre JavaScript, abans de seguir endavant? AUDIÈNCIA: [inaudible] VERD SAM: Molt bé, fresc. Així que ara ell va a parlar de l'API. HUGH Zabriskie: Cool. Gràcies, Sam. VERD SAM: És clar. HUGH Zabriskie: impressionant, per la qual cosa anem a passar de JavaScript. Així que hem parlat d'alguns l'essencial de JavaScript, i aquestes són les variables, funcions, objectes, funcions com a variables, càrrega asíncrona. Aquestes són totes les coses que vostè va a veure com s'utilitza la Web Àudio. Així que només anem a parlar sobre el primer en un nivell alt. És una API, així que és una cosa que es construeix, com va dir Sam, a la dreta en el codi JavaScript que s'utilitza en la consola. I en realitat és com codi C ++ el que realment es van construir a Chrome i Firefox, i tots aquests navegadors. Així que la idea principal amb la web Audio és que tens aquest tipus de canonada d'àudio, oi? Així les seves dades d'àudio ve en alguna forma. Hi ha classe de de tres forms-- principal vostè té l'oscil·lador, que crea una ona sinusoïdal, ona cosinus, anem a veure com funciona. Un altre molt comú, per descomptat, és un MP3. Així que potser vostè comença amb una cançó, i després voler fer algun tipus de filtrat a això i de sortida que- que podria ser una possible font. I després un molt cool un és el micròfon. Així que vostè pot utilitzar alguns molt trucades bàsiques en JavaScript per accedir a la micròfon, pel que si vostè volia fer una aplicació com un detector de to, per exemple, que porta a la seva veu i dades fora el pitch-- manera molt fàcil d'això. Pot només tipus de llegir-lo en, esbrinar la freqüència, i llavors la sortida un nombre. Així que anem a veure com funciona, també. El destí és bàsicament on les dades d'àudio s'emet. Així que en general, això és com els altaveus portàtils. Altres opcions són com 1 ScriptProcessorNode-- arribarem als nodes d'un second-- però bàsicament, ja sigui que vostè està posant so a terme a través del seu ordinador a través d'altaveus, o si busques tipus de gravació, per la qual estàs emmagatzemar com a dades d'àudio. Així que potser si algú crea la música en la seva aplicació i després que voleu escriure això i potser com exportar-ho a SoundCloud, per exemple-- això seria una manera de fer això. Totes les coses divertides, que parlarem, que ocorre entre aquests dos punts, on carreguem en la música i després sortida de la mateixa. Així que vaig a parlar dels cinc etapes de producció d'àudio en un segon. Tenim aquesta cosa anomenada 1 AudioContext, que és aquest petit embolcall que veiem aquí. Bàsicament el AudioContext és-- si anar a la consola de JavaScript en aquest moment, podem crear-ne un ara mateix. Només un exemple de REPL, oi? Estem llegint, avaluar i que imprimeix. AudioContext és un estat global. És una estructura, és un objecte aquí, i manté la informació sobre les coses que estan passant a la pantalla relacionats amb l'àudio. Un exemple és l'hora actual. Això li indica el nombre de segon, amb molta precisió, des de la pàgina web carregada. Així que aquesta és una molt útil petita propietat que pot utilitzar. Ha llegit only-- crec que en realitat es pot tractar d'establir un valor. Es dirà que estableixi, i després, si ho imprimeixi nou-- no va ser així en realitat força feina. Així que no són de només lectura propietats en JavaScript. Això és realment útil si estàs tipus de sincronització una gran quantitat de diferents informació, quan estàs tipus de tocar diferents sons. Una altra molt útil és el destí context. En definitiva, si t'interessa, ja sigui intentar això en el seu propi dret de la consola ara. Així que aquest és un AudioDestinationNode. Bàsicament el que diu és, Cap a on va la sortida? Així que hi ha dues opcions reals aquí. En general, el valor per defecte és només dels altaveus, així AudioDestinationNode bàsicament diu hi ha zero sortides al so entrant, enviat a l'altaveu. Així que en general, no ho fa has de jugar amb això. Si vostè està interessat en utilitzar realment la ScriptProcessorNode per a la gravació, Definitivament em an disparar correu electrònic més tard perquè això és una mica més complicat. Però, en general, vostè és només una mica de la sortida de so en alguna forma. Tan guai, anem a saltar de nou aquí. AUDIÈNCIA: Ho sento. HUGH Zabriskie: Sí. AUDIÈNCIA: Sé que vostè va dir que parlar a vostè més tard sobre la gravació. Pots interfície que amb Pro Tools? HUGH Zabriskie: Amb Pro Tools? Anem a veure. No penso així. Així que va entre el client, que és el JavaScript consola, i la seva real ordinador, és generalment cosa que és una espècie de fora dels límits, si voluntat, tipus per la naturalesa d'ell-- és una mena de cosa disseny, però intenta mantenir l'explorador independent des de l'ordinador real de l'usuari. En general, l'únic que és capaç de d'accés és el micròfon o la càmera. No ets capaç de fer-ho, em no crec, utilitzeu Pro Tools. No obstant això, si ha creat una pista en Pro Tools, exportat que, vostè podria carregar aquest aquí, filtrar-la, per exemple, procés que, i registrar que en un Audio Destination-- o no-- una Esfera Node processador. I a continuació, a partir d'aquí, es podia exportar que a SoundCloud, que podria enviar en un correu electrònic, o el que vulgui a partir d'aquí. Però hi ha una mena de petita barrera entre fer música a l'ordinador i fer música en línia. SAM VERD: I això és no és exclusiu d'aquesta API. És una característica de seguretat de Chrome, i Crec que qualsevol altre navegador modern. El navegador és autònom. Així, per exemple, una pàgina web no pot utilitzar JavaScript per activar el so en els altaveus, per exemple. O no pot apagar l'ordinador. I no hi ha punt intermedi entre aquestes dues coses, a la dreta, així que o tens una completa abstracció, o s'obre la falla de seguretat de deixar un programador amb males intencions fer el que vulguin amb el seu ordinador portàtil. I és per això Chrome és autònom. HUGH Zabriskie: Sí. Això té sentit? Fresc, fresc. Jo només anava a mostrar un exemple d'un. Això és més o menys com la mesura del que s'obté, en termes d'accedir a l'ordinador de l'usuari. Si té un teclat USB connectat, pot utilitzar una cosa que es diu la web API MIDI, que no ho farem realment parlar aquí, però això és una altra API que és incorporada en almenys Chrome-- de nou, és per això que ens encanta Chrome-- Crec que el Firefox o Safari, això és una cosa fàcil de Google-- navegadors diferents tenen diferent de suport per als quals APIs que han implementat. Però si vostè vol connectar un teclat i treballar amb aquesta informació, tipus d'enviar el teclat la informació a l'ordinador i després utilitzar aquesta línia, aquesta API és el lloc on vol estar treballant això. Fresc. D'ACORD. Així, movent-se ràpidament d'aquí. Com anem a temps? ALTAVEU 1: Sobre 15. HUGH Zabriskie: 15 minuts per al final? D'acord, guai. Així que anem a cursa per davant aquí. Així que, bàsicament, el principal punt de pensar en això com una canonada és que cada pas en la canonada és una sèrie de nodes d'àudio. La nostra font, diguem, és un oscil·lador. Hem de crear un node d'oscil·lador. I això és només una mica de la petita function-- i estan tots basats terme del context àudio aquí. AUDIÈNCIA: Quan es va dir oscil·lador, ¿vol dir que en realitat és, literalment, en passar de dos pols diferents d'anada i tornada? HUGH Zabriskie: No, és com una representació digital. S'aplica realment en C ++. En realitat no sé les especificacions de com es porten a la pràctica, però tot això està funcionant com dades binàries. En realitat, si. Això estaria dient, que vaig poder En realitat, si t'interessa, Jo podria enviar una mica més informació sobre com les formes d'ona es mantenen amb un format digital. D'acord, guai. Així que estem generant un to com un sine ona o alguna cosa així, potser 440 Hertz. Creem un oscil·lador. Si volem ajustar el volum, ens connecti res a un GainNode, que podríem veure amb .creategain. Que estableix el seu volum. Pot passar que en qualsevol de l'altre options-- així, pel que una font de memòria intermèdia d'àudio node és on vostè pot ser emmagatzemar un MP3 que vostè ha carregat en. Biquad filtre és per al filtrat si vostè vol prendre tota la base fos d'una cançó, o alguna cosa així. Déu no ho vulgui vostè vol prendre la base d'una cançó. I el node AudioDestination és, de nou, igual que la nostra conclusió és. Si alguna vegada interessat en veure totes les diferents opcions possibles, només ha d'anar a la pestanya i deixar l'auto-completar pujar. I si vostè no creu, vostè veurà tot el diferents coses que es poden crear. Podeu crear dinàmica processadors de seqüència de comandaments, Ni tan sols sé el que és a dir, per la barreja de fusions de canal i divisors de canal i tot això. Fresc. Així que això és només una exemple d'una canonada. Així que tenim tres fonts entrant. Potser aquests són formes d'ona, potser es tracta d'arxius MP3. Un va a través d'un filtre, d'una altra sent distorsionada altra la pròpia pane d'esquerra i dreta. Vostè pot fer tot tipus de coses i tots ells es barregen tot junt, i després surt l'àudio al final, com a destinació. Aquest és un exemple del més complicada Web codi d'àudio es sembla. Vostè està creant tots aquests diferents objectes dret aquí-- No estic segur d'això. No, no té zoom. D'ACORD. VERD SAM: Fas de control, Scroll-Up. HUGH Zabriskie: Control Scroll-- VERD SAM: No, no. Control-- HUGH Zabriskie: Oh, control, cerqueu? Oh, et vaig enxampar. Sí. Vaja, doncs no, doncs no. D'ACORD. No faré això. Així que sí, en aquesta primera secció aquí, veus estem creant totes aquestes diferents nodes fora del context. Estem formant amb elles junts en la segona part per aquesta funció anomenada Connect. Aquesta és una realitat clau funció en Web Àudio. Simplement vol dir que una vegada que has fet alguna cosa amb el so en un node, passar-lo a la següent node. Així que tenim la font, connecta a l'analitzador, l'analitzador fa alguna cosa amb ell, que va a la distorsió, i així successivament, i al destí baix a la dreta aquí. Fresc. OK, així que seguirem avançant. El pipeline-- de nou, aquests són les canonades més comunes, així que parlem de totes aquestes coses com distorsió, pane, totes aquestes coses. Si vostè està realment interessat en l'ús de les coses de Pro Tools, qui probablement li interessen. Si no és així, potser només vull jugar el so, o potser el que desitja és ajustar el volum del so. Aquests són els dos tipus més comú de gasoductes en la producció d'àudio. Un cop més, les formes en què poden prendre-ho en com oscillator-- així, anem a fer la demostració que aquí. Així que anem a crear un context d'àudio senzill aquí, i que anem crear el nostre oscil·lador. Així que això és, de nou, només estem va a cridar Crear oscil·lador. Anem a establir una freqüència de que, 440 Hertz, de tots favorit. Llavors ens connectem que a la destinació point-- que és l'altaveu, per la qual el destí context. Finalment, ens limitem a dir, començar de zero segon a partir d'ara, i què ens sona? [SO] HUGH Zabriskie: Aquí anem. És només una ona sinusoïdal. D'acord, guai. I després ens aturarem això. AUDIÈNCIA: D'on que la retroalimentació ve? HUGH Zabriskie: La retroalimentació? Oh, probablement els nostres micròfons. Així que sí, així és com ho fas. I de fet, si tingués mantingut en funcionament, podria tenir la freqüència valor que s'està executant, així que això és una cosa divertida de jugar. Fresc. Això és sempre una encantadora 01:00 a presentar. VERD SAM: No ho va fer pensem en això, vam fer? HUGH Zabriskie: Sí, això és una desagradable. Així, tampó loading-- vaig a mostrar un exemple d'això en el final. Això és carregar un MP3. I el micròfon, s'utilitza només una funció anomenat Navigator.getUserMedia () per sol·licitar l'accés a l'usuari de micròfon per a aquesta informació. Aquí està filtrant, vaig a simplement mantenir-se en moviment d'aquest. Això és molt alt nivell, però els filtres només li permeten [SO] Filtrat també li permet per crear coses com el rosa el soroll, el soroll marró, soroll blanc. Per crear soroll pur, que algunes persones els encanta perdre el temps amb, pot utilitzar Web Audio filtrat per fer això. Audio Panning-- així que imagina si vostè està escrivint un joc i desitja que el so sona com si vingués, com, disparar a través de la pantalla, pot utilitzar el pane de l'àudio per crear aquest tipus de con, que com-- és bastant Mathy, però en realitat és molt fresc si aconsegueixes que funcioni, i hi ha algunes bones tutorials sobre el que es pot enviar. Bàsicament, vostè pot classe de crear el so que alguna cosa surti per una forma 3D. I si vostè té un interès de DJ, pot començar a barrejar i creuar cançons esvaniment. Aquest és només un molt bàsic codi, bàsicament el que vaig fer abans. Ajusta el volum de la oscil·lador, així que vam crear el nostre oscil·lador que crea la forma d'ona. Creem la nostra GainNode, establir la nostra freqüència, i després connectar l'oscil·lador a la GainNode, que després canvia bàsicament la quantitat de senyal es permet a través. Però, en realitat, és una càmera digital cosa, pel que és més sol-- si. Això no és el que està succeint realment, però això és el que succeeix en la vida real amb un guany. AUDIÈNCIA: --quantization del paràmetre de volum? HUGH Zabriskie: Ho sento? AUDIÈNCIA: ¿És una paràmetre de volum quantificat? HUGH Zabriskie: Sí. I això és una cosa que estic molt deficient en el meu coneixement, com funciona el guany a nivell digital. Sé que amb real senyals, és bàsicament la quantitat de control que ets amplificar el senyal. Així que, sí. Et vaig a enviar més informació sobre això, perquè tinc curiositat realitat saber més sobre això. Però bàsicament els paràmetres són, un és el fold-- el signal-- més fort i el zero no és senyal, o no se sent cap so. Ens saltarem temps de demostració que, a causa de que és bàsicament el que vaig fer abans. I de nou, la Context.Destination és el node de destinació àudio. Impressionant, OK. Així que em vaig a fer un ràpid dos donem. Com anem a temps? ALTAVEU 1: Prop de 10 minuts. HUGH Zabriskie: 10 minuts? Genial! Impressionant. Així que el primer que jo vaig a do, es diu la meva cançó favorita. Així que això és només una mica d'HTML JavaScript. Tindrem dos botons a la pàgina de jugar la meva cançó preferida i aturar la meva cançó preferida. Vaig a canviar això. AUDIÈNCIA: Cobreixi el seu micròfon. HUGH Zabriskie: Sí. I jo he carregat aquí un guió que basically-- i això és realment útil per carregar un MP3, així que això només fa carregar manera MP3s més ràpid. És bàsicament un embolcall. Simplement fa que el procés de loading MP3s molt més ràpid, en cas contrari utilitzeu petició HTTP, alguna cosa així com el que estàvem fent en la peça actual establert amb el servidor. És molt lleig, que no volen fer-ho. Així que aquest noi, Boris SMUS, va escriure una realitat petita eina útil anomenada BufferLoader. Tot el que fem és simplement passar-ho al context, es passa un pel·lícules-- o, sí, és una llista en JavaScript? SAM VERD: Una matriu. HUGH Zabriskie: Oh, és una matriu, que sigui adequat. És un conjunt de camins a diferents arxius. I després se li passa una funció. Es tracta de la devolució de trucada parlàvem sobre amb la càrrega asíncrona. Això es diu Una vegada que els arxius carregats. I aquesta funció que es diu quan l'arxiu de càrrega pren com un perímetre una sèrie d'amortidors carregats. Així que es produeix aquí. Bàsicament, és BufferList serà un value-- o que serà una sèrie de longitud un, que té en ella en l'índex zero l'arxiu carregat sencera de l'MP3. Així que el que faig quan acabo càrrega és, simplement crear una font de tampó, que és un node d'origen memòria intermèdia d'àudio. El següent pas és que es carrega en el source.buffer com tampó de càrrega completa Del BufferList-- que és un munt de buffers-- i després connectar aquest àudio esmorteir a la destinació. Llavors, què es va a fer és simplement posar l'MP3 directament a través de la sortida, i començar immediatament en arribar a aquesta crida. Fresc, així que anem a veure això succeeix en l'acció. El meu [inaudible] aquí, anem a veure. Així que només vaig a iniciar un servidor bàsic. Això és una cosa que que ha de fer si estàs fer peticions d'arxius de càrrega. Vaig a iniciar un servidor bàsic. Això és bàsicament la seva totalitat PSET ara mateix en una línia, però s'acaba de començar un servidor al port 80/80. Així que anem per aquí, ens va a carregar 80/80, anirem a la meva cançó preferida. Així que si em va colpejar "Jugar el meu cançó favorita "en aquest moment, que va a carregar la meva cançó favorita i jugar it-- [MÚSICA - The Eagles, "LA VIDA AL RÀPID  CARRIL "] -que passa a ser "La vida a el carril ràpid "de The Eagles. Ara, jo podria colpejar "Deixa de la meva cançó favorita "i reproduir-lo. [MÚSICA - The Eagles, "LA VIDA AL RÀPID  CARRIL "] I si em vaig a consolar, perquè He utilitzat una variable global per aquí fer un seguiment d'aquest valor, que en realitat ara serà reconegut a la consola. Per tant, acte-crea per a mi. Així que això és el que està sonant en aquest moment, i jo simplement puc cridar source.stop () en això. Bé, saps què? Només perquè vostès han sentit això song-- és possible reconèixer aquesta cançó. [MÚSICA - Rick Astley, "Never Gonna DONAR  VOSTÈ UP "] [MÚSICA - The Eagles, "LA VIDA AL RÀPID  CARRIL "] Hem ara tots han rickrolled. OK, genial, de seguir endavant. Fresc. Així que això és bàsicament un exemple de el que podria carregar un MP3 file-- [MÚSICA - The Eagles, "LA VIDA AL RÀPID  CARRIL "] --i jugar-ho, i detenir i començar a ella. Jo podria haver fet molt més [inaudible] L'últim que vaig a fer és, Et vaig a mostrar un [inaudible]. [REPRODUCCIÓ DE MÚSICA] És com, ogg.wave.mp3. Crec que, si no recordo malament, M'he topat amb alguns problemes amb .m4a, però no estic segur d'això. Crec mp3.wave-- [MÚSICA - Rick Astley, "Never Gonna DONAR  VOSTÈ UP "] D'acord perfecte. No hauria d'haver dit això. De totes maneres, hola. Així que tenim aquesta oberta. Així que ara tot el que faig és, bàsicament creat una sintaxi bàsica per crear música. Així que si no faig alguna cosa així, afegiu g4 l'1 de 2, el que això significa és que, afegir la nota piano, G4, que és la quarta G dalt al piano de la part inferior. Així que això és una espècie de MIDI parlar, així que per a aquells que es basen la música, això és simplement notes MIDI. AUDIÈNCIA: Aquesta és la G del Medi C, oi? HUGH Zabriskie: Aquesta és la G per sobre de Medi C, és cert. AUDIÈNCIA: Sobre Medi C. HUGH Zabriskie: Sí. En realitat, si. Crec que en realitat vaig fer ens [inaudible], de manera que aquesta podria ser una octava per sobre d'això. Així que anem a veure. Si em va colpejar Play-- [PIANO REPETITIUS NOTA] --we're va sentir això. La idea és que opera de la mateixa manera que una línia d'ordres seria, així que si em vaig amunt i avall en el meu teclat, pot tornar a l'anterior ordres, la qual cosa és força útil. I a continuació és la meva llista de pistes, que estan tots funcionant en bucle. AUDIÈNCIA: Vostè va ser assumint la 88 tecles del teclat en això, oi? HUGH Zabriskie: La pregunta era, estic assumint un teclat de 88 tecles, i sí, ho sóc. El que vaig fer és que bàsicament va prendre 88 mostres del piano, un per a cada nota. I així, cada vegada que escoltar una nota d'ara endavant, que en realitat és un bucle que s'assembla com-- Això s'està posant reproduir en bucle, de manera que per cada nota, això s'està executant. El que passa és que jo crear un tampó de nou, Puc crear un node de guany per ajustar el volum. Això només una realitat complicada manera de dir que emmagatzemar el tampó en un source.buffer. Li dono el guany, jo connectar al guany, el guany està connectat a la de sortida, i després la toco. Així que és una mena de procés de prendre en una font de memòria intermèdia. AUDIÈNCIA: Pot vostè realment prendre aquest so sec i que sigui humida [inaudible]? HUGH Zabriskie: Pot, si. Hi ha re-verb, hi ha retard, distorsió. Bàsicament, pot posar qualsevol cosa en entri en aquest sandvitx de-- així, canonada és una metàfora millor, però vostè pot afegir res a això. Fresc. Així que vaig a acabar la demo aquí per donar-li un sentit tot just de la gran quantitat de vegades que es pot executar aquesta funció alhora. Així que em vaig a treure això. Vaig a crear un generador que-- bàsicament el does-- això és realment una mena de syntax-- complicat però és generarà notes sobre la marxa, i acaba de començar a jugar ells ja que els avalua. [PIANO interposant] Així que només podem fer una mica de música aquí. [PIANO interposant] Així que el que aquesta comanda fa, per exemple, és que pren aquestes tres notes per al piano i després els posa en B3. Aquesta sintaxi pot fer una mica més de sentit per a aquells que tenen un música de fons aquí. Puc afegir un bombo. Jo puc-- [Interposant INSTRUMENTS] --només jugar amb això. Així que vostè pot make-- [Interposant INSTRUMENTS] Que un és una mica més molest. [Interposant INSTRUMENTS] Així que se suma a l'atzar címbal seca en cada nota 16a, amb un 16% [Inaudible]. [Interposant INSTRUMENTS] Sí, de manera que la forma en què aquesta works-- sempre en 4: 4. [Interposant INSTRUMENTS] Sí, de manera que els quatre trimestres, i 16/8. [Interposant INSTRUMENTS] Així que, de mitjana, s'obté el 60% d'accessos a les notes 16. De totes maneres, això era només tipus de mostrar- algunes de les coses que podria construir amb la Web API Audio. És molt potent, és molt ràpid, i vostè pot fer un munt de coses interessants amb ell. Així que de nou, qualsevol pregunta que tingui, email myself-- Hugh-- o Sam, i honestament, Google té un munt de bons recursos. Alguna darrera pregunta? Sí. AUDIÈNCIA: Així que vostè pot accedir a el micròfon incorporat. Què passa si vostè vol utilitzar un micròfon millor? HUGH Zabriskie: Si volies per utilitzar millor micròfon? Així que de nou, això és part de la abstracció entre Crom i la resta del seu equip. Si no sou disponible a través de una API, com API Web MIDI, que probablement podria trobar alguns hacks, però generalment no és tan viable. VERD SAM: Pot també-- tot el crom sap és el que el micròfon predeterminat és, i té accés a això. Així que si vostè tenia un micròfon poguessis establir com micròfon predeterminat de l'equip, vostè pot accedir-hi d'aquesta manera i probablement treballar. HUGH Zabriskie: Aquest és un bon punt. Mai ho he intentat, però vostè podria ser capaç de classe de-- si redirigeix ​​l'altaveu d'entrada, vostè podria ser capaç de fer això, si. Alguna darrera pregunta? Fresc. Bé, gràcies nois tant per la seva atenció. Estic Hugh. VERD SAM: Sóc Sam. HUGH Zabriskie: I això és CS50.