Likes
" ); } else { wrap = '
Attachments:
- '; count = 0; for (i = 0; i < response.length; i++) { if (response[i].Inline == false) { wrap += '
- ' + response[i].Name + ' (' + response[i].HumanSize + ') "; count++; } } wrap += '
'; if (count > 0) { $('#attachments' + id).replaceWith(wrap); } else { $('#attachments' + id).replaceWith( "
" ); } } }); } var modTimeoutId; function modOnFormChange(id, draftid, groupurl, csrf) { clearTimeout(modTimeoutId); if (modSaving == true) { modTimeoutId = setTimeout(function () { // Runs 1 second (1000 ms) after the last change modOnFormChange(id, draftid, groupurl, csrf); }, 1000); return; } modTimeoutId = setTimeout(function () { // Runs 1 second (1000 ms) after the last change modSaveDraft(id, draftid, groupurl, csrf, false); }, 1000); } var modSaving = false; // modSaveDraft saves the current form state in the draft. function modSaveDraft(id, draftid, groupurl, csrf, onLeave) { if (draftid == 0) { console.log("DraftID 0, not modSaving"); return; } console.log("DELETEDDRAFT IS:", modDeletedDraft); console.log("DESTROYEDEDITOR IS:", modDestroyedEditor); if (modDeletedDraft == true) { console.log('NOT SAVING BECAUSE OF DELETED'); return; } if (modDestroyedEditor == true) { console.log('NOT SAVING BECAUSE OF DESTROYED'); return; } modSaving = true; console.log('modSaving'); var fromval = $('#from' + id).val(); var subject = $('#subject' + id).val(); var body = $('#editor' + id).val(); var bodytype = $('#bodytype' + id).val(); var replyto = $('#replyto' + id).val(); var special = '0'; if ($('#special').prop('checked') == true) { special = '1'; } var bccme = '0'; if ($('#bccmecheck' + id).prop('checked') == true) { bccme = '1'; } var bccall = '0'; if ($('#bccall' + id).prop('checked') == true) { bccall = '1'; } var saveval = '1'; if (onLeave == true) { saveval = '2'; } var hashtags = $('#hashtags').val(); upload = { draftid: draftid, csrf: csrf, from: fromval, subject: subject, body: body, bodytype: bodytype, special: special, replyto: replyto, bccme: bccme, bccall: bccall, hashtags: JSON.stringify(hashtags), mid: id, save: saveval }; let opts = { url: groupurl + '/draftop', cache: false, data: upload, method: 'POST', xhrFields: { withCredentials: true }, dataType: 'json' }; if (modUnloading == false) { // if we are unloading we don't want to retry, because sometimes // that can result in a spurious error, esp on Firefox opts.retryCount = 5; opts.retryVerify = modRetryVerify; } $.ajax(opts).done(function (response) { // Do something with the request console.log('saved'); modSaving = false; }); } // called to see if we need to continue retrying function modRetryVerify() { if (modDeletedDraft == true || modDestroyedEditor == true) { return false; } return true; } // stop modSaving drafts when we do a submit var postVar = null; // Code to find and return a selected piece of HTML. function modGetSelection(id) { var flag = 0; var sel = document.getSelection(); var selText = ''; id = 'msgbody' + id; var forkfork = document.getElementById(id); if (sel.rangeCount > 0) { var range = sel.getRangeAt(0); var test = range.cloneContents(); var clonedSelection = ''; if (typeof test.getElementByID != 'undefined') { clonedSelection = range.cloneContents().getElementById(id); } if (clonedSelection) { selText = clonedSelection.innerHTML; } else { clonedSelection = range.cloneContents(); var startNode = sel.getRangeAt(0).startContainer.parentNode; //console.log(modIsChild(startNode, forkfork)); if (modIsChild(startNode, forkfork)) { var div = document.createElement('div'); div.appendChild(clonedSelection); selText = div.innerHTML; } } } return selText.toString(); } function modIsChild(child, parent) { if (child === parent) return true; var current = child; while (current) { if (current === parent) return true; current = current.parentNode; } return false; } return { InitEditor: function ( id, bodyType, draftid, groupurl, csrf, handleAttachments, noFontChanges, isReply, isWiki, body, sig, onInitFunc ) { if (typeof onInitFunc === 'undefined') { onInitFunc = null; } document.body.addEventListener('htmx:beforeSwap', modDestroyAllEditors, {once: true}); modDeletedDraft = false; modDestroyedEditor = false; modUnloading = false; $('#preview' + id).hide(); $('#addattachments' + id).hide(); $('#return' + id).hide(); $('#markdownlink' + id).hide(); if (bodyType == 'html') { if (sig != '') { $('#editor' + id).val(sig); //tinyMCE.get('editor'+id).setContent(sig); } editor.initHTMLEditor( id, draftid, groupurl, csrf, handleAttachments, noFontChanges, isReply, isWiki, body, sig, onInitFunc ); } else { if (sig != '') { $('#editor' + id).val(sig); } editor.initPlainEditor(id, bodyType, groupurl, handleAttachments, sig); } }, initHTMLEditor: function ( id, draftid, groupurl, csrf, handleAttachments, noFontChanges, isReply, isWiki, body, sig, onInitFunc ) { if (typeof onInitFunc === 'undefined') { onInitFunc = null; } // extras: print, emoticons, image, insert, media, print /* All plugins: 'advlist autolink lists link image print preview hr anchor pagebreak', 'searchreplace wordcount visualblocks visualchars code fullscreen', 'insertdatetime media nonbreaking save table contextmenu directionality', 'emoticons template paste textcolor colorpicker textpattern imagetools codesample toc' */ modDeletedDraft = false; modDestroyedEditor = false; modUnloading = false; let attachments = ''; if (handleAttachments == 0 || handleAttachments == 3) { attachments = ' addPictures addAttachments'; } let fontchanges = ''; if (noFontChanges == false) { fontchanges = ' fontselect fontsizeselect forecolor backcolor'; } let fontawesome = ' charmap'; let forceRootBlock = false; if (isWiki == true) { attachments += ' addWikiImage addWikiLink addWikiTOC'; fontawesome = ' fontawesome'; // BORK fontawesome = ''; forceRootBlock = 'p'; } let toolbar1 = 'styleselect bold italic bullist numlist link blockquote alignleft aligncenter alignright' + attachments + ' advancedToolbar'; let toolbar2 = 'strikethrough underline hr alignjustify' + fontchanges + ' removeformat' + fontawesome + ' outdent indent undo redo preview code'; let small_toolbar1 = 'bold italic link blockquote' + attachments + ' advancedToolbar'; let small_toolbar2 = 'strikethrough underline hr alignjustify removeformat outdent indent'; let tm_fonts = 'Arial=arial,helvetica,sans-serif;' + 'Arial Black=arial black,avant garde;' + 'Comic Sans MS=comic sans ms;' + 'Courier Neue=courier_newregular,courier;' + 'Helvetica Neue=helvetica neue;' + 'Helvetica=helvetica;' + 'Impact=impactregular,chicago;' + 'Lucida Grande=lucida grande;' + 'Tahoma=tahoma,arial,helvetica,sans-serif;' + 'Times New Roman=times new roman,times;' + 'Verdana=verdana,geneva'; let plugins = [ 'SplitBlockquote', 'advlist autolink lists link image preview hr anchor', 'code fullscreen', 'nonbreaking table charmap', 'textcolor colorpicker imagetools noneditable' ]; let css = '/bootstrap/3.3.6/css/bootstrap.min.css,/bootstrap/3.3.6/css/bootstrap-theme.min.css,/css/groupsio.css,/css/tinymce.css,/fontawesome/all.min.css'; let fontsizes = '8pt 10pt 11pt 12pt 14pt 18pt 24pt 36pt'; let codesample_languages = [ { text: 'C', value: 'c' }, { text: 'C#', value: 'csharp' }, { text: 'C++', value: 'cpp' }, { text: 'CSS', value: 'css' }, { text: 'Go', value: 'go' }, { text: 'HTML/XML', value: 'markup' }, { text: 'Java', value: 'java' }, { text: 'JavaScript', value: 'javascript' }, { text: 'PHP', value: 'php' }, { text: 'Python', value: 'python' }, { text: 'Ruby', value: 'ruby' } ]; let style_formats = [ { title: 'Paragraph', block: 'p' }, { title: 'Header 1', block: 'h1' }, { title: 'Header 2', block: 'h2' }, { title: 'Header 3', block: 'h3' }, { title: 'Header 4', block: 'h4' }, { title: 'Header 5', block: 'h5' }, { title: 'Header 6', block: 'h6' } ]; if (isReply == true) { toolbar1 = 'quoteMessage ' + toolbar1; small_toolbar1 = 'quoteMessage ' + small_toolbar1; } if (document.documentElement.clientWidth > 1000) { tinymce.init({ noneditable_noneditable_class: 'fa', extended_valid_elements: 'span[*]', branding: false, link_context_toolbar: true, default_link_target: '_blank', link_assume_external_targets: true, elementpath: false, forced_root_block: forceRootBlock, content_css: css, relative_urls: false, remove_script_host: false, menubar: false, statusbar: true, plugins: plugins, toolbar1: toolbar1, toolbar2: toolbar2, font_formats: tm_fonts, browser_spellcheck: true, contextmenu: false, selector: '#editor' + id, resize: true, fontsize_formats: fontsizes, style_formats: style_formats, setup: function (teditor) { teditor.on('Init', function (e) { // see if any text is selected toquote = modGetSelection(id); if (toquote != '') { console.log('id=' + id); editor.ShowMessageHistory(id, groupurl, 'html', toquote, sig, true); } else { if (body != "") { console.log("body setContent"); teditor.setContent(body); } else if (sig != "") { console.log("sig setContent " + sig); teditor.setContent(sig); } } if (onInitFunc != null) { onInitFunc(e); } }); teditor.on('BeforeRenderUI', function (e) { teditor.theme.panel .find('toolbar') .slice(1) .hide(); }); teditor.addButton('advancedToolbar', { tooltip: 'Show advanced toolbar', icon: 'fa fa-bars', onclick: function () { if (!this.active()) { this.active(true); teditor.theme.panel .find('toolbar') .slice(1) .show(); } else { this.active(false); teditor.theme.panel .find('toolbar') .slice(1) .hide(); } } }); teditor.addButton('addPictures', { tooltip: 'Add pictures', icon: 'fa fa-image', onclick: function () { modUploaderPrompt("pictures", id, draftid, groupurl, csrf); } }); teditor.addButton('addAttachments', { tooltip: 'Add attachments', icon: 'fa fa-paperclip', onclick: function () { modUploaderPrompt("attachments", id, draftid, groupurl, csrf); } }); if (groupurl != '') { teditor.addButton('quoteMessage', { tooltip: 'Quote post', icon: 'fa fa-comment', onclick: function () { editor.ShowMessageHistory(id, groupurl, 'html', '', sig, false); } }); } if (draftid != '' && draftid != '0' && draftid != 0) { teditor.on('NodeChange', function () { //tinymce.triggerSave(); if (tinymce.activeEditor != null) { let markupStr = tinymce.activeEditor.getContent(); $('#editor' + id).val(markupStr); modOnFormChange(id, draftid, groupurl, csrf); } }); teditor.on('keyup', function () { //tinymce.triggerSave(); let markupStr = tinymce.activeEditor.getContent(); $('#editor' + id).val(markupStr); modOnFormChange(id, draftid, groupurl, csrf); }); } if (isWiki == true) { // special wiki buttons teditor.addButton('addWikiImage', { tooltip: 'Insert image', icon: 'fa fa-image', onclick: function () { $('#ImageModal').modal({}); } }); teditor.addButton('addWikiLink', { tooltip: 'Insert link to wiki page', icon: 'fa fa-book', onclick: function () { $('#LinkModal').modal({}); } }); teditor.addButton('addWikiTOC', { tooltip: 'Insert table of contents', icon: 'fa fa-list-alt', onclick: function () { $('#TOCModal').modal({}); } }); } } }); } else { tinymce.init({ branding: false, link_context_toolbar: true, default_link_target: '_blank', link_assume_external_targets: true, elementpath: false, forced_root_block: forceRootBlock, content_css: css, relative_urls: false, remove_script_host: false, menubar: false, statusbar: true, plugins: plugins, toolbar1: small_toolbar1, toolbar2: small_toolbar2, font_formats: tm_fonts, browser_spellcheck: true, contextmenu: false, selector: '#editor' + id, resize: true, fontsize_formats: fontsizes, style_formats: style_formats, setup: function (teditor) { teditor.on('Init', function (e) { // see if any text is selected toquote = modGetSelection(id); if (toquote != '') { console.log('id=' + id); editor.ShowMessageHistory(id, groupurl, 'html', toquote, sig, true); } else { if (body != "") { console.log("body setContent"); teditor.setContent(body); } else if (sig != "") { console.log("sig setContent" + sig); teditor.setContent(sig); } } if (onInitFunc != null) { onInitFunc(e); } }); teditor.on('BeforeRenderUI', function (e) { teditor.theme.panel .find('toolbar') .slice(1) .hide(); }); teditor.addButton('advancedToolbar', { tooltip: 'Show advanced toolbar', icon: 'fa fa-bars', onclick: function () { if (!this.active()) { this.active(true); teditor.theme.panel .find('toolbar') .slice(1) .show(); } else { this.active(false); teditor.theme.panel .find('toolbar') .slice(1) .hide(); } } }); teditor.addButton('addPictures', { tooltip: 'Add pictures', icon: 'fa fa-image', onclick: function () { modUploaderPrompt("pictures", id, draftid, groupurl, csrf); } }); teditor.addButton('addAttachments', { tooltip: 'Add attachments', icon: 'fa fa-paperclip', onclick: function () { modUploaderPrompt("attachments", id, draftid, groupurl, csrf); } }); if (groupurl != '') { teditor.addButton('quoteMessage', { tooltip: 'Quote post', icon: 'fa fa-comment', onclick: function () { editor.ShowMessageHistory(id, groupurl, 'html', '', sig, false); } }); } if (draftid != '' && draftid != '0' && draftid != 0) { teditor.on('NodeChange', function () { if (tinymce.activeEditor != null) { //tinymce.triggerSave(); let markupStr = tinymce.activeEditor.getContent(); $('#editor' + id).val(markupStr); modOnFormChange(id, draftid, groupurl, csrf); } }); teditor.on('keyup', function () { //tinymce.triggerSave(); let markupStr = tinymce.activeEditor.getContent(); $('#editor' + id).val(markupStr); modOnFormChange(id, draftid, groupurl, csrf); }); } // special wiki buttons teditor.addButton('addWikiImage', { tooltip: 'Add Image', icon: 'fa fa-image', onclick: function () { $('#ImageModal').modal({}); } }); teditor.addButton('addWikiLink', { tooltip: 'Add Link', icon: 'fa fa-book', onclick: function () { $('#LinkModal').modal({}); } }); teditor.addButton('addWikiTOC', { tooltip: 'Table of Contents', icon: 'fa fa-list-alt', onclick: function () { $('#TOCModal').modal({}); } }); } }); // disable tooltips because they require double taps on mobile $('.note-editor *').tooltip('disable'); } }, initPlainEditor: function (id, bodyType, groupurl, handleAttachments, sig) { $('#addattachments').show(); if (bodyType == 'plain') { $('#bodytype' + id).val('plain'); $('#preview' + id).hide(); $('#return' + id).hide(); $('#preview' + id).hide(); $('#markdownlink' + id).hide(); } else { $('#bodytype' + id).val('markdown'); $('#markdownbuttons' + id).show(); $('#preview' + id).show(); $('#return' + id).hide(); $('#previewWindow' + id).hide(); $('#markdownlink' + id).show(); } toquote = modGetSelection(id); if (toquote != '') { editor.ShowMessageHistory(id, groupurl, 'plain', toquote, sig, true); //$('#editor' + id).val(toquote); } }, InitPostDraft: function (id, draftid, csrf, groupurl) { // save the draft when leaving the page. $(window).on('beforeunload', function () { modUnloading = true; modSaveDraft(id, draftid, groupurl, csrf, true); }); // save the draft 1 second after a change $('form input, form textarea').on('input propertychange change', function () { modOnFormChange(id, draftid, groupurl, csrf); }); modUpdateAttachments(id, draftid, csrf, groupurl); if (typeof Capacitor !== 'undefined') { modInitDeviceUploader(id, draftid, csrf, groupurl); } else { modInitWebUploader(id, draftid, csrf, groupurl); } }, // InitReplyDraft creates a new draft, assumes a hidden form input called #draftidmid, and then calls initWindow(). InitReplyDraft: function ( id, bodytype, draftid, groupurl, csrf, handleAttachments, noFontChanges, isReply, isWiki, body, sig, onInitFunc ) { console.log('in InitReplyDraft draftid=' + draftid); modDeletedDraft = false; modDestroyedEditor = false; modUnloading = false; if (draftid == 0) { // create a new draft console.log('generating new draft' + groupurl); console.log('id=' + id); upload = { mid: id, csrf: csrf, body: sig }; $.ajax({ url: groupurl + '/reply', cache: false, method: 'POST', data: upload, xhrFields: { withCredentials: true }, dataType: 'json', error: function (xhr, ajaxOptions, thrownError) { if (modDeletedDraft == false && modDestroyedEditor == false) { createAlert("There was an error saving the draft. Please reload the page.", true, false) } } }).done(function (response) { console.log('reply draft created'); console.log('draftid:' + response.DraftID); draftid = response.DraftID; $('#draftid' + id).val(response.DraftID); editor.InitEditor( id, bodytype, draftid, groupurl, csrf, handleAttachments, noFontChanges, true, false, body, sig, onInitFunc ); editor.InitPostDraft(id, draftid, csrf, groupurl); console.log('id=' + id); $('#bodytype' + id).val(bodytype); $('#cancel-' + id).attr( 'onclick', 'editor.discardReplyDraft("' + id + '", "' + draftid + '","' + bodytype + '","' + csrf + '","' + groupurl + '");' ); return; }); return; } editor.InitEditor( id, bodytype, draftid, groupurl, csrf, handleAttachments, noFontChanges, true, false, body, sig, onInitFunc ); editor.InitPostDraft(id, draftid, csrf, groupurl); $('#bodytype' + id).val(bodytype); $('#cancel-' + id).attr( 'onclick', 'editor.discardReplyDraft("' + id + '", "' + draftid + '","' + bodytype + '","' + csrf + '","' + groupurl + '");' ); console.log('DONE'); }, // discardReplyDraft deletes the draft and any attachments and returns the user to the previous page. discardReplyDraft: function (id, draftid, bodytype, csrf, groupurl) { console.log('editor delete reply draft'); upload = { draftid: draftid, csrf: csrf, jsondelete: '1' }; $.ajax({ url: groupurl + '/draftop', cache: false, data: upload, method: 'POST', xhrFields: { withCredentials: true }, dataType: 'json' }).done(function (response) { // Do something with the request console.log("success delete reply draft"); $('#draftid' + id).val(''); if (bodytype == 'html') { tinymce.get('editor' + id).remove(); } $('#subject' + id).val($('#origsubject' + id).val()); $('#editor' + id).val(''); modDeletedDraft = true; modDestroyedEditor = true; }); }, PreviewMarkdown: function (id, groupurl) { let markdown = $('#editor' + id).val(); upload = { md: markdown }; $.ajax({ url: groupurl + '/previewmd', cache: false, data: upload, method: 'POST', xhrFields: { withCredentials: true }, dataType: 'json' }).done(function (response) { // Do something with the request console.log(response.markdown); wrap = '
' + response.markdown + '
'; $('#editwindow' + id).hide(); $('#previewWindow' + id).replaceWith(wrap); $('#previewWindow' + id).show(); }); $('#preview' + id).hide(); $('#return' + id).show(); }, ReturnMarkdown: function (id) { $('#preview' + id).show(); $('#return' + id).hide(); $('#previewWindow' + id).hide(); $('#editwindow' + id).show(); }, ClearTimeout: function() { clearTimeout(modTimeoutId); }, ShowMessageHistory: function( id, groupurl, bodytype, selectedText, sig, firstTime ) { console.log('URL ' + groupurl); console.log('ID ' + id); if (bodytype == 'html' && firstTime == false) { existingmsg = tinyMCE.get('editor' + id).getContent(); } else { existingmsg = $('#editor' + id).val(); } if (selectedText == '') { upload = { preview: bodytype, id: id }; } else { upload = { preview: bodytype, id: id, text: selectedText }; if (firstTime == true) { existingmsg = sig; } } $.ajax({ url: groupurl + '/previewmd', cache: false, data: upload, method: 'POST', xhrFields: { withCredentials: true }, dataType: 'json' }).done(function (response) { $('#editor' + id).val(response.reply + existingmsg); if (bodytype == 'html') { console.log('SETTING ' + response.reply + existingmsg); tinyMCE.get('editor' + id).setContent(response.reply + existingmsg); tinyMCE.get('editor' + id).selection.select(tinyMCE.get('editor' + id).getBody(), true); tinyMCE.get('editor' + id).selection.collapse(false); console.log('DONE'); } }); $('#editor' + id).focus(); } /* $('form').submit(function(e) { clearTimeout(modTimeoutId); if (postVar != null) { postVar.abort(); } console.log("SETTING DELETED TO TRUE"); console.log("EVENT:", e); modDeletedDraft = true; if ($(this).hasClass('form-submitted')) { e.preventDefault(); return; } $(this).addClass('form-submitted'); }); */ };}());async function uploadAttachments(doctype, id, draftid, groupurl, csrf) { const result = await Capacitor.Plugins.FilePicker.pickFiles(); const file = result.files[0]; console.log("in uploadAttachments"); console.log("files:", result.files); console.log("mimeType:", file.mimeType); console.log("name:", file.name); console.log("doctype:", doctype);const b64toBlob = (base64, type = 'image/jpeg') => fetch(`data:${type};base64,${base64}`).then(res => res.blob());const result2 = await Capacitor.Plugins.Filesystem.readFile({path:file.path})console.log("result2: ", result2);const blob = await b64toBlob(result2.data, file.mimeType);console.log("in uploadAttachments 2, " + file.mimeType); uploadImage(doctype, id, draftid, groupurl, csrf, blob, file.name);}async function takePicture2(doctype, id, draftid, groupurl, csrf) { console.log("in takePicture2"); try { const image = await Capacitor.Plugins.Camera.getPhoto({ quality: 90, allowEditing: false, resultType: "uri" }); console.log("got image");const b64toBlob = (base64, type = 'image/jpeg') => fetch(`data:${type};base64,${base64}`).then(res => res.blob());const result = await Capacitor.Plugins.Filesystem.readFile({path:image.path})const blob = await b64toBlob(result.data);console.log("path: ", image.path); uploadImage(doctype, id, draftid, groupurl, csrf, blob, image.path.split("/").pop()); } catch (err) { console.log("catch err 1: ", err); }}async function uploadImage(doctype, id, draftid, groupurl, csrf, raw, name) { console.log("here0"); const controller = new AbortController(); const formData = new FormData(); console.log("here1"); formData.append("csrf", csrf); formData.append("draftid", draftid); formData.append("upload", "1"); if (doctype === "pictures") { formData.append("inline", "1"); } console.log("FORMDATA:", formData); formData.append("fileupload", raw, name); console.log("here3"); const myRequest = new Request(groupurl + '/draftop', { method: 'POST', credentials: 'include', body: formData, signal: controller.signal, mode: 'cors' }); console.log("uploading"); try { const response = await fetch(myRequest); const result = await response.json(); if (doctype === "pictures") { console.log("picture processing"); for (let i = result.length - 1; i >= 0; i--) { console.log("Processing: ", i); const fileurl = result[i]; console.log('FILE: ' + result[i]); console.log('URL: ' + fileurl); const imghtml = ''; console.log('imghtml: ' + imghtml); tinymce.activeEditor.insertContent(imghtml); } } else { console.log("attachment processing"); updateAttachments(id, draftid, csrf, groupurl); console.log("attachment processing done"); } } catch (error) { console.error('Error:', error); }}
- SDRPlayUsers
- Topics
Search
DateDate1 - 20 of 24
Command line decoder for NRSC5 (aka HD Radio here in the US) now available for SDRplay RSPs#rsp
Franco Venturi
#3536 I ported the command line decoder for NRSC5 to use the SDRplay RSPs directly via the SDRplay API driver version 3.X For those not familiar with NRSC5, it is the standard adopted by the FCC for digital commercial broadcasting in the FM band here in the US (and I think on AM too, although I am not very familiar with it): it is commonly known here as 'HD Radio'. The code, along with precompiled binaries for Windows (32 and 64 bit) and MacOS, is here: https://github.com/fventuri/nrsc5 A few important notes: I hope you have fun playing with it! |
Bob Dengler
#3537 At 6/5/2021 01:24 PM, you wrote: I ported the command line decoder for NRSC5 to use the SDRplay RSPs directly via the SDRplay API driver version 3.X Zip file is password protected. Bob NO6B |
Franco Venturi
#3539 Bob, Since those licenses (which I had to include because of the precompiled binary distribution) are long here is just the beginning and end of it: GNU GENERAL PUBLIC LICENSE 73, |
Bob Dengler
#3541 At 6/5/2021 06:30 PM, you wrote: Bob, Thanks Franco. Works great! I used to use the RTL-SDR version until I lost my Nooelec SDR, so this lets me listen to HD FM again. Bob NO6B |
j.vankatwjk
#3542 Interesting, Is there somewhere a reasonable (technical) description of HD Radio, is it e.g. (more or less) similar to what DAB or DRM+ is using? best jan Op za 5 jun. 2021 om 22:56 schreef Franco Venturi <fventuri@...>: toggle quoted messageShow quoted text I ported the command line decoder for NRSC5 to use the SDRplay RSPs directly via the SDRplay API driver version 3.X -- Jan van Katwijk |
Franco Venturi
#3543 Jan, You'll notice that the NRSC-5 standard specifies modulation, error correction, channel coding, interleaving, etc, but does not say how the audio streams should be encoded; that is left to the implementer. In the US the implementer is Ibiquity (https://en.wikipedia.org/wiki/IBiquity); if you are in the US and have a car radio that can listen to HD Radio you usually see their logo next to the words 'HD Radio'. The significant thing about the work from theori.io is that they figured out that the HD Radio audio stream codec is just a slightly modified version of HE-AAC - their research is documented in this very interesting post that I recommend: https://blog.theori.io/research/nrsc-5-c/ As you noticed, NRSC-5 and DAB+ are kind of 'cousins', since they both use COFDM for their modulation and their codecs are AAC+ and a derivative of HE-AAC - the Wikipedia page on HD Radio (https://en.wikipedia.org/wiki/HD_Radio) is another very interesting read, and has a section where they compare HD radio with DAB/DAB+ and with DRM. Finally I forgot yesterday to mention that for those who prefer a graphic UI instead of a command line interface, there are at least two programs that I know of that offer a GUI to control the same command line nsrc5 decoder, and therefore should work with this version too (but I haven't tried them): - NRSC5-DUI: https://www.rtl-sdr.com/nrsc5-dui-an-updated-nrsc-5-hd-radio-decoder-for-rtl-sdr - yellowShoes: https://www.rtl-sdr.com/yellowshoes-a-browser-based-hd-radio-nrsc-5-user-interface/ Franco - K4VZ |
j.vankatwjk
#3545 Franco, Thanks for the links, very interesting! Here in Europe we are moving slowly - but steadily - towards DAB+, In Norway FM is completely abandoned and DAB is the system of choice. DAB+ here in the Netherlands is typically implemented as Single Frequency Network; with a small antenna I receive in some channels simultaneously data from 4 to 5 transmitters, most of them 10 to 20 Km away. I have written a DAB/DAB+ decoder for use on PC (Linux and Windows) and RPI (Qt-DAB) Variants are a library with some command line examples, one with an extensive GUI and one with a minimal GUI, As an experiments - basically a gadget - the Qt-DAB software -usng a Adalm Pluto device - the audio from a selected audio service is retransmitted as an FM signal. I also wrote some software for DRM and DRM+, there are not much DRM transmission here, but technique is interesting. I even wrote a plugin for SDRuno for running DRM (not officially released though). I do not know about HDRadio, but for DRM one needs a reasonable signal, I get transmissions from Romenia (2000 Km( abd usually there is quite some fading and signal loss I'll study both the standard and the implementation for HDRadio, thanks for the effort best jan Op zo 6 jun. 2021 om 15:46 schreef Franco Venturi <fventuri@...>: toggle quoted messageShow quoted text Jan, -- Jan van Katwijk |
W4RLS
#3554 Thanks, Franco. This is really cool. It's also very light on CPU usage. Bob, W4RLS |
HB
#3560 Thanks Franco!!! I have several HD radio stations in my area. 2 comments - the software still needs a password after download from github for Windows. - 2nd, the instructions there indicate the syntax to start the software is 'nrs5-64 89.9 0' - it should read nrsc5-64 89.9 0 Thanks again! |
Franco Venturi
#3569 Hank, thanks for your kind words. The files with the binary builds for Windows 32, Windows 64, and MacOS contain a non-encrypted header with the licenses that begins and ends like this: GNU GENERAL PUBLIC LICENSE I had to add that because the FAAD2 decoder used to decode the audio streams has a license (see here: https://en.wikipedia.org/wiki/FAAC#Licensing), that I think may require to be accepted explicitly when built into a binary. Also thanks for noticing the typos in the README file; they are fixed now. 73, |
@KC2TAU
#5214 I'm having a bit of difficulty using this program under Windows 10. Each time I attempt to launch the program from a command line it returns the error of: "'nrsc-64' is not recognized as an internal or external command, I've made sure that the executable is in my PATH. I'm a bit confused as to why I am receiving this error. Any help would be greatly appreciated. Thank you. |
Franco Venturi
#5216 I think the program is called 'nrsc5-64', not 'nrsc-64'. Franco |
@KC2TAU
#5217 Hello Franco, Thank you! I have it working now. I have one question about one of the arguments. When using the -g argument for determining the gain of the SDR when you have an SDRPlay receiver is the correct way to write it "-g IFGR=0"? I keep receiving an error of "invalid gain" when I try to type it this way. |
Jon Hudson
#5219 For anyone interested in NRSC5, this video demonstrates HD Radio decoding if you wind forward to 18 minutes 20 seconds:https://youtu.be/jMYUvOPHwno |
Franco Venturi
#5222 Jon, thanks for the link to the video! KC2TAU, 73, |
Rob Keeney
#5565 Hi Franco, I'm getting c:\HDdecoder nrsc5-64 97.1 0 06:45:11 Open device failed. running with RSPDuo. I've copied the API dll 3.09 into the HDdecoder dir and restarted the machine. Any ideas on this? Thanks, |
Franco Venturi
#5568 Rob, You can find the zips with the updated binaries here: https://github.com/fventuri/nrsc5/releases/tag/v0.1.1 Hope it works for you too, |
Rob Keeney
#5569 Hi Franco, I downloaded the new zip for Windows 64 bit, but I'm still getting the same "Open device failed." message. I'm not running any plugins, RDS or anything else. Thanks, |
Randy-W4LKS
#5574 Those zip files appear to be password protected. Can you give me a hint? Randy On 3/29/2022 6:36 AM, Franco Venturi wrote: toggle quoted messageShow quoted text Rob, |
Franco Venturi
#5580 @Rob: sorry for answering you only now, but I had a very busy day at work. @Randy: the password is 'accept all licenses' - please see this post https://groups.io/g/SDRPlayUsers/message/3569 for further details. Franco |
1 - 20 of 24 |
|
Previous TopicNext Topic