ios - SKEmiterNode with AVAudioPlayer for music visuals -


please help!

i want have skemiternode's scale(meaning size) larger , smaller music have built application using avaudioplayer. right pretty have skemiternode , looks great:

beatparticle?.position = cgpoint(x: self.size.width * 0.5, y: self.size.height * 0.5)  var beatparticleeffectnode = skeffectnode() beatparticleeffectnode.addchild(beatparticle!) self.addchild(beatparticleeffectnode) 

all looks done in .sks file.

here call "updatebeatparticle" function in continual loop can put code making particle's scale(meaning size) larger , smaller music.

var dplink : cadisplaylink?  dplink = cadisplaylink(target: self, selector: "updatebeatparticle") dplink?.addtorunloop(nsrunloop.currentrunloop(), formode: nsrunloopcommonmodes)  func updatebeatparticle(){ //put code here } 

any idea how can this? looked @ tutorials such this: https://www.raywenderlich.com/36475/how-to-make-a-music-visualizer-in-ios

however, can't quite head around because they're using emitterlayer , in obj-c , interested in other ideas wonderful people may have!

warning: following code has not been tested. please let me know if works.

firstly, looks using spritekit, therefore put code needed alter emitter scale in skscene method update:, automatically gets called virtually cadisplaylink.

essentially need update emitter scale in update: method based on volume of channels of avaudioplayer. note audio player may have multiple channels running, need average out average power each.

firstly...

player.meteringenabled = true  

set after initialise audio player, monitor levels of channels.

next, add in update method.

override func update(currenttime: cftimeinterval) {      var scale: cgfloat = 0.5      if audioplayer.playing { // if audio playing         audioplayer.updatemeters() // tell audio player update , fetch latest readings          let channels = audioplayer.numberofchannels          var power: float = 0         // loop on each channel , add average power         in 0..<channels {             power += audioplayer.averagepowerforchannel(i)         }         power /= float(channels) // give average power across channels in decibels          // convert power in decibels more appropriate percentage representation         scale = cgfloat(getintensityfrompower(power))      }      // set particle scale match     emitternode.particlescale = scale } 

the method getintensityfrompower used convert power in decibels, more appropriate percentage representation. method can declared so...

// return value between 0.0 ... 1.0, based on decibels func getintensityfrompower(decibels: float) -> float {     // minimum possible decibel returned avaudioplayer channel     let mindecibels: float = -160     // maximum possible decibel returned avaudioplayer channel     let maxdecibels: float = 0      // clamp decibels value     if decibels < mindecibels {         return 0     }     if decibels >= maxdecibels {         return 1     }      // value can adjusted affect curve of intensity     let root: float = 2      let minamp = powf(10, 0.05 * mindecibels)     let inverseamprange: float = 1.0 / (1.0 - minamp)     let amp: float = powf(10, 0.05 * decibels)     let adjamp = (amp - minamp) * inverseamprange      return powf(adjamp, 1.0 / root) } 

the algorithm conversion taken stackoverflow response https://stackoverflow.com/a/16192481/3222419.


Comments