1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-07-30 16:24:09 +03:00

Audio library to the new format

This commit is contained in:
Fede85
2013-06-27 19:15:53 +02:00
parent c13779daae
commit b28104b795
11 changed files with 18 additions and 8 deletions

View File

@ -0,0 +1,138 @@
/*
* Copyright (c) 2012 by Cristian Maglie <c.maglie@bug.st>
* DAC library for Arduino Due.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#include <DAC.h>
void DACClass::begin(uint32_t period) {
// Enable clock for DAC
pmc_enable_periph_clk(dacId);
dacc_reset(dac);
// Set transfer mode to double word
dacc_set_transfer_mode(dac, 1);
// Power save:
// sleep mode - 0 (disabled)
// fast wakeup - 0 (disabled)
dacc_set_power_save(dac, 0, 0);
// DAC refresh/startup timings:
// refresh - 0x08 (1024*8 dacc clocks)
// max speed mode - 0 (disabled)
// startup time - 0x10 (1024 dacc clocks)
dacc_set_timing(dac, 0x08, 0, DACC_MR_STARTUP_1024);
// Flexible channel selection with tags
dacc_enable_flexible_selection(dac);
// Set up analog current
dacc_set_analog_control(dac,
DACC_ACR_IBCTLCH0(0x02) |
DACC_ACR_IBCTLCH1(0x02) |
DACC_ACR_IBCTLDACCORE(0x01));
// Enable output channels
dacc_enable_channel(dac, 0);
dacc_enable_channel(dac, 1);
// Configure Timer Counter to trigger DAC
// --------------------------------------
pmc_enable_periph_clk(ID_TC1);
TC_Configure(TC0, 1,
TC_CMR_TCCLKS_TIMER_CLOCK2 | // Clock at MCR/8
TC_CMR_WAVE | // Waveform mode
TC_CMR_WAVSEL_UP_RC | // Counter running up and reset when equals to RC
TC_CMR_ACPA_SET | TC_CMR_ACPC_CLEAR);
const uint32_t TC = period / 8;
TC_SetRA(TC0, 1, TC / 2);
TC_SetRC(TC0, 1, TC);
TC_Start(TC0, 1);
// Configure clock source for DAC (2 = TC0 Output Chan. 1)
dacc_set_trigger(dac, 2);
// Configure pins
PIO_Configure(g_APinDescription[DAC0].pPort,
g_APinDescription[DAC0].ulPinType,
g_APinDescription[DAC0].ulPin,
g_APinDescription[DAC0].ulPinConfiguration);
PIO_Configure(g_APinDescription[DAC1].pPort,
g_APinDescription[DAC1].ulPinType,
g_APinDescription[DAC1].ulPin,
g_APinDescription[DAC1].ulPinConfiguration);
// Enable interrupt controller for DAC
dacc_disable_interrupt(dac, 0xFFFFFFFF);
NVIC_DisableIRQ(isrId);
NVIC_ClearPendingIRQ(isrId);
NVIC_SetPriority(isrId, 0);
NVIC_EnableIRQ(isrId);
}
void DACClass::end() {
TC_Stop(TC0, 1);
NVIC_DisableIRQ(isrId);
dacc_disable_channel(dac, 0);
dacc_disable_channel(dac, 1);
}
bool DACClass::canQueue() {
return (dac->DACC_TNCR == 0);
}
size_t DACClass::queueBuffer(const uint32_t *buffer, size_t size) {
// Try the first PDC buffer
if ((dac->DACC_TCR == 0) && (dac->DACC_TNCR == 0)) {
dac->DACC_TPR = (uint32_t) buffer;
dac->DACC_TCR = size;
dac->DACC_PTCR = DACC_PTCR_TXTEN;
if (cb)
dacc_enable_interrupt(dac, DACC_IER_ENDTX);
return size;
}
// Try the second PDC buffer
if (dac->DACC_TNCR == 0) {
dac->DACC_TNPR = (uint32_t) buffer;
dac->DACC_TNCR = size;
dac->DACC_PTCR = DACC_PTCR_TXTEN;
if (cb)
dacc_enable_interrupt(dac, DACC_IER_ENDTX);
return size;
}
// PDC buffers full, try again later...
return 0;
}
void DACClass::setOnTransmitEnd_CB(OnTransmitEnd_CB _cb, void *_data) {
cb = _cb;
cbData = _data;
if (!cb)
dacc_disable_interrupt(dac, DACC_IDR_ENDTX);
}
void DACClass::onService() {
uint32_t sr = dac->DACC_ISR;
if (sr & DACC_ISR_ENDTX) {
// There is a free slot, enqueue data
dacc_disable_interrupt(dac, DACC_IDR_ENDTX);
if (cb)
cb(cbData);
}
}
DACClass DAC(DACC_INTERFACE, DACC_INTERFACE_ID, DACC_ISR_ID);
void DACC_ISR_HANDLER(void) {
DAC.onService();
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2012 by Cristian Maglie <c.maglie@bug.st>
* DAC library for Arduino Due.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#ifndef DAC_INCLUDED
#define DAC_INCLUDED
#include "Arduino.h"
typedef void (*OnTransmitEnd_CB)(void *data);
class DACClass
{
public:
DACClass(Dacc *_dac, uint32_t _dacId, IRQn_Type _isrId) :
dac(_dac), dacId(_dacId), isrId(_isrId), cb(NULL) { };
void begin(uint32_t period);
void end();
bool canQueue();
size_t queueBuffer(const uint32_t *buffer, size_t size);
uint32_t *getCurrentQueuePointer();
void setOnTransmitEnd_CB(OnTransmitEnd_CB _cb, void *data);
void onService();
void enableInterrupts() { NVIC_EnableIRQ(isrId); };
void disableInterrupts() { NVIC_DisableIRQ(isrId); };
private:
Dacc *dac;
uint32_t dacId;
IRQn_Type isrId;
OnTransmitEnd_CB cb;
void *cbData;
};
extern DACClass DAC;
#endif

View File

@ -0,0 +1,83 @@
/*
Simple Audio Player
Demonstrates the use of the Audio library for the Arduino Due
Hardware required :
* Arduino shield with a SD card on CS4
* A sound file named "test.wav" in the root directory of the SD card
* Speaker attched to ground and DAC0
Original by Massimo Banzi September 20, 2012
Modified by Scott Fitzgerald October 19, 2012
This example code is in the public domain
http://arduino.cc/en/Tutorial/SimpleAudioPlayer
*/
#include <SD.h>
#include <SPI.h>
#include <Audio.h>
void setup()
{
// debug output at 9600 baud
Serial.begin(9600);
// setup SD-card
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println(" failed!");
return;
}
Serial.println(" done.");
// hi-speed SPI transfers
SPI.setClockDivider(4);
// 44100Khz stereo => 88200 sample rate
// 100 mSec of prebuffering.
Audio.begin(88200, 100);
}
void loop()
{
int count=0;
// open wave file from sdcard
File myFile = SD.open("test.wav");
if (!myFile) {
// if the file didn't open, print an error and stop
Serial.println("error opening test.wav");
while (true);
}
const int S=1024; // Number of samples to read in block
short buffer[S];
Serial.print("Playing");
// until the file is not finished
while (myFile.available()) {
// read from the file into buffer
myFile.read(buffer, sizeof(buffer));
// Prepare samples
int volume = 1024;
Audio.prepare(buffer, S, volume);
// Feed samples to audio
Audio.write(buffer, S);
// Every 100 block print a '.'
count++;
if (count == 100) {
Serial.print(".");
count = 0;
}
}
myFile.close();
Serial.println("End of file. Thank you for listening!");
while (true) ;
}

View File

@ -0,0 +1,21 @@
#######################################
# Syntax Coloring Map For Audio
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
Audio KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
prepare KEYWORD2
write KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################

View File

@ -0,0 +1,10 @@
name=Audio
author=cmaglie
email=Cristian Maglie <c.maglie@bug.st>
sentence=The libary to play audio files through the DAC outputs of the Arduino Due.
paragraph=With this library you can use the Arduino Due DAC outputs to play audio files.<br />The audio files must be in the raw .wav format.
url=http://arduino.cc/en/Reference/Audio
architectures=sam
version=1.0
dependencies=
core-dependencies=arduino (>=1.5.0)

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2012 by Cristian Maglie <c.maglie@bug.st>
* Audio library for Arduino Due.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#include "Audio.h"
void AudioClass::begin(uint32_t sampleRate, uint32_t msPreBuffer) {
// Allocate a buffer to keep msPreBuffer milliseconds of audio
bufferSize = msPreBuffer * sampleRate / 1000;
if (bufferSize < 1024)
bufferSize = 1024;
buffer = (uint32_t *) malloc(bufferSize * sizeof(uint32_t));
half = buffer + bufferSize / 2;
last = buffer + bufferSize;
// Buffering starts from the beginning
running = buffer;
next = buffer;
// Start DAC
dac->begin(VARIANT_MCK / sampleRate);
dac->setOnTransmitEnd_CB(onTransmitEnd, this);
}
void AudioClass::end() {
dac->end();
free( buffer);
}
void AudioClass::prepare(int16_t *buffer, int S, int volume){
uint16_t *ubuffer = (uint16_t*) buffer;
for (int i=0; i<S; i++) {
// set volume amplitude (signed multiply)
buffer[i] = buffer[i] * volume / 1024;
// convert from signed 16 bit to unsigned 12 bit for DAC.
ubuffer[i] += 0x8000;
ubuffer[i] >>= 4;
}
}
size_t AudioClass::write(const uint32_t *data, size_t size) {
const uint32_t TAG = 0x10000000;
int i;
for (i = 0; i < size; i++) {
*next = data[i] | TAG;
next++;
if (next == half || next == last) {
enqueue();
while (next == running)
;
}
}
return i;
}
void AudioClass::enqueue() {
if (!dac->canQueue()) {
// DMA queue full
return;
}
if (next == half) {
// Enqueue the first half
dac->queueBuffer(buffer, bufferSize / 2);
} else {
// Enqueue the second half
dac->queueBuffer(half, bufferSize / 2);
next = buffer; // wrap around
}
}
void AudioClass::onTransmitEnd(void *_me) {
AudioClass *me = reinterpret_cast<AudioClass *> (_me);
if (me->running == me->buffer)
me->running = me->half;
else
me->running = me->buffer;
}
AudioClass Audio(DAC);

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2012 by Cristian Maglie <c.maglie@bug.st>
* Audio library for Arduino Due.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#ifndef AUDIO_H
#define AUDIO_H
#include "Arduino.h"
#include "Print.h"
#include "DAC.h"
class AudioClass : public Print {
public:
AudioClass(DACClass &_dac) : dac(&_dac) { };
void prepare(int16_t *buffer, int S, int volume);
void begin(uint32_t sampleRate, uint32_t msPreBuffer);
void end();
virtual size_t write(uint8_t c) { /* not implemented */ };
virtual size_t write(const uint8_t *data, size_t size) { return write(reinterpret_cast<const uint32_t*>(data), size/4) * 4; };
virtual size_t write(const uint16_t *data, size_t size) { return write(reinterpret_cast<const uint32_t*>(data), size/2) * 2; };
virtual size_t write(const int16_t *data, size_t size) { return write(reinterpret_cast<const uint32_t*>(data), size/2) * 2; };
virtual size_t write(const uint32_t *data, size_t size);
void debug() {
// Serial1.print(running-buffer, DEC);
// Serial1.print(" ");
// Serial1.print(current-buffer, DEC);
// Serial1.print(" ");
// Serial1.print(next-buffer, DEC);
// Serial1.print(" ");
// Serial1.println(last-buffer, DEC);
}
private:
void enqueue();
static void onTransmitEnd(void *me);
uint32_t bufferSize;
uint32_t *buffer;
uint32_t *half;
uint32_t *last;
uint32_t *volatile running;
uint32_t *volatile next;
uint32_t *cook(const uint32_t *buffer, size_t size);
DACClass *dac;
};
extern AudioClass Audio;
#endif

View File

@ -1,10 +1,10 @@
name=SD
author=SparkFun Electronics
email=info@arduino.cc
sentence=The libary to use the Arduino Ethernet shield or the Arduino Ethernet based on the WizNet W5100 ic.
paragraph=With this library you can use the Arduino Ethernet (shield or board) to connect to Internet. The library provides both Client and server functionalities. The library permits you to connect to a local network also with DHCP and to resolve DNS.
sentence=With this library you can use an SD card to save data and operate on files.
paragraph=Once an SD memory card is connected to the SPI interfare of the Arduino board you are enabled to create files and read/write on them. You can also move through directories on the SD card.
url=http://arduino.cc/en/Reference/SD
architectures=avr, sam
architectures=*
version=1.0
dependencies= IPAddress, SPI
dependencies= SPI
core-dependencies=arduino (>=1.5.0)

View File

@ -17,7 +17,7 @@
* along with the Arduino SdFat Library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include <SdFat.h>
#include "SdFat.h"
#ifdef __AVR__
#include <avr/pgmspace.h>
#endif

View File

@ -17,7 +17,7 @@
* along with the Arduino SdFat Library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include <SdFat.h>
#include "SdFat.h"
//------------------------------------------------------------------------------
// raw block cache
// init cacheBlockNumber_to invalid SD block number

View File

@ -2,8 +2,8 @@ name=Servo
author=cmaglie
email=Cristian Maglie <c.maglie@bug.st>
sentence=Controls a lot of Servos.
paragraph=This library can control a great number of servos.<br />It makes careful use of timers: the library can control 12 servos with only 1 timer!<br />
url=http://github.com/cmaglie/Servo
paragraph=This library can control a great number of servos.<br />It makes careful use of timers: the library can control 12 servos with only 1 timer!<br />On the Arduino Due you can control up to 60 servos.<br />
url=http://arduino.cc/en/Reference/Servo
architectures=avr,sam
version=1.0
dependencies=