Skip to content
This repository was archived by the owner on Oct 27, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
*.pem
*.crx
*.zip
*.bak
*.db
nacl-src/pnacl
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,29 @@
# Modifications in this fork:

* Automatically pauses recording if signal is below the squelch threshold.

* m key mutes audio instantly (recording is not affected). Adjust volute to resume.

* Signal level is displayed with a bar. Hover mouse to read numerical value.

* Clicking signal bar sets squelch level.

* PgDn/PgUp moves through the list of saved preset stations.

* Shift-PgDn begins (or ends) scanning through preset stations. Scanning stops when signal is above preset squelch level and resumes when signal drops below squelch level for a while.

* Export/Import preset list includes the squelch setting for each station.

* Clicking on the "Squelch" heading enters or leaves MONITOR mode, where squelch is temporarily set to zero to monitor frequency.

* f/F key moves to the frequency display for editing (this is in the original help file, but didn't work).


# Radio Receiver

An application to listen to broadcast FM and AM radio from your Chrome browser or your ChromeBook computer using a $15 USB digital TV tuner.

![Radio Receiver screenshot](image-src/interface.png)
![Radio Receiver screenshot](image-src/interface2.png)

## What is this

Expand Down
2 changes: 1 addition & 1 deletion extension/appconfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function AppConfig() {
/** Upconverter. */
upconverter: {
enable: false,
frequency: 125000000
frequency: 99999020 // Peter's up converter
},
/** Whether free tuning is enabled. */
freeTuning: false
Expand Down
30 changes: 27 additions & 3 deletions extension/audio.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ function Player() {
var frameno = 0;

var wavSaver = null;

var dampedLevel = 0;

var ac = new (window.AudioContext || window.webkitAudioContext)();
var gainNode = ac.createGain ? ac.createGain() : ac.createGainNode();
Expand All @@ -38,7 +40,10 @@ function Player() {
*/
function play(leftSamples, rightSamples, level, squelch) {
var buffer = ac.createBuffer(2, leftSamples.length, OUT_RATE);
if (level >= squelch) {
dampedLevel = 0.75 * dampedLevel + .25*level*100;
signalBar.value = Math.floor(dampedLevel);
signalBar.title = signalBar.value;
if ((dampedLevel/100) >= squelch) {
buffer.getChannelData(0).set(leftSamples);
buffer.getChannelData(1).set(rightSamples);
}
Expand All @@ -50,7 +55,26 @@ function Player() {
ac.currentTime + TIME_BUFFER);
source.start(lastPlayedAt);
if (wavSaver != null) {
wavSaver.writeSamples(leftSamples, rightSamples);
if ((dampedLevel/100) >= squelch) {
wavSaver.writeSamples(leftSamples, rightSamples);
}
}
if (typeof scanPresets == 'undefined') { // proof of concept for preset scanning
scanPresets = false; // not likely to be the way it will be implemented
scanCount = 0; // a test to find the possible problems...
}
if (radio.requestingBlocks > 0) {
return;
}
if ( scanPresets ) {
scanCount++;
if ((dampedLevel/100) > squelch) {
scanCount = -5; // resume scanning after x+n no signal events
}
if ( scanCount > 5 && (level < squelch)) { // scan every n events
interface.nextPreset(); // tweak this parameter if too fast for dongle/decoder
scanCount = 0;
}
}
}

Expand Down Expand Up @@ -93,7 +117,7 @@ function Player() {
function setVolume(volume) {
gainNode.gain.value = volume;
}

return {
play: play,
setVolume: setVolume,
Expand Down
3 changes: 2 additions & 1 deletion extension/auxwindows.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ var AuxWindows = (function() {
win.contentWindow['opener'] = window;
var modeData = copyObject(band.getMode());
modeData['step'] = band.getStep();
modeData['squelch'] = squelch;
var stationData = {
'frequency': frequency,
'display': band.toDisplayName(frequency, true),
Expand Down Expand Up @@ -138,7 +139,7 @@ var AuxWindows = (function() {
'width': 700,
'height': 600
},
'state': 'maximized',
'state': 'normal',
'resizable': true
});
}
Expand Down
12 changes: 11 additions & 1 deletion extension/help.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ <h2>Using presets</h2>
<p>To switch to a preset, click the preset selection box (<b>7</b>) and choose your new preset. The radio will switch to it immediately.</p>
<p>To delete a preset, switch to it and press the &ldquo;Remove&rdquo; button (<b>8</b>).</p>
<p>To change a preset's name, switch to it and click the &ldquo;Save&rdquo; button (<b>6</b>). Type the new name and press &ldquo;Save&rdquo;.</p>
<p>To export a set of presets for loading later, go to &ldquo;Settings&rdquo; (<b>12</b>) and
click on the <a href="#settings">Manage your Presets</a> link.</p>
<p>Use the <b>PgUp</b> and <b>PgDn</b> keys to select the previous or next preset station in the list.</p>
<p>Hold down the <b>shift</b> key and press <b>PgDn</b> to begin automatic scanning of preset stations.
The scan will pause if the squelch level is exceeded. Each preset can have its own squelch value assigned.</p>

<h2>Changing volume and stereo</h2>
<p>To change the volume, click on the &ldquo;loudspeaker&rdquo; icon (<b>9</b>) and move the slider left and right to decrease or increase the volume. You can also use your mouse wheel on the icon to change volume directly.</p>
Expand Down Expand Up @@ -101,7 +106,8 @@ <h2>Using Free Tuning</h2>

<p>If you have <a href="#settings">configured an upconverter in the settings window</a> you can enable and disable it here by clicking the &ldquo;Upconverter&rdquo; field (<b>5</b>).</p>

<p>The &ldquo;Squelch&rdquo; setting (<b>6</b>) lets you monitor a frequency without having to hear static when nobody is transmitting. The squelch level is the minimum strength level the signal must reach before you can hear it; if it's set to 0, you'll hear everything.</p>
<p>The &ldquo;Squelch&rdquo; setting (<b>6</b>) lets you monitor a frequency without having to hear static when nobody is transmitting. The squelch level is the minimum strength level the signal must reach before you can hear it; if it's set to 0, you'll hear everything.
Click on the signal strength display to set the squelch value slightly above the noise level.</p>

<h1 id="settings">Settings</h1>
<p>You can change a lot of settings by clicking on the &ldquo;wrench&rdquo; icon (<b>12</b>). There you can change several settings:</p>
Expand All @@ -124,8 +130,12 @@ <h1 id="shortcuts">Keyboard shortcuts</h1>
<tr><td><tt>Space Bar</tt></td><td>Turn radio on/off</td></tr>
<tr><td><tt>Up Arrow</tt></td><td>Volume Up</td></tr>
<tr><td><tt>Down Arrow</tt></td><td>Volume Down</td></tr>
<tr><td><tt>m</tt></td><td>Mute Volume</td></tr>
<tr><td><tt>Left Arrow</tt></td><td>Decrease Frequency</td></tr>
<tr><td><tt>Right Arrow</tt></td><td>Increase Frequency</td></tr>
<tr><td><tt>PgUp</tt></td><td>Previous Preset</td></tr>
<tr><td><tt>PgDn</tt></td><td>Next Preset</td></tr>
<tr><td><tt>Shift-PgDn</tt></td><td>Scan Preset List</td></tr>
<tr><td><tt>&lt;</tt></td><td>Scan for stations by decreasing frequency</td></tr>
<tr><td><tt>&gt;</tt></td><td>Scan for stations by increasing frequency</td></tr>
<tr><td><tt>f</tt></td><td>Edit frequency</td></tr>
Expand Down
21 changes: 21 additions & 0 deletions extension/interface.css
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,27 @@ option {
width: 30px;
}

.signalDisplay {
bottom: 10px;
left: 10px;
width: 125px;
}

progress {
left: 0px;
width: 100px;
height: 15px;
border: 1px solid #afd;
background: #343;
// visibility: hidden;
}
progress::-webkit-progress-bar {
background: #343;
}
progress[value]::-webkit-progress-value {
background-image: -webkit-linear-gradient(left, red 0%, orange 70%, yellow 90%, white 100%);
}

.freqMinusButton, .freqPlusButton {
position: absolute;
top: 0;
Expand Down
3 changes: 2 additions & 1 deletion extension/interface.html
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,12 @@
<button id="upconverterDisplay" class="upconverterDisplay invisibleButton freeTuningButton" tabindex="16"></button>
</div>
<div id="squelchBox" class="squelchBox freeTuningBox">
<div class="freeTuningLabel">Squelch:</div>
<div class="freeTuningLabel" id="Squelch">Squelch:</div>
<div id="squelchDisplay" class="squelchDisplay freeTuningDisplay">100</div>
<input type="text" id="squelchInput" class="squelchInput freeTuningInput invisible" autocomplete="off" tabindex="17"></input>
</div>
</div>
<div id="signalDisplay" class="signalDisplay freeTuningDisplay"><progress id='signalBar' max='100' value='1'></progress></div>
</div>
<button id="freqPlusButton" class="freqPlusButton" title="Increase frequency" tabindex="23"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" version="1.1"><path d="M9.5,6l-5,5l-2,-2l3,-3l-3,-3l2,-2z" /></svg><br/>Freq+</button>
<button id="scanUpButton" class="scanUpButton" title="Scan increasing frequency" tabindex="25">Scan+<br/><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" version="1.1"><path d="M5.5,6l-4,4l-1,-1l3,-3l-3,-3l1,-1z M11.5,6l-5,5l-2,-2l3,-3l-3,-3l2,-2z" /></svg></button>
Expand Down
96 changes: 94 additions & 2 deletions extension/interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function Interface(fmRadio) {
* The current band configuration;
*/
var currentBand = Bands['WW']['FM'];

var currentSquelch = 0;
/**
* Updates the UI.
*/
Expand Down Expand Up @@ -262,6 +262,12 @@ function Interface(fmRadio) {
function changeVolumeUp() {
setVolume(fmRadio.getVolume() + 0.1);
}
/**
* Mute volume (change to 0).
*/
function muteVolume() {
setVolume(0.0);
}

/**
* Changes volume with the mouse wheel.
Expand Down Expand Up @@ -684,6 +690,78 @@ function Interface(fmRadio) {
saveSettings();
update();
}

/**
* Monitor - open squelch by clicking on "Squelch:" to monitor frequency
* Click again on "MONITOR" to resume stored squelch setting
*/

function squelchClick() {
var mode = appConfig.state.mode.get();
if ( Squelch.textContent == 'Squelch:') {
currentSquelch = mode.params.squelch;
fmRadio.setSquelch(0);
squelchDisplay.hidden = true;
Squelch.textContent = 'MONITOR';
} else {
fmRadio.setSquelch(currentSquelch);
Squelch.textContent = 'Squelch:';
squelchDisplay.hidden = false;
}
}


/**
* Change squelch by clicking on signal strength display.
*/

function clickChangeSquelch(value){
changeSquelch(value.offsetX);
}

/**
* Selects the previous preset in the list.
*/

function prevPreset(shiftKey){
if ( presetsBox.length < 3 ) { return; }
signalBar.value = 0;
if ( presetsBox[0].selected || presetsBox[1].selected ) {
presetsBox[presetsBox.length-1].selected = true;
selectPreset();
} else {
for (i = 0; i < presetsBox.length; i++){
if ( presetsBox[i].selected ){
presetsBox[i-1].selected = true;
selectPreset();
break;
}
}
}
}

/**
* Selects the next preset in the list.
*/
function nextPreset(shiftKey){
if ( presetsBox.length < 3 ) { return; }
if ( shiftKey ) {
scanPresets = ! scanPresets;
}
signalBar.value = 0;
if ( presetsBox[presetsBox.length-1].selected ) {
presetsBox[1].selected = true;
selectPreset();
} else {
for (i = 0; i < presetsBox.length; i++){
if ( presetsBox[i].selected ){
presetsBox[i+1].selected = true;
selectPreset();
break;
}
}
}
}

/**
* Closes the window.
Expand Down Expand Up @@ -777,6 +855,12 @@ function Interface(fmRadio) {
}
if (e.type == 'keydown') {
switch (e.keyCode) {
case 33: // PgUp
prevPreset(e.shiftKey);
break;
case 34: // PgDn
nextPreset(e.shiftKey);
break;
case 37:
frequencyMinus();
break;
Expand Down Expand Up @@ -809,8 +893,13 @@ function Interface(fmRadio) {
case 98: // b
switchBand();
break;
case 70: // F
case 102: // f
showFrequencyEditor();
frequencyDisplay.click();
break;
case 77: // M
case 109: // m
muteVolume();
break;
case 80: // P
case 112: // p
Expand Down Expand Up @@ -905,6 +994,7 @@ function Interface(fmRadio) {
upconverterDisplay.addEventListener('click', toggleUpconverter);
attachDisplayInputEvents(squelchDisplay, squelchInput, changeSquelch);
squelchDisplay.addEventListener('mousewheel', changeSquelchWheel);
signalDisplay.addEventListener('click', clickChangeSquelch);
freqMinusButton.addEventListener('click', frequencyMinus);
freqPlusButton.addEventListener('click', frequencyPlus);
scanDownButton.addEventListener('click', scanDown);
Expand All @@ -917,6 +1007,7 @@ function Interface(fmRadio) {
window.addEventListener('message', getMessage);
window.addEventListener('keydown', handleShortcut);
window.addEventListener('keypress', handleShortcut);
Squelch.addEventListener('mousedown',squelchClick);
fmRadio.setInterface(this);
fmRadio.setOnError(showErrorWindow);
loadSettings(function() {
Expand All @@ -928,6 +1019,7 @@ function Interface(fmRadio) {

return {
attach: attach,
nextPreset: nextPreset,
update: update
};
}
Expand Down
5 changes: 4 additions & 1 deletion extension/presetmanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ function showPresets(table, presets, delPresets, precheck) {
var isDouble = preset && delPreset;
var line;
if (delPreset) {
line = makePresetLine(value, delPreset, i, true, isDouble, precheck);
line = makePresetLine(value, delPreset, i, true, isDouble, true);
table.firstElementChild.appendChild(line);
}
if (preset) {
Expand Down Expand Up @@ -173,6 +173,9 @@ function makeModeCell(preset) {
if (mode['upconvert']) {
text += '; upconvert=on';
}
if (mode['squelch']) {
text += '; squelch='+mode['squelch'];
}
}
td.appendChild(document.createTextNode(text));
return td;
Expand Down
8 changes: 7 additions & 1 deletion extension/radiocontroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ function RadioController() {
function getSquelch() {
return squelch;
}

function getRB() {
return requestingBlocks;
}

/**
* Searches a given frequency band for a station, starting at the
Expand Down Expand Up @@ -686,6 +690,8 @@ function RadioController() {
stopRecording: stopRecording,
isRecording: isRecording,
setInterface: setInterface,
setOnError: setOnError
setOnError: setOnError,
requestingBlocks: getRB

};
}
Loading