diff --git a/README.md b/README.md index 189f62b6..3d8eb4a6 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ This repository contains all code for http://www.eegsynth.org. ## Installation instructions for Raspbian +## Installation instructions for Raspbian + Use "raspi-config" to configure the correct keyboard, time-zone, to extend the partition on the SD card and to disable the automatic start of the graphical interface upon boot. @@ -38,6 +40,12 @@ export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/opt/local/lib sudo apt-get install libportmidi0 sudo apt-get install libportmidi-dev +sudo apt-get install python-pyaudio python3-pyaudio + +sudo apt-get install alsa-utils +sudo apt-get install mpg321 +sudo apt-get install lame + Note: To use the Launch Control XL with the Raspberry Pi you must first switch it to low power mode. To do this hold down both the User and Factory Template buttons and insert the USB cable. Release diff --git a/module/launchcontrol/launchcontrol.ini b/module/launchcontrol/launchcontrol.ini index a851d9f5..bf11b78b 100644 --- a/module/launchcontrol/launchcontrol.ini +++ b/module/launchcontrol/launchcontrol.ini @@ -6,8 +6,8 @@ hostname=localhost port=6379 [midi] -;device=Launch Control XL ; this is the name on my macbook pro -device=Launch Control XL MIDI 1 ; this is the name on my raspberry pi +device=Launch Control XL ; this is the name on my macbook pro +;device=Launch Control XL MIDI 1 ; this is the name on my raspberry pi [output] prefix=launchcontrol diff --git a/module/pulsegenerator/pulsegenerator.py b/module/pulsegenerator/pulsegenerator.py index 503209a3..ea112642 100755 --- a/module/pulsegenerator/pulsegenerator.py +++ b/module/pulsegenerator/pulsegenerator.py @@ -9,8 +9,6 @@ config.read('pulsegenerator.ini') r = redis.StrictRedis(host=config.get('redis','hostname'), port=config.getint('redis','port'), db=0) -r.set('foo', 'bar') -r.get('foo') s = serial.Serial(config.get('serial','device'), config.getint('serial','baudrate'), timeout=3.0) diff --git a/module/synthesizer/README.md b/module/synthesizer/README.md index 21dc8b82..493fc0b0 100644 --- a/module/synthesizer/README.md +++ b/module/synthesizer/README.md @@ -5,21 +5,25 @@ The purpose of this module is to provide a simple virtual synthesizer using the ** VCO - voltage controlled oscillator ** -The VCO generates a simultaneous triangle, saw and square wave signal, which are mixed into the audio output. It has one input control for the pitch and three input controls for the mixer. +The VCO generates a simultaneous sine-, triangle-, saw- and square-wave signal, which are mixed into the audio output. It has one input control for the pitch and four input controls for the mixer. + +** LFO - low frequency oscillator ** + +The LFO shapes the audio envelope. The LFO has two input controls for the frequency and the depth. ** VCA - voltage controlled amplifier ** -The VCA shapes the audio envelope. Each VCA has two input controls for the attenuator and the passthrough level. +The VCA shapes the audio envelope. The VCA has a single input controls for the attenuation. -** ADSR - attack, decay, sustain, release ** +** NOT YET IMPLEMENTED: ADSR - attack, decay, sustain, release ** The ADSR takes a trigger as input and generates a continuous envelope as output. It has four input controls. -** VCF - voltage controlled filter ** +** NOT YET IMPLEMENTED: VCF - voltage controlled filter ** The filter can be toggled between lowpass, highpass and bandpass filtering of the audio signal. It has two input controls for the frequency and bandwidth. ** Requirements ** The REDIS buffer should be running. -A pair of speakers or headphones should be connected to the raspberry Pi audio output. +A pair of speakers or headphones should be connected to the Raspberry Pi audio output. diff --git a/module/synthesizer/synthesizer.ini b/module/synthesizer/synthesizer.ini index 03b9fb08..fbf6a078 100644 --- a/module/synthesizer/synthesizer.ini +++ b/module/synthesizer/synthesizer.ini @@ -1,6 +1,6 @@ [general] name="Synthesizer" -bitrate=16000 +bitrate=48000 blocksize=120 taper=linear ; linear or logarithmic @@ -13,8 +13,10 @@ sin=0.75 tri=0.00 saw=0.25 sqr=0.00 -pitch=1000 -vca=1 +pitch=64 +lfo_frequency=64 +lfo_depth=64 +vca=64 [input] sin=launchcontrol.channel00.control077 @@ -22,7 +24,6 @@ tri=launchcontrol.channel00.control078 saw=launchcontrol.channel00.control079 sqr=launchcontrol.channel00.control080 pitch=launchcontrol.channel00.control081 -vca=launchcontrol.channel00.control053 - -[output] -channel=left ; left/right/both +lfo_frequency=launchcontrol.channel00.control082 +lfo_depth=launchcontrol.channel00.control083 +vca=launchcontrol.channel00.control084 diff --git a/module/synthesizer/synthesizer.py b/module/synthesizer/synthesizer.py index a1193a93..3be8ebb6 100755 --- a/module/synthesizer/synthesizer.py +++ b/module/synthesizer/synthesizer.py @@ -70,18 +70,42 @@ control_saw = control_saw/control_total control_sqr = control_sqr/control_total + ################################################################################ + # LFO + ################################################################################ + + lfo_frequency = r.get(config.get('input','lfo_frequency')) + if lfo_frequency: + lfo_frequency = float(lfo_frequency) + else: + lfo_frequency = config.getfloat('default','lfo_frequency') + # assume that this value is between 0 and 127 + lfo_frequency = lfo_frequency/3 + + lfo_depth = r.get(config.get('input','lfo_depth')) + if lfo_depth: + lfo_depth = float(lfo_depth) + else: + lfo_depth = config.getfloat('default','lfo_depth') + # assume that this value is between 0 and 127 + lfo_depth = lfo_depth/127 + ################################################################################ # VCA ################################################################################ control_vca = r.get(config.get('input','vca')) - if control_sqr: + if control_vca: control_vca = float(control_vca) else: control_vca = config.getfloat('default','vca') # assume that this value is between 0 and 127 control_vca = control_vca/127.0 + ################################################################################ + # generate the signal + ################################################################################ + BUFFER = '' PERIOD = int(BITRATE/FREQUENCY) for t in xrange(offset,offset+BLOCKSIZE): @@ -91,6 +115,10 @@ wave_saw = control_saw * float(t % PERIOD)/PERIOD wave_sqr = control_sqr * float((t % PERIOD) > PERIOD/2) waveform = (wave_sin + wave_tri + wave_saw + wave_sqr)*127 + # compose and apply the LFO + control_lfo = (math.sin(math.pi*lfo_frequency*t/BITRATE)+1)/2 + control_lfo = lfo_depth + (1-lfo_depth)*control_lfo + waveform = control_lfo * waveform # apply the VCA waveform = control_vca * waveform BUFFER = BUFFER+chr(int(waveform))