Tuesday, August 25, 2026

Class D AM transmitter build

I built a Class D AM transmitter with mostly recycled parts based on what I learned when I wrote the previous post. The only parts that weren't junk were the TC4426A MOSFET driver and the FPGA board.

Unlike in the virtual example, it needs the square wave to range from +/- 1 instead of just 0-1. To do that, you need 2 MOSFET's connected to the sides of a center-tap transformer and controlled by opposing square waves. That makes it so both sides are alternately sending power to one side of the transformer while the other one is off. Since they have opposing polarity, they make a fluctuating magnetic field. At first I thought that you could do it with just 1 MOSFET but that would be Class E and you would want to use an oscilloscope to make sure that it's turning off exactly when the output crosses 0.

Here is a schematic of what I built



TR1, TR2, and L1 are from PC power supplies, with TR1 being optimized for high switching frequencies around 500 kHz instead of 60 Hz. TR2 was from a different power supply and I chose it because one side had high inductance.

Q1 and Q2 are the MOSFET's. As you can see, I used 6[0]R280E6's from a switching power supply. These are rated for up to 600 volts and since the max RF stage voltage is 56, even the inductive spike from the output transformer can't burn them out. They're wired with common source (negative) so I could do push-pull with both of them operating as low-side switches which meant that I didn't have to do anything annoying like having one N-MOSFET on the low side and one P-MOSFET on the high side and have to use a high-side driver and bootstrap components for the higher voltage on the high side. P-MOSFET's are also slower so this means both sides switch equally fast.

L1 was a random inductor that I found. It's supposed to stop RF from going back to the power supply since switching power supplies can misinterpret that as an overload and turn off for protection. I originally tested this with a 19-volt switching power supply and it kept turning off until I added that. It eventually started happening again so I started using LiFePO4 (lithium iron phosphate) batteries instead.

TR2 was another random power supply transformer. This is used as a modulation transformer. In the previous post, I talked about using the audio to change the voltage to the RF stage. I thought about using a 6[0]R190E6 MOSFET for that since I had one and got my FPGA board to read WAV audio from a microSD card and play it to the headphone jack with PWM but decided to use a modulation transformer and stereo so I could test the RF stage sooner.

A modulation transformer works by passing the power supply voltage as DC in series and inducing the audio on it so you have fluctuating DC. You just connect a high-power speaker driver to the other side. I used a stereo from by the road and connected the left speaker output to the transformer. With 12 volts from 1 battery, I didn't have to turn up the volume much before the signal started clipping. You would want to turn it up more with a higher input voltage. This is because you want AM to be just below clipping and a higher DC input voltage needs to fluctuate more to get close to 0.

For the DDS, I needed 2 opposing square-wave outputs. This sets the output frequency. You can divide the main clock evenly which gives you fractional powers of 2 like half, quarter, etc. or you can generate arbitrary frequencies with a phase accumulator and tuning word. I wrote some Verilog code that generates opposing square waves on 2 GPIO pins based on a tuning word. The tuning word is

round((desired_frequency / clock_frequency) * 2bits)

where bits is how many bits are in the phase accumulator which is a variable or "register" as it's called in logic design that holds the current phase offset. To generate the output at whatever frequency, you just output the most-significant bit (MSB) while adding the tuning word on every cycle of the main clock. For example, to get 600 kHz with a 32-bit phase accumulator, the tuning word would be round((600000 / 12000000) * 4294967296) or 214748365 and I would just have to add that to the phase accumulator on every 12 MHz clock cycle. It's going to overflow and wrap which is what we want.

C1 is a bypass capacitor. It lets the MOSFET driver quickly get a lot of power. The 12-volt power supply can deliver enough but it takes time to get it over the wire and the power supply has to notice that the voltage is lower and compensate and MOSFET's have to switch really fast so this capacitor gives it a quick source while it waits for the power supply to recharge it.

R3 and R4 are gate resistors. They're supposed to help with ringing so the MOSFET gate drive stabilizes faster.

R1 and R2 are pulldown resistors. They guarantee that the MOSFET's will be perfectly off with nothing connected. This is important because MOSFET gates are capacitors and they can randomly turn on a bit from tiny charges in the air or from your finger. This is bad because you only ever want MOSFET's to be perfectly on or off. 10k ohms is enough to keep them off without wasting much power from the gate driver.

The TC4426A is an inverting driver so I think it would turn the MOSFET's on with a logic 0 input (I didn't test that because I didn't want to burn them up). This means that you have to be extremely careful about how you turn on the entire setup. This means you can't turn on the RF stage with the MOSFET's until you're sure that the FPGA is on and supplying opposing logic signals to the driver. If it's not supplying 2 signals, then one of the MOSFET's would probably stay on if the driver sees a logic 0. If one or both of them stay on, that would make a short circuit through the coil. I think a switching power supply would see that as an overload and turn off but large batteries would probably just melt something. MOSFET's often fail on which means they're stuck on when they burn out so you would have a short circuit until you replace it. A large battery would supply a lot of current and probably melt something. Another problem is that the TC4426A seems to have floating inputs so if you don't also use pulldown resistors on the FPGA side, it just amplifies whatever value it sees which can also burn out the MOSFET's. I didn't want to use pulldown resistors on the FPGA side so I was just really careful to not turn on the RF stage until I made sure the DDS inputs were connected.

For the antenna, you would want to either ground one side and connect an antenna to the other, or connect both sides to a dummy load. I currently live far enough from everyone else that I was able to just use a short wire for a while without worrying about building a filter until I accidentally touched one side and burned myself. I realized that the feeling and the mark it left were almost the same as when I accidentally touched a ballast output wire for one of my sodium streetlights and that gave me the idea to use a sodium light as a dummy load. Sure enough, it lit up and fluctuated with the audio which looked cool.

I used a large Pentium 4 heatsink for the MOSFET's. I also saved a thermistor from one of the power supplies and verified its output in ice water and room air with a voltmeter and an online calculator. The heatsink is cooled with a 120/240-volt EC (electronically-commutated) fan.

The yellow and blue are the DDS inputs









I unplugged my phone from the audio cable so I could take the pictures




An RF burn from touching the transformer output


This looks like a mess so as the YouTuber grav3yardgirl would say, "Does this THING really WORK?" Yes it does and I took some SDR recordings to demonstrate.

As you can see, after I was sure that it was safe with 12 volts, I tried 24 volts and it still worked and the light got brighter. After that, I tried it with my 56-volt power supply and it still worked and the light got so bright that it started turning a bit yellower and making a dot crawl pattern before resetting the power supply over and over. I think this was because it finally got hot enough to vaporize the sodium which lowered the resistance and made it use more power than the 56-volt power supply could handle. A family member also reported hearing buzzing in their wired headphones toward the end.

Here is a video on Odysee showing the signal and audio quality. It was really quiet (probably low modulation) so I had to turn up the volume after recording it. I left some silence at the beginning so you could see how clean the carrier is.

https://odysee.com/class_d_am_transmitter_test_20260824:5b4a5b7bbbcb57dcf65cd6c86562fb9d0424d61f

Tuesday, August 11, 2026

Class D AM

Years ago I learned about a type of AM transmitter (more like RF stage) called Class D that is really efficient and flexible. The regular way of transmitting AM involves generating a carrier sine wave at the desired frequency and changing its amplitude with the audio, but that requires (1) a good/clean/stable sine wave source and (2) a device that can change the output voltage based on an audio signal. The simplest way to do part 2 is with an amplifier like a vacuum tube or transistor, but the problem is that those are linear devices so they're inefficient. What you actually want is a switching device.

As a kid, I always wondered why power supplies couldn't just be some series resistors. I also experimented with linear regulators (a chip-controlled variable resistor that maintains a constant voltage at the output) and wondered why they got so hot and assumed that I must be using them wrong. What I didn't realize was that they're the same thing and that that doesn't work because of Ohm's law.

The problem is that lowering a voltage with resistance wastes all the energy that the resistor is reducing by. For example, if you use a linear voltage regulator to convert 120 volts DC to 5 volts 1 amp to charge a phone, the input would also use 1 amp which would be 120 watts but since the output is only 5 watts, that's 115 watts of waste that is going to be released as heat which is incredibly wasteful. The way to fix that is with a switching power supply. Those work by switching the high voltage on and off really fast but (usually) leaving it on for way less time than off so the output only gets tiny slices of the higher voltage which gets averaged to a lower voltage. This is how good dimmers work and why some LED's flicker and look annoying.

This square-wave switching can also be used to generate AM radio. A square wave is a sine wave at the fundamental frequency plus all of the odd harmonics. You obviously wouldn't want to transmit that because it would pollute other frequencies like an arc transmitter, but if you add a low-pass filter (removes everything above its frequency), you get just the original sine wave at the desired frequency. This is your carrier. You can use whatever good square-wave source you want, such as an FPGA or a dedicated DDS (direct digital synthesis) chip. Some people even do it with microcontrollers like a Raspberry Pi or Arduino/ESP32. I prefer precise and exact timing so I've been using an FPGA. It sounds like the output would be unstable but dividing a higher square-wave clock from a crystal and using that either directly or in a DDS design can produce an extremely clean and stable carrier for an AM station.

Once you have a square wave at the frequency you want, you use it at the gate of a MOSFET or GAN FET to switch it perfectly on and off really fast like a power supply. This gets filtered and sent to the antenna. Because FET's are really efficient, they hardly get hot if you do it right even with several watts of output power but you have to use a gate driver because logic pins are fast (like megabits/second or faster) for other logic circuits but power circuits require something heavy-duty that can take a weak but fast information signal and turn it into amps of power in nanoseconds to charge and discharge a FET gate. If you use an audio signal or a logic signal that is slowed down by trying to drive something heavy-duty, the FET will spend a while between perfectly on and perfectly off and operate in its linear region and become a variable resistor like a linear regulator and get really hot and self-destruct in seconds. You can buy a gate driver like the TC4426A or build your own totem pole driver with regular transistors to drive a MOSFET fast enough but you need a different type if you use a GAN FET.

A solid carrier isn't really useful so how do you get the audio into it? Normally you would want to get as close as possible to a 50% duty cycle for the RF PWM but you could modulate the duty cycle with the audio. This works and makes recognizable audio but you would need a REALLY fast FET to switch fast enough for it to make sense because the PWM needs to be able to cover your audio waveform levels (the same as the bit depth on the computer). For example, if you have a 12 MHz FPGA board like mine and divide the clock to 600 kHz, you only get 20 total clock cycles for every RF PWM cycle (ideally 10 on and 10 off). If you lower the carrier frequency to 300 kHz (longwave) then you get 40 (ideally 20 on and 20 off). With 40 clock cycles per RF PWM output cycle, you could do 5-bit audio with a bit of overhead but that sounds horrible and you would need to be able to switch your FET at close to 12 MHz which is hard even with good recent devices because you have to watch out for parasitic stuff on the PCB traces.

A much better solution is to maintain a 50% RF PWM duty cycle on the RF stage and modulate the power going to it. To do that, you should convert your audio signal to PWM at a lower frequency and use that to drive a FET, filter the output to remove the switching frequency, and use the smooth amplified audio output as the input voltage for the RF stage. Here is a comparison.


There's a guy in the UK called John Stretch A.K.A. Stretchyman who builds custom transmitters like this for AM and lower shortwave frequencies. I bought one from him once (totally for a ham AM net ðŸ˜‰) and I can confirm his build quality and the clean output signal. With his transmitter, I was able to reach across much of the eastern US at only about 45 watts PEP with a longwire antenna in a tree and I didn't even need a fan for the transmitter. Here is a link to his YouTube channel. https://www.youtube.com/channel/UCnDdvpAi7FcSrETGwc6dT0Q. There are also a lot of similar options on eBay with more frequency coverage if you search for terms like "DDS".

I lost my "Stretchy" transmitter in an accident so I was wondering if I could build one that's good enough for now. To test that method before building one, I wrote a C++ program to modulate the square wave and generate a WAV file that I could play in HDSDR. I tried the modulated PWM duty cycle method first but it looked and sounded terrible so I asked Google's new search AI for advice and it told me about the modulated input voltage method. I updated the code to do that and then it looked and sounded amazing. Here are some things I noticed.

This is how the raw output looks in Audacity (that's as much as I could zoom in because the sample rate is 12 MHz).


This is how it looks in HDSDR. Notice all the harmonics and other dirty output even though all we want is the one signal at 600 kHz, and how there's a lot of energy right at DC. The reason it appears every 300 kHz is because I upsampled the audio to that rate to try and simulate PWM output at that frequency. If you leave it at 48 kHz then those will appear about every 50 kHz above and below the desired frequency


We can clean that up with "sox" and a bandpass filter. The high-pass filter at 550 kHz takes care of the lower interference and also the DC offset.

sox --ignore-length 12mhztest.wav 12mhztest_bpf_550k-650k.wav sinc -L 550k-650k

It's now a sine wave centered around 0


The harmonics and other mess are gone but it's still not completely clean. This is mostly because this is the only signal in the file and it's very strong so it's overpowering the virtual receiver. We can add some noise in Audacity so it's a bit weaker to make it more like a real-world signal. I mixed the signal with white noise with an amplitude of 0.03 for the next picture.

That looks a lot more like something you'd pick up over the air. Let's zoom in.

I included the audio waterfall so you could see the hard cutoff that I added at 15 kHz when I was doing the broadcast audio processing in Audacity. I think the remaining wider parts are from clipping.

You really don't want to just transmit stuff over the radio without processing it with something like an expander or Thimeo StereoTool. These make it sound better over the radio and help to maximize the modulation and amplify the higher frequencies so the signal is easier to hear when the band conditions are bad. As I currently understand it, a good audio processing toolchain should keep the sound close to clipping the whole time so the signal is rectangular like in the picture. Here is a quality example on Odysee just to make sure it doesn't get a copyright strike. For this file, I downmixed to mono, used Thimeo StereoTool's AM processor with pre-emphasis including the NRSC modified 75 µS one and 3 dB AM Brilliance, manually amplified the musical notes at the beginning, and used a 15 kHz low-pass filter.

https://odysee.com/softwarepwmamtransmittertest:dceb3749b76458e81ea61c6d0a7ca30721104556

Friday, November 6, 2020

7-zip optimization: sorting by file type

 Recently I was compressing the assets I scraped from a now-deleted Discord server and was able to save almost 600 MiB by having 7-zip sort by file type (the default behavior is to sort by filename) in addition to a few other options. This lets 7-zip take advantage of similarities between files of the same type.


The original data was 6,661,786,104 bytes, with the default compression it was 6,041,019,462 bytes (90.682%), and with "sort by file type" enabled, it was 5,427,406,392 bytes (81.471%). In this case, the optional parameters reduced the size of the output by 613,613,070 bytes (585.19 MiB).

This article was updated on February 11, 2021 because one of the parameters, "tr=on", doesn't exist and causes an error. I changed a few other parameters as well and updated the results in the previous paragraph because the new ones saved an extra 2.15 MiB.

Wednesday, July 15, 2020

Delivering GPS updates with TV datacasting

In 2011 my family got a Garmin GPS and a few years later I found it fascinating when I heard that it could get traffic data from FM radio. It occurred to me more recently that map updates could be sent over a broadcast with more capacity, such as a TV channel.

As you may know, my UTSC standard supports file transfers. Each packet is only 125,000 bytes, so you can't transfer much in each one, but it's possible to send large files as a split archive.

I set up an experiment to see how quickly I could transfer a full GPS map of South Carolina. Since I'm near the Georgia border I originally included a Georgia map but later decided to just do one state to make it faster.

I downloaded a copy of the OpenStreetMap data for South Carolina. I signed the map with my PGP key because I figured that automatic map updates should be signed and that unsigned ones, or those without a trusted signature, should require user intervention. I added a license file to the folder and then used my UTSC packet muxer to create packets that include a NoCopyrightSounds music compilation, an image that says this is a GPS map update and gives attribution for the map and music, and file transfers consisting of a split 7-Zip archive.

These are the 3 files I transmitted.


My packet muxer reads a JSON file with a list of content and an optional datacasting field. If datacasting is enabled, it finds the content with the highest bitrate and uses 7-Zip to compress the contents of a folder specified in the JSON. It instructs 7-Zip to split the archive into parts just small enough to fit in the least space (packets with the highest content bitrate).

The total content length was 23h23m00s and the file transfer was 104.9 MiB. The packet muxer reported that it had included the files 60 times. By coincidence, each full transfer took 1403 seconds or 23m23s. That means the map can be transmitted 61 times every 24 hours or about once every 23½ minutes.

After the muxer finished, I used my open-source UTSC transmitter (GitHub link) to transmit the output file. I used UTSC channel 2 (center freq 903.265625 MHz). Here's what it looks like in HDSDR.


Unfortunately, I don't know how to demodulate QPSK at the moment so I can't test the signal but I did some verification of the muxer output with a hex editor before I used it.

Wednesday, May 27, 2020

Multithreaded RRC for Raspberry Pi

In my last post I explained that I couldn't transmit continuous QPSK from my Raspberry Pi 3B because the single-threaded RRC function couldn't keep up with the transmitter. In other words the transmitter was transmitting and consuming the data buffer faster than the RRC function could supply it. This led to a situation in which there were short data bursts separated by slightly longer empty sections.

Tonight I resolved that. I carefully examined the RRC function until I understood how it worked and was sure that nothing depended on previous results, then split it into 4 equal parts, since the Pi has a quad-core CPU. The code uses pthreads in C to run a method that does 1/4 of the work. It populates the start and end indices for each thread, starts all 4, and waits for them to finish. The Pi can now transmit smooth QPSK with just a few sparse dropouts. I was using composite video for this test so it might be fast enough with HDMI which lets the system clocks run faster.


Sunday, May 24, 2020

May 2020 Hackerthon

Over the weekend, the owner of a Discord server called The Hive Mind ran a "hackerthon" during which members were supposed to build something and show pictures on Sunday. Since I was already working on a UTSC broadcast utility for LimeSDR's, I decided to finish it if possible and have something to enter if that was all I could do, and then see if I could transmit the same thing from a Raspberry Pi running on a power bank. If you're not familiar with UTSC, it's a TV standard I created in 2017 as a highly reliable and license-free alternative to ATSC.

Before I begin the description, here are the pictures I submitted when the event ended.







One of the first things I did during the hackerthon was to test the range of the LimeSDR Mini at its highest power. I used DATV Express to transmit QPSK at 625 kilosymbols/sec to make it as much like UTSC as possible and walked around outside with a laptop, SDRplay RSP1, and TV rabbit ears. The setup was on the second floor, about 25 feet above ground level, on a table near a window. The transmitting antenna was an adjustable TV dipole with ladder line oriented vertically. I walked until I was about 955 feet away (291 meters) and the signal was roughly 21 dB above the noise.

After I was done, I worked on a QPSK transmitter in Visual Studio. I copied the modulator from Charles Brain's (G4GUO) DATV Express code, which is public domain. I first tried this about a year ago and it worked but stuttered badly. I copied the code from an older version that had an issue with accessing the webcam when I compiled it so I assumed the modulator code was broken as well. It took a while for G4GUO to get back to me the second time I contacted him so I paused the project until a few days ago. That's when I tried again and succeeded. I think the issue was due to using a different buffer size the first time. I made sure to notify him via Twitter that I didn't need his help anymore.

Now that I could transmit QPSK, I wanted to see if I could use my LimeSDR Mini to do it from a Raspberry Pi. I have a Raspberry Pi 3B V1.2 and it was easy to set up the SDR and C++ environments. Since it uses Linux (specifically Raspbian), I didn't need any drivers. All I had to do was download the LimeSuite repo from GitHub and build and install it. When it was done, it left some include and library files in a folder that was easily accessible. I found them and used them with g++ to compile an example I found.

Once I checked that the API was accessible from C++ on the Pi, I copied my code from Visual Studio and removed everything specific to Windows. When I was done, it was able to transmit but had the stuttering issue. I spent hours trying different buffer sizes and noticed something odd: with a small buffer it stuttered rapidly, but with a large one it would transmit smoothly for a few seconds, nothing for slightly longer, and repeat. I tried transmitting pure noise and it didn't stutter so I decided to profile the code. What I found was that the RRC (root-raised cosine) method was too slow on the Pi's CPU. The large buffer size was letting it build up a large array of samples to transmit but the RRC method couldn't keep up, causing gaps longer than what was being transmitted. I decided to create a dummy signal generator instead. This would transmit QPSK with the same bandwidth as UTSC but with no real data. This was done by filling the data buffer with random bytes and using a bool variable called rrcRanOnce. I ran the RRC method once and set the variable to true, and then I had an "if" block that kept it from running again after that. This let me transmit the same RRC-filtered samples in a loop, producing a smooth QPSK signal on the Pi.

On Windows, my code originally had a GUI but I changed to a command-line project because I wanted to print debug information. I added methods to create UTSC packets and do the interleaving and de-interleaving. I wrote the output to a file and verified it in a hex editor. I also added command-line switches so I could use it outside of Visual Studio.

My transmitter is called UTSCTransmitterCli.exe and takes arguments such as an input file and the channel to use. UTSC is meant for the 902-928 MHz band. Each signal takes up about 850 kHz, so there's space for 30 channels. Here's the current UTSC air interface specification.

Intended band: 902-928 MHz
Bandwidth: 843.75 kHz
Modulation: QPSK (or Ï€/4 QPSK)
Symbol rate: 625 kilosymbols/sec
Rolloff: 0.35
Total data rate: 1.25 megabits/sec
FEC: LDPC, 4/5 (250 kilobits/sec)
Usable data rate: 1 megabit/sec

My transmitter uses π/4 QPSK. To achieve this, I duplicated the QPSK symbol array in my code and rotated each one by π/4 radians (45 degrees). Then, for each bit pair, the code checks if the index is odd or even and uses a ternary operator to choose the array that the symbol comes from.

As I said, my app takes an input file and transmits it without any processing. I have an option to create a file with UTSC packets but you can transmit anything you want. If the file is highly random, like if it's compressed, then the signal will be smooth but if not, then there will be patterns based on the content. Here are some examples.

A 7-zip file

A WAV file with music

A Visual Studio 2013 ISO image

Having visible patterns isn't desirable because they could violate power spectral density requirements. Here's what a basic UTSC signal without video would look like without any padding or interleaving.


The empty timeslots with spikes are the empty space for video that is zeroed out. Here's what it looks like when the empty space is filled with random bytes.


Notice the timeslots with peaks. That's from the WAV audio (8 bits, 44.1 kHz). With this method you can see how much of the packet is taken up by sound.

In this case the peaks aren't that bad but even if we were operating within the rules for PSD, there's another problem. If you live in the US then you probably have smart energy meters transmitting in this band. Those can briefly interfere with the signal. If we assume that a burst lasts 20 ms, then it could corrupt 25,000 bits (0.02 seconds * 1250000 bits/second) or 3125 bytes. This could mean the difference between a visible image or blocky colorful garbage, or it could cause bursts of noise in the audio.

To solve this, UTSC uses an interleaver. This is a scrambler that randomly and uniformly rearranges the data bit by bit at the transmitter and restores it at the receiver. If a burst of noise damages the scrambled data, the damage will be spread very evenly over the packet after it's unscrambled, which is not only easier to fix with error correction, but also produces audio that sounds better than bursts of noise if the error correction fails.

Here is the same broadcast from the last picture but with the interleaver enabled.


As I said earlier, the interleaver scrambles bit-by-bit. For example, bit 1633 in a plain packet would end up as bit 32 in an interleaved one, bit 952430 would become bit 33, and so on. Bits 0-31 inclusive are taken by the "UTSC" sync header. I generated a lookup table for this and it's defined in interleaver.h in my project.

Now that I've explained how this works, here's the full UTSC broadcast sequence.

(audio, video, EPG, files, etc.)->[packet muxer]->[FEC generator]->[interleaver]->[transmitter]

I don't have a FEC generator yet so I use random bytes as a placeholder.

Conclusion

I want it to be as easy as possible for people to get started with UTSC so I'm starting what I call the UTSC Ecosystem Project. It's a collection of guides and open-source programs for setting up a station. The goal is for anyone to be able to start with a PC or Raspberry Pi and a LimeSDR and be broadcasting in about 15 minutes instead of needing a week of free time and a PhD in Linux as is the case for too many open source projects.

Monday, December 16, 2019

MP3 player bug (RCA M6204-B)

Tonight I tried to put music on my RCA M6204-B MP3 player but when I tried to play it, it said the music section was empty.

TL;DR If your RCA MP3 player says the music section is empty even though you know it's not, make sure the MUSIC folder has at least 14 audio files. If that fails, split your music into at least 14 subfolders.

Full story:

This issue didn't make sense but I thought maybe I needed to use RCA easyRip. After installing that I had the same problem. I tried putting music directly in the MUSIC folder and a subfolder in MUSIC, making sure it was formatted as FAT32, formatting it in Windows and from its Settings menu, and trying MP3's from various sources. Nothing worked. I found other people online with this issue but most of the results were on fixya.com where they suggested calling a support number.

Fortunately, before clearing my player I had saved everything to a 7-zip file. I deleted everything and extracted the file onto the player and it worked. I thought there was some kind of database that the official RCA app populates when it transfers music, but the manual says you can copy music in Windows Explorer so that didn't make sense, but it was still worth trying. RCA easyRip was able to copy the music and list it when I restarted the program, so it should have worked but it still didn't.

Finally I copied everything from the 7-zip file onto the player again and decided to delete some of the music folders until the player said it was empty. I eventually discovered that the player requires the MUSIC folder to have at least 14 files, or folders with files, before it will recognize any music.

Tuesday, November 5, 2019

Purse.io review

Recently I became interested in growing grain so I decided to buy 3 types of grain seed on Amazon and try them out. Since I didn't have a credit or debit card at the time I placed the order, I used a platform called Purse.io to buy from Amazon using cryptocurrency. While most people think of Bitcoin when they hear "cryptocurrency", I actually used Bitcoin Cash (BCH) because it has lower fees.

I decided that I wanted wheat, barley, and rye seeds so I found them on Amazon and copy-pasted their URL's into Purse.io. The checkout process was quick and easy. I kept the discount slider at the lowest setting of 5% so it would be shipped immediately. Then I chose Bitcoin Cash from a drop-down menu and was given a QR code. I used the Electron Cash desktop wallet and scanned the QR code with a webcam. This populated the "address" and "amount" fields in the wallet, so all I had to do was quickly verify the info and click Send. Bitcoin Cash is designed to finalize payments in seconds and the website responded quickly once I sent the money.

It cost 98.2089 mBCH (milli-Bitcoin Cash) or 0.0982089 BCH if you don't like the mBCH unit. Bitcoin Cash was about $289 when I placed the order so the equivalent price in USD was $28.57.

I placed the order on Tuesday, October 29, 2019. Purse.io ordered the products from Amazon on Friday, November 1 and the package arrived on Tuesday, November 5.

Some people are concerned that Purse.io is a scam, so I decided to document my success.





Saturday, March 30, 2019

Avoiding Windows 10 in 2019

There's a lot of hype surrounding Windows 10 right now and I'm not sure why. I notice several problems and no real benefits. Everyone is saying to just upgrade, but I don't feel like upgrading to something that is hugely inefficient and spies on me. If anyone has a good reason to upgrade, let me know in the comments.

If Windows versions were cars:



Why do Windows and Office get bigger and slower with each release? Windows XP came on a CD and a typical installation could fit in a couple of gigabytes, let's say just under 2 GiB. Windows Vista and up come on DVD's and a typical installation takes about 15 GiB. Why is that? I use Windows 7 and it works very well for me but I don't know what it could possibly have that would take up an extra 13 GiB compared to Windows XP.

Upgrading past Windows 8.1 just doesn't make sense in my opinion. More importantly, we all know Windows 10 sends usage data to Microsoft. How much is it sending? We probably won't know until there's a data breach and it ends up in the news.

Another thing to ask is, why was Windows 10 free? And why did the free offer last so long past the deadline? I was able to activate Windows 10 using my Windows 7 COA in April 2017, long after that was supposed to stop working. An article on howtogeek.com says this still works as of January 5, 2018. They write, "it’s also possible Microsoft will look the other way and keep this trick around to encourage more Windows 10 upgrades for a long time to come."

At first I thought it was just a way to get free beta testers, but I suspect it also has to do with the data collection. If something is free then you're (usually) the product. I hear that people are quitting Facebook because of privacy and data collection issues, but what if using Windows 10 is just as bad as using Facebook, or even worse? Windows 10 could provide far more data than any social network since it can potentially watch everything you do.

The biggest problem with Windows 10 may not even be the data collection, but instead the forced updates. It almost feels like Microsoft owns any computer running Windows 10 and they're just letting you use it. I heard that they're also moving to a new driver signing system where you have to pay to get kernel-mode drivers signed before Windows 10 can use them. This reminds me of how Blackberry phones won't run native C++ apps unless they're signed by a Blackberry-issued certificate, even for development. Thankfully Blackberry's signing process is free, but it's still not cool to have to get permission to run things on your own devices. Windows should not be as locked-down as iPhone and Blackberry.

Recently a family member bought a laptop from Wal-Mart but after I explained how bad Windows 10 is, they took my suggestion to migrate their old laptop's Windows 8.1 license. After I installed Windows 8.1, I found out that many of the new laptop's devices only had drivers for Windows 10. It seemed odd since Windows 8.1 isn't that old. I've never seen a hardware manufacturer support only one version of Windows, but that was how it was for this laptop.

I tried everything, including unzipping the installers and attempting to manually install the drivers, but nothing worked. It turns out that Intel, the company that made the laptop's CPU, graphics, and Wifi, doesn't want to support anything below Windows 10. I can almost understand with the GPU and Wifi, but since when is an x86 CPU intended for only one version of Windows? In the end, I was asked to just install Linux. I set up Ubuntu and now everything works like it should, without the data collection.

I've decided to keep using older Windows versions as long as possible. I use Windows 7 on my desktop and XP on my laptop. And yes, my laptop is online. I also dual-boot my desktop with Windows XP so I can use an old analog video capture card.

I really like Windows XP because of its simple interface and low requirements. Everyone seems to freak out when they hear of people keeping an XP system on the Internet. I know about viruses like WannaCry, but as I understand it, they depend on someone to run them before than can infect a LAN. I'm behind a firewall and I'm always careful about what I download so I don't see a problem yet.

I'm not saying Windows XP is for everyone. In fact, I only recommend it if you're a power user who can secure it properly. Even then, it's probably better to use Windows 7 since it has better software support.

I can see that Microsoft, Intel, and probably others are planning to push everyone they can onto Windows 10. To prepare, I've archived my Windows ISO's on an external hard drive and downloaded a large collection of offline update installers. In fact, as I write this, I'm downloading all the updates for Windows Server 2003, XP, 7, 8, and 8.1, and Office 2003 and 2007.

Here are some OS options if, like me, you want to avoid Windows 10.

Windows 7


If possible, I'd say to stay with Windows 7 as long as possible unless you're using a tablet, in which case I think Windows 8.1 is best.

You should acquire and archive Windows 7 installation media and updates now, just in case Microsoft tries to kill this version later. After I installed Windows 7 and activated it, I used DriveImage XML to make a drive image so I can revert to a fresh installation whenever I need to.

I can see Windows 7 being supported by software and most hardware for a long time so this should be a good option for quite a while.

Ubuntu or Lubuntu


There are many apps that run on Linux such as Chrome, Opera, LibreOffice, 4K Video Downloader, and Veracrypt, so switching to Linux might work for you. It might be your only other option if you get a new computer.

Windows 8.1 (best for tablets, not PC's)


I know many people disagree, but I think Windows 8.1 is great for tablets. Unfortunately, the Windows 8 app store seems to be losing apps rapidly. If you're interested, you should acquire and archive Windows 8 installation media.

Windows XP


I use this every day on my laptop and it works well for me. It has decent software and hardware support but be prepared for some recent software to not work. I'll probably publish and maintain a list of XP-compatible software and hardware in the future.

Windows XP x64 Edition (not really recommended)


Recently I heard about Windows XP x64 Edition. It sounded interesting so I exercised my Windows 7 Pro downgrade rights (pictured below) to install a copy in a VM and on a laptop. (Don't worry, I had enough spare Windows 7 licenses to cover this)

Above: an excerpt from the Windows 7 Pro license agreement.

It looked and acted just like regular 32-bit Windows XP, and I was surprised at how many current 64-bit apps run on it. The downside is that it requires special drivers. I've observed some drivers to work in 32-bit Windows 7 and XP, but 64-bit Windows 7 and up cannot share drivers with 64-bit Windows XP. It turns out that 64-bit Windows XP uses a different driver model, one that it shares with Windows Server 2003 x64. Because 64-bit Windows XP is so rare, it's hard to find drivers for it but I think searching for drivers for Windows Server 2003 x64 might help. I was able to find a 64-bit XP driver for my GTX 750 Ti, but some Sandisk flash drives don't work.

As for compatibility, I can confirm that the following items work in 64-bit Windows XP:

  • Seagate's 5 TB GPT-formatted external hard drive
  • K-Lite Codec Pack, including Media Player Classic 64-bit
  • UltraSearch x64
  • Chromium 44 x64

Sunday, October 7, 2018

YouTube adds AV1 codec, also available in 4K Video Downloader

I noticed an article that says that YouTube has added support for the AV1 codec. Until recently, YouTube videos were usually either MP4 or VP9. I've been following the progress of the AV1 codec for the past few years, starting back when they still called it VP10. They finalized the codec this year but I couldn't figure out when it would go into mainstream use. Here is the article I found: YouTube testing AV1 codec on Chrome, Firefox for more efficient streaming

I installed Chrome 70 beta and tried the playlist. Sure enough, when I right-clicked and chose "Stats for nerds", it said the video was in AV1 format. I tried the URL in 4K Video Downloader and it showed a bunch of unknown entries in the MP4 category.


The article mentioned AV1 only being available up to 480p, so I wondered why there were so many options and why they went up to 40.3 MiB. I downloaded the largest one and tried to play it. MPC-HC didn't recognize the codec but thankfully I just had to update it. Once I did, I was able to play the video.

The file turned out to be 1080p, so YouTube must have encoded higher resolutions after the article was written. MPC-HC was able to play it at the full 29.97 fps on an Intel Core 2 Quad CPU.

It also played surprisingly well in the browser at 1080p.


The only issue I noticed is that the downloaded file had no sound.

Monday, October 1, 2018

Offline Blackberry 10 Development

Recently I've become interested in developing for Blackberry 10. After getting set up, I learned that Blackberry's security is so tight that you can't even run homemade apps on your own phone without a key from Blackberry's servers. I also heard that they would be closing their app store at the end of 2019, which concerned me because I didn't know if they would allow developers to keep writing apps after that.

I asked about it on Reddit and via direct email to Blackberry, with mixed responses. Fortunately, after I asked about it a Blackberry rep told the community that there are no plans to disable the app signing process, so we should be able to keep writing apps after the app store closes.

I decided to archive everything I could from Blackberry's official app development sources, including developer.blackberry.com and the entire BlackberryDev YouTube channel. The YouTube channel is not as interesting as the website, but I thought I might as well get everything in case things start getting taken down.

In this post I'm going to show you how you can download everything you need to develop for Blackberry 10 and install it from disk, in case Blackberry's site goes down. This obviously won't help if they can't sign your apps, but perhaps a solution for signing will be found by the time it's needed.

First, I downloaded developer.blackberry.com using HTTrack. The way I configured it, it was able to get the entire website, including the API documentation and many ZIP files. Unfortunately, I must have made a mistake with my job file because it missed a huge collection of EXE files, so I had to make a list and copy-paste it into a new HTTrack job so I could get them.

I decided to keep the two sets separate because the website and ZIP collection is 2.95 GiB, while the EXE set is 297 GiB, which is mostly phone firmware.

Anyway, to develop apps we need the Momentics IDE. The latest version right now is 2.1.2.


Direct links:
32-bit:
http://downloads.blackberry.com/upr/developers/downloads/momentics-2.1.2-201503050937.win32.x86.setup.exe

64-bit:
http://downloads.blackberry.com/upr/developers/downloads/momentics-2.1.2-201503050937.win32.x86_64.setup.exe

Once you pick a version, download and install it. I'm going to use the 32-bit version and install it with the default settings so it will end up in C:\bbndk. At the end, leave the option checked to start the IDE.





I unplugged my Internet cable so I could demonstrate how to do this offline. Click Cancel.


Click Yes because we will be installing an SDK from a pair of ZIP files. In the main IDE, go to Help->Update API Levels...


In the next dialog, go to the Custom tab. Note that this dialog will be much wider if you're connected to the Internet, because the other tabs will be populated.


I suggest API level 10.3.1.995. You'll need the following two files:
http://downloads.blackberry.com/upr/developers/update/bbndk/ndktargetrepo_10.3.1.995/packages/bbndk.win32.libraries.10.3.1.995.zip

http://downloads.blackberry.com/upr/developers/update/bbndk/ndktargetrepo_10.3.1.995/packages/bbndk.win32.tools.10.3.1.12.zip

Download and extract them. I used the C drive, so they ended up in C:\[zip file name]\.

(Update) I couldn't get the visual QML designer to work and it turns out I was missing some files.

http://downloads.blackberry.com/upr/developers/update/bbndk/ndktargetrepo_10.3.1.995/packages/bbndk.win32.cshost.10.3.1.995.zip (Necessary for the visual QML designer).

http://downloads.blackberry.com/upr/developers/update/bbndk/ndktargetrepo_10.3.1.995/packages/bbndk.win32.qmldocs.10.3.1.995.zip

http://downloads.blackberry.com/upr/developers/update/bbndk/ndktargetrepo_10.3.1.995/packages/bbndk.win32.documents.10.3.1.995.zip

These last three files will contain a folder called "target_10_3_1_995". Extract them to the same folder where you extracted win32.libraries.10.3.1.995.zip, so that the "target_10_3_1_995" folders from each zip file get merged with the one you already extracted.


In the dialog shown above, click Add New Custom SDK.


For "Target Path", click Browse and find the target folder from bbndk.win32.libraries.10.3.1.995.


Now for "Host Path", click Browse and find the host folder from bbndk.win32.tools.10.3.1.12.


In the Import SDK Platform dialog, change the Name field as desired.


Click Finish.


Now you have a fully functional API level so click OK.

(Update) If you want to be extra sure that you archive a working API level for offline installation, it looks like you can also use the automatic installer in the API Levels window to install an API, then close Momentics IDE and create a ZIP archive of your C:\bbndk folder.

In the IDE, go to File->New->Blackberry Project.


Just to finish the tutorial quickly, accept all the default options to create the project.


Click Yes.


Now you have a project ready to compile and run on a Blackberry 10 phone. Even though I have a BB10 phone, I don't want to have to get it set up and get a debug token yet, so let's use an emulator.

First we need VMware Player. My computer can't handle the latest version but older versions are still available from the official site. They're unlisted so you have to know the direct URL. I'm going to be using VMware Player 7.1.0.

https://download3.vmware.com/software/player/file/VMware-player-7.1.0-2496824.exe

Download this and install it.

Now you need the Blackberry emulation files. These files contain everything you need to emulate BB10 phones of various sizes, like square screens with a physical keyboard, or regular "tall" screens.

http://downloads.blackberry.com/upr/developers/update/bbndk/simulator/simulatorrepo_10.3.1.995/packages/bbndk.win32.simulator.10.3.1.995.zip

http://downloads.blackberry.com/upr/developers/update/bbndk/simulator/simulatorrepo_10.3.1.995/packages/bbndk.win32.simulatorController.10.3.1.995.zip

(Optional) http://downloads.blackberry.com/upr/developers/update/bbndk/simulator/simulatorrepo_10.3.1.995/packages/bbndk.win32.bbmServerSimulator.10.3.1.995.zip

Download these and extract them to a folder called "10.3.1.995_emulator" or something similar.

If you click the green play button at the top-left of the IDE, you'll get this error message:


Click in the box the message is pointing to and select Add New Target...


In the Device Manager dialog, go to the Simulator tab.


Click Begin Simulator Setup.


You'll get this error if you're not online but that's okay because we already have all the files we need. Click OK on the error message, then click the link at the bottom left.


Browse for the VMX file within the bbndk.win32.simulator.10.3.1.995 subfolder.


Click Open, then OK. The simulator will start automatically. By default, it will pick a "tall" resolution similar to a normal smartphone. If you want, you can choose a different resolution before it starts. To do that, click in the VM to capture the mouse and keyboard, press Enter, and follow the prompts. To un-capture the mouse and keyboard, press Ctrl+Alt.

For this first test, we're going to let it use the default resolution.




Back in the Momentics IDE Device Manager, it will ask for an IP address. It was entered automatically for me but if it's not automatic for you, you can find the right address at the bottom-left of the emulator.



Click Pair.


Now you have a working emulator that is recognized and listed by Momentics IDE's Device Manager. Notice that the "Open Controller" button is disabled. Since we installed from disk rather than the Internet, Momentics IDE doesn't know where to find the controller. To start it manually, navigate to the bbndk.win32.simulatorController.10.3.1.995 subfolder where you extracted the emulator ZIP's. Go into the subfolders to find "controller.exe". The full path is shown in the address bar in the next picture.


Double-click "controller.exe".


Again, mine was able to find the IP address automatically but if yours doesn't, you can enter it at the bottom.

Back in the Momentics IDE Device Manager, click Close. Notice that in the main IDE, you now have a valid simulator that you can run apps on.


Try clicking the green play button again.


Don't worry about these warnings. If you get an error dialog about a Java NullPointerException, just click OK and compile again.

When it's done, it should look like this.


Let's try it again but with a 720x720 square phone. To do that, we'll close and re-open the emulator. Once it starts, we'll click inside the VM, wait for the prompt, and press Enter, 2, and Enter again. Don't forget to press Ctrl+Alt to get out when you're done.





You may have to reconfigure the simulator in the IDE's Device Manager if it gives an error when you try to run the app. One time it said it didn't know the simulator's API level so I had to re-import the *.vmx file and pair it again.

If you're successful, the app should look like this.


I don't know why the color scheme is different for the BB10 keyboard phone.


On a side note, this simulator is surprisingly fast. I ran it on a computer from 2011 with a Core 2 Quad and 4GB RAM and it feels as fast as a real phone. In contrast, the Android emulator is barely usable on the same computer.