https://forum.pjrc.com/threads/27409-Play-RAW-from-Serial-Flash?p=77666#post77666dds
@@ -85,6 +85,7 @@ | |||
#include "play_queue.h" | |||
#include "play_sd_raw.h" | |||
#include "play_sd_wav.h" | |||
#include "play_serialflash_raw.h" | |||
#include "record_queue.h" | |||
#include "synth_tonesweep.h" | |||
#include "synth_sine.h" |
@@ -10,6 +10,7 @@ | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
// Create the Audio components. These should be created in the | |||
// order data flows, inputs/sources -> processing -> outputs |
@@ -14,6 +14,7 @@ | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
// Create the Audio components. These should be created in the | |||
// order data flows, inputs/sources -> processing -> outputs |
@@ -15,6 +15,7 @@ | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
const int myInput = AUDIO_INPUT_LINEIN; | |||
//const int myInput = AUDIO_INPUT_MIC; |
@@ -13,6 +13,7 @@ | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
// GUItool: begin automatically generated code | |||
AudioInputAnalog adc1; //xy=164,95 |
@@ -7,6 +7,7 @@ This example code is in the public domain | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
const int myInput = AUDIO_INPUT_LINEIN; | |||
// const int myInput = AUDIO_INPUT_MIC; |
@@ -3,6 +3,7 @@ | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
// GUItool: begin automatically generated code | |||
AudioInputI2S i2s1; //xy=139,91 |
@@ -50,6 +50,7 @@ many blocks you provided with AudioMemory(). | |||
#include <Wire.h> | |||
#include <SD.h> | |||
#include <SPI.h> | |||
#include <SerialFlash.h> | |||
#include <Bounce.h> | |||
@@ -13,6 +13,7 @@ | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
// GUItool: begin automatically generated code | |||
AudioSynthWaveformSine sine1; //xy=158,74 |
@@ -2,6 +2,7 @@ | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
// GUItool: begin automatically generated code | |||
AudioInputI2S i2s1; //xy=99,60 |
@@ -25,6 +25,7 @@ The audio board uses the following pins. | |||
#include <Wire.h> | |||
#include <SD.h> | |||
#include <SPI.h> | |||
#include <SerialFlash.h> | |||
#include <Bounce.h> | |||
#include "filters.h" | |||
@@ -51,6 +51,7 @@ many blocks you provided with AudioMemory(). | |||
#include <Wire.h> | |||
#include <SD.h> | |||
#include <SPI.h> | |||
#include <SerialFlash.h> | |||
#include <Bounce.h> | |||
// Number of samples in each delay line |
@@ -9,6 +9,7 @@ | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
// GUItool: begin automatically generated code | |||
AudioInputAnalog adc1; //xy=161,80 |
@@ -9,6 +9,7 @@ | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
// GUItool: begin automatically generated code | |||
AudioInputI2S i2s1; //xy=200,69 |
@@ -6,6 +6,7 @@ This example code is in the public domain | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
const int myInput = AUDIO_INPUT_LINEIN; | |||
// const int myInput = AUDIO_INPUT_MIC; |
@@ -7,6 +7,7 @@ This example code is in the public domain | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
const int myInput = AUDIO_INPUT_LINEIN; |
@@ -7,6 +7,7 @@ This example code is in the public domain | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
const int myInput = AUDIO_INPUT_LINEIN; | |||
// const int myInput = AUDIO_INPUT_MIC; |
@@ -7,6 +7,7 @@ This example code is in the public domain | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
const int myInput = AUDIO_INPUT_LINEIN; |
@@ -7,6 +7,7 @@ This example code is in the public domain | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
const int myInput = AUDIO_INPUT_LINEIN; |
@@ -26,6 +26,7 @@ The audio board uses the following pins. | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
#include <Bounce.h> | |||
AudioSynthToneSweep myEffect; |
@@ -23,6 +23,7 @@ | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
// GUItool: begin automatically generated code | |||
AudioSynthWaveform waveform1; //xy=110,75 |
@@ -17,6 +17,7 @@ | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
// GUItool: begin automatically generated code | |||
AudioSynthWaveformSine sine1; //xy=125,221 |
@@ -15,6 +15,7 @@ | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
// GUItool: begin automatically generated code | |||
AudioInputI2S i2s2; //xy=105,63 |
@@ -2,6 +2,7 @@ | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
#include <Bounce.h> | |||
// WAV files converted to code by wav2sketch |
@@ -9,6 +9,7 @@ | |||
#include <Wire.h> | |||
#include <SD.h> | |||
#include <SPI.h> | |||
#include <SerialFlash.h> | |||
#include "PlaySynthMusic.h" | |||
@@ -5,6 +5,7 @@ | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
// GUItool: begin automatically generated code | |||
AudioSynthWaveform waveform1; //xy=188,240 |
@@ -29,6 +29,7 @@ | |||
#include <Wire.h> | |||
#include <SPI.h> | |||
#include <SD.h> | |||
#include <SerialFlash.h> | |||
AudioPlaySdWav playWav1; | |||
// Use one of these 3 output types: Digital I2S, Digital S/PDIF, or Analog DAC |
@@ -549,7 +549,7 @@ | |||
<h3>Summary</h3> | |||
<p>Play a short sound clip, stored directly in memory. | |||
Data files are created with the | |||
<a href="https://github.com/PaulStoffregen/Audio/tree/master/examples/PlayFromSketch/wav2sketch" target="_blank">wav2sketch program</a>, | |||
<a href="https://github.com/PaulStoffregen/Audio/tree/master/examples/SamplePlayer/wav2sketch" target="_blank">wav2sketch program</a>, | |||
and copied to the sketch folder to become part of your sketch.</p> | |||
<h3>Audio Connections</h3> | |||
<table class=doc align=center cellpadding=3> | |||
@@ -599,7 +599,7 @@ | |||
<script type="text/javascript"> | |||
RED.nodes.registerType('AudioPlaySdWav',{ | |||
shortName: "playWav", | |||
shortName: "playSdWav", | |||
inputs:0, | |||
outputs:2, | |||
category: 'play-function', | |||
@@ -672,7 +672,7 @@ | |||
<script type="text/javascript"> | |||
RED.nodes.registerType('AudioPlaySdRaw',{ | |||
shortName: "playRaw", | |||
shortName: "playSdRaw", | |||
inputs:0, | |||
outputs:1, | |||
category: 'play-function', | |||
@@ -734,6 +734,73 @@ | |||
</script> | |||
<script type="text/javascript"> | |||
RED.nodes.registerType('AudioPlaySerialflashRaw',{ | |||
shortName: "playFlashRaw", | |||
inputs:0, | |||
outputs:1, | |||
category: 'play-function', | |||
color:"#E6E0F8", | |||
icon: "arrow-in.png" | |||
}); | |||
</script> | |||
<script type="text/x-red" data-help-name="AudioPlaySerialflashRaw"> | |||
<h3>Summary</h3> | |||
<div> | |||
<p>Play a RAW data file, stored on a Serial Flash chip. These chips | |||
are far more efficient than SD cards, allowing many files to be | |||
played simultaneously by copies of this object. | |||
</p> | |||
<p align=center><img src="w25q128fv.jpg"><br><small>W25Q128FV Serial Flash</small></p> | |||
</div> | |||
<h3>Audio Connections</h3> | |||
<table class=doc align=center cellpadding=3> | |||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||
<tr class=odd><td align=center>Out 0</td><td>Sound Output</td></tr> | |||
</table> | |||
<h3>Functions</h3> | |||
<p class=func><span class=keyword>play</span>(filename);</p> | |||
<p class=desc>Begin playing a RAW data file. If a file is already playing, | |||
it is stopped and this file starts playing from the beginning. | |||
</p> | |||
<p class=func><span class=keyword>stop</span>();</p> | |||
<p class=desc>Stop playing. If not playing, this function has no effect. | |||
</p> | |||
<p class=func><span class=keyword>isPlaying</span>();</p> | |||
<p class=desc>Return true (non-zero) if playing, or false (zero) | |||
when not playing. | |||
</p> | |||
<p class=func><span class=keyword>positionMillis</span>();</p> | |||
<p class=desc>While playing, return the current time offset, in | |||
milliseconds. When not playing, the return from this function | |||
is undefined. | |||
</p> | |||
<p class=func><span class=keyword>lengthMillis</span>();</p> | |||
<p class=desc>Return the total length of the current sound clip, | |||
in milliseconds. When not playing, the return from this function | |||
is undefined. | |||
</p> | |||
<h3>Examples</h3> | |||
<!--<p class=exam>File > Examples > Audio > Recorder--> | |||
<p class=exam>TODO: play example needed.... | |||
</p> | |||
<p class=exam>File > Examples > SerialFlash > CopyFromSD | |||
</p> | |||
<h3>Notes</h3> | |||
<p>The data file must be RAW 16 bit signed integers in LSB-first format. | |||
</p> | |||
<p>The <a href="https://github.com/PaulStoffregen/SerialFlash" target="_blank">SerialFlash library</a> | |||
is used to access the flash chip. You can also use SerialFlash's functions | |||
to access the stored files, or add data to the flash chip. | |||
</p> | |||
</script> | |||
<script type="text/x-red" data-template-name="AudioPlaySerialflashRaw"> | |||
<div class="form-row"> | |||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||
<input type="text" id="node-input-name" placeholder="Name"> | |||
</div> | |||
</script> | |||
<script type="text/javascript"> | |||
RED.nodes.registerType('AudioPlayQueue',{ |
@@ -0,0 +1,112 @@ | |||
/* Audio Library for Teensy 3.X | |||
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com | |||
* Modified to use SerialFlash instead of SD library by Wyatt Olson <wyatt@digitalcave.ca> | |||
* | |||
* Development of this audio library was funded by PJRC.COM, LLC by sales of | |||
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop | |||
* open source software by purchasing Teensy or other PJRC products. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a copy | |||
* of this software and associated documentation files (the "Software"), to deal | |||
* in the Software without restriction, including without limitation the rights | |||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
* copies of the Software, and to permit persons to whom the Software is | |||
* furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice, development funding notice, and this permission | |||
* notice shall be included in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
* THE SOFTWARE. | |||
*/ | |||
#include "play_serialflash_raw.h" | |||
#include "spi_interrupt.h" | |||
void AudioPlaySerialflashRaw::begin(void) | |||
{ | |||
playing = false; | |||
file_offset = 0; | |||
file_size = 0; | |||
} | |||
bool AudioPlaySerialflashRaw::play(const char *filename) | |||
{ | |||
stop(); | |||
AudioStartUsingSPI(); | |||
rawfile = SerialFlash.open(filename); | |||
if (!rawfile) { | |||
//Serial.println("unable to open file"); | |||
AudioStopUsingSPI(); | |||
return false; | |||
} | |||
file_size = rawfile.size(); | |||
file_offset = 0; | |||
//Serial.println("able to open file"); | |||
playing = true; | |||
return true; | |||
} | |||
void AudioPlaySerialflashRaw::stop(void) | |||
{ | |||
__disable_irq(); | |||
if (playing) { | |||
playing = false; | |||
__enable_irq(); | |||
rawfile.close(); | |||
AudioStopUsingSPI(); | |||
} else { | |||
__enable_irq(); | |||
} | |||
} | |||
void AudioPlaySerialflashRaw::update(void) | |||
{ | |||
unsigned int i, n; | |||
audio_block_t *block; | |||
// only update if we're playing | |||
if (!playing) return; | |||
// allocate the audio blocks to transmit | |||
block = allocate(); | |||
if (block == NULL) return; | |||
if (rawfile.available()) { | |||
// we can read more data from the file... | |||
n = rawfile.read(block->data, AUDIO_BLOCK_SAMPLES*2); | |||
file_offset += n; | |||
for (i=n/2; i < AUDIO_BLOCK_SAMPLES; i++) { | |||
block->data[i] = 0; | |||
} | |||
transmit(block); | |||
} else { | |||
rawfile.close(); | |||
AudioStopUsingSPI(); | |||
playing = false; | |||
Serial.println("Finished playing sample"); //TODO | |||
} | |||
release(block); | |||
} | |||
#define B2M (uint32_t)((double)4294967296000.0 / AUDIO_SAMPLE_RATE_EXACT / 2.0) // 97352592 | |||
uint32_t AudioPlaySerialflashRaw::positionMillis(void) | |||
{ | |||
return ((uint64_t)file_offset * B2M) >> 32; | |||
} | |||
uint32_t AudioPlaySerialflashRaw::lengthMillis(void) | |||
{ | |||
return ((uint64_t)file_size * B2M) >> 32; | |||
} | |||
@@ -0,0 +1,52 @@ | |||
/* Audio Library for Teensy 3.X | |||
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com | |||
* Modified to use SerialFlash instead of SD library by Wyatt Olson <wyatt@digitalcave.ca> | |||
* | |||
* Development of this audio library was funded by PJRC.COM, LLC by sales of | |||
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop | |||
* open source software by purchasing Teensy or other PJRC products. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a copy | |||
* of this software and associated documentation files (the "Software"), to deal | |||
* in the Software without restriction, including without limitation the rights | |||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
* copies of the Software, and to permit persons to whom the Software is | |||
* furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice, development funding notice, and this permission | |||
* notice shall be included in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
* THE SOFTWARE. | |||
*/ | |||
#ifndef play_serial_raw_h_ | |||
#define play_serial_raw_h_ | |||
#include <AudioStream.h> | |||
#include <SerialFlash.h> | |||
class AudioPlaySerialflashRaw : public AudioStream | |||
{ | |||
public: | |||
AudioPlaySerialflashRaw(void) : AudioStream(0, NULL) { begin(); } | |||
void begin(void); | |||
bool play(const char *filename); | |||
void stop(void); | |||
bool isPlaying(void) { return playing; } | |||
uint32_t positionMillis(void); | |||
uint32_t lengthMillis(void); | |||
virtual void update(void); | |||
private: | |||
SerialFlashFile rawfile; | |||
uint32_t file_size; | |||
volatile uint32_t file_offset; | |||
volatile bool playing; | |||
}; | |||
#endif |