334 lines
12 KiB
PHP
334 lines
12 KiB
PHP
<style>
|
|
* {
|
|
box-sizing: border-box;
|
|
margin: 0;
|
|
padding: 0;
|
|
font-family: system-ui, -apple-system, sans-serif;
|
|
}
|
|
|
|
.wav-calculator-container {
|
|
background-color: #ffffff;
|
|
padding: 24px;
|
|
border-radius: 0px;
|
|
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
|
|
border: 1px solid #e5e5e5;
|
|
}
|
|
|
|
.wav-calculator-title {
|
|
color: #000000;
|
|
margin-bottom: 24px;
|
|
font-size: 20px;
|
|
font-weight: 500;
|
|
letter-spacing: -0.2px;
|
|
}
|
|
|
|
.wav-calculator-input-group {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.wav-calculator-label {
|
|
display: block;
|
|
margin-bottom: 8px;
|
|
color: #000000;
|
|
font-weight: 400;
|
|
font-size: 13px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
|
|
.wav-calculator-input {
|
|
width: 100%;
|
|
padding: 12px;
|
|
border: 1px solid #e5e5e5;
|
|
border-radius: 0px;
|
|
font-size: 16px;
|
|
background-color: #ffffff;
|
|
}
|
|
|
|
.wav-calculator-input:focus {
|
|
outline: none;
|
|
border-color: #000000;
|
|
box-shadow: none;
|
|
}
|
|
|
|
.wav-calculator-results {
|
|
margin-top: 24px;
|
|
padding: 20px;
|
|
background-color: #fafafa;
|
|
border-radius: 0px;
|
|
border: 1px solid #e5e5e5;
|
|
}
|
|
|
|
.wav-calculator-result-item {
|
|
margin-bottom: 12px;
|
|
font-size: 14px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
color: #333333;
|
|
}
|
|
|
|
.wav-calculator-result-item:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.wav-calculator-result-item strong {
|
|
color: #000000;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.wav-calculator-radio-group {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 8px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.wav-calculator-radio-button {
|
|
position: relative;
|
|
text-align: center;
|
|
}
|
|
|
|
.wav-calculator-radio-button input[type="radio"] {
|
|
display: none;
|
|
}
|
|
|
|
.wav-calculator-radio-button label {
|
|
display: block;
|
|
padding: 12px;
|
|
background-color: #ffffff;
|
|
border: 1px solid #e5e5e5;
|
|
border-radius: 0px;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
margin: 0;
|
|
font-size: 13px;
|
|
text-transform: none;
|
|
letter-spacing: 0;
|
|
}
|
|
|
|
.wav-calculator-radio-button input[type="radio"]:checked + label {
|
|
background-color: #000000;
|
|
color: white;
|
|
border-color: #000000;
|
|
}
|
|
|
|
.wav-calculator-select-group {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 8px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.wav-calculator-select-button {
|
|
position: relative;
|
|
}
|
|
|
|
.wav-calculator-select-button input[type="radio"] {
|
|
display: none;
|
|
}
|
|
|
|
.wav-calculator-select-button label {
|
|
display: block;
|
|
padding: 12px;
|
|
background-color: #ffffff;
|
|
border: 1px solid #e5e5e5;
|
|
border-radius: 0px;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
margin: 0;
|
|
text-align: center;
|
|
font-size: 13px;
|
|
text-transform: none;
|
|
letter-spacing: 0;
|
|
}
|
|
|
|
.wav-calculator-select-button input[type="radio"]:checked + label {
|
|
background-color: #000000;
|
|
color: white;
|
|
border-color: #000000;
|
|
}
|
|
|
|
.wav-calculator-input-with-unit {
|
|
position: relative;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.wav-calculator-input-with-unit input {
|
|
padding-right: 50px;
|
|
}
|
|
|
|
.wav-calculator-unit {
|
|
position: absolute;
|
|
right: 12px;
|
|
color: #666666;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.wav-calculator-invalid {
|
|
border-color: #999999;
|
|
background-color: #fafafa;
|
|
}
|
|
|
|
.wav-calculator-invalid + .wav-calculator-unit {
|
|
color: #999999;
|
|
}
|
|
|
|
.wav-calculator-invalid:focus {
|
|
border-color: #999999;
|
|
}
|
|
</style>
|
|
|
|
<div class="wav-calculator-container">
|
|
<h1 class="wav-calculator-title">WAV Recording Time Calculator</h1>
|
|
|
|
<div class="wav-calculator-input-group">
|
|
<label class="wav-calculator-label">SD Card Size</label>
|
|
<div class="wav-calculator-input-with-unit">
|
|
<input type="number" id="wavCalculatorCardSize" class="wav-calculator-input" min="1" value="32" placeholder="Size in GB">
|
|
<span class="wav-calculator-unit">GB</span>
|
|
</div>
|
|
</div>
|
|
|
|
<label class="wav-calculator-label">Sample Rate</label>
|
|
<div class="wav-calculator-radio-group">
|
|
<div class="wav-calculator-radio-button">
|
|
<input type="radio" id="wavCalculatorRate48" name="wavCalculatorSampleRate" value="48" checked>
|
|
<label for="wavCalculatorRate48">48 kHz</label>
|
|
</div>
|
|
<div class="wav-calculator-radio-button">
|
|
<input type="radio" id="wavCalculatorRate96" name="wavCalculatorSampleRate" value="96">
|
|
<label for="wavCalculatorRate96">96 kHz</label>
|
|
</div>
|
|
<div class="wav-calculator-radio-button">
|
|
<input type="radio" id="wavCalculatorRate192" name="wavCalculatorSampleRate" value="192">
|
|
<label for="wavCalculatorRate192">192 kHz</label>
|
|
</div>
|
|
</div>
|
|
|
|
<label class="wav-calculator-label">Bit Depth</label>
|
|
<div class="wav-calculator-select-group">
|
|
<div class="wav-calculator-select-button">
|
|
<input type="radio" id="wavCalculatorBit16" name="wavCalculatorBitDepth" value="16">
|
|
<label for="wavCalculatorBit16">16-bit</label>
|
|
</div>
|
|
<div class="wav-calculator-select-button">
|
|
<input type="radio" id="wavCalculatorBit24" name="wavCalculatorBitDepth" value="24" checked>
|
|
<label for="wavCalculatorBit24">24-bit</label>
|
|
</div>
|
|
<div class="wav-calculator-select-button">
|
|
<input type="radio" id="wavCalculatorBit32" name="wavCalculatorBitDepth" value="32">
|
|
<label for="wavCalculatorBit32">32-bit</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="wav-calculator-input-group">
|
|
<label class="wav-calculator-label">Number of Tracks</label>
|
|
<input type="number" id="wavCalculatorTracks" class="wav-calculator-input" min="1" value="1">
|
|
</div>
|
|
|
|
<div class="wav-calculator-results">
|
|
<div class="wav-calculator-result-item">
|
|
<span>Recording Time (<span id="wavCalculatorCardSizeDisplay">32</span> GB):</span>
|
|
<strong id="wavCalculatorRecordingTime">--</strong>
|
|
</div>
|
|
<div class="wav-calculator-result-item">
|
|
<span>Data Rate:</span>
|
|
<strong id="wavCalculatorDataRate">--</strong>
|
|
</div>
|
|
<div class="wav-calculator-result-item">
|
|
<span>Storage per Hour:</span>
|
|
<strong id="wavCalculatorStorageRequired">--</strong>
|
|
</div>
|
|
<div class="wav-calculator-result-item">
|
|
Note: Storage cards have slightly less usable space than their advertised capacity due to file system overhead. Plan accordingly when recording near maximum capacity.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
class WavCalculator {
|
|
calculateRecordingTime(cardSizeGB, sampleRate, bitDepth, tracks = 1) {
|
|
const totalBytes = cardSizeGB * 1000000000;
|
|
const bytesPerSecond = (sampleRate * 1000) * (bitDepth / 8) * tracks;
|
|
const totalSeconds = totalBytes / bytesPerSecond;
|
|
|
|
const hours = Math.floor(totalSeconds / 3600);
|
|
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
|
const seconds = Math.floor(totalSeconds % 60);
|
|
|
|
const dataRateKbps = (bytesPerSecond * 8) / 1000;
|
|
const dataRateMbps = dataRateKbps / 1000;
|
|
|
|
const storagePerHour = (bytesPerSecond * 3600) / 1000000000;
|
|
|
|
return {
|
|
hours,
|
|
minutes,
|
|
seconds,
|
|
formattedTime: `${hours}h ${minutes}m ${seconds}s`,
|
|
dataRateKbps: dataRateKbps.toFixed(1),
|
|
dataRateMbps: dataRateMbps.toFixed(2),
|
|
storagePerHour: storagePerHour.toFixed(2)
|
|
};
|
|
}
|
|
}
|
|
|
|
const wavCalculator = new WavCalculator();
|
|
|
|
function wavCalculatorUpdateCalculation() {
|
|
const cardSize = parseFloat(document.getElementById('wavCalculatorCardSize').value);
|
|
const sampleRate = parseInt(document.querySelector('input[name="wavCalculatorSampleRate"]:checked').value);
|
|
const bitDepth = parseInt(document.querySelector('input[name="wavCalculatorBitDepth"]:checked').value);
|
|
const tracks = parseInt(document.getElementById('wavCalculatorTracks').value);
|
|
|
|
const cardSizeInput = document.getElementById('wavCalculatorCardSize');
|
|
const tracksInput = document.getElementById('wavCalculatorTracks');
|
|
|
|
let isValid = true;
|
|
|
|
if (!cardSize || cardSize <= 0) {
|
|
cardSizeInput.classList.add('wav-calculator-invalid');
|
|
isValid = false;
|
|
} else {
|
|
cardSizeInput.classList.remove('wav-calculator-invalid');
|
|
document.getElementById('wavCalculatorCardSizeDisplay').textContent = cardSize;
|
|
}
|
|
|
|
if (!tracks || tracks < 1) {
|
|
tracksInput.classList.add('wav-calculator-invalid');
|
|
isValid = false;
|
|
} else {
|
|
tracksInput.classList.remove('wav-calculator-invalid');
|
|
}
|
|
|
|
if (!isValid) {
|
|
document.getElementById('wavCalculatorRecordingTime').textContent = '--';
|
|
document.getElementById('wavCalculatorDataRate').textContent = '--';
|
|
document.getElementById('wavCalculatorStorageRequired').textContent = '--';
|
|
return;
|
|
}
|
|
|
|
const result = wavCalculator.calculateRecordingTime(cardSize, sampleRate, bitDepth, tracks);
|
|
|
|
document.getElementById('wavCalculatorRecordingTime').textContent = result.formattedTime;
|
|
document.getElementById('wavCalculatorDataRate').textContent =
|
|
`${result.dataRateKbps} Kbps (${result.dataRateMbps} Mbps)`;
|
|
document.getElementById('wavCalculatorStorageRequired').textContent =
|
|
`${result.storagePerHour} GB/hour`;
|
|
}
|
|
|
|
document.getElementById('wavCalculatorCardSize').addEventListener('input', wavCalculatorUpdateCalculation);
|
|
document.getElementById('wavCalculatorTracks').addEventListener('input', wavCalculatorUpdateCalculation);
|
|
|
|
document.querySelectorAll('input[name="wavCalculatorSampleRate"]').forEach(radio => {
|
|
radio.addEventListener('change', wavCalculatorUpdateCalculation);
|
|
});
|
|
|
|
document.querySelectorAll('input[name="wavCalculatorBitDepth"]').forEach(radio => {
|
|
radio.addEventListener('change', wavCalculatorUpdateCalculation);
|
|
});
|
|
|
|
wavCalculatorUpdateCalculation();
|
|
</script>
|