Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: main.cpp
- Revision:
- 4:c989412b91ea
- Parent:
- 3:c04d8d0493f4
- Child:
- 5:9f4ffb2b0e6b
--- a/main.cpp Wed May 15 15:32:34 2013 +0000
+++ b/main.cpp Wed May 15 17:53:33 2013 +0000
@@ -32,17 +32,23 @@
Serial pc(USBTX, USBRX);
const unsigned SAMPLE_RATE_HZ = 7889;
-const unsigned SAMPLE_PERIOD_US = (1000000U / SAMPLE_RATE_HZ);
+const unsigned SAMPLE_PERIOD_US = (1000000U / SAMPLE_RATE_HZ);
const unsigned SAMPLE_BUFFER_SIZE = 9000;
-const float CHUNK_DURATION = 0.08;
+const unsigned CHUNK_DURATION_MS = 80;
+const unsigned CHUNK_SIZE = SAMPLE_RATE_HZ * CHUNK_DURATION_MS / 1000;
+const unsigned NUM_CHUNKS = SAMPLE_BUFFER_SIZE / CHUNK_SIZE;
Ticker sampleTicker;
Timer timer;
+// audio samples
int8_t sampleBuffer[SAMPLE_BUFFER_SIZE]; // 1 second buffer
int8_t * volatile nextSample;
uint16_t volatile samplesRemaining;
+// vowel decisions
+bool vowels[ NUM_CHUNKS ];
+
extern "C"
void ADC0_IRQHandler(void)
{
@@ -97,16 +103,14 @@
pc.printf("Done. %u samples in %f usec = %f samples/sec\r\n", SAMPLE_BUFFER_SIZE, elapsed * 1.0e6, SAMPLE_BUFFER_SIZE / elapsed);
}
-void playAudio(float duration, int8_t *start=sampleBuffer, uint16_t nsamples=SAMPLE_BUFFER_SIZE)
+void playAudio(unsigned duration_ms, int8_t *start=sampleBuffer, uint16_t nsamples=SAMPLE_BUFFER_SIZE)
{
- greenLED = 0.0;
resetSampleBuffer(start, nsamples);
timer.reset();
timer.start();
- sampleTicker.attach(&playAudioSample, duration/nsamples);
+ sampleTicker.attach_us(&playAudioSample, duration_ms*1000/nsamples);
while (samplesRemaining) {
- wait_us(50000);
- greenLED.write(1.0 - (1.0 * samplesRemaining / nsamples));
+ wait_us(CHUNK_DURATION_MS * 1000);
}
}
@@ -122,47 +126,57 @@
}
// returns true if chunk was louder than minimum
-bool analyzeChunk(int8_t *chunkStart, uint16_t chunkSize, float powerRef)
+bool analyzeChunk(int8_t *chunkStart, uint16_t CHUNK_SIZE, float powerRef, bool *pisvowel = 0)
{
- AudioAnalyzer analyzer(chunkStart, chunkSize);
+ AudioAnalyzer analyzer(chunkStart, CHUNK_SIZE);
uint32_t power = analyzer.getPower();
uint16_t zcs = analyzer.getZeroCrossings();
int8_t min, max;
analyzer.getMinMaxValues(&min, &max);
- float logPower = ::log((double)power);
- if (isnan(logPower) || logPower < 1.0) {
- return false;
- }
- float zcRatio = (float)zcs / chunkSize;
- pc.printf("%.2f\t%.2f\t%d\t%d\t", zcRatio*100, logPower-powerRef, min, max);
- return true;
+ analyzer.setPowerRef(powerRef);
+ float logPower = analyzer.getLogPower();
+ float zcRatio = analyzer.getZeroCrossingRatioPercent();
+ pc.printf("%.2f\t%.2f\t%.2f\t%d\t%d\t%d\t", zcRatio, logPower, zcRatio / (logPower - AudioAnalyzer::VowelXIntercept), min, max, analyzer.isVowel());
+ if (pisvowel)
+ *pisvowel = analyzer.isVowel();
+ return analyzer.isVoiced();
}
void analyze(bool playToo = false)
{
- uint16_t chunkSize = SAMPLE_RATE_HZ * CHUNK_DURATION;
- uint16_t nChunks = SAMPLE_BUFFER_SIZE / chunkSize;
int8_t *chunkStart = sampleBuffer;
AudioAnalyzer analyzer(sampleBuffer, SAMPLE_BUFFER_SIZE);
uint32_t power = analyzer.getPower();
float powerRef = ::log((double)power);
pc.printf("Reference power = %.2f\r\n", powerRef);
- pc.printf("Analyzing %d chunks of %d samples (%.2f seconds):\r\n", nChunks, chunkSize, CHUNK_DURATION);
- pc.printf("chunk\tstart\tzcratio\tlogp\tmin\tmax\tvowel\r\n");
- for (uint16_t chunk = 0; chunk < nChunks; chunk++) {
- pc.printf("%u\t%.2f\t", chunk, chunk * CHUNK_DURATION);
- bool loudEnough = analyzeChunk(chunkStart, chunkSize, powerRef);
+ pc.printf("Analyzing %d chunks of %d samples (%.2f seconds):\r\n", NUM_CHUNKS, CHUNK_SIZE, CHUNK_DURATION_MS);
+ pc.printf("chunk\tstartms\tzcratio\tlogp\tmaxs\tmin\tmax\tisVowel\tvowel\r\n");
+ for (uint16_t chunk = 0; chunk < NUM_CHUNKS; chunk++) {
+ pc.printf("%u\t%u\t", chunk, chunk * CHUNK_DURATION_MS);
+ bool loudEnough = analyzeChunk(chunkStart, CHUNK_SIZE, powerRef, &vowels[chunk]);
if (loudEnough) {
if (playToo) {
while (! pc.readable())
- playAudio(CHUNK_DURATION, chunkStart, chunkSize);
+ playAudio(CHUNK_DURATION_MS, chunkStart, CHUNK_SIZE);
int c = pc.getc();
pc.putc(c);
} else
pc.puts("-");
}
pc.puts("\r\n");
- chunkStart += chunkSize;
+ chunkStart += CHUNK_SIZE;
+ }
+}
+
+// assumes that vowels[] has been set by analyze
+void playWithBilly()
+{
+ int8_t *chunkStart = sampleBuffer;
+ for (uint16_t chunk = 0; chunk < NUM_CHUNKS; chunk++) {
+ greenLED = vowels[chunk] ? 0.0 : 1.0;
+ playAudio(CHUNK_DURATION_MS, chunkStart, CHUNK_SIZE);
+ chunkStart += CHUNK_SIZE;
+
}
}
@@ -189,17 +203,19 @@
#if 0
audioTest();
- playAudio(1.0);
+ playAudio(1000);
analyze();
#endif
recordAudio();
float duration = timer.read();
- playAudio(duration);
+ // playAudio(duration * 1000);
float elapsed = timer.read();
pc.printf("Done. %u samples in %f usec = %f samples/sec", SAMPLE_BUFFER_SIZE, elapsed * 1.0e6, SAMPLE_BUFFER_SIZE / elapsed);
pc.printf(" (Rate %#+0.2f%%)\r\n", (duration-elapsed)*100/duration);
- analyze(true);
+ analyze(false);
// dumpAudio();
+
+ playWithBilly();
}
}