Search Results

Search found 6580 results on 264 pages for 'require'.

Page 264/264 | < Previous Page | 260 261 262 263 264 

  • c# Truncate HTML safely for article summary

    - by WickedW
    Hi All, Does anyone have a c# variation of this? This is so I can take some html and display it without breaking as a summary lead in to an article? http://stackoverflow.com/questions/1193500/php-truncate-html-ignoring-tags Save me from reinventing the wheel! Thank you very much ---------- edit ------------------ Sorry, new here, and your right, should have phrased the question better, heres a bit more info I wish to take a html string and truncate it to a set number of words (or even char length) so I can then show the start of it as a summary (which then leads to the main article). I wish to preserve the html so I can show the links etc in preview. The main issue I have to solve is the fact that we may well end up with unclosed html tags if we truncate in the middle of 1 or more tags! The idea I have for solution is to a) truncate the html to N words (words better but chars ok) first (be sure not to stop in the middle of a tag and truncate a require attribute) b) work through the opened html tags in this truncated string (maybe stick them on stack as I go?) c) then work through the closing tags and ensure they match the ones on stack as I pop them off? d) if any open tags left on stack after this, then write them to end of truncated string and html should be good to go!!!! -- edit 12112009 Here is what I have bumbled together so far as a unittest file in VS2008, this 'may' help someone in future My hack attempts based on Jan code are at top for char version + word version (DISCLAIMER: this is dirty rough code!! on my part) I assume working with 'well-formed' HTML in all cases (but not necessarily a full document with a root node as per XML version) Abels XML version is at bottom, but not yet got round to fully getting tests to run on this yet (plus need to understand the code) ... I will update when I get chance to refine having trouble with posting code? is there no upload facility on stack? Thanks for all comments :) using System; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Xml; using System.Xml.XPath; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace PINET40TestProject { [TestClass] public class UtilityUnitTest { public static string TruncateHTMLSafeishChar(string text, int charCount) { bool inTag = false; int cntr = 0; int cntrContent = 0; // loop through html, counting only viewable content foreach (Char c in text) { if (cntrContent == charCount) break; cntr++; if (c == '<') { inTag = true; continue; } if (c == '>') { inTag = false; continue; } if (!inTag) cntrContent++; } string substr = text.Substring(0, cntr); //search for nonclosed tags MatchCollection openedTags = new Regex("<[^/](.|\n)*?>").Matches(substr); MatchCollection closedTags = new Regex("<[/](.|\n)*?>").Matches(substr); // create stack Stack<string> opentagsStack = new Stack<string>(); Stack<string> closedtagsStack = new Stack<string>(); // to be honest, this seemed like a good idea then I got lost along the way // so logic is probably hanging by a thread!! foreach (Match tag in openedTags) { string openedtag = tag.Value.Substring(1, tag.Value.Length - 2); // strip any attributes, sure we can use regex for this! if (openedtag.IndexOf(" ") >= 0) { openedtag = openedtag.Substring(0, openedtag.IndexOf(" ")); } // ignore brs as self-closed if (openedtag.Trim() != "br") { opentagsStack.Push(openedtag); } } foreach (Match tag in closedTags) { string closedtag = tag.Value.Substring(2, tag.Value.Length - 3); closedtagsStack.Push(closedtag); } if (closedtagsStack.Count < opentagsStack.Count) { while (opentagsStack.Count > 0) { string tagstr = opentagsStack.Pop(); if (closedtagsStack.Count == 0 || tagstr != closedtagsStack.Peek()) { substr += "</" + tagstr + ">"; } else { closedtagsStack.Pop(); } } } return substr; } public static string TruncateHTMLSafeishWord(string text, int wordCount) { bool inTag = false; int cntr = 0; int cntrWords = 0; Char lastc = ' '; // loop through html, counting only viewable content foreach (Char c in text) { if (cntrWords == wordCount) break; cntr++; if (c == '<') { inTag = true; continue; } if (c == '>') { inTag = false; continue; } if (!inTag) { // do not count double spaces, and a space not in a tag counts as a word if (c == 32 && lastc != 32) cntrWords++; } } string substr = text.Substring(0, cntr) + " ..."; //search for nonclosed tags MatchCollection openedTags = new Regex("<[^/](.|\n)*?>").Matches(substr); MatchCollection closedTags = new Regex("<[/](.|\n)*?>").Matches(substr); // create stack Stack<string> opentagsStack = new Stack<string>(); Stack<string> closedtagsStack = new Stack<string>(); foreach (Match tag in openedTags) { string openedtag = tag.Value.Substring(1, tag.Value.Length - 2); // strip any attributes, sure we can use regex for this! if (openedtag.IndexOf(" ") >= 0) { openedtag = openedtag.Substring(0, openedtag.IndexOf(" ")); } // ignore brs as self-closed if (openedtag.Trim() != "br") { opentagsStack.Push(openedtag); } } foreach (Match tag in closedTags) { string closedtag = tag.Value.Substring(2, tag.Value.Length - 3); closedtagsStack.Push(closedtag); } if (closedtagsStack.Count < opentagsStack.Count) { while (opentagsStack.Count > 0) { string tagstr = opentagsStack.Pop(); if (closedtagsStack.Count == 0 || tagstr != closedtagsStack.Peek()) { substr += "</" + tagstr + ">"; } else { closedtagsStack.Pop(); } } } return substr; } public static string TruncateHTMLSafeishCharXML(string text, int charCount) { // your data, probably comes from somewhere, or as params to a methodint XmlDocument xml = new XmlDocument(); xml.LoadXml(text); // create a navigator, this is our primary tool XPathNavigator navigator = xml.CreateNavigator(); XPathNavigator breakPoint = null; // find the text node we need: while (navigator.MoveToFollowing(XPathNodeType.Text)) { string lastText = navigator.Value.Substring(0, Math.Min(charCount, navigator.Value.Length)); charCount -= navigator.Value.Length; if (charCount <= 0) { // truncate the last text. Here goes your "search word boundary" code: navigator.SetValue(lastText); breakPoint = navigator.Clone(); break; } } // first remove text nodes, because Microsoft unfortunately merges them without asking while (navigator.MoveToFollowing(XPathNodeType.Text)) { if (navigator.ComparePosition(breakPoint) == XmlNodeOrder.After) { navigator.DeleteSelf(); } } // moves to parent, then move the rest navigator.MoveTo(breakPoint); while (navigator.MoveToFollowing(XPathNodeType.Element)) { if (navigator.ComparePosition(breakPoint) == XmlNodeOrder.After) { navigator.DeleteSelf(); } } // moves to parent // then remove *all* empty nodes to clean up (not necessary): // TODO, add empty elements like <br />, <img /> as exclusion navigator.MoveToRoot(); while (navigator.MoveToFollowing(XPathNodeType.Element)) { while (!navigator.HasChildren && (navigator.Value ?? "").Trim() == "") { navigator.DeleteSelf(); } } // moves to parent navigator.MoveToRoot(); return navigator.InnerXml; } [TestMethod] public void TestTruncateHTMLSafeish() { // Case where we just make it to start of HREF (so effectively an empty link) // 'simple' nested none attributed tags Assert.AreEqual(@"<h1>1234</h1><b><i>56789</i>012</b>", TruncateHTMLSafeishChar( @"<h1>1234</h1><b><i>56789</i>012345</b>", 12)); // In middle of a! Assert.AreEqual(@"<h1>1234</h1><a href=""testurl""><b>567</b></a>", TruncateHTMLSafeishChar( @"<h1>1234</h1><a href=""testurl""><b>5678</b></a><i><strong>some italic nested in string</strong></i>", 7)); // more Assert.AreEqual(@"<div><b><i><strong>1</strong></i></b></div>", TruncateHTMLSafeishChar( @"<div><b><i><strong>12</strong></i></b></div>", 1)); // br Assert.AreEqual(@"<h1>1 3 5</h1><br />6", TruncateHTMLSafeishChar( @"<h1>1 3 5</h1><br />678<br />", 6)); } [TestMethod] public void TestTruncateHTMLSafeishWord() { // zero case Assert.AreEqual(@" ...", TruncateHTMLSafeishWord( @"", 5)); // 'simple' nested none attributed tags Assert.AreEqual(@"<h1>one two <br /></h1><b><i>three ...</i></b>", TruncateHTMLSafeishWord( @"<h1>one two <br /></h1><b><i>three </i>four</b>", 3), "we have added ' ...' to end of summary"); // In middle of a! Assert.AreEqual(@"<h1>one two three </h1><a href=""testurl""><b class=""mrclass"">four ...</b></a>", TruncateHTMLSafeishWord( @"<h1>one two three </h1><a href=""testurl""><b class=""mrclass"">four five </b></a><i><strong>some italic nested in string</strong></i>", 4)); // start of h1 Assert.AreEqual(@"<h1>one two three ...</h1>", TruncateHTMLSafeishWord( @"<h1>one two three </h1><a href=""testurl""><b>four five </b></a><i><strong>some italic nested in string</strong></i>", 3)); // more than words available Assert.AreEqual(@"<h1>one two three </h1><a href=""testurl""><b>four five </b></a><i><strong>some italic nested in string</strong></i> ...", TruncateHTMLSafeishWord( @"<h1>one two three </h1><a href=""testurl""><b>four five </b></a><i><strong>some italic nested in string</strong></i>", 99)); } [TestMethod] public void TestTruncateHTMLSafeishWordXML() { // zero case Assert.AreEqual(@" ...", TruncateHTMLSafeishWord( @"", 5)); // 'simple' nested none attributed tags string output = TruncateHTMLSafeishCharXML( @"<body><h1>one two </h1><b><i>three </i>four</b></body>", 13); Assert.AreEqual(@"<body>\r\n <h1>one two </h1>\r\n <b>\r\n <i>three</i>\r\n </b>\r\n</body>", output, "XML version, no ... yet and addeds '\r\n + spaces?' to format document"); // In middle of a! Assert.AreEqual(@"<h1>one two three </h1><a href=""testurl""><b class=""mrclass"">four ...</b></a>", TruncateHTMLSafeishCharXML( @"<body><h1>one two three </h1><a href=""testurl""><b class=""mrclass"">four five </b></a><i><strong>some italic nested in string</strong></i></body>", 4)); // start of h1 Assert.AreEqual(@"<h1>one two three ...</h1>", TruncateHTMLSafeishCharXML( @"<h1>one two three </h1><a href=""testurl""><b>four five </b></a><i><strong>some italic nested in string</strong></i>", 3)); // more than words available Assert.AreEqual(@"<h1>one two three </h1><a href=""testurl""><b>four five </b></a><i><strong>some italic nested in string</strong></i> ...", TruncateHTMLSafeishCharXML( @"<h1>one two three </h1><a href=""testurl""><b>four five </b></a><i><strong>some italic nested in string</strong></i>", 99)); } } }

    Read the article

  • racket scheme get-argb-pixels

    - by Giles Roberts
    I have a 32 by 32 pixel png file. I'm trying to read the values within it using get-argb-pixels. My code is as follows: #lang racket/gui (require racket/gui/base) (define floor (make-object bitmap% "C:\\floortile.png")) (define pixels (make-bytes (* 32 32 4))) (send floor get-argb-pixels 0 0 32 32 pixels) After executing the code I was expecting a series of 8 bit values to be contained within pixels. Examining pixels gives me the following output: > pixels #"\377\2148\30\377\214<\30\377\234E\30\377\245I\30\377\245I\30\377\234E\30\377\234A\30\377\224A\30\377\224A\30\377\234A\30\377\245E\30\377\255M\30\377\224A\30\377\234E\30\377\245I\30\377\224A\30\377\234E\30\377\234E\30\377\255I\30\377\245I\30\377\245E\30\377\234A\30\377\234E\30\377\234A\30\377\245I\30\377\265Q\30\377\306]\30\377\306Y\30\377\275U\30\377\265Q\30\377\306a!\377\306]!\377\214<\30\377\224A\30\377\224A\30\377\245I\30\377\255M\30\377\255M\30\377\245I\30\377\234E\30\377\234E\30\377\245I\30\377\245I\30\377\255M\30\377\234A\30\377\245E\30\377\265M\30\377\234A\30\377\245I\30\377\245E\30\377\245E\30\377\255M\30\377\245I\30\377\245E\30\377\234A\30\377\234E\30\377\255I\30\377\275U\30\377\306]\30\377\326e!\377\336e!\377\265Q\30\377\326e!\377\326a!\377{8\30\377\224E\30\377\224A\30\377\245I\30\377\245I\30\377\255M\30\377\255M\30\377\255I\30\377\245I\30\377\245I\30\377\245I\30\377\265Q\30\377\214<\30\377\245I\30\377\255M\30\377\265M\30\377\255M\30\377\265M\30\377\265M\30\377\245I\30\377\234E\30\377\234E\30\377\234E\30\377\245E\30\377\275Q\30\377\306]!\377\316a!\377\336i!\377\357q!\377\275Y\30\377\316e!\377\347i!\377k0\20\377\2048\30\377\224A\30\377\265U!\377\234E\30\377\234E\30\377\245M\30\377\255M\30\377\255M\30\377\255I\30\377\255M\30\377\265M\30\377\2048\20\377\245I\30\377\245I\30\377\306Y!\377\265Q\30\377\255M\30\377\265Q\30\377\265M\30\377\265M\30\377\255I\30\377\265Q\30\377\265M\30\377\275U\30\377\316a!\377\326i!\377\347m!\377\367\216)\377\347y)\377\336m)\377\326]!\377s0\20\377{8\30\377{4\20\377\2048\30\377s4\20\377\2048\30\377{4\20\377\214<\30\377\224A\30\377\234A\30\377\224A\30\377\224A\30\377\214<\30\377\2148\30\377\224<\30\377\234A\30\377\214<\30\377\234E\30\377\245I\30\377\265Q\30\377\255M\30\377\265U\30\377\306Y\30\377\265Q\30\377\275U\30\377\326a!\377\336i!\377\347u!\377\357\206)\377\326q)\377\326i)\377\347i!\377s0\20\377{4\20\377{4\30\377\214<\30\377s4\20\377\2048\30\377s4\20\377\224A\30\377\224A\30\377\224<\30\377\234A\30\377\245E\30\377\234E\30\377\234I\30\377\234E\30\377\245I\30\377\245I\30\377\245I\30\377\265Q\30\377\306]\30\377\255M\30\377\255M\30\377\255M\30\377\255M\30\377\275U\30\377\255M\30\377\275U\30\377\316a!\377\306]!\377\326i!\377\367\206)\377\377})\377s4\30\377k,\20\377k,\20\377s4\30\377{4\20\377\2048\30\377c(\20\377\2048\20\377\234A\30\377\245E\30\377\245E\30\377\255I\30\377\245I\30\377\245I\30\377\245I\30\377\265Q\30\377\275U!\377\255M\30\377\255M\30\377\255M\30\377\255M\30\377\275U\30\377\306]!\377\275U\30\377\255M\30\377\306Y!\377\306]!\377\316e!\377\316a!\377\326i!\377\347y)\377\367y)\377c(\20\377c,\20\377k,\20\377s0\20\377s4\20\377\2048\30\377\214<\30\377{4\20\377\214<\30\377\234E\30\377\234A\30\377\245I\30\377\255M\30\377\255M\30\377\255M\30\377\265Q\30\377\265M\30\377\265Q\30\377\265Q\30\377\255M\30\377\265U\30\377\255M\30\377\265Q\30\377\265U\30\377\265U\30\377\265Q\30\377\306Y\30\377\316a!\377\306a!\377\326i!\377\347y)\377\367\202)\377c,\20\377k,\20\377s0\20\377s0\20\377{8\30\377\214<\30\377s,\20\377s0\20\377\214<\30\377\234A\30\377\245E\30\377\255M\30\377\255M\30\377\245I\30\377\255M\30\377\275U\30\377\265U\30\377\265Q\30\377\265Q\30\377\275Y\30\377\255M\30\377\255I\30\377\275U\30\377\275Y!\377\275Y\30\377\265U\30\377\306Y!\377\326e!\377\336m!\377\336q!\377\347})\377\357\202)\377s0\20\377s4\30\377s4\30\377\2048\30\377\234E\30\377\2048\20\377\2148\30\377c(\20\377\2048\30\377\214<\30\377\234E\30\377\265Q\30\377\265Q\30\377\255M\30\377\265M\30\377\316a!\377\275U\30\377\275Y\30\377\265Q\30\377\265Q\30\377\265Q\30\377\265Q\30\377\255M\30\377\275Y\30\377\275Y!\377\275Y\30\377\275U\30\377\316a!\377\347q)\377\367\202)\377\357})\377\347y)\377k0\20\377\2048\30\377{4\30\377\2048\30\377\214A\30\377\2048\30\377\2044\30\377s4\20\377k,\20\377\2048\30\377\224A\30\377\245I\30\377\234A\30\377\234E\30\377\255Q\30\377\275U\30\377\306Y!\377\265Q\30\377\255Q\30\377\265U\30\377\265U\30\377\265Q\30\377\265Q\30\377\316e!\377\316a!\377\306]!\377\275Y!\377\306]!\377\336i!\377\357})\377\367\202)\377\336u)\377k0\20\377s0\30\377\2048\30\377\204<\30\377\204<\30\377\2048\30\377\2048\30\377\214<\30\377s4\20\377\2048\30\377\214A\30\377\224A\30\377\224E\30\377\234E\30\377\265Q\30\377\275U\30\377\306Y\30\377\255M\30\377\265Q\30\377\265Q\30\377\316]!\377\326e!\377\316]!\377\336m)\377\336i)\377\316e!\377\306a!\377\326e!\377\367y)\377\367})\377\367\2061\377\367\2061\377s4\30\377{8\30\377{8\30\377\214<\30\377\214<\30\377\204<\30\377{4\20\377\214<\30\377\214<\30\377\214<\30\377\234E\30\377\234E\30\377\224E\30\377\234E\30\377\245M\30\377\275U\30\377\275U!\377\275U\30\377\306]!\377\306]!\377\316a!\377\326i)\377\347u)\377\326e!\377\347q)\377\336q)\377\326i)\377\326i)\377\347q)\377\367\202)\377\367})\377\367\2061\377{8\30\377s4\30\377{8\30\377\214<\30\377\224A\30\377\234E\30\377\214<\30\377\214<\30\377\224A\30\377\224<\30\377\234E\30\377\255M\30\377\245I\30\377\245I\30\377\255M\30\377\265U\30\377\306]!\377\306]!\377\316a!\377\316e!\377\326e!\377\347m)\377\316e!\377\306]!\377\347u)\377\347u)\377\336m)\377\316e)\377\336q)\377\357y)\377\367\202)\377\367\2021\377{4\30\377s4\30\377\2048\30\377\214A\30\377\224A\30\377\224A\30\377\224E\30\377\214<\30\377\214<\30\377\245I\30\377\234A\30\377\255M\30\377\255M\30\377\245I\30\377\255M\30\377\255Q\30\377\306]!\377\306]!\377\316a!\377\316a!\377\316a!\377\347u)\377\326e!\377\275Y!\377\265Y!\377\336m)\377\306a)\377\336m)\377\336m)\377\326e)\377\347q)\377\336q)\377s0\30\377s0\30\377\204<\30\377\224A\30\377\224E\30\377\234I\30\377\234E\30\377\234E\30\377\255M\30\377\234E\30\377{4\30\377\224<\30\377\245M\30\377\255I\30\377\234A\30\377\255M\30\377\245E\30\377\255M\30\377\265Q\30\377\245I\30\377\275U\30\377\255I\30\377\234A\30\377\224E\30\377\265U\30\377\234I\30\377\224E\30\377\245M\30\377\234M!\377\224A\30\377\234I\30\377\224E\30\377k0\20\377s0\20\377{4\30\377\214<\30\377\224E\30\377\234E\30\377\245I\30\377\234I\30\377\245I\30\377\214<\30\377\214<\30\377\255M\30\377\265Q!\377\265Q!\377\255M\30\377\306]!\377\316a)\377\326e)\377\326a!\377\316]!\377\265Q\30\377\326a!\377\255M\30\377\204<\20\377\245M\30\377\234I\30\377\245M\30\377\275]!\377\234I\30\377\255U!\377\265Y!\377\245M!\377c(\20\377k,\20\377k0\20\377\2048\30\377\224A\30\377\224E\30\377\234I\30\377\245I\30\377\275Y!\377\234E\30\377\245I\30\377\245I\30\377\265U!\377\265Q!\377\265Q!\377\306]!\377\306]!\377\316a!\377\316a!\377\336e)\377\326a!\377\316]!\377\265Q\30\377\224A\30\377\234I\30\377\275]!\377\265Y!\377\275Y!\377\275Y!\377\265U!\377\265])\377\275])\377s4\30\377c(\20\377k,\20\377s0\20\377\214A\30\377\224E\30\377\234E\30\377\306]!\377\234I\30\377\224A\30\377\265U!\377\245I\30\377\265Q!\377\265Q!\377\265M!\377\255M\30\377\306]!\377\306Y!\377\306]!\377\306]!\377\326a)\377\336i)\377\275U!\377\224A\30\377\224A\30\377\306a!\377\275]!\377\275Y!\377\275]!\377\275])\377\275Y!\377\275Y!\377s0\20\377k,\20\377s0\20\377\2048\30\377\214<\30\377\224E\30\377\234E\30\377\245M\30\377\224A\30\377\214A\30\377\245M\30\377\265Q!\377\275U!\377\255I\30\377\245I\30\377\245I\30\377\275U!\377\306Y!\377\275Y!\377\306]!\377\306]!\377\265Q\30\377\255M\30\377\224A\30\377\204<\30\377\255Q\30\377\245M\30\377\255Q!\377\265Y!\377\275]!\377\265Y!\377\275Y!\377s0\20\377k0\20\377{0\20\377\2048\30\377\204<\30\377\204<\30\377\214<\30\377\224A\30\377\316a!\377\245I\30\377\234E\30\377\245I\30\377\265U!\377\265Q!\377\265Q!\377\255M!\377\275U!\377\275U!\377\275U!\377\275Q!\377\255I\30\377\255M\30\377\255Q\30\377\234E\30\377{4\30\377\224A\30\377\214<\30\377\275Y!\377\275Y!\377\275]!\377\255Q!\377\255Q!\377k,\20\377k,\20\377s0\20\377\2044\30\377{4\20\377{4\30\377\2048\30\377\245M\30\377\265U!\377\245I\30\377\214A\30\377\275Y!\377\234A\30\377\255M\30\377\265Q!\377\245M!\377\265U!\377\275Q!\377\245I\30\377\245I\30\377\245M\30\377\265Q!\377\255Q!\377\255M\30\377\214<\30\377\245I\30\377\255Q!\377\306]!\377\306]!\377\275U!\377\265U!\377\255Q!\377c(\20\377Z(\20\377c(\20\377k,\20\377{8\30\377{4\30\377\214<\30\377\214A\30\377\234E\30\377\245I\30\377\245M\30\377\214<\30\377s0\30\377\255M!\377\255I!\377\255M!\377\255M!\377\265Q!\377\265Q!\377\255M!\377\265Q\30\377\245I\30\377\255I\30\377\306Y!\377\275Y!\377\214A\30\377\255Q\30\377\275]!\377\306])\377\306]!\377\255U!\377\255Q!\377k0\30\377k0\20\377k,\20\377s0\20\377s0\20\377s4\30\377{4\30\377\214<\30\377\245I\30\377\224A\30\377\306Y!\377\234A\30\377s0\20\377\245I\30\377\255M!\377\255M!\377\255M!\377\255M!\377\255Q!\377\265M!\377\316]!\377\245E\30\377\316]!\377\306Y!\377\275U!\377{8\30\377\255Q!\377\265Y!\377\275]!\377\275Y!\377\275Y!\377\255Q!\377k0\20\377c,\20\377k,\20\377s0\20\377{4\30\377s0\20\377{4\30\377{4\30\377\2048\30\377\245I\30\377\234E\30\377\234E\30\377k,\20\377\214<\30\377\224A\30\377\245M\30\377\214<\30\377\224E\30\377\214<\30\377\214<\30\377\214<\30\377\245I\30\377\234E\30\377\224A\30\377\224A\30\377k,\20\377\224A\30\377\265Q!\377\265Y!\377\265U!\377\265Y!\377\275Y!\377c(\20\377c,\20\377k,\20\377s0\20\377k,\20\377k0\20\377\2048\30\377\234A\30\377\214<\30\377\224A\30\377\245I\30\377\245I\30\377k0\20\377{4\20\377\214<\30\377\214A\30\377\214<\30\377\204<\30\377\2048\30\377\234I\30\377\224A\30\377\214<\30\377\234E\30\377\234E\30\377\255M\30\377\224A\30\377{8\30\377\255Q!\377\265U!\377\255U!\377\255U!\377\265U!\377c(\20\377k,\20\377s0\20\377s0\20\377{4\20\377\2048\30\377\2048\30\377\2048\30\377\224A\30\377\245M\30\377\245E\30\377\234E\30\377{4\20\377Z(\20\377k0\30\377{8\30\377\2048\30\377\214A\30\377\224A\30\377\234I\30\377\214<\30\377\224A\30\377\224A\30\377\234E\30\377\245I\30\377\255M\30\377{8\30\377\214A\30\377\255U!\377\255U!\377\245Q!\377\265U!\377c,\20\377c(\20\377k,\20\377Z$\20\377Z$\20\377Z(\20\377c(\20\377k,\20\377k,\20\377c(\20\377c(\20\377c,\20\377k0\20\377R \20\377c,\20\377s4\30\377{4\30\377\204<\30\377\2048\30\377\214A\30\377\224A\30\377\224A\30\377\234I\30\377\234I\30\377\224A\30\377\245I\30\377\224E\30\377\2048\30\377\255U!\377\255Q!\377\265U!\377\265Y)\377J \20\377J\34\20\377Z(\20\377k,\20\377k(\20\377c(\20\377R \20\377c(\20\377k,\20\377s0\20\377k0\20\377k0\20\377c,\20\377Z(\20\377c,\20\377s4\20\377s4\20\377\2048\30\377\2048\20\377\2048\30\377\224A\30\377\214A\30\377\234I\30\377\245I\30\377\234I\30\377\245M!\377\245M\30\377\204<\30\377\234M!\377\245Q!\377\265U!\377\255U!\377c,\20\377c,\20\377c(\20\377c(\20\377c(\20\377c(\20\377c(\20\377k,\20\377k,\20\377k,\20\377k0\20\377s4\20\377s0\30\377\204<\30\377c(\20\377s4\20\377s4\30\377{4\20\377{4\30\377\204<\30\377\224A\30\377\234E\30\377\234E\30\377\234E\30\377\234E\30\377\245I\30\377\245I\30\377\224E\30\377\204<\30\377\245Q!\377\255Q!\377\347\327\326\377R$\20\377k,\20\377c(\20\377c(\20\377c(\20\377c(\20\377Z$\20\377c(\20\377c(\20\377k,\20\377k,\20\377k,\20\377s0\20\377{4\30\377\204<\30\377k,\20\377s4\20\377s4\20\377{8\30\377\2048\20\377\214<\30\377\214<\30\377\214A\30\377\234E\30\377\234E\30\377\224A\30\377\224E\30\377\224E\30\377s4\30\377\214A\30\377\265\206s\377\377\377\377\377c,\20\377k,\30\377k0\20\377k,\20\377c(\20\377Z$\20\377Z(\20\377Z$\20\377c(\20\377c(\20\377c(\20\377k,\20\377k0\20\377{4\30\377{8\30\377k,\20\377c,\20\377k0\20\377s0\20\377{8\30\377\2048\30\377\2048\30\377\214<\30\377\224A\30\377\224E\30\377\214<\30\377\214A\30\377\234I\30\377{8!\377\214M1\377\377\373\377\377\377\377\377" This doesn't look like a series of 8 bit values to me. Have I done something wrong or am I misinterpreting the results?

    Read the article

  • Passing variables to shopping cart with Javascript

    - by albatross
    This question is an extension of this one: http://stackoverflow.com/questions/2359238/calculate-order-price-by-date-selection-value I'm trying to make a conference registration page based off the previous page, which passes the variables(name, email, price) to my organization's outdated shopping cart using javascript. I'm also using Seminar Registration by CSSTricks (http://css-tricks.com/examples/SeminarRegTutorial/) Currently, my proceed to payment button produces an 'element is undefined' error on line 298(same thing on unresolved previous question, linked above^): switch (document.Information.amount.value) { Any help would be greatly appreciated. I'm at my wits end with this. Here is the page: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Seminar Registration Form with jQuery</title> <link rel="stylesheet" type="text/css" href="css/style.css" media="screen" /> <script src="js/jquery-1.2.6.js" type="text/javascript" charset="utf-8"></script> <script src="js/form-fun.jquery.js" type="text/javascript" charset="utf-8"></script> <!--[if IE]> <style type="text/css"> legend { position: relative; top: -30px; } fieldset { margin: 30px 10px 0 0; } </style> <script type="text/javascript"> $(function(){ $("#step_2 legend").css({ opacity: 0.5 }); $("#step_3 legend").css({ opacity: 0.5 }); }); </script> <![endif]--> </head> <body> <div id="page-wrap"> <h1>Conference <span>Registration</span></h1> <form action="#" method="post"> <fieldset id="step_1"> <legend>Step 1</legend> <label for="num_attendees"> How cool are you? </label> <select id="amount"> <option id="0" value="0">Please Choose</option> <option id="prof" value="90.00">Professional</option> <option id="grad" value="55.00">Graduate Student</option> </select> <br /> <div id="attendee_1_wrap" class="name_wrap push"> <h3>Who are you?</h3> <p> <label for="FirstName"> First Name: </label> <input type="text" id="FirstName" class="name_input"></input> </p> <p> <label for="LastName"> Last Name: </label> <input type="text" id="LastName" class="name_input"></input> </p> <p> <label for="OfficialTitle"> Official Title: </label> <input type="text" id="OfficialTitle" class="name_input"></input> </p> <h3>How do we find you?</h3> <label for="email">Email: </label> <input id="email" name="email" class="required email" /> </p> <p> <label for="Address">Street Address: </label><input name="Address" id="Address" type="text" size="20" maxlength="75" /> </p> <p> <label for="City">City: </label><input name="City" id="City" /> </p> <p> <label for="State">State: </label><select name="State" id="State"> <option selected value="IL">IL</option> <option value="AL">AL</option> <option value="AK">AK</option> <option value="AZ">AZ</option> <option value="AR">AR</option> <option value="CA">CA</option> <option value="CO">CO</option> <option value="CT">CT</option> <option value="DE">DE</option> <option value="DC">DC</option> <option value="FL">FL</option> <option value="GA">GA</option> <option value="HI">HI</option> <option value="ID">ID</option> <option value="IN">IN</option> <option value="IA">IA</option> <option value="KS">KS</option> <option value="KY">KY</option> <option value="LA">LA</option> <option value="ME">ME</option> <option value="MD">MD</option> <option value="MA">MA</option> <option value="MI">MI</option> <option value="MN">MN</option> <option value="MS">MS</option> <option value="MO">MO</option> <option value="MT">MT</option> <option value="NE">NE</option> <option value="NV">NV</option> <option value="NH">NH</option> <option value="NJ">NJ</option> <option value="NM">NM</option> <option value="NY">NY</option> <option value="NC">NC</option> <option value="ND">ND</option> <option value="OH">OH</option> <option value="OK">OK</option> <option value="OR">OR</option> <option value="PA">PA</option> <option value="RI">RI</option> <option value="SC">SC</option> <option value="SD">SD</option> <option value="TN">TN</option> <option value="TX">TX</option> <option value="UT">UT</option> <option value="VT">VT</option> <option value="VA">VA</option> <option value="WA">WA</option> <option value="WV">WV</option> <option value="WI">WI</option> <option value="WY">WY</option> </select> </p> <p> <label for="Zip">Zip Code: </label><input name="Zip" id="Zip" type="text" value="" size="5" maxlength="10" /> </p> <p> <label for="Phone">Telephone: </label><input name="Phone" id="Phone" type="text" value="" size="10" maxlength="13" /> </p> </div> </fieldset> <fieldset id="step_2"> <legend>Step 2</legend> <p> Do you work in Higher Education? </p> <input type="radio" id="company_name_toggle_on" name="company_name_toggle_group"></input> <label for="company_name_toggle_on">Yes</label> &emsp; <input type="radio" id="company_name_toggle_off" name="company_name_toggle_group"></input> <label for="company_name_toggle_off">No</label> <div id="company_name_wrap"> <label for="company_name"> Which School? </label> <input type="text" id="company_name"></input> </div> <div class="push"> <p> Will anyone in your group require special accommodations? </p> <input type="radio" id="special_accommodations_toggle_on" name="special_accommodations_toggle"></input> <label for="special_accommodations_toggle_on">Yes</label> &emsp; <input type="radio" id="special_accommodations_toggle_off" name="special_accommodations_toggle"></input> <label for="special_accommodations_toggle_off">No</label> </div> <div id="special_accommodations_wrap"> <label for="special_accomodations_text"> Please explain below: </label> <textarea rows="10" cols="10" id="special_accomodations_text"></textarea> </div> </fieldset> <fieldset id="step_3"> <legend>Step 3</legend> <label for="rock"> Are you ready to rock? </label> <input type="checkbox" id="rock"></input> <p> <INPUT onclick="javascript:PaymentButtonClick()" type=button value="Proceed to payment" name=PaymentButton> <img src="images/visa1.gif" /> <img src="images/mastercard1.gif" /> </p> </fieldset> </form> </div> <FORM name="emailForm" action="mailform.asp" method=post"> <INPUT type="hidden" value="Conference Registration" name="mf_subject"> <INPUT type="hidden" value="Yes" name="mf_email_results"> <INPUT type="hidden" title="" style="BACKGROUND-COLOR: #ffffa0" size="20" name="num_attendees"> <INPUT type="hidden" title="" style="BACKGROUND-COLOR: #ffffa0" size="17" name="FirstName"> <INPUT type="hidden" title="" style="BACKGROUND-COLOR: #ffffa0" size="22" name="LastName"> <INPUT type="hidden" title="" style="BACKGROUND-COLOR: #ffffff" size="64" name="OfficialTitle"> <INPUT type="hidden" title="" style="BACKGROUND-COLOR: #ffffff" size="40" name="email"> <INPUT type="hidden" title="" style="BACKGROUND-COLOR: #ffffff" size="48" name="Address"> <INPUT type="hidden" title="" style="BACKGROUND-COLOR: #ffffa0" size="17" name="City"> <INPUT type="hidden" title="" style="BACKGROUND-COLOR: #ffffa0" size="17" name="State"> <INPUT type="hidden" title="" style="BACKGROUND-COLOR: #ffffa0" size="17" name="Zip"> <INPUT type="hidden" title="" style="BACKGROUND-COLOR: #ffffa0" size="17" name="Phone"> <INPUT type="hidden" title="" style="BACKGROUND-COLOR: #ffffa0" size="17" name="company_name"> <INPUT type="hidden" title="" style="BACKGROUND-COLOR: #ffffff" size="20" name="special_accomodations_text"> <INPUT type="hidden" value="[email protected]" name="mf_from"> <INPUT type="hidden" value="[email protected]" name="mf_to"> </FORM> <FORM name="addform" action="https://webcluster.niu.edu/CreditCard/servlet/Shopping_Cart_Add_Item_Servlet" method="post"> <INPUT type="hidden" value="orient" name="Dept_ID"> <INPUT type="hidden" value="Orientation" name="Product_Name"> <INPUT type="hidden" value="z000000" name="Product_Code"> <INPUT type="hidden" value="" name="amount"> <INPUT type="hidden" value="/orientation/index.shtml" name="return_link"> <INPUT type="hidden" value="http://www.niu.edu" name="return_server"> <INPUT type="hidden" value="1" name="quantity"> <INPUT type="hidden" value="0" name="tax"> <INPUT type="hidden" value="0" name="ship"> <INPUT type="hidden" value="DQ83225" name="sale_id"> <INPUT type="hidden" value="XXXXXX" name="sale_acct"> </FORM> <SCRIPT language="Javascript"> function PaymentButtonClick() { switch (document.Information.amount.value) { case 'prof': document.Information.amount.value = 90.00; break; case 'grad': document.Information.amount.value = 55.00; break; } document.addform.Product_Name.value = document.Information.FirstName.value + ","+ document.Information.LastName.value+","+ document.Information.OfficialTitle.value+","+ document.Information.email.name+","+","+ document.Information.Address.value+ "," + document.Information.City.value+ "," + document.Information.State.value+ "," + document.Information.Zip.value+ "," + document.Information.Phone.value+ "," + document.Information.company_name.value+ "," + document.Information.special_accomodations_text.value; document.addform.Product_Code.value = document.Information.LastName.value; if ((document.Information.UCheck.checked==true) && (document.Information.altDate1.value != "") && (document.Information.altDate1.value != "x")) { if (document.Information.StudentLastName.value != "" || document.Information.StudentFirstName.value != "" || document.Information.StudentID.value != "" ) { document.addform.submit(); } else { alert("Please enter missing information"); } } } </SCRIPT> </body> </html>

    Read the article

  • trying to validate user input in php

    - by user225269
    I'm trying to validate user input in php. This code will check if the values are null or not. If it is null, this will require the user to input the values that are null. When all the text boxes in the html form that came before this. This code will show the submit button, and that submit button will save the inputted data into the mysql database. But the problem is that the value that is saved is zero zero and zero, what might be the cause of this? <html> <head> <title>Admission Information Sheet</title> <meta http-equiv="Content-Type" content="text/html; Western (ISO-8859-1)"> <meta name="author" content=" "> <title> <style> input { font-size: 16px;} </style> <?php include('header.php'); ?> <div id="main_content"> </div> <?php include('footer.php'); ?> <table border="1" width="900" border="0" align="left" cellpadding="0" cellspacing="1" bgcolor="#CCCCCC"> <tr> <form name="form1.1" method="POST" action="aisaction.php"> <?php $NURSE = $_POST[nurse]; $TELNUM = $_POST[telnum]; $HOSPNUM = $_POST[hnum]; $ROOMNUM = $_POST[rnum]; $LASTNAME = $_POST[lname]; $FIRSTNAME = $_POST[fname]; $MIDNAME = $_POST[mname]; $AD = $_POST[ad]; $ADATE = $_POST[adate]; $ADTIME = $_POST[adtime]; $CSTAT = $_POST[cs]; $AGE = $_POST[age]; $BDAY = $_POST[bday]; $SEX = $_POST[sex]; ?> <td> <table width="100%" border="0" cellpadding="2" cellspacing="1" bgcolor="#FFFFFF"> <tr> <td colspan="12" style="background:#9ACD32; color:white; border:white 1px solid; text-align: center"><strong><font size="3">ADMISSION INFORMATION SHEET</strong></td> </tr> <tr> </td><br> <td width="54"><font size="3">Hospital #</td> <td width="3">:</td> <td width="168"><input type="display" name="hnum" disabled="true" value= "<?php print "$HOSPNUM";?>"><br> <font color="red"> <?php if(empty($HOSPNUM)) print "* Hospital Number required!<br>"; ?> </td> <td width="41"><font size="3">Room #</td> <td width="3">:</td> <td width="168"><input type="display" name="rnum" disabled="true" value= "<?php print "$ROOMNUM";?>"><br> <font color="red"> <?php if(empty($ROOMNUM)) print "* Room Number required!<br>"; ?> </td> <td width="67"><font size="3">Admission Date</td> <td width="3">:</td> <td width="168"><input type="display" name="adate" disabled="true" value= "<?php print "$ADATE";?>"><br> <font color="red"> <?php if(empty($ADATE)) print "* Admission Date required!<br>"; ?> </td> </tr> <tr> <td><font size="3">Last Name</td> <td>:</td> <td><input type="display" name="lname" disabled="true" value= "<?php print "$LASTNAME";?>"><br> <font color="red"> <?php if(empty($LASTNAME)) print "* Last Name required!<br>"; ?> </td> <td><font size="3">First Name</td> <td>:</td> <td><input type="display" name="fname" disabled="true" value= "<?php print "$FIRSTNAME";?>"><br> <font color="red"> <?php if(empty($FIRSTNAME)) print "* First Name required!<br>"; ?> </td> <td><font size="3">Middle Name</td> <td>:</td> <td><input type="display" name="mname" disabled="true" value= "<?php print "$MIDNAME";?>"><br> <font color="red"> <?php if(empty($MIDNAME)) print "* Middle Name required!<br>"; ?> </td> <td><font size="3">Admit time</td> <td>:</td> <td><input type="display" name="mname" disabled="true" value= "<?php print "$ADTIME";?>"><br> <font color="red"> <?php if(empty($ADTIME)) print "* Adtime required!<br>"; ?> </td> </tr> <tr> <td><font size="3">Civil Status</td> <td>:</td> <td><input type="display" name="cs" disabled="true" value= "<?php print "$CSTAT";?>"><br> <font color="red"> <?php if(empty($CSTAT)) print "* Civil Status required!<br>"; ?> </td> <td><font size="3">Age</td> <td>:</td> <td><input type="display" name="age" disabled="true" value= "<?php print "$AGE";?>"><br> <font color="red"> <?php if(empty($AGE)) print "* Age required!<br>"; ?> </td> <td><font size="3">Birthday</td> <td>:</td> <td><input type="display" name="bday" disabled="true" value= "<?php print "$BDAY";?>"><br> <font color="red"> <?php if(empty($BDAY)) print "* Birthday required!<br>"; ?> </td> </tr> <tr> <td><font size="3">Address</td> <td>:</td> <td><input type="display" name="address" disabled="true" value= "<?php print "$AD";?>"><br> <font color="red"> <?php if(empty($AD)) print "* Address required!<br>"; ?> </td> <td><font size="3">Telephone #</td> <td>:</td> <td><input type="display" name="telnum" disabled="true" value= "<?php print "$TELNUM";?>"></td> <td width="23"><font size="3">Sex</td> <td width="3">:</td> <td width="174"><input type="display" name="sex" disabled="true" value= "<?php print "$SEX";?>"><br> <font color="red"> <?php if(empty($SEX)) print "* Gender required!<br>"; ?> </td> </tr> <tr> <td><font size="3">Pls. Check</td> <td>:</td> <td><input name="stats1" type="checkbox" id="SSS" value="SSS">SSS</td> <td><font size="3"></td> <td>:</td> <td><input name="stats1" type="checkbox" id="nonmed" value="NonMedicare">Non Medicare</td> <td><font size="3"></td> <td>:</td> <td><input name="stats1" type="checkbox" id="sh" value="stockholder">Stockholder</td> </tr> <tr> <td><font size="3"></td> <td></td> <td><input name="stats1" type="checkbox" id="gsis" value="GSIS">GSIS</td> <td><font size="3"></td> <td></td> <td><input name="stats1" type="checkbox" id="senior" value="seniorcitizen">Senior-Citizen</td> <tr> <td><font size="3"></td> <td></td> <td><input name="stats1" type="checkbox" id="dep" value="dependent">Dependent</td> <td><font size="3"></td> <td></td> <td><input name="stats1" type="checkbox" id="emp" value="employee">Employee</td> </tr> <tr> <td><font size="3">Attending Nurse</td> <td>:</td> <td><input type="display" name="nurse" disabled="true" value= "<?php print "$NURSE";?>"><br> <font color="red"> <?php if(empty($NURSE)) print "* Admitting/Attending Nurse required!<br>"; ?> </td> </tr> <tr> <td>&nbsp;</td> <td>&nbsp;</td> <td><input type="button" value="Back" onClick="history.go(-1);return true;"> <?php $val1 = $_POST['NURSE']; if($_POST['NURSE'] !="") { ?> <form action="aisaction.php" method="POST" target="_window"> <input type="hidden" name="submit" value="yes"> <input type="submit" value="submit"> </form> <?php } ?> </td> </td> </tr> </table> </td> </form> </tr> </table> </head> </html>

    Read the article

  • Conceal packet loss in PCM stream

    - by ZeroDefect
    I am looking to use 'Packet Loss Concealment' to conceal lost PCM frames in an audio stream. Unfortunately, I cannot find a library that is accessible without all the licensing restrictions and code bloat (...up for some suggestions though). I have located some GPL code written by Steve Underwood for the Asterisk project which implements PLC. There are several limitations; although, as Steve suggests in his code, his algorithm can be applied to different streams with a bit of work. Currently, the code works with 8kHz 16-bit signed mono streams. Variations of the code can be found through a simple search of Google Code Search. My hope is that I can adapt the code to work with other streams. Initially, the goal is to adjust the algorithm for 8+ kHz, 16-bit signed, multichannel audio (all in a C++ environment). Eventually, I'm looking to make the code available under the GPL license in hopes that it could be of benefit to others... Attached is the code below with my efforts. The code includes a main function that will "drop" a number of frames with a given probability. Unfortunately, the code does not quite work as expected. I'm receiving EXC_BAD_ACCESS when running in gdb, but I don't get a trace from gdb when using 'bt' command. Clearly, I'm trampimg on memory some where but not sure exactly where. When I comment out the *amdf_pitch* function, the code runs without crashing... int main (int argc, char *argv[]) { std::ifstream fin("C:\\cc32kHz.pcm"); if(!fin.is_open()) { std::cout << "Failed to open input file" << std::endl; return 1; } std::ofstream fout_repaired("C:\\cc32kHz_repaired.pcm"); if(!fout_repaired.is_open()) { std::cout << "Failed to open output repaired file" << std::endl; return 1; } std::ofstream fout_lossy("C:\\cc32kHz_lossy.pcm"); if(!fout_lossy.is_open()) { std::cout << "Failed to open output repaired file" << std::endl; return 1; } audio::PcmConcealer Concealer; Concealer.Init(1, 16, 32000); //Generate random numbers; srand( time(NULL) ); int value = 0; int probability = 5; while(!fin.eof()) { char arr[2]; fin.read(arr, 2); //Generate's random number; value = rand() % 100 + 1; if(value <= probability) { char blank[2] = {0x00, 0x00}; fout_lossy.write(blank, 2); //Fill in data; Concealer.Fill((int16_t *)blank, 1); fout_repaired.write(blank, 2); } else { //Write data to file; fout_repaired.write(arr, 2); fout_lossy.write(arr, 2); Concealer.Receive((int16_t *)arr, 1); } } fin.close(); fout_repaired.close(); fout_lossy.close(); return 0; } PcmConcealer.hpp /* * Code adapted from Steve Underwood of the Asterisk Project. This code inherits * the same licensing restrictions as the Asterisk Project. */ #ifndef __PCMCONCEALER_HPP__ #define __PCMCONCEALER_HPP__ /** 1. What does it do? The packet loss concealment module provides a suitable synthetic fill-in signal, to minimise the audible effect of lost packets in VoIP applications. It is not tied to any particular codec, and could be used with almost any codec which does not specify its own procedure for packet loss concealment. Where a codec specific concealment procedure exists, the algorithm is usually built around knowledge of the characteristics of the particular codec. It will, therefore, generally give better results for that particular codec than this generic concealer will. 2. How does it work? While good packets are being received, the plc_rx() routine keeps a record of the trailing section of the known speech signal. If a packet is missed, plc_fillin() is called to produce a synthetic replacement for the real speech signal. The average mean difference function (AMDF) is applied to the last known good signal, to determine its effective pitch. Based on this, the last pitch period of signal is saved. Essentially, this cycle of speech will be repeated over and over until the real speech resumes. However, several refinements are needed to obtain smooth pleasant sounding results. - The two ends of the stored cycle of speech will not always fit together smoothly. This can cause roughness, or even clicks, at the joins between cycles. To soften this, the 1/4 pitch period of real speech preceeding the cycle to be repeated is blended with the last 1/4 pitch period of the cycle to be repeated, using an overlap-add (OLA) technique (i.e. in total, the last 5/4 pitch periods of real speech are used). - The start of the synthetic speech will not always fit together smoothly with the tail of real speech passed on before the erasure was identified. Ideally, we would like to modify the last 1/4 pitch period of the real speech, to blend it into the synthetic speech. However, it is too late for that. We could have delayed the real speech a little, but that would require more buffer manipulation, and hurt the efficiency of the no-lost-packets case (which we hope is the dominant case). Instead we use a degenerate form of OLA to modify the start of the synthetic data. The last 1/4 pitch period of real speech is time reversed, and OLA is used to blend it with the first 1/4 pitch period of synthetic speech. The result seems quite acceptable. - As we progress into the erasure, the chances of the synthetic signal being anything like correct steadily fall. Therefore, the volume of the synthesized signal is made to decay linearly, such that after 50ms of missing audio it is reduced to silence. - When real speech resumes, an extra 1/4 pitch period of sythetic speech is blended with the start of the real speech. If the erasure is small, this smoothes the transition. If the erasure is long, and the synthetic signal has faded to zero, the blending softens the start up of the real signal, avoiding a kind of "click" or "pop" effect that might occur with a sudden onset. 3. How do I use it? Before audio is processed, call plc_init() to create an instance of the packet loss concealer. For each received audio packet that is acceptable (i.e. not including those being dropped for being too late) call plc_rx() to record the content of the packet. Note this may modify the packet a little after a period of packet loss, to blend real synthetic data smoothly. When a real packet is not available in time, call plc_fillin() to create a sythetic substitute. That's it! */ /*! Minimum allowed pitch (66 Hz) */ #define PLC_PITCH_MIN(SAMPLE_RATE) ((double)(SAMPLE_RATE) / 66.6) /*! Maximum allowed pitch (200 Hz) */ #define PLC_PITCH_MAX(SAMPLE_RATE) ((SAMPLE_RATE) / 200) /*! Maximum pitch OLA window */ //#define PLC_PITCH_OVERLAP_MAX(SAMPLE_RATE) ((PLC_PITCH_MIN(SAMPLE_RATE)) >> 2) /*! The length over which the AMDF function looks for similarity (20 ms) */ #define CORRELATION_SPAN(SAMPLE_RATE) ((20 * (SAMPLE_RATE)) / 1000) /*! History buffer length. The buffer must also be at leat 1.25 times PLC_PITCH_MIN, but that is much smaller than the buffer needs to be for the pitch assessment. */ //#define PLC_HISTORY_LEN(SAMPLE_RATE) ((CORRELATION_SPAN(SAMPLE_RATE)) + (PLC_PITCH_MIN(SAMPLE_RATE))) namespace audio { typedef struct { /*! Consecutive erased samples */ int missing_samples; /*! Current offset into pitch period */ int pitch_offset; /*! Pitch estimate */ int pitch; /*! Buffer for a cycle of speech */ float *pitchbuf;//[PLC_PITCH_MIN]; /*! History buffer */ short *history;//[PLC_HISTORY_LEN]; /*! Current pointer into the history buffer */ int buf_ptr; } plc_state_t; class PcmConcealer { public: PcmConcealer(); ~PcmConcealer(); void Init(int channels, int bit_depth, int sample_rate); //Process a block of received audio samples. int Receive(short amp[], int frames); //Fill-in a block of missing audio samples. int Fill(short amp[], int frames); void Destroy(); private: int amdf_pitch(int min_pitch, int max_pitch, short amp[], int channel_index, int frames); void save_history(plc_state_t *s, short *buf, int channel_index, int frames); void normalise_history(plc_state_t *s); /** Holds the states of each of the channels **/ std::vector< plc_state_t * > ChannelStates; int plc_pitch_min; int plc_pitch_max; int plc_pitch_overlap_max; int correlation_span; int plc_history_len; int channel_count; int sample_rate; bool Initialized; }; } #endif PcmConcealer.cpp /* * Code adapted from Steve Underwood of the Asterisk Project. This code inherits * the same licensing restrictions as the Asterisk Project. */ #include "audio/PcmConcealer.hpp" /* We do a straight line fade to zero volume in 50ms when we are filling in for missing data. */ #define ATTENUATION_INCREMENT 0.0025 /* Attenuation per sample */ #if !defined(INT16_MAX) #define INT16_MAX (32767) #define INT16_MIN (-32767-1) #endif #ifdef WIN32 inline double rint(double x) { return floor(x + 0.5); } #endif inline short fsaturate(double damp) { if (damp > 32767.0) return INT16_MAX; if (damp < -32768.0) return INT16_MIN; return (short)rint(damp); } namespace audio { PcmConcealer::PcmConcealer() : Initialized(false) { } PcmConcealer::~PcmConcealer() { Destroy(); } void PcmConcealer::Init(int channels, int bit_depth, int sample_rate) { if(Initialized) return; if(channels <= 0 || bit_depth != 16) return; Initialized = true; channel_count = channels; this->sample_rate = sample_rate; ////////////// double min = PLC_PITCH_MIN(sample_rate); int imin = (int)min; double max = PLC_PITCH_MAX(sample_rate); int imax = (int)max; plc_pitch_min = imin; plc_pitch_max = imax; plc_pitch_overlap_max = (plc_pitch_min >> 2); correlation_span = CORRELATION_SPAN(sample_rate); plc_history_len = correlation_span + plc_pitch_min; ////////////// for(int i = 0; i < channel_count; i ++) { plc_state_t *t = new plc_state_t; memset(t, 0, sizeof(plc_state_t)); t->pitchbuf = new float[plc_pitch_min]; t->history = new short[plc_history_len]; ChannelStates.push_back(t); } } void PcmConcealer::Destroy() { if(!Initialized) return; while(ChannelStates.size()) { plc_state_t *s = ChannelStates.at(0); if(s) { if(s->history) delete s->history; if(s->pitchbuf) delete s->pitchbuf; memset(s, 0, sizeof(plc_state_t)); delete s; } ChannelStates.erase(ChannelStates.begin()); } ChannelStates.clear(); Initialized = false; } //Process a block of received audio samples. int PcmConcealer::Receive(short amp[], int frames) { if(!Initialized) return 0; int j = 0; for(int k = 0; k < ChannelStates.size(); k++) { int i; int overlap_len; int pitch_overlap; float old_step; float new_step; float old_weight; float new_weight; float gain; plc_state_t *s = ChannelStates.at(k); if (s->missing_samples) { /* Although we have a real signal, we need to smooth it to fit well with the synthetic signal we used for the previous block */ /* The start of the real data is overlapped with the next 1/4 cycle of the synthetic data. */ pitch_overlap = s->pitch >> 2; if (pitch_overlap > frames) pitch_overlap = frames; gain = 1.0 - s->missing_samples * ATTENUATION_INCREMENT; if (gain < 0.0) gain = 0.0; new_step = 1.0/pitch_overlap; old_step = new_step*gain; new_weight = new_step; old_weight = (1.0 - new_step)*gain; for (i = 0; i < pitch_overlap; i++) { int index = (i * channel_count) + j; amp[index] = fsaturate(old_weight * s->pitchbuf[s->pitch_offset] + new_weight * amp[index]); if (++s->pitch_offset >= s->pitch) s->pitch_offset = 0; new_weight += new_step; old_weight -= old_step; if (old_weight < 0.0) old_weight = 0.0; } s->missing_samples = 0; } save_history(s, amp, j, frames); j++; } return frames; } //Fill-in a block of missing audio samples. int PcmConcealer::Fill(short amp[], int frames) { if(!Initialized) return 0; int j =0; for(int k = 0; k < ChannelStates.size(); k++) { short *tmp = new short[plc_pitch_overlap_max]; int i; int pitch_overlap; float old_step; float new_step; float old_weight; float new_weight; float gain; short *orig_amp; int orig_len; orig_amp = amp; orig_len = frames; plc_state_t *s = ChannelStates.at(k); if (s->missing_samples == 0) { // As the gap in real speech starts we need to assess the last known pitch, //and prepare the synthetic data we will use for fill-in normalise_history(s); s->pitch = amdf_pitch(plc_pitch_min, plc_pitch_max, s->history + plc_history_len - correlation_span - plc_pitch_min, j, correlation_span); // We overlap a 1/4 wavelength pitch_overlap = s->pitch >> 2; // Cook up a single cycle of pitch, using a single of the real signal with 1/4 //cycle OLA'ed to make the ends join up nicely // The first 3/4 of the cycle is a simple copy for (i = 0; i < s->pitch - pitch_overlap; i++) s->pitchbuf[i] = s->history[plc_history_len - s->pitch + i]; // The last 1/4 of the cycle is overlapped with the end of the previous cycle new_step = 1.0/pitch_overlap; new_weight = new_step; for ( ; i < s->pitch; i++) { s->pitchbuf[i] = s->history[plc_history_len - s->pitch + i]*(1.0 - new_weight) + s->history[plc_history_len - 2*s->pitch + i]*new_weight; new_weight += new_step; } // We should now be ready to fill in the gap with repeated, decaying cycles // of what is in pitchbuf // We need to OLA the first 1/4 wavelength of the synthetic data, to smooth // it into the previous real data. To avoid the need to introduce a delay // in the stream, reverse the last 1/4 wavelength, and OLA with that. gain = 1.0; new_step = 1.0/pitch_overlap; old_step = new_step; new_weight = new_step; old_weight = 1.0 - new_step; for (i = 0; i < pitch_overlap; i++) { int index = (i * channel_count) + j; amp[index] = fsaturate(old_weight * s->history[plc_history_len - 1 - i] + new_weight * s->pitchbuf[i]); new_weight += new_step; old_weight -= old_step; if (old_weight < 0.0) old_weight = 0.0; } s->pitch_offset = i; } else { gain = 1.0 - s->missing_samples*ATTENUATION_INCREMENT; i = 0; } for ( ; gain > 0.0 && i < frames; i++) { int index = (i * channel_count) + j; amp[index] = s->pitchbuf[s->pitch_offset]*gain; gain -= ATTENUATION_INCREMENT; if (++s->pitch_offset >= s->pitch) s->pitch_offset = 0; } for ( ; i < frames; i++) { int index = (i * channel_count) + j; amp[i] = 0; } s->missing_samples += orig_len; save_history(s, amp, j, frames); delete [] tmp; j++; } return frames; } void PcmConcealer::save_history(plc_state_t *s, short *buf, int channel_index, int frames) { if (frames >= plc_history_len) { /* Just keep the last part of the new data, starting at the beginning of the buffer */ //memcpy(s->history, buf + len - plc_history_len, sizeof(short)*plc_history_len); int frames_to_copy = plc_history_len; for(int i = 0; i < frames_to_copy; i ++) { int index = (channel_count * (i + frames - plc_history_len)) + channel_index; s->history[i] = buf[index]; } s->buf_ptr = 0; return; } if (s->buf_ptr + frames > plc_history_len) { /* Wraps around - must break into two sections */ //memcpy(s->history + s->buf_ptr, buf, sizeof(short)*(plc_history_len - s->buf_ptr)); short *hist_ptr = s->history + s->buf_ptr; int frames_to_copy = plc_history_len - s->buf_ptr; for(int i = 0; i < frames_to_copy; i ++) { int index = (channel_count * i) + channel_index; hist_ptr[i] = buf[index]; } frames -= (plc_history_len - s->buf_ptr); //memcpy(s->history, buf + (plc_history_len - s->buf_ptr), sizeof(short)*len); frames_to_copy = frames; for(int i = 0; i < frames_to_copy; i ++) { int index = (channel_count * (i + (plc_history_len - s->buf_ptr))) + channel_index; s->history[i] = buf[index]; } s->buf_ptr = frames; return; } /* Can use just one section */ //memcpy(s->history + s->buf_ptr, buf, sizeof(short)*len); short *hist_ptr = s->history + s->buf_ptr; int frames_to_copy = frames; for(int i = 0; i < frames_to_copy; i ++) { int index = (channel_count * i) + channel_index; hist_ptr[i] = buf[index]; } s->buf_ptr += frames; } void PcmConcealer::normalise_history(plc_state_t *s) { short *tmp = new short[plc_history_len]; if (s->buf_ptr == 0) return; memcpy(tmp, s->history, sizeof(short)*s->buf_ptr); memcpy(s->history, s->history + s->buf_ptr, sizeof(short)*(plc_history_len - s->buf_ptr)); memcpy(s->history + plc_history_len - s->buf_ptr, tmp, sizeof(short)*s->buf_ptr); s->buf_ptr = 0; delete [] tmp; } int PcmConcealer::amdf_pitch(int min_pitch, int max_pitch, short amp[], int channel_index, int frames) { int i; int j; int acc; int min_acc; int pitch; pitch = min_pitch; min_acc = INT_MAX; for (i = max_pitch; i <= min_pitch; i++) { acc = 0; for (j = 0; j < frames; j++) { int index1 = (channel_count * (i+j)) + channel_index; int index2 = (channel_count * j) + channel_index; //std::cout << "Index 1: " << index1 << ", Index 2: " << index2 << std::endl; acc += abs(amp[index1] - amp[index2]); } if (acc < min_acc) { min_acc = acc; pitch = i; } } std::cout << "Pitch: " << pitch << std::endl; return pitch; } } P.S. - I must confess that digital audio is not my forte...

    Read the article

< Previous Page | 260 261 262 263 264