web audio soundcloud crossfade - soundcloud

I'm struggling to get this basic fade-in / fade-out Web Audio code to work with SoundCloud. It appears that the gainNode.gain.linearRampToValueAtTime functions are bypassed (ie, play starts and ends at gain.volume = 1.0.)
Code needs to work with iOS mobile Safari webkit.
CSS included:
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,600' rel='stylesheet' type='text/css'>
HTML Follows:
<div id="wrapper">
<div id="content">
<div class="post">
<h2>Fading in a Soundcloud Track</h2>
</p>
</div>
</div>
</div>
JS Follows:
<script>
var audioCtx = new (window.AudioContext ||
window.webAudioContext ||
window.webkitAudioContext)();
var audio = new Audio();
var url = 'https://api.soundcloud.com/tracks/179612876/stream' + '?client_id=<MY_ID>';
audio.src = url;
audio.preload = true;
audio.load();
audio.addEventListener('canplay', function(){
var currTime = audioCtx.currentTime;
var duration = 30;
var fadeTime = 6;
var gainNode = audioCtx.createGain();
gainNode.gain.value = 0.0;
var source = audioCtx.createMediaElementSource(audio);
source.connect(gainNode);
gainNode.connect(audioCtx.destination);
// Then fade in
gainNode.gain.linearRampToValueAtTime(0.0, currTime);
gainNode.gain.linearRampToValueAtTime(1.0, currTime + fadeTime);
// Then fade it out.
gainNode.gain.linearRampToValueAtTime(1.0, currTime + duration-fadeTime);
gainNode.gain.linearRampToValueAtTime(0.0, currTime + duration);
//source.connect(audioCtx.destination);
source.mediaElement.play();
},false);
</script>

"gainNode.gain.value = 0.0;" doesn't actually set a schedule point in the scheduler, it just sets the current value. Since there's no start point in the scheduler, it's jumping up when it hits the first schedule point (i.e. at time currTime + fadeTime). Try this:
gainNode.gain.setValueAtTime(0.0, currTime);
gainNode.gain.linearRampToValueAtTime(1.0, currTime + fadeTime);
// Then fade it out.
gainNode.gain.setValueAtTime(1.0, currTime + duration-fadeTime);
gainNode.gain.linearRampToValueAtTime(0.0, currTime + duration);
(and don't bother setting gain.gain.value).

Related

Get play position of audio buffer in web audio API

I am making a browser based DJ app, and need an indicator to show how much of an audio track(audio buffer) has played on a waveform. I have a waveform but cant get the current position.
The Web Audio API uses a common time frame to synchronise all running and scheduled sounds, which can be read from AudioContext.currentTime. You can store the timestamp of when you start your sound and measure the elapsed time while the sound is played. By this you get the position in seconds. If you need the frame index position of the AudioBuffer you can multiply the elapsed time by the sampleRate of the AudioBuffer.
<!DOCTYPE HTML>
<html>
<head>
<title>Time Elapsed Demo</title>
<script>
const audioCtx = new AudioContext()
async function startSample() {
const output = document.getElementById("output")
const response = await fetch('test.wav')
const sample = await response.arrayBuffer()
const audioBuffer = await audioCtx.decodeAudioData(sample)
const sampleRate = audioBuffer.sampleRate
const sourceNode = audioCtx.createBufferSource()
sourceNode.buffer = audioBuffer
sourceNode.connect(audioCtx.destination)
let ended = false
sourceNode.onended = () => { ended = true }
const startTime = audioCtx.currentTime + 0.01
sourceNode.start(startTime)
function showTimeElapsed() {
if (ended == false) {
elapsed = audioCtx.currentTime - startTime;
if (elapsed >= 0) {
output.innerHTML =
"Time elapsed: " + elapsed.toFixed(3) + ", " +
"Frame index: " + (sampleRate * elapsed).toFixed(0)
}
requestAnimationFrame(showTimeElapsed)
}
}
showTimeElapsed()
}
</script>
</head>
<body>
<button id="start" onclick="startSample()">Start Sample</button>
<p>
<div id="output"></div>
</body>
</html>

Mapbox Polyline too complex, maybe?

I am using Mapbox API to locate two gps locations and draw a polyline between them. The code that I have written works...sometimes.
It seems that if the two locations are physically close to each other it works more often than not, but if the two points are further away then it doesn't work more often than not, but I can't duplicate the results consistently. My working theory right now is that the polyline gets too complex for the API to decode. Is there a way to simplify a polyline or request a simpler one in the first place?
I've marked the line in the code below that is problematic. Does anyone have any ideas why it sometimes works and sometimes doesn't???
If it matters, my ultimate goal with this is generating a static map image that will be used in a report, so I'm not really worried about bandwidth or efficiency, I just need the image to work.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=<device-width>, initial-scale=1.0">
<title>Document</title>
<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous">
</script>
<script src="js/jquery.fileDownload.js"></script>
<script>
//Declare Variables
var token = "myuniquetoken";
var longitude;
var latitude;
var longitude2;
var latitude2;
var polyline;
//When first Get GPS Button is Pressed
$(document).ready(function() {
$("#btnGetGPS").click(function(){
var address = $("#address").val();
var addressstring = address.replace(" ", "%20");
var url = "https://api.mapbox.com/geocoding/v5/mapbox.places/" + addressstring + ".json?access_token=" + token;
var jqxhr = $.getJSON( url, function(data) {
longitude = data["features"][0]["center"][0];
latitude = data["features"][0]["center"][1];
$("#gpslong").text(longitude);
$("#gpslat").text(latitude);
var mapPinUrl = "https://api.mapbox.com/styles/v1/mapbox/streets-v11/static/pin-s-l+000(" + longitude + "," + latitude + ")/" + longitude + "," + latitude + ",14/500x300?access_token=" + token;
$('#mapDiv').html('<img id="mapImg" src=' + mapPinUrl +' />');
$('#secondlocation').show();
});
});
});
//When second Get GPS Button is Pressed
$(document).ready(function() {
$("#btnGetGPS2").click(function(){
var address2 = $("#address2").val();
var addressstring2 = address2.replace(" ", "%20");
var url2 = "https://api.mapbox.com/geocoding/v5/mapbox.places/" + addressstring2 + ".json?access_token=" + token;
var jqxhr2 = $.getJSON( url2, function(data) {
longitude2 = data["features"][0]["center"][0];
latitude2 = data["features"][0]["center"][1];
$("#gpslong2").text(longitude2);
$("#gpslat2").text(latitude2);
//Get a polyline
var polyURL = "https://api.mapbox.com/directions/v5/mapbox/driving/" + longitude + "," + latitude + ";" + longitude2 + "," + latitude2 + "?access_token=" + token;
console.log(polyURL);
var polyJSON = $.getJSON( polyURL, function(data2) {
polyline = data2["routes"][0]["geometry"];
console.log(polyline);
//////////////////The next line is the problematic one.//////////////////
var mapRoute = "https://api.mapbox.com/styles/v1/mapbox/streets-v11/static/pin-s-a+9ed4bd(" + longitude + "," + latitude + "),pin-s-b+000(" + longitude2 + "," + latitude2 + "),path-5+f44-0.5(" + polyline + ")/auto/500x300?access_token=" + token;
console.log(mapRoute);
$('#mapDiv2').html('<img id="mapImg" src=' + mapRoute +' />');
});
});
});
});
</script>
</head>
<body>
Enter an address (i.e. 1600 Pennsylvania Avenue NW, Washington, DC 20500):</br>
<input id="address"/></br>
<button id="btnGetGPS" type="button">Get GPS</button>
<div id = "gpslong"></div>
<div id = "gpslat"></div>
<div id="mapDiv"></div>
<div id="secondlocation" style="display:none">
Enter a second location:
<input id="address2"/></br>
<button id="btnGetGPS2" type="button">Get GPS</button>
<div id = "gpslong2"></div>
<div id = "gpslat2"></div>
<div id="mapDiv2"></div>
</div>
</body>
</html>
I'm leaving this question up and proving the answer that someone helped me discover in hopes of helping other people in the future.
.
The problem was that the polyline I was getting in the first API request contained special characters like `,~,|, etc. When I tried to use that same string in the second API request, those special characters were sometimes causing problems. I added the line of code below to scrub out those special characters and replace them with safe ASCII.
.
polyline = encodeURIComponent(polyline);

Date Picker work without internet

I need to use a date picker to work without internet.
I have changed my source links from https links to downloaded files in my local. But then Date picker stops working.
Can someone please let me know how to overcome this issue?
ideal source links :
<link href = "https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css" rel = "stylesheet">
<script src = "https://code.jquery.com/jquery-1.10.2.js"></script>
<script src = "https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
Changed to locally downloaded files
<script src = "jquery-ui.js"></script>
<script src = "jquery-1.10.2.js"></script>
<script src = "jquery-ui.css"></script>
I shall be good if I can assure that even if https links used, it will work fine for my date pickers when internet is not there. Might be through some caching.
Updating my Question with datepickers code:
<span style="float: left;margin-left:2em"> <b>Date Range: </b>
<input type="text" id="datepicker" > <b>to </b>
<input type="text" id="datepicker2"> </span><div id = "Alert" style="float:left;margin-left:2em"> Please select a valid Date Range!</div>
.............................................
var startDate;
var endDate;
var start;
var end;
$(function() {
$("#datepicker").datepicker({
onSelect: function() {
startDate = $(this).datepicker('getDate');
start = formatDate(startDate);
if( start!=null && end!=null && end>=start)
{document.getElementById('Alert').style.visibility = 'hidden';
document.getElementById('canvas-holder').style.visibility = 'visible';
initial(start, end);
}
else {
document.getElementById('Alert').style.visibility = 'visible'; //Will show
document.getElementById('canvas-holder').style.visibility = 'hidden';
}
}
});
$("#datepicker2").datepicker({
onSelect: function() {
endDate = $(this).datepicker('getDate');
end = formatDate(endDate);
alert('skn here s' + startDate);
alert('skn here e' + endDate);
if( start!=null && end!=null && end>=start)
{document.getElementById('Alert').style.visibility = 'hidden';
document.getElementById('canvas-holder').style.visibility = 'visible';
initial(start, end);
}
else {
document.getElementById('Alert').style.visibility = 'visible'; //Will show
document.getElementById('canvas-holder').style.visibility = 'hidden';
}
}
});
});
Please find below error I get in browser console.
Uncaught TypeError: $(...).datepicker is not a function
at HTMLDocument.<anonymous> (index.html:64)
at fire (jquery-1.10.2.js:3048)
at Object.fireWith [as resolveWith] (jquery-1.10.2.js:3160)
at Function.ready (jquery-1.10.2.js:433)
at HTMLDocument.completed (jquery-1.10.2.js:104)
I have incorporated changes as suggested. In that case date picker shows but not as expected.
Date PickerIssue:
Date Picker Expected
try changing this to
<link href = "jquery-ui.css" rel = "stylesheet">
<script src = "jquery-1.10.2.js"></script>
<script src = "jquery-ui.js"></script>
you need to load jquery before jquery-ui.js

Facebook Tracking of In-Page Events with Conversion Pixel Code

Full disclosure - I'm not a programmer, but I'm the only one in my organisation who might be able to get this working. Can anyone help with the following please?
I'm trying to use Facebook's conversion pixel code to track certain button clicks on our site. Facebook's developer docs give the following instructions for tracking in-page events:
After the base code snippet is installed, you can track in-page actions, such as clicks on a button, by making a _fbq.push('track') call for the conversion pixel through registering different event handlers on an HTML DOM element. For example:
function trackConversionEvent(val, cny) {
var cd = {};
cd.value = val;
cd.currency = cny;
_fbq.push(['track', '<pixel_id>', cd]);
}
<button onClick="trackConversionEvent('10.00','USD');" /
The problem I'm facing is it's not clear to me what Facebook means by "the base code snippet". My initial assumption was that it's the conversion pixel code they give you to install in the head section of the page, i.e.
<!-- Facebook Conversion Code -->
<script>(function() {
var _fbq = window._fbq || (window._fbq = []);
if (!_fbq.loaded) {
var fbds = document.createElement('script');
fbds.async = true;
fbds.src = '//connect.facebook.net/en_US/fbds.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(fbds, s);
_fbq.loaded = true;
}
})();
window._fbq = window._fbq || [];
window._fbq.push(['track', '<pixel_id>', {'value':'0.00','currency':'USD'}]);
</script>
<noscript><img height="1" width="1" alt="" style="display:none" src="https://www.facebook.com/tr?ev=<pixel_id>&cd[value]=0.00&cd[currency]=USD&noscript=1" /></noscript>
However, if I install the above on our page it loads/fires the conversion pixel code each time the page loads rather than on the button click (presumably because it's typically used on a thank you/confirmation page). Can anyone shed any light on this for me? I believe I understand where to position the onClick code to associate it with a button click but I'm struggling to understand where I need to position the trackConversionEvent code and what the base code snippet is. Through testing, I know that removing the following lines from the larger code snippet stops the pixel from loading:
window._fbq = window._fbq || [];
window._fbq.push(['track', '<pixel_id>', {'value':'0.00','currency':'USD'}]);
but I'm not sure if that's actually what I need to do. Do I for example, need to replace those two lines with the trackConversionEvent code so that the pixel doesn't fire when the page loads but the onClick code actually functions instead when the button is clicked?
Many thanks in advance for any pointers or suggestions.
This should work, I.ve just tested on a blog based on WP.
<!-- Facebook Conversion Code -->
<script>(function() {
var _fbq = window._fbq || (window._fbq = []);
if (!_fbq.loaded) {
var fbds = document.createElement('script');
fbds.async = true;
fbds.src = '//connect.facebook.net/en_US/fbds.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(fbds, s);
_fbq.loaded = true;
}
})();
window._fbq = window._fbq || [];
</script>
<noscript><img height="1" width="1" alt="" style="display:none" src="https://www.facebook.com/tr?ev=<pixel_id>&cd[value]=0.00&cd[currency]=USD&noscript=1" /></noscript>
<!-- End Of Facebook Conversion Code -->
This is the event handler that you could bind to any button, link or any DOM element::
function trackConversionEvent(val, cny) {
var cd = {};
cd.value = val;
cd.currency = cny;
_fbq.push(['track', '<pixel_id>', cd]);
}
<button onClick="trackConversionEvent('10.00','USD');"

Limit number of tweets in Tumblr

I'm using the twitter block in tumblr which displays the latest tweets from my twitter feed. Right now it displays the last 20 tweets but I want it to only show the last 5 tweets. anyone have any idea how I can do that?
the code I'm using right now is below. I tried changing the .length variable to 5 in the loop, but that didn't do anything:
{block:Twitter}
<div id="twitter" style="display:none;">
<h3>Latest Tweets</h3>
<div id="tweets"></div>
</div>
<script type="text/javascript">
function recent_tweets(data) {
for (i=0; i<data.length; i++) {
document.getElementById("tweets").innerHTML =
document.getElementById("tweets").innerHTML +
'<a href="http://twitter.com/{TwitterUsername}/status/' +
(data[i].id_str ? data[i].id_str : data[i].id) +
'"><div class="content">' + data[i].text +
'</div></a>';
}
document.getElementById("twitter").style.display = 'block';
}
</script>
{/block:Twitter}
Not sure how you changed the variable, but this should work:
<script type="text/javascript">
function recent_tweets(data) {
for (i=0; i<5; i++) {
document.getElementById("tweets").innerHTML =
document.getElementById("tweets").innerHTML +
'<a href="http://twitter.com/{TwitterUsername}/status/' +
(data[i].id_str ? data[i].id_str : data[i].id) +
'"><div class="content">' + data[i].text +
'</div></a>';
}
document.getElementById("twitter").style.display = 'block';
}
</script>
Update
You'll also need to remove the 2nd recent_tweets function that your are calling. The one you change to be i<5 is being overwritten by another one being called later in your theme file.