First jameswitzema.net commit

This commit is contained in:
Lao Tzu
2026-05-29 11:30:10 -07:00
commit 32cc108c4a
200 changed files with 1200635 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
<h1>|= ABOUT JAMES</h1>
<p>
Caden James Witzeman is a programmer and jazz musician
based in the US! James likes progamming in C, PHP,
systems administration, Gentoo, DWM, and other forms of
linux-based pain. James was trained in computer engineering
for 3 years for college, but didn't finish.
</p>
<p>
James plays mostly piano, and knows a bit of guitar. He started
playing keyed percussion in high school and later at Northern Arizona
University. James is currently listening to lots of Herbie Hancock
(specifically Mr. Hands and Future Shock),
Thelonious Monk, 9th Wonder, Victor Vaughn, and is <i>obsessed</i>
lately with Hiromi's <i>OUT THERE</i> album. Really good stuff.
</p>
<h3>LINKS</h3>
<ul>
<li><a href="mailto: me@jameswitzeman.net">me@jameswitzeman.net</a></li>
<li><a href="https://jaufheben.bandcamp.com/">Bandcamp</a></li>
<li><a href="https://github.com/jameswitzeman?tab=repositories">GitHub</a></li>
<li><a href="https://www.instagram.com/xu4nde/">Instagram</a></li>
</ul>
+101
View File
@@ -0,0 +1,101 @@
<title>I AM IBM</title>
<body>
<div id="body">
<h1>BUILDING A 6502-BASED COMPUTER</h1>
<h6>9/1/2023</h6>
<p>
Over the summer of 2023 I decided to keep myself busy with a relatively ambitious project;
I wanted to build an 80s-style terminal computer based off of the classic 6502 processor chip,
and I wanted to build a graphics processing circuit capable of terminal-style text-based video
output. This project essentially followed <a href="https://eater.net/6502"> Ben
Eater's 6502 computer video series,</a> with some minor tweaks and additions of my own. I
haven't even come close to a conclusion for this project, and I want the final product to be
printed on a custom PCB with a nice-looking enclosure (probably an old PC case retrofitted
for this purpose.)
</p>
<p>
The MOS 6502 processor was one of the earliest processor chips that were affordable enough
for large-scale home PC and console manufacturing. Early computer and game consoles such as
the apple I and II, Nintendo Entertainment System, Commodore 64, and many of the 8-bit atari
home computers used the 6502 processor or a similar variant. The original MOS chips are out
of production, but Western Design Center manufactures a near-identical 6502 chip with some
modern amenities such has higher max clock speeds and easier halting protocol. This is the
chip Ben Eater uses in his project and I will be using the same one.
</p>
<p>
In Ben's guide, he primarily uses a serial connection to a modern computer for interfacing
with the terminal, instead of implementing standalone graphics circuitry. He does include a
tangential project where he builds a rudimentary graphics system that supports color but
requires that the CPU write each pixel to the frame buffer manually, and uses a very rough
but straightforward method to provide DMA to the graphics unit. This is the main area where
I would like to insert my own improvements.
</p>
<p>
For my project, I want to implement basic terminal-style graphics support, similar to the
graphics functionality of the original Apple I computer. I am not interested in color support
whatsoever, I just want the CPU to write ASCII characters into the frame buffer in black and
white. I believe that when color and pixel-by-pixel frame writing are scrapped, my video
system could easily support much larger ASCII-based frame buffers at higher resolutions.
</p>
<p>
But before I could get started on the video system, I had to actually build the 6502 computer.
My computer is pretty much the same as Ben's, except I really had an issue with his memory
address allocation for peripherals. He sacrificed a lot of address space for the sake of
ease of implementation, and I wasn't as concerned about ease of implementation. Ben managed
his addressing with a few NAND gates. I upgraded to a set of demuxers/decoders so that
more specific address ranges could be reserved. I also halved the amount of ROM space
and doubled RAM space, just because I doubt any program on this computer will exceed
a few kilobytes. I kept the peripherals; A general I/O chip (6522), serial chip (6551), and
an added graphics processor. My new addressing logic allows for a greater addition of
peripheral however, and I'd like to add a few DAC's at the least. The last step of building the
computer was getting Wozmon working. Wozmon was an extremely rudimentary kernel designed by
Steve Wozniak for the Apple I which allowed for program writing (In hexadecimal assembly)
and executing, as well as browsing the address space. After I was able to confirm Wozmon was
working via a serial connection, I was ready to get started on my graphics system.
</p>
<p>
Fortunately, in order to implement graphics, I don't need to diverge much from Ben's video design
except for the last bits of the logic chain. The largest portion of the complexity of the
design comes from the logic that reads the pixel-by-pixel frame buffer and transmits the buffer
to the screen via a VGA signal. At the end of this logic chain is a system that reads the buffer
from memory. This end ought to be replaced by a ROM which contains the pixel-by-pixel ACSII
character set where each line of a character is addressed by its corresponding ASCII code
and the line number that should be displayed. This means the ROM's address lines should
be tied to the video system (which counts lines), and the frame buffer in memory. If the width
of each character is 8 bits/pixels, then this means the ROM will have to access memory directly every
8th pixel on the screen. I plan to run the video system at 40MHz, which means
every 8th pixel occurs every 200ns, or at a frequency of 5Mhz. Before that 8th
pixel is written by the video logic, some system must halt the 6502 (or otherwise stop it from
accessing memory), read from the proper address in memory, increment that address before the
start of the next cycle, make sure that the ROM has had enough time for its output to stabilize,
and shift each bit from the ROM into the VGA signal. This time constraint is the greatest
hurdle to this design, although I still believe I may be able to find parts that can run this
fast. Once I can actually write a character to the screen (via hard-coding and not DMA), then
I have to find a way for the processor to be able to run for some portion of this time. This
means that the graphics processor needs to access the RAM for as little time as possible. This
problem iz significant, and may require the pixel frequency to be halfed or quartered
to reduce resolution and allow the hardware more time. As of writing, I have built this video
circuitry without DMA, but have been unable to get a character to output to a screen. I
believe this is a timing issue, and will update once I have solved the issue.
</p>
<p>
This is the state of my project so far. But before I conclude, I would like to lay out my plans
for this project once the hardware is working. I would like to use the computer to interface
with analog synthesis circuitry to mak some kind of roided-up sound card for music. I would
also like to get a more complex operating system running on the computer. I would start this
process by getting a C compiler running on the 6502, and then getting some kind of basic Unix-
like kernel up and running. This is likely overambitious and I suspect I will just end up
getting BASIC running on it instead, but these are the end goals for the project.
</p>
<p>
This project has been very valuable to me in several ways. Building a computer from chips,
getting to the point of writing code for it in assembly, and seeing a basic kernel running
really helps build a rigorous understanding of how computer code really is just a high-level
abstraction from the bare metal hardware. I think with modern computers and their complexity,
this is a kind of holistic understanding that is lost. The hardware becomes a black box which
just runs code. This project helps remind me that no matter how complex our computers get,
at the end of the day they really do just execute binary instructions.
</p>
</div>
</body>
+6
View File
@@ -0,0 +1,6 @@
<title>BLANK</title>
<body>
<div id="body">
<h1>HEADER.</h1>
</div>
</body>
+58
View File
@@ -0,0 +1,58 @@
<title>PALESTINE</title>
<body>
<div id="body">
<h1>THE GENOCIDE IN PALESTINE</h1>
<p>
As of May 2024, nearly 50,000 Palestinians have been murdered by the Israeli government. Nearly all of
these lives were innocents. About 14,000 of these lives were children. There is absolutely no excuse
or justification for this fact. The fact of the matter is as follows:
</p>
<p>
Since its foundation ~70 years go, the nation of Israel has dedicated itself in part to the
extermination of the Palestinian people regional to the area. This has never ceased to be true.
Today, and since October 7th 2023, we see another example of Israel's commitment to genocide.
The far right Israeli government under Benjamin Netanyahu has a near-outright bloodthirst for children.
They want all Palestinians dead and they will not stop until there is nothing but rubble left in Gaza.
Then, they will move on to the West Bank. Anyone who challenges the idea that the West Bank is safe
from occupation because Hamas does not reside there is woefully unaware of the reality of the situation.
Although presently the bulk of Israel's occupation is focused on Gaza, they have countless times
aggressed on the West Bank. Hamas exists in part as a result of Israel's effort to prevent the spread
of the PLO to Gaza, to keep Palestinian people from uniting effectively in resistance.
</p>
<p>
It is FALSE that if Hamas laid down their arms, this conflict would end. This is false because the
bulk of the conflict has not been directed at Hamas, it has been completely <i>undirected.</i>
Israel chooses to intentionally level Gaza with indiscriminant bombing. This is not the strategy
of a military force trying to fight an enemy in a populated civilian area. It is the strategy of
genocide.
</p>
<p>
So what is the solution? Two-state? One-state? Frankly, I don't know. I know there will only be peace
once ISRAEL commits to a cease-fire, and when ISRAEL commits to allowing Palestinians in Gaza the same
rights and access to the democratic process as Israeli citizens. The current state of affairs <i>is</i>
a one-state solution. Israel is one state, and it has chosen to abandon millions of its citizens in
Gaza and the West Bank in the name of 'autonomy.' What a sick joke.
</p>
<p>
The only reason Hamas exists and commits terror attacks is because Israel has raised a generation of
Palestinians without families, without food and water and basic human respect. Of course this generation
has been driven to acts of terror, because Israel has terrorized them and their family daily for
generations. Additionally, this radicalization process has been inflamed by Israel as Israel has
destroyed every attempt by Palestinians to direct their suffering and agitation towards effective
organization. They bomb Gaza until all that is left is guns and hate and pain. Israel has the power
to stop the violence, and they choose instead to kill indiscriminantly. Our country (the United States)
refuses to revoke funding and support, we enable the genocide. Any rational humane actor will conclude
that this genocide must be stopped by any means necessary. I must add that wanton terror against Israeli
civilians is NOT an efffective means to stop the genocide. It is a war crime. It is a war crime when
Israel does it by the tens of thousands, and it is a war crime when Hamas does it by the hundreds.
For this reason, I cannot include wanton terror within 'any means necessary.' Wanton terror is not
a necessary means.
I can include many other forms of resistance, some of which
are violent. Sometimes occupation and oppression must be resisted violently. Our founding fathers
understood this very well when they violently resisted the British government. They added a Second
Amendment to our constitution to enshrine our right to maintain arms in the event that our
government must be violently resisted. I say, this issue is the same. I say to you, reader:
</p>
<h1>CEASEFIRE NOW.</h1>
</div>
</body>
+20
View File
@@ -0,0 +1,20 @@
<title>BLANK</title>
<body>
<py-config>
packages = [
"pandas",
"bokeh",
"xyzservices"
]
</py-config>
<div id="body">
<h1>HEADER.</h1>
<py-script>
import json
import pyodide
from js import Bokeh, console, JSON
p = figure(width=400, height=400)
</py-script>
</div>
</body>
+140
View File
@@ -0,0 +1,140 @@
<title>MACHINE LEARNING IN C</title>
<body>
<div id="body">
<h1>LEARNING NEURAL NETWORKING IN C</h1>
<h6>10/19/2023</h6>
<p>
To keep myself entertained between classes this fall semester (2023), I decided to try to learn a
little about machine learning mathematics. I've heard of the Python library TensorFlow, which does
a lot of the heavy lifting for you (in c++, so likely not at the expense of Python's slow interpreter).
I am interested in learning these types of python libraries, but first I wanted to develop a very
strong familiarity with the basics and mathematics of machine learning. I also am trying to get
as familiar as possible with C for my own personal enrichment. As of starting this project, I thought
it would be nice to have a machine learning library in C for any of those who didn't want to use
python for whatever reason. I realize now that this was foolish. My code probably doesn't have much
utility for anyone else, but it was a very good learning experience for me.
</p>
<h3>DOING MY RESEARCH</h3>
<p>
I started my journey by scouring a
<a href="http://neuralnetworksanddeeplearning.com/index.html">book by Michael Nielsen</a> on machine
learning. The book is a few years old and behind the times now, but I'm not going to be setting the
state of the art here so I'm not too concerned. I quickly learned that training a neural network really
is just a minimization problem, and the whole thing can be elegantly expressed as pure math instead of
as a programming problem. I started taking notes like I was in any other math class. The first big
concept to learn was gradient descent.
</p>
<p>
For those who have taken a multivariable calculus class, gradient descent is a pretty straightforward
exercise. For those who haven't, the core idea is still not too inaccessable. We can think of
a neural network as a huge, crazy black box with a million different parameters to tweak. We throw
a bunch of data into the box with an idea of what we want the network to spit back out. As long as we
can quantify how far off our network is from the ideal output, we can use this quantity as a function
of these million parameters. The idea here is to find the multivariable derivative of this error metric,
usually called a cost function. If we can find a method to figure out how tweaking each parameter
changes our output, then we can use that information to tweak them in just the right way to minimize the
cost and maximize how close our output is to the ideal. This multivariable differential is called the
gradient. Once we have our table of which parameters to tweak and in what way, we then choose how large
a step to take and we actually change all of our parameter values. This is very similar to the idea
of walking down a hill until you reach the lowest valley you can find. Because the network is a
complex mathematical entity with many moving parts, the hard part is figuring out how to even calculate
this gradient. That's where backpropagation comes in.
</p>
<p>
Backpropagation is the method by which a gradient is calculated for a neural network. The important
thing to remember is that all backpropagation does is find the gradient of the cost function. The
complicated part is figuring out how every single parameter should be tweaked to minimize the cost.
The first step is to figure out how the output should change in order to minimize the cost. Usually this
means the output will have a random set of activations that do not correlated to the input at all.
Our cost will likely be high. We know that the cost is a function of each output neuron's activation,
so we can take the derivative of the cost with respect to each activation value. Once we have this
differential, we then think of our output activations as functions of the activation of the previous
neuron, as well as the weight and bias for the current neuron. We can find this differential with
respect to these values. We then consider the activations of the previous neuron as functions of the
parameters of the neurons before that, and so on and so forth. This is why the process is called
backpropagation, we start by looking at how the output ought to change and work backwards from there.
The complicated part is the nuts and bolts of the math required to compute all this, which I will
not cover here. I highly recommend checking out Nielsen's online book.
</p>
<h3>IMPLEMENTATION</h3>
<p>
I started my program by building structures to hold all the neuron, weight, and bias data for each
layer. My goal was to have one structure which holds the entirety of the network for ease of reference.
I decided to use a structure to represent a single layer in a network. This structure holds vectors
which represent the data for each neuron, and a matrix for the weights. I used the GNU Scientific
library for my vector maths, which may have been a little overkill but it allows me to work
with complex math structures easily. It will also help when I expand into convolutional networks.
</p>
<p>
Once I was sure I had my network data structures working, I started building code for importing data
into the network. The example problem I used to get the network functioning was the classic digit
recognization problem. The idea is to train a network to reconize and correctly categorize a low-
resolution image of a handwritten digit, in black and white. In order to import an image, I
had to open the file containing the images and scan through each line (where one line is one image)
and import the 0-255 greyscale values into my dayta structure. Firstly, the network only works
with values from 0-1, so I had to map the 0-255 values to 0-1. I decided to use a simple linear
mapping between values, as opposed to some non-linear function like the sigmoid. I did experiment
with the sigmoid function once the network was working, but the results were not as good. I suspect
this is because the sigmoid is capable of mapping an infinite domain of values to a range of 0-1,
meaning you could plug in an arbitrarily large number in and get a number restricted to the finite
range out. This is very useful for calculating network activations, when the weights and biases can
sum up to very large numbers. But if your data input is already restricted to a finite domain,
then a simple linear map is better. Long story short, after some tweaking I had the image data properly
converted and imported to my network's input.
</p>
<p>
The next task was to get my network to properly <i>feedforward</i>, that is, to properly calculate
the activations for every neuron in every layer up to the output. Of course, the untrained network
will output nonsense, but the important part is that it is properly calculated. The calculus will not
work otherwise. Once the output can be calculated from the input data, then the cost needs to be
calculated. I started using mean squared error for my cost function, then switched to log-likelihood
later. I know the cost is working properly if it is very high for the untrained network, usually
in the ballpark of 1-3. I can't really know for sure that the cost is working until I see it going
down during the training process, but I was confident at this point it was doing okay. Once this was
all up and running, I could move on to backpropagation.
</p>
<p>
The first really serious programming challenge was getting backpropagation up and running, although
because the algorithm is so well-documented it boiled down to effectively implementing the algorithm
in code. The first step is to find the <i>'error'</i> of the output layer, which really just means
figuring out how the output should change to decrease the cost. Then the error for the layer before
it is calculated, and so on, until we get to the input layer. The input activations cannot be controlled
by the network of course, but we can control the weights and biases connected to the inputs. We
can figure out how the weights and biases ought to change, then we tweak them. This is the gradient
descent step. We choose a value for the small step we should take, then we change the value
of each weight and bias by the product of that step and the corresponding differential. The idea is
analogous to stepping down a hill, but if the hill was a surface in a 13,000-dimensional space.
We know that these steps are working if we watch the cost go down after each descent. After many hours
of watching the cost jump around or not move at all or return a divide by zero error, I eventually
was able to get my program to descent properly and actually recognize features of different digits.
</p>
<p>
Watching the network's cost function minimize is extremely satisfying and important, but it doesn't
matter at all if we aren't actually categorizing digits properly. It is possible for the network
to get stuck in small valleys of its cost function, where it categorizes all data the same way
and gets a mildly acceptable cost, or to spit out 0 on all of its output neurons, or something like
that. It's also common for the network to learn to recognize the training dataset with 100% accuracy,
but when shown new data it wasn't trained on it gets totally lost. This is sort of like the difference
between memorization and actual understanding of a concept in human brains. So in order to avoid this,
we show the network a set of digits it wasn't trained on and test how many it correctly categorizes.
This gives us a direct accuracy metric that shows us how well it has actually learned, instead of
'memorizing' the dataset. The general task list for my program is to train the network, test the
network, and return the score so the user can tell how well the network has learned. The first
version of my code got an accuracy of around 75-80%. After implementing some better cost functions,
better activation functions, and tweaking the backpropagation a little, I was able to get
around 90% max accuracy. This is not nearly as high as Nielsen's program, which achieved around 95-96%
with the same methods. Frankly, I am still trying to figure out where the disparity comes from. I am
relatively happy with the network so far however.
</p>
<p>
The next step for this project is to implement a <i>convolutional</i> neural network, which is
a different architecture specialize in image processing. This requires a lot more math and complexity,
but it is doable (I think.) Currently, I have been able to get the data structure up and running,
but I have not implemented feedforwarding and backpropagation. I will make the code available
on my GitHub once I can get this working. So far, the project has been extremely educational for me,
not only on the math of machine learning but also for my general literacy in C. I would recommend
that any software engineer with some spare time and hunger for learning and challenge try this
themselves.
</p>
</div>
</body>
Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

+101
View File
@@ -0,0 +1,101 @@
<title>MODULAR SYNTH</title>
<body>
<div id="body">
<h1>BUILDING A SYNTHESIZER FROM SCRATCH</h1>
<h6>10/30/2022</h6>
<p>
This project got started the summer of 2022 when I got really into analog circuitry and additionally realized I would not have enough money
to buy my own synthesizer for several years. I stumbled upon the Youtube channel of <a href="https://www.youtube.com/c/MoritzKlein0">Moritz Klein,</a>
a synth hardware designer who makes educational videos on synth circuitry in his free time. This inevitably lead me down an endless rabbit hole that I may never escape from.
Since then I have spent endless hours researching oscillators, exponential converters, ladder filters, SR-latch envelope generators, etc and I have learned a lot about audio
hardware. This page will be a tome to my learning and plan to update it regularly. Let's jump in!
</p>
<h3>STEP ONE: THE VCO</h3>
<p>
When it comes to synth hardware, probably one of the most vital circuits is the Voltage Controlled Oscillator, or VCO. As the name implies, the VCO is an oscillating circuit whose
pitch can be controlled by a voltage input. VCO's usually offer sawtooth, square, and triangle waves as standard base waves. This task is relatively simple, but trying to build a robust VCO with
consistent tuning, wide range, and accurate voltage control turns out to be quite a difficult task. This is something I learned the hard way.
</p>
<figure class="centerimg">
<img src="4069vco.png" />
<figcaption>4069 VCO schematic mine was based off of.</figcaption>
</figure>
<p>
The first guide I followed was Klein's VCO video, which is based off of <a href="https://www.schmitzbits.de/vco4069.html">Rene Schmitz's VCO 4069.</a> I quickly learned that Schmitz's website would be a prime resource
for synth circuit learning: it contains many different circuits for just about every essential synth part. This VCO is based off of a 4069 Hex Schmitt Trigger CMOS chip, a pretty classic chip in the DIY synth
scene. It is comprised of three main sections: The input processing, oscillator, and wave shaper. The input processing sums each of the several voltage inputs, and then sends them to the exponential converter. Because
musical pitch is exponential and per the V/Oct standard one volt corresponds to one octave, the converter must turn the linear voltage to an exponential current for proper tracking.
Next is the oscillator, it takes the current and spits out a sawtooth wave. Finally is the wave shaping, which converts the sawtooth to a square wave with pulse width
modulation. The circuit is pretty straightforward, but I couldn't get it to work and I had issues with its thermistor temperature compensation.
</p>
<figure class="wrapimg">
<img src="schmitzexpco.png" />
<figcaption>Common exponential converter transistor setup.</figcaption>
</figure>
<p style="margin-bottom:7vh;">
The main reason I moved on from this circuit is because I coulnd't get the exponential converter to work with the 4069. I think the issue was a poorly matched set of transistors, but regardless I got stuck.
So I abandoned the converter and went off to research the circuitry. I learned that this circuit's converter is rather unusual for using a PNP and NPN. Most converters I found used matched NPN or PNP transistors
to convert the linear voltage. The next thing I tried was just swapping the converter from the original with a version of this one, which worked fine. The V/Oct tracking wasn't great and the circuit only uses one trigger
alongside a whole bunch of opamps. When I tried to scale this circuit up to utilize all six schmitt triggers, I quicly realized the circuit became way too big to use. I decided to move on to a different circuit.
</p>
<figure class="wrapimg", style="display:inline;">
<img src="vconeu.png" />
<figcaption>The final schematic I went with, built around a 555 timer.</figcaption>
</figure>
<p style="margin-bottom:10vh;">
At this point, I'd discovered Schmitz's website and was looking through his VCO designs. After considering the viability of each one, I decided to build his <a href="https://www.schmitzbits.de/vco2.html">VCO 2,</a> a 555-timer-based VCO with a pretty simple schematic.
After about two weeks of troubleshooting and trying to understand the circuit, I finally got a working VCO with a square and saw wave output, decent V/Oct tracking, and a sensible count of chips!
Next, I decided to take the circuit off the breadboard and build a stripboard prototype. I've considered designing and ordering
an actual PCB for this circuit, but because most PCB outfits require an order of at least 5 or 10 boards and I really have
no need for that many, I'm gonna wait on doing it the proper way until this project is a little more concrete. So instead I
sketched up a board layout I was happy with (I did this on paper, I just couldn't find a decent stripboard layout software),
I soldered it all together! Of course, it didn't work right off the bat and I had to do some troubleshooting, but eventually
I got it working as expected. All that's left now is to cut some aluminum for a faceplate that I can screw into a synth rack.
</p>
<h3>STEP TWO: ENVELOPE AND VCA</h3>
<figure class="wrapimg">
<img src="vcaneu.png" />
<figcaption>Schmitz's VCA circuit I used for my synth.</figcaption>
</figure>
<p>
Now I have an oscillator that can be tuned and used to play melodies, but there's a pretty glaring problem with it:
It's always on! I don't have any system for actually triggering the VCO on or off by presisng a button or hooking
up a sequencer. I need a Voltage Controlled Amplifier or VCA to gate the volume on or off. The VCA is pretty simple,
it's just a voltage-controlled volume knob that I could hook up to a gate signal to control the volume like a piano key.
Again, I turned to the Schmitz page for this. His <a href="https://www.schmitzbits.de/vca.html">VCA</a> design is also a pretty common one, based on that same matched
transistor pair to allow for a voltage control of the signal. VCA circuits tend to be pretty straightforward, and all the other
components are just input and output formatting, with the other three transistors just processing the CV to work properly with
the amp. The opamp similarly just serves as an output buffer. I've got this circuit on my breadboard right now (11/2/22) and
it works well, although it doesn't seem to completely silence the signal at CV 0V, so I will experiment with it further before
putting it on a board.
</p>
<p>
The convenient thing about this design for my purposes is that it only uses a single opamp, which for most opamp chips means
that there will be at least one unused amp. Schmitz accounts for this by using a single-opamp chip in his design, but I don't
have anything like that on hand so I ended up using the classic TL072 chip. To take advantage of this, I decided to build an
envelope generator with the second opamp and let this module be a two-in-one VCA-Envelope because the two already pair together
quite well.
</p>
<p>
An envelope generator takes in a gate signal and converts it to a more complex four-stage signal. It smoothes out the rising
edge of the gate into an "attack," then immediately goes into a falling "decay" until it settles on the "sustain" level.
I will stay at its sustain level until the gate is released, then the falling edge of the gate is converted into a "release."
This allows a gate signal to produce a much more musical control voltage and can imitate the sharp attack and slow release of a
guitar string, or the schmultzy slow attack and release of a bowed violin, etc. This is an essential function of any synthesizer.
</p>
<figure class="centerimg">
<img src="adsr.png" />
<figcaption>Schmitz's 555-based ADSR envelope. One opamp, yay!</figcaption>
</figure>
<p>
Surprisingly, the envelope is probably one of the simplest circuits to build yet. The most basic form, which just has an attack and release,
just charges and discharges a capacitor through two diodes to separate the two stages. To implement a decay and sustain, an SR
latch is often used to control when the circuit enters its decay phase. <a href="https://www.schmitzbits.de/adsr.html">Schmitz's schematic</a> uses the SR latch inside the 555 timer
(alongside its other features) to do basically all of the heavy lifting, and the rest of the circuit is just resistors, transistors,
and pots for controlling the ADSR. Perhaps most importantly, the circuit only uses one opamp! This means I can build it on the
other side of the TL072 and have a nice combo module for my synth. Also, the two circuits are so simple I might be able to fit it
onto a tiny stripboard and save some space (although all the knobs and patchcable sockets may foil my plans). This is my final plan,
and once I get that issue with the VCA fixed I'll put it all on a board and be finished with a good chunk of this synth!
</p>
</div>
</body>
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

+108
View File
@@ -0,0 +1,108 @@
<body>
<title>MY PAGE</title>
<div id="body">
<h1>THIS PAGE</h1>
<h3>PROGRAMMING THE LIKES OF WHICH NASA HAS NEVER SEEN</h3>
<h6>3/24/2024</h6>
<p>
Hey, what's the deal with the URL up there? It's not just a simple filesystem, there's a
question mark and some text. What's going on?
</p>
<p>
The site may look effectively the same, but the backend has been completely overhauled and launched into 1996!
The old architecture was a basic filesystem hosting static html with a little bit of client-side javascript.
This was acceptable, but as my ideas increase in complexity I realize that making new pages is more and more of a pain
with this old setup. So welcome to the future!
</p>
<p>
Now all page content is managed by PHP and served up by an internal SQL server! This means in order to add a page,
I just have to write the html for the body of text and PHP deals with the rest. It also makes my system more modular.
I can specify the type of page (article, video page, image gallery, interactive app, etc) to change the styling,
format, header/footer, etc. of the page. I can also add entirely new page types whenever I please and I can
specify what to do when a type is given. At the moment, the only implemented page type is the simple tex article like
what you're reading now. But I can make new ones as I please. Pretty cool!
</p>
<p>
Using a LAMP stack system also allows for <i>dynamic</i> webpages! I can pull in data and then swap it for something else!
I can get videos up and running, or send machine learning data back and forth for fun interactive ML toys! Fun stuff is
abound...
</p>
<h3>UPENDING THE ORDER</h3>
<h6>2/1/2024</h6>
<p>
Starting October 2023, I began working as an all-purpose programmer for the USGS in Flagstaff. Effectively,
my job is to run their web services and help develop data visualization apps for them. As a refult, I have
learned a lot about modern web architecture. Looking back here at this website, I realized an overhaul was
in order. So over the last few weeks, I've been fixing up the backend.
</p>
<p>
The main thing I've done so far was to get each service and put it in a Docker container which pulls all its
web content from Github. This means each service can be invididually controlled and deployed on any machine
and setup can be highly automated and synced quickly. This makes everything easier.
</p>
<h3>10/10/2022</h3>
<p>
This humble website I've made to host my portfolio is the first serious trek I've made into web design.
Of course, I've played around with style sheets and javascript here and there, but this is the first time I've tried to make
something polished. I learned some about neat css styling, javascript, and a lot about mobile web design.
The site is not at all perfect (I threw the first version together in a week with only a little knowledge of web design), but it's
something I'm actually happy with and even a little proud of. Hopefully this page will give some insight to my journey down the web-hole.
</p>
<p>
I decided to make a webpage for several reasons:
</p>
<ul class="number">
<li>
I realized my resume is pathetic and doesn't really show off any of my programming skills as of now (being a second-year engineering student with no field experience),
</li>
<li>
I thought it would be a fun challenge and learning experience to flex my dusty web design muscles on a project that has real utility,
</li>
<li>
I was bored of killing my free time playing Disco Elysium and wanted something to do.
</li>
</ul>
<p>
So I sat down and started throwing some markup together!
</p>
<h3>THE JOURNEY</h3>
<p>
The first thing I wanted to do was make a really slick home page that was like a night sky overlooking a synthwave landscape thing.
The problem was, I can't draw nor do I have experience in graphic design, so I wrote up some scripts for making a night sky and a gridded landscape.
The landscape was the easy one. All I did was draw some horizontal lines with a distance between them that decreases as they approach the horizon , then draw angled lines radiating from the horizon and BOOM! done.
Next was the starry night. For full detail on this side-project, see my page on it <a href="starsky.html">here</a>.
I basically just draw stars with random temperatures, sizes, and locations. I also have a cluster drawn along a randomly defined line, to simulate a galaxy.
As of writing I'm not done with this night sky project, I have plans to add more galaxy clusters and nebulae and all that. But that's for another time.
</p>
<p>
Next, I had to actually put this pictures onto a webpage. I wanted the viewport to be filled with the night sky and a title heading: 'JAMES WITZEMAN.'
Then if the user scrolls down, they're taken to the land where the navbar is. I also wanted there to be a nice parallax effect between the sky and the landscape,
to really make it feel like it was behind the land. This was challenging part for me to wrap my head around. What I ended up doing was employing the z-index and transform attributes to get the desired effect.
The end result is a simple but pretty home page. Next, I want to include some 'fun' activities to play around with on the homepage (if I find time).
</p>
<p>
The next challenge was trying to make sure the site loads properly on mobile. I probably could have just built a style sheet that can flex enough to work on a totally different viewport,
but frankly I am not capable enough for that. So instead I decided to throw a little javascript together that detects if the page is loaded with a giant regex that returns true if
the device is a phone. If the device is a smartphone, then the javascript replaces the main css pointer with a different pointer to a mobile css file. The mobile file has everything arranged vertically,
instead of a standard sort of desktop blend of wide bodies and left-to-right navbars. To get a feel for what a readable text-heavy mobile page looks like, I tried to take some pointers from Wikipedia.
Wikipedia's mobile pages are text-heavy, but the text is often broken by paragraph spaces, lists, photos, and title headings. The text is also in a no-abrasive font, the line spacing keeps the paragraphs
from being too dense and intimidating, and the margins are tight. I tried to lift as much of this advice as I could to keep my pages readable.
</p>
<p>
Finally I had a somewhat readable page on mobile, but the navbar was totally broken. It was made for a page with planty of horizontal space to fill, but on mobile there's barely
space for a single link. So I decided to build a simple drop-down bar for mobile only. This meant I needed to add some kind of single button or element that, when clicked, reveals a hidden vertical navbar.
Because the original HTML doesn't have any kind of button element, I needed to add it in wih JS when a mobile device is detected. I threw this in the main javascript file, and added some code that
reveals the vertical navbar when the button is clicked. Now I have a nice mobile dropdown!
</p>
<h3>THE END; THE FUTURE</h3>
<p>
So that's about it. As far as the website goes for now, that's all I've gotten to. I think it's been a rewarding challenge for myself and I learned some about how all this works.
The website is still pretty barebones, and I want to try to add some fun physics stuff, encryption and security, a blog-editor GUI so I don't have to type all this in raw HTML,
and maybe a login-password system for fun. Until then, that's all for now I think. Thanks!
</p>
<p>-James</p>
</div>
</body>
+350
View File
@@ -0,0 +1,350 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html >
<head><title>Oscillators</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="generator" content="TeX4ht (https://tug.org/tex4ht/)">
<meta name="originator" content="TeX4ht (https://tug.org/tex4ht/)">
<!-- html -->
<meta name="src" content="oscillators.tex">
<link rel="stylesheet" type="text/css" href="oscillators.css">
</head><body
>
<h3 class="sectionHead"><span class="titlemark">1 </span> <a
id="x1-10001"></a>Oscillating Circuits</h3>
<!--l. 12--><p class="noindent" >A discussion of synthesizer oscillators requires an introduction to simple oscillating circuits. We
will discuss the most basic oscillating circuits, then we will move on to oscillators with
easily-tunable frequencies. Then we will tackle the most complex issue for the purposes of musical
synthesis: <span
class="ecti-1000">voltage control. </span>This is the important part! If we can control an oscillator&#8217;s frequency by
voltage, then we can make another circuit change its voltage, like a sequencer for example. Let&#8217;s
check it out!
<!--l. 18--><p class="noindent" >
<h4 class="subsectionHead"><span class="titlemark">1.1 </span> <a
id="x1-20001.1"></a>Passive Oscillators</h4>
<!--l. 20--><p class="noindent" >The simplest oscillators are those which rely on <span
class="ecti-1000">passive components</span>, electrical components which
do not generate power or &#8217;add amplitude&#8217; to a signal. These are components like resistors,
inductors, and capacitors which only dissipate, store, or release already-existing power introduced
by another component. An example of a non-passive component would be a power supply or a
transistor. Passive components tend to be governed by simpler rules that are easier to understand
and exploit.
<!--l. 26--><p class="indent" > The simplest oscillating circuit to my knowledge is the Resistor-Inductor-Capacitor or RLC
circuit. It&#8217;s not an &#8217;RIC&#8217; circuit because the letter I commonly represents current in electrical
engineering, so we use L to indicate inductors or inductance.
<div class="center"
>
<!--l. 30--><p class="noindent" >
<!--l. 36--><p class="noindent" ><img
src="oscillators0x.svg" alt="RLC
" ></div>
<!--l. 39--><p class="indent" > The diagram above depicts an RLC-circuit, with each component in series. We can come up
with an equation to describe its behavior, but first we need to know how each component responds
to voltage and current. <span
class="ecbx-1000">Resistors </span>are governed by <span
class="ecbx-1000">Ohm&#8217;s Law</span>:
<div class="math-display" >
<img
src="oscillators1x.svg" alt="V = IR, I = V-,
R
" class="math-display" ></div>
<!--l. 43--><p class="nopar" > where <span
class="cmmi-10">R </span>is resistance, measured in Ohms (<span
class="cmr-10">&#x03A9;</span>). Resistors are called <span
class="ecbx-1000">linear components </span>because
their voltage-current response is linear i.e. an increase in voltage or current causes a linear increase
in the other. <span
class="ecbx-1000">Inductors </span>are governed by:
<div class="math-display" >
<img
src="oscillators2x.svg" alt=" &#x222B;
V = Ldi, i = 1 V dt
dt L
" class="math-display" ></div>
<!--l. 49--><p class="nopar" > where <span
class="cmmi-10">L </span>is inductance, measured in Henries (H). Note that this means that the voltage across an
inductor responds to a change in current. If a current is constant, then the voltage vanishes. But if
we change the current, a voltage is generated across the inductor. That means if we send an
<span
class="ecti-1000">alternating current </span>which is always changing through the inductor, then we will get a
voltage across the inductor. This is unusual because an inductor is essentially just a
short-circuit and yet when a changing current passes through it, it will have a voltage like a
resistive element! You could say that inductors <span
class="ecti-1000">resist a change in current </span>in this sense of
resistance.
<!--l. 59--><p class="indent" > Finally, <span
class="ecbx-1000">Capacitors </span>are governed by the equation:
<div class="math-display" >
<img
src="oscillators3x.svg" alt="i = C dv,
dt
" class="math-display" ></div>
<!--l. 60--><p class="nopar" > where <span
class="cmmi-10">C </span>is the capacitance of the component, measured in Farads (F). Here, the capacitor&#8217;s
behavior is similar but the relationship is sort of reversed or flipped, if you will. Now, if we have a
constant voltage across the capacitor then no current will flow. This makes sense because a
capacitor is essentially made from two conductive plates seperated from one another by a
non-conductive material. This is effectively a break in the circuit, as indicated by the standard
electrical symbol for a capacitor. But if we change the voltage across the capacitor, it starts to
conduct! changing the voltage somehow forces current to flow between the plates! It&#8217;s no mystery,
this is due to some complicated rules of physics known generally as <span
class="ecti-1000">electrodynamics</span>, but that&#8217;s for
another time.
<!--l. 69--><p class="indent" > Okay. We can connect these three equations mathematically by utilizing <span
class="ecbx-1000">Kirchoff&#8217;s Laws of</span>
<span
class="ecbx-1000">Voltage and Current</span>. This sounds a little complicated but it relies on some straightforward
principles. The core idea is that any current which enters a wire junction (usually called a <span
class="ecti-1000">node</span>)
must exit the junction in some way. For many reasons, another logical rule that follows from this is
that the voltages across each component in a loop must sum to zero. If this were not true, it would
result in charge pooling somewhere in the wire, which is almost always impossible. Here&#8217;s the
laws:
<ul class="itemize1">
<li class="itemize">
<!--l. 76--><p class="noindent" ><span
class="ecbx-1000">KIRCHOFF&#8217;S CURRENT LAW: </span>All current entering a node must exit i.e. the
sum of currents entering/leaving a node must always be <span
class="ecti-1000">zero.</span>
</li>
<li class="itemize">
<!--l. 78--><p class="noindent" ><span
class="ecbx-1000">KIRCHOFF&#8217;S VOLTAGE LAW: </span>The sum of component voltages over any loop
of wire must be zero.</li></ul>
<!--l. 81--><p class="indent" > If the current entering each node must also be leaving it, in our RLC circuit this means the
current through each node is the same. This is because the circuit is a closed loop! If the current
were not the same across each node, then it would have to pool somewhere or escape into thin air.
We can express this mathematically:
<div class="math-display" >
<img
src="oscillators4x.svg" alt="iR + iL + iC = 0.
" class="math-display" ></div>
<!--l. 84--><p class="nopar" > We know the equations for the current through a resistor and capacitor:
<div class="math-display" >
<img
src="oscillators5x.svg" alt="v dv
--+ iL + C --= 0.
R dt
" class="math-display" ></div>
<!--l. 86--><p class="nopar" > We know that voltage across an inductor is proportional to the change in current.
If we integrate with respect to time, we can get a figure for the current through an
inductor:
<div class="math-display" >
<img
src="oscillators6x.svg" alt=" &#x222B;
iL =-1 vdt
L
" class="math-display" ></div>
<!--l. 89--><p class="nopar" >
<div class="math-display" >
<img
src="oscillators7x.svg" alt="v 1 &#x222B; dv
R-+ L- v dt+ C-dt = 0.
" class="math-display" ></div>
<!--l. 90--><p class="nopar" > Now we just differentiate:
<div class="math-display" >
<img
src="oscillators8x.svg" alt="C d2v + 1-dv+ -1v = 0,
dt2 R dt L
" class="math-display" ></div>
<!--l. 92--><p class="nopar" > or
<div class="math-display" >
<img
src="oscillators9x.svg" alt=" &#x2032;&#x2032; &#x2032; 1 1
av + bv + cv = 0; a = C, b = R-, c = L-.
" class="math-display" ></div>
<!--l. 93--><p class="nopar" > I would like to state here that the variable <span
class="cmmi-10">v </span>is a function dependent on time, so it should be
written as <span
class="cmmi-10">v</span><span
class="cmr-10">(</span><span
class="cmmi-10">t</span><span
class="cmr-10">) </span>for clarity. We prefer to be unclear here, because it is less cluttered to write
equations that way. Just keep this in mind.
<!--l. 97--><p class="indent" > What we have stumbled upon here is a truth that I find quite exciting but it has been the
nightmare of many underclassmen electrical engineers forced to learn this before finishing their
math coursework (who could I possibly be talking about here?): This circuit is governed by a
<span
class="ecbx-1000">homogenous second-order ordinary differential equation! </span>Unfortunately we cannot go over
the basics of ODE&#8217;s here. Like many stressed undergraduate engineers before you, you
will have to take my word as gospel. A homogenous second-order ODE is basically
an equation where the function (<span
class="cmmi-10">v </span>in this case) is not defined directly in terms of an
independent variable like time or <span
class="cmmi-10">x </span>or space etc, but in terms of its own differentials. This
equation is <span
class="ecti-1000">second-order </span>because the function is defined in terms of its second differential.
If you are very clever, you may already be thinking of how one might solve such an
equation to find <span
class="cmmi-10">v</span><span
class="cmr-10">(</span><span
class="cmmi-10">t</span><span
class="cmr-10">) </span>in terms of <span
class="cmmi-10">t </span>alone and not in terms of its differentials. If you are
even cleverer, you may be thinking about the classic function <span
class="cmmi-10">f</span><span
class="cmr-10">(</span><span
class="cmmi-10">t</span><span
class="cmr-10">) = </span><span
class="cmmi-10">e</span><sup><span
class="cmmi-7">x</span></sup><span
class="cmmi-10">, </span>because its
differential/integral is itself. If you are some kind of genius, you may even be considering also the
trigonometric functions (sine, cosine, not so much tangent here), because they have a similar
property. This will put you on the right track. Going forward, you will find that the
equations that govern these circuits involve many natural exponentials and sine waves
because of this property. Most ordinary differential equations are solved using complicated
techniques that involve relating differentials with natural exponentials and waves. I
cannot get into specifics here but if you are interested, I would keep this property in
mind.
<!--l. 115--><p class="indent" > OKAY. Back to the equation. Our equation can be represented by something called its
<span
class="ecti-1000">characteristic equation:</span>
<div class="math-display" >
<img
src="oscillators10x.svg" alt="ar2 + br+ c = 0.
" class="math-display" ></div>
<!--l. 116--><p class="nopar" > This is just a representation of the equation that represents the order of each differential by a
power of the variable <span
class="ecti-1000">r</span>. If we solve it like a polynomial we get the quadratic formula:
<div class="math-display" >
<img
src="oscillators11x.svg" alt=" &#x221A; -2-----
r1,2 = - b±--b---4ac.
2a
" class="math-display" ></div>
<!--l. 119--><p class="nopar" > You might realize that it is possible for the root of our characteristic equation to be complex
(<span
class="cmmi-10">r </span><span
class="cmr-10">= </span><span
class="cmmi-10">&#x03BB; </span><span
class="cmr-10">+ </span><span
class="cmmi-10">&#x03BC;i</span>). When this is the case, our solution is of the form:
<div class="math-display" >
<img
src="oscillators12x.svg" alt="v(t) = C1e&#x03BB;tcos(&#x03BC;t)+ C2e&#x03BB;tsin(&#x03BC;t),
" class="math-display" ></div>
<!--l. 122--><p class="nopar" > where <span
class="cmmi-10">C</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,C</span><sub><span
class="cmr-7">2</span></sub> are constants determined by the <span
class="ecti-1000">initial conditions </span>of the system. Once all
the math is done, we will take a break to build some intuition for all this nonsense.
The important part is that the reason this is a solution has to do with the fact that
the differentials of exponentials and sine waves are equal to themselves or related to
themselves.
<!--l. 127--><p class="indent" > Now we can start getting specific with our constants. If we assume our system begins
with the components already charged (meaning we have allowed a current source to
keep a constant voltage across the components for enough time for the capacitor to
be charged to the positive voltage <span
class="cmmi-10">V</span> <sub><span
class="cmr-7">+</span></sub>), then we can say <span
class="cmmi-10">v</span><sub><span
class="cmr-7">0</span></sub> <span
class="cmr-10">= </span><span
class="cmmi-10">V</span> <sub><span
class="cmr-7">+</span></sub><span
class="cmmi-10">. </span>If it has sat for a
long long time, then there will be no change in voltage, so also we can say <span
class="cmmi-10">v</span><span
class="cmsy-10">&#x2032;</span><sub><span
class="cmr-7">0</span></sub> <span
class="cmr-10">= 0</span><span
class="cmmi-10">.</span>
So:
<div class="math-display" >
<img
src="oscillators13x.svg" alt="v(0) = V+ = C1, v&#x2032;(0) = 0 = &#x03BB;C1 + &#x03BC;C2,
" class="math-display" ></div>
<!--l. 131--><p class="nopar" >
<div class="math-display" >
<img
src="oscillators14x.svg" alt="C1 = V+, C2 = - &#x03BB;V+.
&#x03BC;
" class="math-display" ></div>
<!--l. 132--><p class="nopar" >
<!--l. 134--><p class="indent" > We can keep defining constants and it will quickly cause your mind to cloud over. The point
here is that if we charge up this circuit and then let it run, the voltage and current will oscillate
back and forth. I have included below a graph of a potential oscillation. The frequency of this
oscillation is determined by the constant <span
class="cmmi-10">&#x03BC;</span>, which is equal to the inverse of the root of
the product of inductance and capacitance (<span
class="cmmi-10">&#x03BC; </span><span
class="cmr-10">=</span> <img
src="oscillators15x.svg" alt="--1-
&#x221A;LC--" class="frac" align="middle">). In electrical engineering, it is
usually called the <span
class="ecbx-1000">angular frequency </span>and is more commonly denoted with the greek
character <span
class="cmmi-10">&#x03C9;</span>. We found the constants <span
class="cmmi-10">C</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,C</span><sub><span
class="cmr-7">2</span></sub> to show that they are dependent on the initial
voltage we charge the circuit to, as well as the properties of the three components. We
have shown mathematically that the behavior of the circuit under certain parameters
(such that <span
class="cmmi-10">b</span><sup><span
class="cmr-7">2</span></sup> <span
class="cmmi-10">&#x003C; </span><span
class="cmr-10">4</span><span
class="cmmi-10">ac</span>) will be oscillatory in nature. But why does the circuit oscillate
sometimes?
<div class="center"
>
<!--l. 147--><p class="noindent" >
<!--l. 148--><p class="noindent" ><img
src="./img/natural-RLC.png" alt="PIC"
width="21" height="21" ></div>
<!--l. 151--><p class="indent" > Well, recall that an inductor generates a voltage once the current through it changes, and that
a capacitor begins conducting current once the voltage across it changes. When we charge the
capacitor to some voltage and then close the circuit, the voltage across the capacitor suddenly
becomes the voltage across the resistor as well. When there is a voltage across a resistor which is
connected in a loop, then a current must flow. Conversely, the moment the circuit is closed it
forces the voltage to drop because a current must flow through the resistor. If the capacitor
were alone in series with the resistor, then it would simply discharge to a voltage of
0.
<!--l. 158--><p class="indent" > As the capacitor pushes current through the inductor, the inductor begins to respond. Initially
it acts as a short, but as the current through it changes, it begins to generate a voltage. That
voltage causes the inductor to push current into the capacitor again, charging it. Then once the
inductor has discharged its stored energy, the capacitor is recharged and it begins to conduct
again. This continues until all of the electrical energy is dissipated through the resistor (and
realistically also through the resistances in the capacitor and inductor) as heat until there is none
left. Kind of cool!
<!--l. 164--><p class="indent" > If we tuned the capacitance and inductance properly, we could get one of these circuits to
oscillate at an audible frequency. This would not be an ideal circuit for music making, and there
are two big reasons for this:
<ul class="itemize1">
<li class="itemize">
<!--l. 168--><p class="noindent" >The circuit will only oscillate for a short period after it is triggered, preventing us from
ever using it to play any sustained note.
</li>
<li class="itemize">
<!--l. 170--><p class="noindent" >YOU CAN&#8217;T TUNE THE FREQUENCY! You would need a variable inductor or
transformer, and those solutions quickly become impractical. Unless you like plucky
drone music, you&#8217;re out of luck here.</li></ul>
<!--l. 174--><p class="indent" > I&#8217;m sure there are many other kinds of passive oscillating circuits, but I think we have done
enough here. Next we will consider <span
class="ecti-1000">active oscillators.</span>
<!--l. 179--><p class="noindent" >
<h4 class="subsectionHead"><span class="titlemark">1.2 </span> <a
id="x1-30001.2"></a>Active Oscillators</h4>
</body></html>
+122
View File
@@ -0,0 +1,122 @@
/* start css.sty */
.cmr-7{font-size:70%;}
.cmmi-7{font-size:70%;font-style: italic;}
.cmmi-10{font-style: italic;}
.cmsy-7{font-size:70%;}
.ecti-1000{ font-style: italic;}
.ecti-1000{ font-style: italic;}
.ecti-1000{ font-style: italic;}
.ecbx-1000{ font-weight: bold;}
.ecbx-1000{ font-weight: bold;}
.ecbx-1000{ font-weight: bold;}
p{margin-top:0;margin-bottom:0}
p.indent{text-indent:0;}
p + p{margin-top:1em;}
p + div, p + pre {margin-top:1em;}
div + p, pre + p {margin-top:1em;}
a { overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; hyphens: auto; }
@media print {div.crosslinks {visibility:hidden;}}
a img { border-top: 0; border-left: 0; border-right: 0; }
center { margin-top:1em; margin-bottom:1em; }
td center { margin-top:0em; margin-bottom:0em; }
.Canvas { position:relative; }
img.math{vertical-align:middle;}
div.par-math-display, div.math-display{text-align:center;}
li p.indent { text-indent: 0em }
li p:first-child{ margin-top:0em; }
li p:last-child, li div:last-child { margin-bottom:0.5em; }
li p~ul:last-child, li p~ol:last-child{ margin-bottom:0.5em; }
.enumerate1 {list-style-type:decimal;}
.enumerate2 {list-style-type:lower-alpha;}
.enumerate3 {list-style-type:lower-roman;}
.enumerate4 {list-style-type:upper-alpha;}
div.newtheorem { margin-bottom: 2em; margin-top: 2em;}
.obeylines-h,.obeylines-v {white-space: nowrap; }
div.obeylines-v p { margin-top:0; margin-bottom:0; }
.overline{ text-decoration:overline; }
.overline img{ border-top: 1px solid black; }
td.displaylines {text-align:center; white-space:nowrap;}
.centerline {text-align:center;}
.rightline {text-align:right;}
pre.verbatim {font-family: monospace,monospace; text-align:left; clear:both; }
.fbox {padding-left:3.0pt; padding-right:3.0pt; text-indent:0pt; border:solid black 0.4pt; }
div.fbox {display:table}
div.center div.fbox {text-align:center; clear:both; padding-left:3.0pt; padding-right:3.0pt; text-indent:0pt; border:solid black 0.4pt; }
div.minipage{width:100%;}
div.center, div.center div.center {text-align: center; margin-left:1em; margin-right:1em;}
div.center div {text-align: left;}
div.flushright, div.flushright div.flushright {text-align: right;}
div.flushright div {text-align: left;}
div.flushleft {text-align: left;}
.underline{ text-decoration:underline; }
.underline img{ border-bottom: 1px solid black; margin-bottom:1pt; }
.framebox-c, .framebox-l, .framebox-r { padding-left:3.0pt; padding-right:3.0pt; text-indent:0pt; border:solid black 0.4pt; }
.framebox-c {text-align:center;}
.framebox-l {text-align:left;}
.framebox-r {text-align:right;}
span.thank-mark{ vertical-align: super }
span.footnote-mark sup.textsuperscript, span.footnote-mark a sup.textsuperscript{ font-size:80%; }
div.tabular, div.center div.tabular {text-align: center; margin-top:0.5em; margin-bottom:0.5em; }
table.tabular td p{margin-top:0em;}
table.tabular {margin-left: auto; margin-right: auto;}
td p:first-child{ margin-top:0em; }
td p:last-child{ margin-bottom:0em; }
div.td00{ margin-left:0pt; margin-right:0pt; }
div.td01{ margin-left:0pt; margin-right:5pt; }
div.td10{ margin-left:5pt; margin-right:0pt; }
div.td11{ margin-left:5pt; margin-right:5pt; }
table[rules] {border-left:solid black 0.4pt; border-right:solid black 0.4pt; }
td.td00{ padding-left:0pt; padding-right:0pt; }
td.td01{ padding-left:0pt; padding-right:5pt; }
td.td10{ padding-left:5pt; padding-right:0pt; }
td.td11{ padding-left:5pt; padding-right:5pt; }
table[rules] {border-left:solid black 0.4pt; border-right:solid black 0.4pt; }
.hline hr, .cline hr{ height : 0px; margin:0px; }
.hline td, .cline td{ padding: 0; }
.hline hr, .cline hr{border:none;border-top:1px solid black;}
.tabbing-right {text-align:right;}
div.float, div.figure {margin-left: auto; margin-right: auto;}
div.float img {text-align:center;}
div.figure img {text-align:center;}
.marginpar,.reversemarginpar {width:20%; float:right; text-align:left; margin-left:auto; margin-top:0.5em; font-size:85%; text-decoration:underline;}
.marginpar p,.reversemarginpar p{margin-top:0.4em; margin-bottom:0.4em;}
.reversemarginpar{float:left;}
table.equation {width:100%;}
.equation td{text-align:center; }
td.equation { margin-top:1em; margin-bottom:1em; }
td.equation-label { width:5%; text-align:center; }
td.eqnarray4 { width:5%; white-space: normal; }
td.eqnarray2 { width:5%; }
table.eqnarray-star, table.eqnarray {width:100%;}
div.eqnarray{text-align:center;}
div.array {text-align:center;}
div.pmatrix {text-align:center;}
table.pmatrix {width:100%;}
span.pmatrix img{vertical-align:middle;}
div.pmatrix {text-align:center;}
table.pmatrix {width:100%;}
span.bar-css {text-decoration:overline;}
img.cdots{vertical-align:middle;}
.partToc a, .partToc, .likepartToc a, .likepartToc {line-height: 200%; font-weight:bold; font-size:110%;}
.index-item, .index-subitem, .index-subsubitem {display:block}
div.caption {text-indent:-2em; margin-left:3em; margin-right:1em; text-align:left;}
div.caption span.id{font-weight: bold; white-space: nowrap; }
h1.partHead{text-align: center}
p.bibitem { text-indent: -2em; margin-left: 2em; margin-top:0.6em; margin-bottom:0.6em; }
p.bibitem-p { text-indent: 0em; margin-left: 2em; margin-top:0.6em; margin-bottom:0.6em; }
.paragraphHead, .likeparagraphHead { margin-top:2em; font-weight: bold;}
.subparagraphHead, .likesubparagraphHead { font-weight: bold;}
.verse{white-space:nowrap; margin-left:2em}
div.maketitle {text-align:center;}
h2.titleHead{text-align:center;}
div.maketitle{ margin-bottom: 2em; }
div.author, div.date {text-align:center;}
div.thanks{text-align:left; margin-left:10%; font-size:85%; font-style:italic; }
div.author{white-space: nowrap;}
div.abstract p {margin-left:5%; margin-right:5%;}
div.abstract {width:100%;}
.abstracttitle{text-align:center;margin-bottom:1em;}
.rotatebox{display: inline-block;}
/* end css.sty */
+333
View File
@@ -0,0 +1,333 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html >
<head><title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="generator" content="TeX4ht (https://tug.org/tex4ht/)">
<meta name="originator" content="TeX4ht (https://tug.org/tex4ht/)">
<!-- html -->
<meta name="src" content="oscillators.tex">
<link rel="stylesheet" type="text/css" href="oscillators.css">
</head><body
>
<h3 class="sectionHead"><span class="titlemark">1 </span> <a
id="x1-10001"></a>Oscillating Circuits</h3>
<!--l. 11--><p class="noindent" >A discussion of synthesizer oscillators requires an introduction to simple oscillating circuits. We
will discuss the most basic oscillating circuits, then we will move on to oscillators with
easily-tunable frequencies. Then we will tackle the most complex issue for the purposes of musical
synthesis: <span
class="ecti-1000">voltage control. </span>This is the important part! If we can control an oscillator&#8217;s frequency by
voltage, then we can make another circuit change its voltage, like a sequencer for example. Let&#8217;s
check it out!
<!--l. 17--><p class="noindent" >
<h4 class="subsectionHead"><span class="titlemark">1.1 </span> <a
id="x1-20001.1"></a>Passive Oscillators</h4>
<!--l. 19--><p class="noindent" >The simplest oscillators are those which rely on <span
class="ecti-1000">passive components</span>, electrical components which
do not generate power or &#8217;add amplitude&#8217; to a signal. These are components like resistors,
inductors, and capacitors which only dissipate, store, or release already-existing power introduced
by another component. An example of a non-passive component would be a power supply or a
transistor. Passive components tend to be governed by simpler rules that are easier to understand
and exploit.
<!--l. 25--><p class="indent" > The simplest oscillating circuit to my knowledge is the Resistor-Inductor-Capacitor or RLC
circuit. It&#8217;s not an &#8217;RIC&#8217; circuit because the letter I commonly represents current in electrical
engineering, so we use L to indicate inductors or inductance.
<!--l. 29--><p class="indent" > The diagram above depicts an RLC-circuit, with each component in series. We can come up
with an equation to describe its behavior, but first we need to know how each component responds
to voltage and current. <span
class="ecbx-1000">Resistors </span>are governed by <span
class="ecbx-1000">Ohm&#8217;s Law</span>:
<div class="math-display" >
<img
src="oscillators0x.png" alt="V = IR, I = V-,
R
" class="math-display" ></div>
<!--l. 33--><p class="nopar" > where <span
class="cmmi-10">R </span>is resistance, measured in Ohms (<span
class="cmr-10">&#x03A9;</span>). Resistors are called <span
class="ecbx-1000">linear components </span>because
their voltage-current response is linear i.e. an increase in voltage or current causes a linear increase
in the other. <span
class="ecbx-1000">Inductors </span>are governed by:
<div class="math-display" >
<img
src="oscillators1x.png" alt=" di 1 &#x222B;
V = Ldt, i = L V dt
" class="math-display" ></div>
<!--l. 39--><p class="nopar" > where <span
class="cmmi-10">L </span>is inductance, measured in Henries (H). Note that this means that the voltage across an
inductor responds to a change in current. If a current is constant, then the voltage vanishes. But if
we change the current, a voltage is generated across the inductor. That means if we send an
<span
class="ecti-1000">alternating current </span>which is always changing through the inductor, then we will get a
voltage across the inductor. This is unusual because an inductor is essentially just a
short-circuit and yet when a changing current passes through it, it will have a voltage like a
resistive element! You could say that inductors <span
class="ecti-1000">resist a change in current </span>in this sense of
resistance.
<!--l. 49--><p class="indent" > Finally, <span
class="ecbx-1000">Capacitors </span>are governed by the equation:
<div class="math-display" >
<img
src="oscillators2x.png" alt="i = C dv,
dt
" class="math-display" ></div>
<!--l. 50--><p class="nopar" > where <span
class="cmmi-10">C </span>is the capacitance of the component, measured in Farads (F). Here, the capacitor&#8217;s
behavior is similar but the relationship is sort of reversed or flipped, if you will. Now, if we have a
constant voltage across the capacitor then no current will flow. This makes sense because a
capacitor is essentially made from two conductive plates seperated from one another by a
non-conductive material. This is effectively a break in the circuit, as indicated by the standard
electrical symbol for a capacitor. But if we change the voltage across the capacitor, it starts to
conduct! changing the voltage somehow forces current to flow between the plates! It&#8217;s no mystery,
this is due to some complicated rules of physics known generally as <span
class="ecti-1000">electrodynamics</span>, but that&#8217;s for
another time.
<!--l. 59--><p class="indent" > Okay. We can connect these three equations mathematically by utilizing <span
class="ecbx-1000">Kirchoff&#8217;s Laws of</span>
<span
class="ecbx-1000">Voltage and Current</span>. This sounds a little complicated but it relies on some straightforward
principles. The core idea is that any current which enters a wire junction (usually called a <span
class="ecti-1000">node</span>)
must exit the junction in some way. For many reasons, another logical rule that follows from this is
that the voltages across each component in a loop must sum to zero. If this were not true, it would
result in charge pooling somewhere in the wire, which is almost always impossible. Here&#8217;s the
laws:
<ul class="itemize1">
<li class="itemize"><span
class="ecbx-1000">KIRCHOFF&#8217;S CURRENT LAW: </span>All current entering a node must exit i.e. the
sum of currents entering/leaving a node must always be <span
class="ecti-1000">zero.</span>
</li>
<li class="itemize"><span
class="ecbx-1000">KIRCHOFF&#8217;S VOLTAGE LAW: </span>The sum of component voltages over any loop
of wire must be zero.</li></ul>
<!--l. 71--><p class="indent" > If the current entering each node must also be leaving it, in our RLC circuit this means the
current through each node is the same. This is because the circuit is a closed loop! If the current
were not the same across each node, then it would have to pool somewhere or escape into thin air.
We can express this mathematically:
<div class="math-display" >
<img
src="oscillators3x.png" alt="iR + iL + iC = 0.
" class="math-display" ></div>
<!--l. 74--><p class="nopar" > We know the equations for the current through a resistor and capacitor:
<div class="math-display" >
<img
src="oscillators4x.png" alt="v dv
R-+ iL + C dt = 0.
" class="math-display" ></div>
<!--l. 76--><p class="nopar" > We know that voltage across an inductor is proportional to the change in current.
If we integrate with respect to time, we can get a figure for the current through an
inductor:
<div class="math-display" >
<img
src="oscillators5x.png" alt=" &#x222B;
iL =-1 vdt
L
" class="math-display" ></div>
<!--l. 79--><p class="nopar" >
<div class="math-display" >
<img
src="oscillators6x.png" alt=" &#x222B;
v-+ 1- v dt+ Cdv = 0.
R L dt
" class="math-display" ></div>
<!--l. 80--><p class="nopar" > Now we just differentiate:
<div class="math-display" >
<img
src="oscillators7x.png" alt=" d2v 1 dv 1
C --2 + ----+ --v = 0,
dt R dt L
" class="math-display" ></div>
<!--l. 82--><p class="nopar" > or
<div class="math-display" >
<img
src="oscillators8x.png" alt="av&#x2032;&#x2032;+ bv&#x2032; + cv = 0; a = C, b = 1-, c = 1-.
R L
" class="math-display" ></div>
<!--l. 83--><p class="nopar" > I would like to state here that the variable <span
class="cmmi-10">v </span>is a function dependent on time, so it should be
written as <span
class="cmmi-10">v</span><span
class="cmr-10">(</span><span
class="cmmi-10">t</span><span
class="cmr-10">) </span>for clarity. We prefer to be unclear here, because it is less cluttered to write
equations that way. Just keep this in mind.
<!--l. 87--><p class="indent" > What we have stumbled upon here is a truth that I find quite exciting but it has been the
nightmare of many underclassmen electrical engineers forced to learn this before finishing their
math coursework (who could I possibly be talking about here?): This circuit is governed by a
<span
class="ecbx-1000">homogenous second-order ordinary differential equation! </span>Unfortunately we cannot go over
the basics of ODE&#8217;s here. Like many stressed undergraduate engineers before you, you
will have to take my word as gospel. A homogenous second-order ODE is basically
an equation where the function (<span
class="cmmi-10">v </span>in this case) is not defined directly in terms of an
independent variable like time or <span
class="cmmi-10">x </span>or space etc, but in terms of its own differentials. This
equation is <span
class="ecti-1000">second-order </span>because the function is defined in terms of its second differential.
If you are very clever, you may already be thinking of how one might solve such an
equation to find <span
class="cmmi-10">v</span><span
class="cmr-10">(</span><span
class="cmmi-10">t</span><span
class="cmr-10">) </span>in terms of <span
class="cmmi-10">t </span>alone and not in terms of its differentials. If you are
even cleverer, you may be thinking about the classic function <span
class="cmmi-10">f</span><span
class="cmr-10">(</span><span
class="cmmi-10">t</span><span
class="cmr-10">) = </span><span
class="cmmi-10">e</span><sup><span
class="cmmi-7">x</span></sup><span
class="cmmi-10">, </span>because its
differential/integral is itself. If you are some kind of genius, you may even be considering also the
trigonometric functions (sine, cosine, not so much tangent here), because they have a similar
property. This will put you on the right track. Going forward, you will find that the
equations that govern these circuits involve many natural exponentials and sine waves
because of this property. Most ordinary differential equations are solved using complicated
techniques that involve relating differentials with natural exponentials and waves. I
cannot get into specifics here but if you are interested, I would keep this property in
mind.
<!--l. 105--><p class="indent" > OKAY. Back to the equation. Our equation can be represented by something called its
<span
class="ecti-1000">characteristic equation:</span>
<div class="math-display" >
<img
src="oscillators9x.png" alt="ar2 + br+ c = 0.
" class="math-display" ></div>
<!--l. 106--><p class="nopar" > This is just a representation of the equation that represents the order of each differential by a
power of the variable <span
class="ecti-1000">r</span>. If we solve it like a polynomial we get the quadratic formula:
<div class="math-display" >
<img
src="oscillators10x.png" alt=" &#x221A; -2-----
r1,2 = - b±--b---4ac.
2a
" class="math-display" ></div>
<!--l. 109--><p class="nopar" > You might realize that it is possible for the root of our characteristic equation to be complex
(<span
class="cmmi-10">r </span><span
class="cmr-10">= </span><span
class="cmmi-10">&#x03BB; </span><span
class="cmr-10">+ </span><span
class="cmmi-10">&#x03BC;i</span>). When this is the case, our solution is of the form:
<div class="math-display" >
<img
src="oscillators11x.png" alt="v(t) = C1e&#x03BB;tcos(&#x03BC;t)+ C2e&#x03BB;tsin(&#x03BC;t),
" class="math-display" ></div>
<!--l. 112--><p class="nopar" > where <span
class="cmmi-10">C</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,C</span><sub><span
class="cmr-7">2</span></sub> are constants determined by the <span
class="ecti-1000">initial conditions </span>of the system. Once all
the math is done, we will take a break to build some intuition for all this nonsense.
The important part is that the reason this is a solution has to do with the fact that
the differentials of exponentials and sine waves are equal to themselves or related to
themselves.
<!--l. 117--><p class="indent" > Now we can start getting specific with our constants. If we assume our system begins
with the components already charged (meaning we have allowed a current source to
keep a constant voltage across the components for enough time for the capacitor to
be charged to the positive voltage <span
class="cmmi-10">V</span> <sub><span
class="cmr-7">+</span></sub>), then we can say <span
class="cmmi-10">v</span><sub><span
class="cmr-7">0</span></sub> <span
class="cmr-10">= </span><span
class="cmmi-10">V</span> <sub><span
class="cmr-7">+</span></sub><span
class="cmmi-10">. </span>If it has sat for a
long long time, then there will be no change in voltage, so also we can say <span
class="cmmi-10">v</span><span
class="cmsy-10">&#x2032;</span><sub><span
class="cmr-7">0</span></sub> <span
class="cmr-10">= 0</span><span
class="cmmi-10">.</span>
So:
<div class="math-display" >
<img
src="oscillators12x.png" alt="v(0) = V+ = C1, v&#x2032;(0) = 0 = &#x03BB;C1 + &#x03BC;C2,
" class="math-display" ></div>
<!--l. 121--><p class="nopar" >
<div class="math-display" >
<img
src="oscillators13x.png" alt="C1 = V+, C2 = - &#x03BB;V+.
&#x03BC;
" class="math-display" ></div>
<!--l. 122--><p class="nopar" >
<!--l. 124--><p class="indent" > We can keep defining constants and it will quickly cause your mind to cloud over. The point
here is that if we charge up this circuit and then let it run, the voltage and current will oscillate
back and forth. I have included below a graph of a potential oscillation. The frequency of this
oscillation is determined by the constant <span
class="cmmi-10">&#x03BC;</span>, which is equal to the inverse of the root of
the product of inductance and capacitance (<span
class="cmmi-10">&#x03BC; </span><span
class="cmr-10">=</span> <img
src="oscillators14x.png" alt="--1-
&#x221A;LC--" class="frac" align="middle">). In electrical engineering, it is
usually called the <span
class="ecbx-1000">angular frequency </span>and is more commonly denoted with the greek
character <span
class="cmmi-10">&#x03C9;</span>. We found the constants <span
class="cmmi-10">C</span><sub><span
class="cmr-7">1</span></sub><span
class="cmmi-10">,C</span><sub><span
class="cmr-7">2</span></sub> to show that they are dependent on the initial
voltage we charge the circuit to, as well as the properties of the three components. We
have shown mathematically that the behavior of the circuit under certain parameters
(such that <span
class="cmmi-10">b</span><sup><span
class="cmr-7">2</span></sup> <span
class="cmmi-10">&#x003C; </span><span
class="cmr-10">4</span><span
class="cmmi-10">ac</span>) will be oscillatory in nature. But why does the circuit oscillate
sometimes?
<div class="center"
>
<!--l. 137--><p class="noindent" >
<!--l. 138--><p class="noindent" ><img
src="./img//natural-RLC.png" alt="PIC"
width="21" height="21" ></div>
<!--l. 141--><p class="indent" > Well, recall that an inductor generates a voltage once the current through it changes, and that
a capacitor begins conducting current once the voltage across it changes. When we charge the
capacitor to some voltage and then close the circuit, the voltage across the capacitor suddenly
becomes the voltage across the resistor as well. When there is a voltage across a resistor which is
connected in a loop, then a current must flow. Conversely, the moment the circuit is closed it
forces the voltage to drop because a current must flow through the resistor. If the capacitor
were alone in series with the resistor, then it would simply discharge to a voltage of
0.
<!--l. 148--><p class="indent" > As the capacitor pushes current through the inductor, the inductor begins to respond. Initially
it acts as a short, but as the current through it changes, it begins to generate a voltage. That
voltage causes the inductor to push current into the capacitor again, charging it. Then once the
inductor has discharged its stored energy, the capacitor is recharged and it begins to conduct
again. This continues until all of the electrical energy is dissipated through the resistor (and
realistically also through the resistances in the capacitor and inductor) as heat until there is none
left. Kind of cool!
<!--l. 154--><p class="indent" > If we tuned the capacitance and inductance properly, we could get one of these circuits to
oscillate at an audible frequency. This would not be an ideal circuit for music making, and there
are two big reasons for this:
<ul class="itemize1">
<li class="itemize">The circuit will only oscillate for a short period after it is triggered, preventing us from
ever using it to play any sustained note.
</li>
<li class="itemize">YOU CAN&#8217;T TUNE THE FREQUENCY! You would need a variable inductor or
transformer, and those solutions quickly become impractical. Unless you like plucky
drone music, you&#8217;re out of luck here.</li></ul>
<!--l. 164--><p class="indent" > I&#8217;m sure there are many other kinds of passive oscillating circuits, but I think we have done
enough here. Next we will consider <span
class="ecti-1000">active oscillators.</span>
<!--l. 169--><p class="noindent" >
<h4 class="subsectionHead"><span class="titlemark">1.2 </span> <a
id="x1-30001.2"></a>Active Oscillators</h4>
</body></html>
+22
View File
@@ -0,0 +1,22 @@
<title>PROJECTS</title>
<body>
<div id="body">
<h1>PROJECTS</h1>
<p>
Here you will find documentation of some of the things I've made (code, circuits, machines, etc):
</p>
<h3>SOFTWARE</h3>
<ul>
<li><a href="index.php?type=article&name=mypage">This website!</a></li>
<li><a href="index.php?type=article&name=mlib-c">Writing a machine learning library in C</a></li>
<li><a href="index.php?type=article&name=starsky">Night sky generator</a></li>
<li><a href="">Progressive Steps to Analog ANNs (coming soon!)</a></li>
<li><a href=""></a></li>
</ul>
<h3>HARDWARE</h3>
<ul>
<li><a href="index.php?type=article&name=modular-synth">Building a modular synthesizer</a></li>
<li><a href="index.php?type=article&name=6502">Building a 6502-based computer with terminal graphics processing</a></li>
</ul>
</div>
</body>
+63
View File
@@ -0,0 +1,63 @@
<title>NIGHT SKY</title>
<body>
<div id="body">
<h1>NIGHT SKY GENERATION</h1>
<p>
This is just a small program I wrote in Python to generate a starry night sky. It uses Pillow for image processing,
and it was a fun exercise in basic random image generation. I wanted to make a program that you could run over
and over and it could always spit out a pretty picture that was completely unique each time. Naturally, the program
employs a lot of random number generation using NumPy as well as some basic linear math for galaxies. The largest
challenge is trying to get the stars to look somewhat natural in color and shape, and that's where I think the
program needs most development. For now however, I think the results are acceptable.
</p>
<p>
I came up with the idea during development of this website. I needed a pretty night sky backround for my homepage,
but I didn't want to just use some stock image and I don't have any graphic design experience, so I just wrote a
script for it in Python. I wanted it to look like a night sky if it was unobstructed by the atmosphere and light
pollution; where the milky way and all the stars are highly visible. I also really wanted to have a program that could
use random number generation to build a really pretty picture every time without the need for human tweaking, so you
could just run the code and get a unique and beautiful picture.
</p>
<p>
The first thing I did was get Pillow (an image-processing library for Python) as well as NumPy (a math library) for its
many random number generators, and I started drawing little yellow circles at random locations with random sizes. This
made a picture, but not really anything close ot a night sky yet. The real night sky has stars distributed in clusters
broken by empy space. It also has a big streak of stars and gasses across the night sky where the Milky Way passes through
our sky. Finally, stars are not just yellow, they're usually closer to blue or white with variation based off of temperature.
I shelved the coloring issure and went on to create a galaxy system. I wrote a function which takes an x-value,
a slope, and an intercept, and spits out a y value corresponding to the linear equation defined by those parameters.
This line will be the center of the galaxy which the stars will cluster around.
</p>
<p>
To actually get the stars clustered around the line, I used a normal distribution random number generator to randomize
the distance of each star from the center line, with an average distance to make the distribution appear more natural.
This produces a nice line distribution , but doing this only once leaves the 'galaxy' looking kind of weak. So I draw stars
around the line multiple times with different normal distributions to produce a layered sort of look, which I think makes it look
much more natural. Finally, I just kept my initial code to generate stars at random locations to build a background
behind the galaxy.
</p>
<p>
Next it was time to tackle the coloration. Initially I just tried generating each star with a random RGB value and tried
restricting the range of the R, G, or B in order to keep the stars within the range of reality (no green or purple stars, etc).
This didn't really work very well. I realized that stars' colors are determined by their temperature and there is a direct
correlation between a star's color and temperature in kelvin. So after doing a little research, I found a Python script that
does just this! It converts degrees kelvin into an RGB value. All I had to do was give each star a random temperature based
on the range of actual star temperatures, and then I could get rid of all impossible RGB values for stars. This works well, although
there are still too many red stars which are generally pretty uncommon in the night sky. I think it actually makes the image look
more interesting from an aesthetic perspective, even if it's not quite accurate.
</p>
<p>
The last thing I've done was add star clusters, in addition to the galaxy system. This one is pretty simple. I just
pick a random set of points and generate stars at a random distance. It leaves the image looking a lot more realistic
and beautiful.
</p>
<p>
That is as far as the script goes for now. I have several issues with it I want to improve in the future. One glaring
issue is that Python is very slow, and generating high-resolution images can take several seconds. I'd like to rewrite
the program in a more memory-efficient langauge like C++ to reduce processing time. Another issure is that the actual individual stars are pretty
rudimentary. They're just circles with a blur effect. I'd like to introduce some kind of flare to them to make them more
interesting. I would also like to include other types of astronomical bodies like comets, nebulae, planets, etc. I think
the program as it exists is still compelling and I am happy with the images it produces. That's all!
</p>
</div>
</body>
+26
View File
@@ -0,0 +1,26 @@
<title>WRITINGS</title>
<body>
<div id="body">
<h1>PERSONAL WRITINGS</h1>
<p>
Here you can find some of the things I've written, as PDF documents. There are some essays and speeches I've written up, mostly.
Take a look!
</p>
<ul>
<li><a href="writings/onitall.pdf">"Where is My Democracy?"</a>
Speech I gave at a local art collective in town, about democracy and freedom and
what to do about all this nonsense.</li>
<li><a href="writings/on-class-war.pdf">On Class War</a>: Short essay providing an introduction to basic Marxist
concepts of economic class, in order to
establish the idea that there are internal class antagonisms that result in such a thing as a 'class war.'
The article was published in the IWW worker's paper <a href="https://sonhuelgaz.org/2024/09/24/what-is-class-war-part-1/">
sonhuelgaz.org</a>.</li>
<li><a href="writings/sept24-police-aggression.pdf">Short report</a> on a homeless eviction that took place at my hometown.
I wrote the report to help inform residents about the way my local police force speaks about the poor folks they are paid
to serve. Just a summary, play-by-play of events, and a little conclusion. It IS a partisan article, I don't lie but I
don't hide my views either. I think any journalist who pretends to have no perspective is being dishonest.
I believe in a form of <i>movement journalism</i> that does not present a pastiche of "objectivity," but instead seeks
to use truth and a perspective to build a better world.</li>
</ul>
</div>
</body>
+6
View File
@@ -0,0 +1,6 @@
<h1>|= CONTACT</h1>
<p>Please reach out to me anytime and for any reason!
The best place to reach me is by my email:
</p>
<ul><li><a href='mailto:me@jameswitzeman.net'>me@jameswitzeman.net</a></li></ul>
+13
View File
@@ -0,0 +1,13 @@
<h1>|= CHECK IT OUT!</h1>
<p>
Welcome to my homepage. This website is a place to look
at my cool things and ideas. You can also contact me!
I am a programmer, musician, and other things also.
If your computer isn't working, <i>I can probably
help you!</i> if you or someone you love wants to learn
to play piano or needs to pass college algebra, <i> I am
your guy!</i> If you want a friend, <i> definitely email me!</i>
</p>
<!--include content/about.html-->
+47
View File
@@ -0,0 +1,47 @@
<h1>SERVICES</h1>
<h2>|= IT SOLUTIONS</h2>
<p>It sounds really fancy phrased that way.
If you need someone to maintain your website, fix
your internet, write you some kind of program, or even
fix up a broken/old PC, I'm your guy!
</p>
<p>
My skillset is somewhat broad. I can do basic electronics
repairs, I was trained in logic design in school. I know
a lot of transistor math. I have experience programming in
C, PHP, JavaScript, Python, CSS, etc. I can do pretty good
web dev and also know how to work with Docker well. Here
at home I have a nice media server full of **legally obtained**
movies and shows. If you have a nasty old or cheap PC and want
help getting it running better, I can speed it up. The secret
is running Linux! Some things I can do:
</p>
<ul>
<li>Hardware repair</li>
<li>Website design and maintenance</li>
<li>Speed up slow, old PCs </li>
<li>Home networking</li>
<li>Programming help in Python, C, PHP, JavaScript</li>
</ul>
<h2>|= MATH TUTORING</h2>
<p>
I am a trained computer engineer and know a lot of
wicked maths. I can most likely help tutor you in any
math up to Calculus III. Some classes I passed:
</p>
<ul>
<li>Algebra I, II</li>
<li>Pre-Calculus</li>
<li>AP Calculus A,B,C</li>
<li>Calculus I</li>
<li>Calculus II</li>
<li>Multivariable Calc/Calc III</li>
</ul>
<h2>|= PIANO LESSONS</h2>
<p>I am also a proficient pianist! If you're trying to
learn, or have a child looking to pick up music, I can
help any beginner to intermediate player!</p>