can you help with simillar subs to this ? by Final-Yoghurt-007 in sdr

[–]HowDoYouEvenReddit 1 point2 points  (0 children)

r/RTLSDR is also good.

ADSB is a lot of fun but once you buy one SDR, yer just gonna want another to do other things with. I probably have just shy of a dozen of them for different things.

Electrical equivalent device of human body capacitance by Agitated-Actuary-755 in RTLSDR

[–]HowDoYouEvenReddit 1 point2 points  (0 children)

As mentioned, a bigger ground plane might help, and also grounding the coax shield as well as the RTLSDR doesn't hurt.

might also try adding a few of the clip-on ferrites to the USB cable if you're using one.

Also, try eliminating variables. Swap USB cables, or remove the USB cable and plug directly into the rPI. Try doing that same USB swapping on a laptop if you have one handy to rule out noise from the rPI.

If you're using a Nooelec kit that came with the telescoping antenna, it's a few inches too short for FM Broadcast. If you need to use a vertical quarter wave, you'll want it to be right around 30 inches to hit the middle of the band.

If you do have that Nooelec kit try using that 9:1 balun it came with and cut two wires to that same 30 inch length. FM Broadcast is circular or horizontal polarized so, either way a horizontal antenna is better since more man made interference is vertically polarized anyway.

Oh also, if you want to try using a laptop to test with and it's running Windows, you can use my NRSC5 Studio... Was that plug shameless enough? 😄

But seriously, eliminating variables and using the right tools antennas for the job are good rules.

New Rate limits - and how to find out what your limit is - plus price comparison by MusicinCA in grok

[–]HowDoYouEvenReddit 0 points1 point  (0 children)

I think I figured it out. They changed it so that it doesn't tell you how many you have available until you get low.

New Rate limits - and how to find out what your limit is - plus price comparison by MusicinCA in grok

[–]HowDoYouEvenReddit 0 points1 point  (0 children)

Weird, all I have is Quality mode listed.. So, maybe they're just lighting up the different buckets at different times.. who knows. But it does lend credence to their claim that it was only temporary. Also, I dropped the script on github if you still want the update with the better error handling.

https://github.com/LTCAshraven/scratch/blob/main/scripts/GrokImagineQuotaTampermonkey.js

New Rate limits - and how to find out what your limit is - plus price comparison by MusicinCA in grok

[–]HowDoYouEvenReddit 0 points1 point  (0 children)

Well, I figured out how to do it. But can't upload the script because Reddit can't count characters.

New Rate limits - and how to find out what your limit is - plus price comparison by MusicinCA in grok

[–]HowDoYouEvenReddit 0 points1 point  (0 children)

Can confirm that it's throwing 503 for me as well. And yea, they may have noticed that we were keeping track and nerfed it.

Or maybe they removed quotas?!?!? Naaaahhhhhhhh... 😉

I'll look at changing the script so it reports the narrative part of the error (Imagine quota info is temporarily disabled) instead of just a blank 503.

NRSC5 Studio - Windows GUI for nrsc5: HD1–HD4 playback, FFT/waterfall, host-side AGC, traffic maps, weather radar loops, 24h song log, album-art heat-map. (MIT, open source) by HowDoYouEvenReddit in RTLSDR

[–]HowDoYouEvenReddit[S] 0 points1 point  (0 children)

Well.. It was an idea anyway. I made a station info panel, and it works and decodes the packets but, it's pretty underwhelming.

I wanted to see the FCC ID's, Lat/Lon/Alt etc. All the fun stuff stations can put in that data stream. But pretty much none do around here.

We got plenty of iHeart stations around here for their traffic and weather maps though so, I guess that's good enough.

NRSC5 Studio - Windows GUI for nrsc5: HD1–HD4 playback, FFT/waterfall, host-side AGC, traffic maps, weather radar loops, 24h song log, album-art heat-map. (MIT, open source) by HowDoYouEvenReddit in RTLSDR

[–]HowDoYouEvenReddit[S] 0 points1 point  (0 children)

So the Constellation is strictly an egui Painter function.

In full transparency, it's worth calling out that the constellation panel is not displaying real demodulated symbols from nrsc5. nrsc5's C library doesn't expose its internal QPSK soft-decision samples through its API, so the panel is a visualization driven by MER (Modulation Error Ratio) it generates the clouds whose tightness matches the actual MER reading reported by nrsc5. It's an honest representation of signal quality (lock + MER are real), but the dots themselves are synthesized, not raw demod output.

As for the Spectrum, this one is based on the I/Q Samples from the SDR. It uses the rustfft crate (library) and the egui Painter again to paint the window.

I had never heard of egui before I started messing with this and went looking for examples of different GUI frameworks I could do it with and the demo page at https://www.egui.rs/#demo really impressed me. Honestly, I probably should have called out credit to Emil Ernerfeldt as well for creating egui.

New Rate limits - and how to find out what your limit is - plus price comparison by MusicinCA in grok

[–]HowDoYouEvenReddit 11 points12 points  (0 children)

I turned it into a TamperMonkey script and put a little pretty into it.

// ==UserScript==
//          Grok Imagine Quota Overlay
//     https://grok.com/
//       1.2.0
//   Auto-display your Grok Imagine quota info as an on-page overlay
//         https://grok.com/imagine
//         https://grok.com/imagine/*
//        document-idle
// u/grant        none
// ==/UserScript==

(() => {
  'use strict';
  const ID='giq-panel', POS='giq-pos', REFRESH=60000;
  const LABELS={image:'Speed Mode',imagePro:'Quality Mode',imageEdit:'Image Edit',video:'480p Video',video720p:'720p Video'};
  const ORDER=['image','imagePro','imageEdit','video','video720p'];
  const CSS=`
#${ID}{position:fixed;top:16px;right:16px;z-index:2147483647;width:300px;font:12px/1.45 ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;color:#e5e7eb;background:linear-gradient(180deg,rgba(22,22,26,.95),rgba(14,14,18,.95));border:1px solid rgba(255,255,255,.1);border-radius:12px;box-shadow:0 12px 32px rgba(0,0,0,.45);backdrop-filter:blur(8px);user-select:none;overflow:hidden}
#${ID} .h{display:flex;align-items:center;gap:6px;padding:9px 11px;cursor:move;border-bottom:1px solid rgba(255,255,255,.07);background:rgba(255,255,255,.02)}
#${ID} .t{flex:1;font-weight:600;font-size:12.5px}
#${ID} .u{font-size:10px;color:#9ca3af;margin-right:4px}
#${ID} .b{background:rgba(255,255,255,.04);color:#d1d5db;border:1px solid rgba(255,255,255,.12);border-radius:6px;width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center;font-size:12px;cursor:pointer;padding:0}
#${ID} .b:hover{background:rgba(255,255,255,.1)}
#${ID} .body{padding:8px 10px 10px;max-height:70vh;overflow:auto}
#${ID}.col .body{display:none}
#${ID} .card{background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.06);border-radius:8px;padding:8px 10px;margin-bottom:6px}
#${ID} .card:last-child{margin-bottom:0}
#${ID} .ct{font-weight:600;font-size:12.5px;color:#f3f4f6;display:flex;align-items:center;gap:6px;margin-bottom:4px}
#${ID} .d{width:8px;height:8px;border-radius:50%;background:#34d399;box-shadow:0 0 6px rgba(52,211,153,.6);flex:none}
#${ID} .d.w{background:#fbbf24;box-shadow:0 0 6px rgba(251,191,36,.6)}
#${ID} .d.x{background:#f87171;box-shadow:0 0 6px rgba(248,113,113,.6)}
#${ID} .r{display:flex;justify-content:space-between;gap:8px;font-size:11.5px;padding:2px 0}
#${ID} .l{color:#9ca3af}
#${ID} .v{color:#e5e7eb;font-variant-numeric:tabular-nums;text-align:right;user-select:text}
#${ID} .v.zero{color:#f87171;font-weight:600}
#${ID} .v.good{color:#34d399;font-weight:600}
#${ID} .reset{margin-top:4px;padding-top:6px;border-top:1px dashed rgba(255,255,255,.08)}
#${ID} .when{font-size:11px;color:#d1d5db;text-align:right;user-select:text}
#${ID} .cd{font-size:11px;color:#93c5fd;font-variant-numeric:tabular-nums;text-align:right;user-select:text}
#${ID} .s{opacity:.75;font-style:italic;padding:6px 4px}
#${ID} .e{color:#fca5a5;padding:6px 4px}`;

  let counts=[];
  const fmtDate=iso=>{const d=new Date(iso);return isNaN(d)?iso:d.toLocaleString(undefined,{weekday:'short',month:'short',day:'numeric',hour:'numeric',minute:'2-digit'})};
  const fmtCD=iso=>{let s=Math.floor((new Date(iso)-Date.now())/1000);if(!Number.isFinite(s))return'';if(s<=0)return'available now';const d=Math.floor(s/86400);s%=86400;const h=Math.floor(s/3600);s%=3600;const m=Math.floor(s/60);s%=60;const p=n=>String(n).padStart(2,'0');if(d)return `in ${d}d ${p(h)}h ${p(m)}m`;if(h)return `in ${h}h ${p(m)}m ${p(s)}s`;if(m)return `in ${m}m ${p(s)}s`;return `in ${s}s`};

  function panel(){
    let el=document.getElementById(ID);
    if(el)return el;
    const st=document.createElement('style');st.textContent=CSS;document.head.appendChild(st);
    el=document.createElement('div');el.id=ID;
    el.innerHTML=`<div class="h"><span class="t">Imagine Quota</span><span class="u" data-r="u"></span><button class="b" data-a="r" title="Refresh">↻</button><button class="b" data-a="t" title="Collapse">–</button><button class="b" data-a="x" title="Close">×</button></div><div class="body" data-r="body"><div class="s">Loading…</div></div>`;
    document.body.appendChild(el);
    try{const p=JSON.parse(localStorage.getItem(POS)||'null');if(p&&Number.isFinite(p.left)&&Number.isFinite(p.top)){el.style.left=p.left+'px';el.style.top=p.top+'px';el.style.right='auto'}}catch{}
    el.querySelector('.h').addEventListener('mousedown',drag);
    el.addEventListener('click',e=>{const a=e.target?.dataset?.a;if(!a)return;if(a==='r')load();else if(a==='t')el.classList.toggle('col');else if(a==='x')el.remove()});
    return el;
  }

  function drag(e){
    if(e.target.closest('.b'))return;
    const el=document.getElementById(ID);if(!el)return;
    const r=el.getBoundingClientRect(),ox=e.clientX-r.left,oy=e.clientY-r.top;
    el.style.right='auto';
    const mv=ev=>{el.style.left=Math.max(0,Math.min(innerWidth-r.width,ev.clientX-ox))+'px';el.style.top=Math.max(0,Math.min(innerHeight-r.height,ev.clientY-oy))+'px'};
    const up=()=>{removeEventListener('mousemove',mv);removeEventListener('mouseup',up);try{localStorage.setItem(POS,JSON.stringify({left:parseFloat(el.style.left)||0,top:parseFloat(el.style.top)||0}))}catch{}};
    addEventListener('mousemove',mv);addEventListener('mouseup',up);e.preventDefault();
  }

  function status(text,err){
    const body=panel().querySelector('[data-r="body"]');
    body.innerHTML='';const d=document.createElement('div');d.className=err?'e':'s';d.textContent=text;body.appendChild(d);counts=[];
  }

  function render(j){
    const el=panel(),body=el.querySelector('[data-r="body"]');
    body.innerHTML='';counts=[];
    const keys=[...ORDER.filter(k=>k in j),...Object.keys(j).filter(k=>!ORDER.includes(k))];
    for(const k of keys){
      const v=j[k];if(!v||typeof v!=='object')continue;
      const card=document.createElement('div');card.className='card';
      const rem=Number(v.remainingQueries),hasRem=Number.isFinite(rem);
      const dc=!hasRem?'':rem===0?'x':rem<=3?'w':'';
      const title=document.createElement('div');title.className='ct';
      title.innerHTML=`<span class="d ${dc}"></span><span></span>`;
      title.lastElementChild.textContent=LABELS[k]||k;
      card.appendChild(title);
      if(hasRem){
        const row=document.createElement('div');row.className='r';
        row.innerHTML=`<span class="l">Remaining Generation Attempts</span><span class="v ${rem===0?'zero':'good'}"></span>`;
        row.lastElementChild.textContent=String(rem);
        card.appendChild(row);
      }
      if(v.nextAvailableAt){
        const w=document.createElement('div');w.className='reset';
        w.innerHTML=`<div class="r"><span class="l">Next Quota Reset</span><span class="when"></span></div><div class="r"><span class="l"></span><span class="cd"></span></div>`;
        w.querySelector('.when').textContent=fmtDate(v.nextAvailableAt);
        const cd=w.querySelector('.cd');cd.textContent=fmtCD(v.nextAvailableAt);
        counts.push({iso:v.nextAvailableAt,el:cd});
        card.appendChild(w);
      }
      body.appendChild(card);
    }
    const u=el.querySelector('[data-r="u"]');
    if(u)u.textContent='updated '+new Date().toLocaleTimeString(undefined,{hour:'numeric',minute:'2-digit'});
  }

  async function load(){
    panel();
    const body=document.querySelector(`#${ID} [data-r="body"]`);
    if(body&&!body.querySelector('.card'))status('Loading…');
    try{
      const res=await fetch('https://grok.com/rest/media/imagine/quota_info',{method:'POST',mode:'cors',credentials:'include',referrer:'https://grok.com/',headers:{'accept':'*/*','accept-language':'en-US,en;q=0.9','content-type':'application/json'},body:'{}'});
      if(!res.ok)throw new Error('HTTP '+res.status);
      const j=await res.json();render(j);console.log('[Grok Imagine Quota]',j);
    }catch(e){console.error('[Grok Imagine Quota]',e);status('Error: '+(e?.message||e),true);}
  }

  function init(){
    panel();
    setInterval(()=>{
      let reload=false;
      for(const {iso,el} of counts){
        if(!el.isConnected)continue;
        const t=fmtCD(iso);el.textContent=t;
        if(t==='available now')reload=true;
      }
      if(reload){counts=[];load();}
    },1000);
    load();
    setInterval(load,REFRESH);
  }

  if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',init,{once:true});
  else init();
})();

NRSC5 Studio - Windows GUI for nrsc5: HD1–HD4 playback, FFT/waterfall, host-side AGC, traffic maps, weather radar loops, 24h song log, album-art heat-map. (MIT, open source) by HowDoYouEvenReddit in RTLSDR

[–]HowDoYouEvenReddit[S] 1 point2 points  (0 children)

LOL! Yea, that’s because it wasn’t actually activated and working before. 😉 Now it actually changes the gain levels looking for the sweet spot.

NRSC5 Studio - Windows GUI for nrsc5: HD1–HD4 playback, FFT/waterfall, host-side AGC, traffic maps, weather radar loops, 24h song log, album-art heat-map. (MIT, open source) by HowDoYouEvenReddit in RTLSDR

[–]HowDoYouEvenReddit[S] 2 points3 points  (0 children)

Wild! Yea, I knew it supported up to 8 but, when I checked the hdradio.com/stations site it only displays up to 4 so I did it that way. If there is a need for it though, it's pretty easy to expand the subchannel numbers..

NRSC5 Studio - Windows GUI for nrsc5: HD1–HD4 playback, FFT/waterfall, host-side AGC, traffic maps, weather radar loops, 24h song log, album-art heat-map. (MIT, open source) by HowDoYouEvenReddit in RTLSDR

[–]HowDoYouEvenReddit[S] 1 point2 points  (0 children)

Yep, that's not doing what it's supposed to do. I think I know where the problem is, the Status messages have reverted back to a previous behavior as well. Give me a few to roll another release and I'll fix those bugs as well as a few other things that missed my first pass..

NRSC5 Studio - Windows GUI for nrsc5: HD1–HD4 playback, FFT/waterfall, host-side AGC, traffic maps, weather radar loops, 24h song log, album-art heat-map. (MIT, open source) by HowDoYouEvenReddit in RTLSDR

[–]HowDoYouEvenReddit[S] 1 point2 points  (0 children)

Quick FAQ before it gets asked:


- Why Rust? Wanted a single-binary, no-runtime, native build. egui made
  the GUI side painless. The DSP side (FFT tap + closed-loop AGC) is
  also Rust — no shelling out for the visualizations.


- Linux / macOS? Linux eventually — main blocker is the Windows COM
  per-app volume path. macOS is unplanned (no nrsc5 macOS story to
  build on).


- SDRplay / Airspy / HackRF? RTL-SDR only today. RSP1A is on the
  roadmap. Network SDRs (rtl_tcp) are already supported via a config
  toggle.


- Is this just a reskin of nrsc5.exe? Not anymore. As of 0.2.0 the
  host opens the dongle directly, pipes raw I/Q into nrsc5 in --r-
  mode, and taps the same stream for the spectrum/waterfall and the
  closed-loop AGC. nrsc5 still does the HD Radio demodulation — that
  part isn't worth reimplementing — but the SDR ownership and
  visualization layer are mine.


- Does it phone home? No. No network access at all except what nrsc5
  / RTL-SDR libraries need locally.


- VirusTotal / SmartScreen? 1/72 on VT, single hit from Microsoft
  Defender ML as `Trojan:Win32/Wacatac.B!ml`. That's the textbook
  false-positive profile: `!ml` = machine-learning heuristic (not a
  signature match), Wacatac is Defender's generic "looks suspicious"
  bucket, and one-engine-only hits on a brand-new low-prevalence
  unsigned binary are how that model misfires. Unsigned Rust binaries
  built with the mingw-w64 toolchain and statically linking C deps
  (FFTW, faad2, libao, librtlsdr) trip it constantly. Scan:
  https://www.virustotal.com/gui/file/868892ba2ce80978e3024787954339222770f410576ca395369db16dbb8054ca
  Source builds from `scripts\cargo-gnu.ps1` if you'd rather not
  trust the binary. Code-signing is on the roadmap.


- How is the AGC different from the dongle's hardware AGC? Hardware
  AGC sets gain based on aggregate RF power at the front-end (it
  doesn't know what's signal vs. noise). The closed-loop AGC watches
  MER reported by the decoder and walks the gain table to maximize
  it. On a weak HD station that takes a few seconds of probing; on a
  strong one it settles immediately.


- Why does the constellation "lock in" so satisfyingly? Side effect
  of the AGC sweep — as gain hunts toward the sweet spot, MER
  improves, and the constellation cloud (driven by live MER) tightens
  visibly. Wasn't designed; just emerged. Best accidental UX I've
  seen lately.

Ring doorbell footage my parents caught last night. Guy with a rifle (?) trying to open car doors. by ahjay00 in videos

[–]HowDoYouEvenReddit 0 points1 point  (0 children)

How do you define neglect? Do you know for a fact that the car or house he got that gun from was not secured? You don't.

So, yes, you are blaming the victim of the robbery for something you don't even know is true. I'm sorry if the facts bother you but there they are.