moving project pages to posts
@ -40,7 +40,7 @@ Mixonomer is a web app for creating smart playlists for __Spotify__. These playl
|
|||||||
|
|
||||||
Updates are run multiple times a day or on-demand. Additionally, __Last.fm__ integration provides listening statistics for your playlists.
|
Updates are run multiple times a day or on-demand. Additionally, __Last.fm__ integration provides listening statistics for your playlists.
|
||||||
|
|
||||||
{{< figure src="/mixonomer/cloud-structure-3.png" alt="cloud structure" >}}
|
{{< figure src="/posts/mixonomer/cloud-structure-3.png" alt="cloud structure" >}}
|
||||||
|
|
||||||
The project began as an exercise in recreating the functionality of [__Paul Lamere‘s__](https://twitter.com/plamere) [__Smarter Playlists__](http://playlistmachinery.com/) app. This tool had become a really important part of my daily listening habits as a way of combining my smaller sub-genre playlists into larger mixes.
|
The project began as an exercise in recreating the functionality of [__Paul Lamere‘s__](https://twitter.com/plamere) [__Smarter Playlists__](http://playlistmachinery.com/) app. This tool had become a really important part of my daily listening habits as a way of combining my smaller sub-genre playlists into larger mixes.
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ The system is now deployed with a fully serverless architecture.
|
|||||||
|
|
||||||
A __Spotify__ listening agent which watches what you listen to and presents related data and information in a live dashboard. __Spotify__ presents some interesting track data that isn’t visible in the official clients such as its beats-per-minute, key signature and a musical descriptor.
|
A __Spotify__ listening agent which watches what you listen to and presents related data and information in a live dashboard. __Spotify__ presents some interesting track data that isn’t visible in the official clients such as its beats-per-minute, key signature and a musical descriptor.
|
||||||
|
|
||||||
{{< figure src="/selector/dashboard.png" alt="dashboard" >}}
|
{{< figure src="/posts/selector/dashboard.png" alt="dashboard" >}}
|
||||||
|
|
||||||
[Read More](/selector)
|
[Read More](/selector)
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ date: 2020-12-25T00:07:40+00:00
|
|||||||
draft: false
|
draft: false
|
||||||
---
|
---
|
||||||
|
|
||||||
{{% image-box-link src="/mixonomer/PlaylistExample.png" href="/mixonomer" title="Mixonomer" %}}
|
{{% image-box-link src="/posts/mixonomer/PlaylistExample.png" href="/mixonomer" title="Mixonomer" %}}
|
||||||
|
|
||||||
Mixonomer is a __Spotify__ playlist manager for creating _smart playlists_. Create mixes with other __Spotify__ playlists and include AI recommendations, playlists are updated multiple times a day. __Last.fm__ integration provides data for listening statistics and visualisation.
|
Mixonomer is a __Spotify__ playlist manager for creating _smart playlists_. Create mixes with other __Spotify__ playlists and include AI recommendations, playlists are updated multiple times a day. __Last.fm__ integration provides data for listening statistics and visualisation.
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ I use Mixonomer to create mixes and big genre playlists out of my smaller sub-ge
|
|||||||
|
|
||||||
[Try It Out](https://mixonomer.sarsoo.xyz)
|
[Try It Out](https://mixonomer.sarsoo.xyz)
|
||||||
|
|
||||||
{{% image-box-link src="/selector/dashboard.png" href="/selector" title="Selector" %}}
|
{{% image-box-link src="/posts/selector/dashboard.png" href="/selector" title="Selector" %}}
|
||||||
|
|
||||||
Selector is a __Spotify__ listening agent for monitoring what you're listening to and presenting a dashboard of stats. Display __Spotify__ stats that you can't typically see in the apps such as the song descriptor, tempo, key and popularity. Connect to Last.fm to present graphs of how frequently you listen to the current track/album/artist.
|
Selector is a __Spotify__ listening agent for monitoring what you're listening to and presenting a dashboard of stats. Display __Spotify__ stats that you can't typically see in the apps such as the song descriptor, tempo, key and popularity. Connect to Last.fm to present graphs of how frequently you listen to the current track/album/artist.
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: "Draught"
|
title: "Draught: Rust WASM Game With AI Player"
|
||||||
date: 2021-07-13T14:02:40+00:00
|
date: 2021-07-13T14:02:40+00:00
|
||||||
draft: false
|
draft: false
|
||||||
---
|
---
|
||||||
@ -8,13 +8,13 @@ draft: false
|
|||||||
|
|
||||||
_I wrote a checkers game with a computer AI player that runs locally in the browser using compiled Rust + WASM. An AI can take a long time to make a move if you let it look many moves in the future, using compiled Rust allows a smarter computer player than if the player were run in Javascript._
|
_I wrote a checkers game with a computer AI player that runs locally in the browser using compiled Rust + WASM. An AI can take a long time to make a move if you let it look many moves in the future, using compiled Rust allows a smarter computer player than if the player were run in Javascript._
|
||||||
|
|
||||||
I wanted to play with Rust + WASM to see what could be done in the browser without Javascript, previously I knew little about either beyond the basic tutorials. In my masters AI module, I studied adversarial game models including the [MiniMax algorithm](https://en.wikipedia.org/wiki/Minimax). This algorithm generates a tree of possible moves and compares scores to decide which move should be made. Generating this tree can be expensive as it explodes exponentially, as such it would be a good candidate to try and speed up using compiled Rust over interpreted Javascript. If I'm honest, I'm not crazy passionate about checkers but I thought it would be a cool application of some of my uni theory
|
I wanted to play with Rust + WASM to see what could be done in the browser without Javascript, previously I knew little about either beyond the basic tutorials. In my masters AI module, I studied adversarial game models including the [MiniMax algorithm](https://en.wikipedia.org/wiki/Minimax). This algorithm generates a tree of possible moves and compares scores to decide which move should be made. Generating this tree can be expensive as it explodes exponentially, I thought it would be a good candidate to try and speed up using compiled Rust over interpreted Javascript. If I'm honest, I'm not crazy passionate about checkers but I thought it would be a cool application of some of my uni theory.
|
||||||
|
|
||||||
{{< figure src="checkers-board.png" alt="checkers board" caption="Standard checkers board rendered on an HTML canvas using Rust" >}}
|
{{< figure src="checkers-board.png" alt="checkers board" caption="Standard checkers board rendered on an HTML canvas using Rust" >}}
|
||||||
|
|
||||||
The project took about 3 weeks off and on. Initially, I wanted to model the game board without the off-diagonal pieces that aren't played on. This would have helped reduce the memory footprint of each board which would be ideal when we are going to be handling a lot. Unfortunately, this significantly increased the complexity of modelling piece movements - after some trial and error I resorted to just modelling the whole board.
|
The project took about 3 weeks off and on. Initially, I wanted to model the game board without the off-diagonal pieces that aren't played on. This would have helped reduce the memory footprint of each board which would be ideal when we are going to be handling a lot. Unfortunately, this significantly increased the complexity of modelling piece movements - after some trial and error I resorted to just modelling the whole board.
|
||||||
|
|
||||||
The MiniMax algorithm was also a bit of a pain. The algorithm relies on a tree structure for which I used the [IndexTree crate](https://crates.io/crates/indextree). Instead of using pointers between nodes that could rely on unsafe code, this library instead relies on a single backing array of nodes. Working out how to effectively create, populate and traverse the trees while following the borrow checker's rules was an effective learning exercise.
|
The MiniMax algorithm was also a bit of a pain. The algorithm relies on a tree structure for which I used the [IndexTree crate](https://crates.io/crates/indextree). Instead of using pointers between nodes that could rely on unsafe code, this library instead relies on a single backing array of nodes. Working out how to effectively create, populate and traverse the trees while following the borrow checker's rules was a good test.
|
||||||
|
|
||||||
{{< figure src="screenshot.png" caption="Javascript UI with a Rust-controlled canvas" >}}
|
{{< figure src="screenshot.png" caption="Javascript UI with a Rust-controlled canvas" >}}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: "Game of Life"
|
title: "Game of Life: Rust WASM Exercise"
|
||||||
date: 2021-06-26T14:14:40+00:00
|
date: 2021-06-26T14:14:40+00:00
|
||||||
draft: false
|
draft: false
|
||||||
---
|
---
|
||||||
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 203 KiB After Width: | Height: | Size: 203 KiB |
Before Width: | Height: | Size: 166 KiB After Width: | Height: | Size: 166 KiB |
@ -2,6 +2,8 @@
|
|||||||
title: "Holoportation with LiveScan3D"
|
title: "Holoportation with LiveScan3D"
|
||||||
date: 2021-01-19T21:49:40+00:00
|
date: 2021-01-19T21:49:40+00:00
|
||||||
draft: false
|
draft: false
|
||||||
|
aliases:
|
||||||
|
- /holo
|
||||||
---
|
---
|
||||||
|
|
||||||
[LiveScan3D](https://github.com/MarekKowalski/LiveScan3D) is a holographic teleportation or _holoportation_ platform. The app has a client-server model for streaming 3D or _volumetric_ video over the internet. It was written in 2015 by a pair of academics at the Warsaw University of Technology, [Marek Kowalski](http://home.elka.pw.edu.pl/~mkowals6/) and [Jacek Naruniec](http://home.elka.pw.edu.pl/~jnarunie/).
|
[LiveScan3D](https://github.com/MarekKowalski/LiveScan3D) is a holographic teleportation or _holoportation_ platform. The app has a client-server model for streaming 3D or _volumetric_ video over the internet. It was written in 2015 by a pair of academics at the Warsaw University of Technology, [Marek Kowalski](http://home.elka.pw.edu.pl/~mkowals6/) and [Jacek Naruniec](http://home.elka.pw.edu.pl/~jnarunie/).
|
Before Width: | Height: | Size: 2.5 MiB After Width: | Height: | Size: 2.5 MiB |
Before Width: | Height: | Size: 243 KiB After Width: | Height: | Size: 243 KiB |
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: "Listening Engineering"
|
title: "Listening Engineering: ML + Spotify + Last.fm"
|
||||||
date: 2021-02-20T12:22:40+00:00
|
date: 2021-02-20T12:22:40+00:00
|
||||||
draft: false
|
draft: false
|
||||||
---
|
---
|
||||||
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 122 KiB |
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 88 KiB |
Before Width: | Height: | Size: 269 KiB After Width: | Height: | Size: 269 KiB |
@ -2,6 +2,8 @@
|
|||||||
title: "Mixonomer: Smart Spotify Playlists"
|
title: "Mixonomer: Smart Spotify Playlists"
|
||||||
date: 2021-01-19T14:23:40+00:00
|
date: 2021-01-19T14:23:40+00:00
|
||||||
draft: false
|
draft: false
|
||||||
|
aliases:
|
||||||
|
- /mixonomer
|
||||||
---
|
---
|
||||||
|
|
||||||
![ci badge](https://github.com/sarsoo/mixonomer/workflows/test%20and%20deploy/badge.svg)
|
![ci badge](https://github.com/sarsoo/mixonomer/workflows/test%20and%20deploy/badge.svg)
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 132 KiB |
@ -1,7 +1,9 @@
|
|||||||
---
|
---
|
||||||
title: "Selector: A Spotify listening agent"
|
title: "Selector: A Spotify Listening Agent"
|
||||||
date: 2022-04-04T21:26:40+00:00
|
date: 2022-04-04T21:26:40+00:00
|
||||||
draft: false
|
draft: false
|
||||||
|
aliases:
|
||||||
|
- /selector
|
||||||
---
|
---
|
||||||
|
|
||||||
![ci](https://github.com/sarsoo/Selector/actions/workflows/ci.yml/badge.svg)
|
![ci](https://github.com/sarsoo/Selector/actions/workflows/ci.yml/badge.svg)
|