I believe this is not the case in today’s ubiquitous equal temperament?
HN user
codyd51
Static analysis, file formats, operating systems, oh my!
The waveform produced by sounding a note on most physical instruments will often not exhibit a peak, or will not exhibit the strongest peak, on the note being sounded. Rather, most instruments will instead produce harmonic overtones and our brains fill in the gap of the pitch that’s intended to be sounded.
You can still absolutely deduce the fundamental with great accuracy via an FFT, but the approach is a bit more involved. The relevant research area here is called ‘fundamental frequency estimation’.
For an example of this, you can see this app I built that lets you give keyboard and mouse inputs via playing notes on a bass guitar, which are recognized over the microphone: https://github.com/codyd51/offkeyboard
Hi, author of axle here - thank you for the shout out! It’s been a wonderfully fun and enriching project to work on over the years. I’m now working on XNU at Apple, so won’t be working further on axle for the foreseeable future.
One potential hiccup with your one-photino-bird-universe theory (which is quite fun!): I believe I remember a scene in which the ‘birth’ of a photino bird was described. If I remember correctly, it was indeed described as a clone of its parent.
What a wonderful thing to say about a stranger's article! Thank you very much for posting this.
Whoa, thank you! I don't know much about RF and learned ad-hoc for this project, and it seems perfectly plausible to me that someone knowledgeable would be able to look at this and identify a root cause - I certainly didn't do anything special for clock recovery, and based on the name I would have blindly assumed that synchronising the carrier wave _would_ be tantamount to recovering the satellite clock. I haven't researched clock recovery yet, and will do so. Once again, thank you!
Thank you for linking this, this course is phenomenal! Several of the videos were immensely helpful in my GPS journey.
Thank you very much for your thoughtful offer! I won't be able to readily work on side projects after starting my new role next week, and am content to consider this project complete for the time being. However, what you've proposed does sound interesting and fun. I'm going to go ahead and shoot an email to the address listed in your profile.
I believe you are correct. My understanding is that the root P key is rotated daily, and needs to be manually uploaded to any military hardware that needs to use it.
Thank you very much! I agree, they are incredible! I really had no idea until making this project, and it makes things like cellular phones so astoundingly impressive.
This project only supports the 'legacy' C/A variant of the NAVSTAR constellation's signals.
Thank you for sharing this! It is sort of a vulnerable thing to write, because it reveals the shapes and bounds of my own ignorance, and the path I took to learning. I am really grateful to hear that you appreciated the approach.
I am really grateful for this nice comment, thank you! As a self taught programmer with no background in RF or EE, this project was definitely a stretch for me and involved lots of (sometimes frustrating) learning and experimentation. Looking back, I'm really glad for it, as it feels as though I've unlocked RF as a domain that I now understand a lot more tangibly and can use as a sort of tool. It reminds me of the things I love about computers themselves!
Thank you very much!
That's so great to hear, thank you for the nice feedback!
This is amazing! I had no idea tech like this was available on the market. Thank you for the correction.
Yes, I forgot to mention downloading the orbital parameters over the network! Thanks for mentioning this as well.
In this case, I was meaning to refer to brute-forcing the Doppler-shifts and PRN phases of each satellite, not the orbital parameters themselves. The project in the OP is able to get a position fix in less than a minute because, if the subframe timings are convenient, you can retrieve the necessary ephemeris parameters from the subframes in that span (and down to as little as 18 seconds in ideal conditions, if my back-of-the-napkin is right).
GPS jamming or spoofing on a wide scale is definitely a viable attack! As another commenter noted well, making everyone appear at exactly the same location would be nigh-impossible, though.
GPS receivers will look for the 'strongest' PRN signal in the noise, so broadcasting louder than the (incredibly weak!) C/A signal is a valid way to jam or spoof GPS. It is, however, generally illegal for civilians.
GPS receivers operating with good practice do tend to try to mitigate this sort of attack, by (for example) ignoring signals with a too-high power level. It's a bit of a cat and mouse game, and there are academic papers exploring each side.
Lastly, GPS receivers also need to deal with interference from GPS itself! If GPS signals bounce off surfaces before reaching the receiver, the receiver might see two sets of GPS signals: one that arrived directly, and one that was scattered off a surface and arrives a bit later. This is called ‘multipath interference’, and part of what goes into making GPS receivers work well is mitigating multipath interference.
Hi! Yes, "from scratch" is definitely always a bit of a funny term. I also implemented the receiver in Python, which is quite far from "scratch" =). What I mean by it in this context is that I'm taking a piece of hardware that knows nothing about GPS, and just has the ability to sample the EM field, and building up a receiver from there.
Re. slow TTFF, or time-to-first-(position)-fix on older hardware, this essentially stems from advancements in processing power.
Traditionally, GPS receivers would need to download the ‘almanac’ of all the satellites, which takes a minimum of 12.5 minutes (under certain conditions) due to the GPS data transmission format and speed. With modern processing power, though, receivers (including gypsum) can just ‘brute force’ the search space to find the in-view satellites, instead of using the hints downloaded over the air. This is the technique described at the end of Part 1.
Yes, you're absolutely correct! The design here totally suffers from unbounded memory use if you draw onto a large canvas. (Restating parts of your comment for confirmation that this is also how I think about it.)
To resolve this while maintaining the spirit of the design, I think two representations need to be kept: one for the rendered pixel data, and one 'out of band' representation (such as the textual data - you also highlighted this in your comment).
The idea is that, when the pixel buffer memory gets too large, some of it can be dropped. When it scrolls back into view again, it can be repopulated by the secondary representation. What I don't like about this is how it doesn't feel like it generalises well - you always need to be able to store the secondary representation, and have code to redraw it.
I think the concept you suggested is a really good one: just make sure everything that's drawn is its own 'encapsulated' widget with its own drawing logic, and you can ask it to render itself whenever that's convenient. I'm grateful for the input here, and think I will end up switching to this sort of approach in the future.
Thanks very much!
The other commenter is correct that the work loop typically revolved around booting a QEMU instance which ships my UEFI application. The main run script will regenerate an EFI filesystem that contains a fresh build of UEFIRC, then pass it to QEMU.
However, the overhead here can get a bit cumbersome when trying to build a GUI. I set things up such that the app could target either bare-bones UEFI, or a hosted environment that runs on my Mac. By flipping a build flag, my GUI toolkit would either draw directly to the UEFI-provided framebuffer, or would hook into my Mac's windowing system and receive/push events to that. You can see some of the overhead of this 'dual-target' approach in the app's entry point: https://github.com/codyd51/uefirc/blob/main/src/main.rs.
Parsing IRC messages also really doesn't need any accoutrements, so I developed those with a unit test suite running directly on my Mac - you can see part of that here: https://github.com/codyd51/uefirc/blob/main/src/irc/response....
Wow, thank you so much! I made these using HTML canvases and TypeScript. I’m drawing everything in code, including the pixel art (which is defined in the source).
The animations are made using a small animation system that I made for this post. This system has two useful properties:
1. It allows me to animate whatever property of the object I’m interested in (alpha, frame, etc).
2. It allows me to set up other work to be triggered when the animation has reached a certain completion threshold, which lets the animations flow into each other. This is how (for example) the grid lines ‘cascade’ in after each other.
The 3D animations are also primarily HTML canvases, and I used Three.js to place them as textures in a 3D scene. I have some logic to map the coordinate system of the canvases to the 3D scene, so that I can draw the connective tissue between the canvases and run animations that operate on objects both on the 2D canvases and the 3D scene.
Ha! I take your point.
I am really glad to hear that there's interest, and hopefully I will have a 3-part series to share on this some time soon! Similar to Andrew's project linked down below, this is a 'true' home-brew receiver. I didn't know anything about DSP, etc, when I started out, so I learned a lot about signal processing (and the incredible techniques that make GPS work), and really hope I'll be able to publish it all soon!
Andrew Holme's receiver was a crucial resource in my journey! There were times when a sentence or two from his post unlocked an insight for me.
Thank you very much, I've spent a lot of time on them over the past week and am really pleased to hear that you enjoyed them!
Hi everyone!
As a bit of a gag, I’ve made a graphical IRC Client that runs entirely in the UEFI preboot environment. It features completely overdone features such as TrueType fonts, a cursor, and GUI decorations.
I first started this project as I was getting a bit tired building a from-scratch GPS receiver, and wanted to make something relatively quick and lighthearted. As tends to happen, this took a fair bit longer than I anticipated at the outset!
A fair chunk of that time was spent on the visualisations in the post showing how scroll views are modelled and how they’re rendered to a static viewport. I really hope you enjoy them!
When I first began wanting to "stuff something in UEFI that really shouldn’t be in UEFI", my first instinct was a Twitter client. As it turns out, someone has already done a great job making this by using UEFI’s HTTP protocol! I therefore decided that whatever I made shouldn’t use HTTP at all, because that’s taken. I went with IRC since it sits on top of TCP and has the same social media feel that doesn’t belong anywhere near a preboot environment.
This was a fun read, kudos to the author! Adding one more typo to this thread:
if let (a, 2) = (1, 2) &&
let (b, 4) = (3, 4) && // <-- This should be an open brace.
println!("Made it, a = {}, b = {}", a, b);
}This is an excellent article, thank you for submitting it! I love how effortlessly this article delivered an intuition for why an ideal antenna length would be half of the wavelength of the signal you want to receive. I was also delighted by the point about how all methods of modulating a wave can be recontextualized as frequency modulation!
This is a funny and digestible read, thanks for sharing!