├── .gitignore ├── screentunes.css ├── song.json ├── Readme.md ├── index.html └── screentunes.js /.gitignore: -------------------------------------------------------------------------------- 1 | .c9/ 2 | -------------------------------------------------------------------------------- /screentunes.css: -------------------------------------------------------------------------------- 1 | * { margin:0; padding:0; } /* to remove the top and left whitespace */ 2 | html, body { width:100%; height:100%; } /* just to be sure these are full screen*/ 3 | canvas { display:block; } /* To remove the scrollbars */ 4 | 5 | /* canvas { */ 6 | /* position: absolute; top: 0px; left: 0px; z-index: -1; */ 7 | /* } */ 8 | 9 | input[type=range] { 10 | width: 300px; 11 | } 12 | 13 | .bubble { 14 | position: relative; 15 | top: 10px; left: 10px; 16 | z-index: 100; 17 | background: #D9E9F5; 18 | width: 350px; 19 | padding: 9px; 20 | border-radius: 5px; 21 | font-family: sans-serif; 22 | } 23 | 24 | .bubble + .bubble + .bubble { 25 | top: 20px; 26 | } 27 | 28 | p { 29 | margin-top: 5pt; 30 | } 31 | -------------------------------------------------------------------------------- /song.json: -------------------------------------------------------------------------------- 1 | { 2 | "duration": 16000, 3 | 4 | "0": 7, 5 | "500": 9, 6 | "1000": 3, 7 | "1250": 4, 8 | "1750": 0, 9 | "2000": 3, 10 | "2250": 2, 11 | "2500": 0, 12 | "3500": 2, 13 | 14 | "4000": 3, 15 | "4750": 2, 16 | "5000": 0, 17 | "5250": 2, 18 | "5500": 4, 19 | "5750": 7, 20 | "6000": 9, 21 | "6250": 4, 22 | "6500": 7, 23 | "6750": 2, 24 | "7000": 4, 25 | "7250": 0, 26 | "7500": 2, 27 | "7750": 0, 28 | 29 | "8000": 4, 30 | "8500": 7, 31 | "9000": 9, 32 | "9250": 4, 33 | "9500": 7, 34 | "9750": 2, 35 | "10000": 4, 36 | "10250": 0, 37 | "10500": 3, 38 | "10750": 4, 39 | "11000": 3, 40 | "11250": 2, 41 | "11500": 0, 42 | "11750": 2, 43 | 44 | "12000": 3, 45 | "12500": 0, 46 | "12750": 2, 47 | "13000": 4, 48 | "13250": 7, 49 | "13500": 3, 50 | "13750": 4, 51 | "14000": 2, 52 | "14250": 0, 53 | "14500": 2, 54 | "15000": 0, 55 | "15500": 2 56 | } -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Screen Tunes 2 | 3 | [](https://codeclimate.com/github/GenaBitu/screentunes) 4 | 5 | It turns out that some LCD monitors will emit a tone when patterns of repeating bars are displayed on the screen. 6 | This pattern varies based on the size of the bars. The goal of this project is to eventually be able to play some 7 | music through the screen using a web page. 8 | 9 | I found out about this effect from the Hacker News comments on a page that was about a completely different bar spacing effect 10 | but produced sound out of some monitors (including my external Samsung LCD). 11 | [Some commenters](https://news.ycombinator.com/item?id=8856930) produced theories including that this is caused by 12 | the expansion and contraction of capacitors/inductors in the display as the screen scans down and the black pixels take a different 13 | amount of power than the white pixels. This theory suggests that varying the width of the bars would change the pitch, 14 | which indeed does happen. 15 | 16 | This is mainly intended as an experiment out of curiosity and geekery; it has no practical use. 17 | 18 | ## Technique 19 | 20 | I simply created a full screen canvas where I draw an animated and variably spaced sequence of black and white bars. 21 | Displaying this pattern in a large browser window on some LCD monitors produces a tone. 22 | 23 | ## Music 24 | 25 | The script can play some basic music, which it loads from the file song.json. In this file, there must be: 26 | 27 | * duration - the overall duration of the song, after which the song will be repeated 28 | * individual notes with starting duration as the attribute and the note as the value 29 | 30 | Notes are not named(due to inconsistent naming) but instead are represented as the number of semitones (half-steps) from the base note. 31 | The script is calibrating the device in such a way, that it tries to fit the first octave (values 0 to 12) to the device tonal range. 32 | 33 | ## Calibration 34 | 35 | Before the actual script is started, the user is prompted to sed the lowest and highest tone, which he can hear. The script then 36 | shifts the whole scale to best fit these settings. 37 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |34 | On some LCD monitors this page will cause the screen to emit a 35 | tone that varies in pitch with the bar height. Maximize window for best results. 36 |
37 |38 |
42 | 43 |44 | For more see the Github Page 45 |
46 |47 | Edit: I kinda managed to get this to play music but it doesn't work very well. If you're ambitious you can download and try out the "music" branch on Github. 48 |
49 |