/*
* SeeSomethingSendSomething is an Spresence sketch for recording photos and audio at the
* flip of a switch! When powered on, the sketch captures 10 images and 10 seconds of audio,
* and stores them on a microSD card which can later be used to upload the images and audio
* to a centralized Cloud (or other) location. The hardware is compact enough to fit in an
* enclosure about the same size as an Altoids tin or pack of cigarettes, so its operation need
* not be conspicuous.
*/
#include <SDHCI.h>
#include <stdio.h> /* for sprintf */
#include <Audio.h>
#include <Camera.h>
#define RECORD_FILE_NAME "Sound.mp3"
#define BAUDRATE (115200)
#define TOTAL_PICTURE_COUNT (10)
SDClass theSD;
AudioClass *theAudio;
File myAudioFile;
bool ErrEnd = false;
/**
* @brief Audio attention callback
*
* When audio internal error occurc, this function will be called back.
*/
static void audio_attention_cb(const ErrorAttentionParam *atprm)
{
puts("Attention!");
if (atprm->error_code >= AS_ATTENTION_CODE_WARNING)
{
ErrEnd = true;
}
}
/**
* @brief Setup recording of mp3 stream to file
*
* Select input device as microphone <br>
* Initialize filetype to stereo mp3 with 48 Kb/s sampling rate <br>
* Open RECORD_FILE_NAME file in write mode
*/
/* Recording time[second] */
static const int32_t recording_time = 10;
/* Recording bit rate
* Set in bps.
* Note: 96kbps fixed
*/
static const int32_t recording_bitrate = 96000;
/* Bytes per second */
static const int32_t recording_byte_per_second = (recording_bitrate / 8);
/* Total recording size */
static const int32_t recording_size = recording_byte_per_second * recording_time;
int take_picture_count = 0;
/**
* Print error message
*/
void recordAudio() {
/* Initialize SD */
while (!theSD.begin())
{
/* wait until SD card is mounted. */
Serial.println("Insert SD card.");
}
theAudio = AudioClass::getInstance();
theAudio->begin(audio_attention_cb);
puts("initialization Audio Library");
/* Select input device as microphone */
theAudio->setRecorderMode(AS_SETRECDR_STS_INPUTDEVICE_MIC);
/*
* Initialize filetype to stereo mp3 with 48 Kb/s sampling rate
* Search for MP3 codec in "/mnt/sd0/BIN" directory
*/
theAudio->initRecorder(AS_CODECTYPE_MP3, "/mnt/sd0/BIN", AS_SAMPLINGRATE_48000, AS_CHANNEL_STEREO);
puts("Init Recorder!");
/* Open file for data write on SD card */
if (theSD.exists(RECORD_FILE_NAME))
{
printf("Remove existing file [%s].\n", RECORD_FILE_NAME);
theSD.remove(RECORD_FILE_NAME);
}
myAudioFile = theSD.open(RECORD_FILE_NAME, FILE_WRITE);
/* Verify file open */
if (!myAudioFile)
{
printf("File open error\n");
exit(1);
}
printf("Open! [%s]\n", RECORD_FILE_NAME);
theAudio->startRecorder();
puts("Recording Start!");
}
void printError(enum CamErr err)
{
Serial.print("Error: ");
switch (err)
{
case CAM_ERR_NO_DEVICE:
Serial.println("No Device");
break;
case CAM_ERR_ILLEGAL_DEVERR:
Serial.println("Illegal device error");
break;
case CAM_ERR_ALREADY_INITIALIZED:
Serial.println("Already initialized");
break;
case CAM_ERR_NOT_INITIALIZED:
Serial.println("Not initialized");
break;
case CAM_ERR_NOT_STILL_INITIALIZED:
Serial.println("Still picture not initialized");
break;
case CAM_ERR_CANT_CREATE_THREAD:
Serial.println("Failed to create thread");
break;
case CAM_ERR_INVALID_PARAM:
Serial.println("Invalid parameter");
break;
case CAM_ERR_NO_MEMORY:
Serial.println("No memory");
break;
case CAM_ERR_USR_INUSED:
Serial.println("Buffer already in use");
break;
case CAM_ERR_NOT_PERMITTED:
Serial.println("Operation not permitted");
break;
default:
break;
}
}
/**
* Callback from Camera library when video frame is captured.
*/
void CamCB(CamImage img)
{
/* Check the img instance is available or not. */
if (img.isAvailable())
{
/* If you want RGB565 data, convert image data format to RGB565 */
img.convertPixFormat(CAM_IMAGE_PIX_FMT_RGB565);
/* You can use image data directly by using getImgSize() and getImgBuff().
* for displaying image to a display, etc. */
Serial.print("Image data size = ");
Serial.print(img.getImgSize(), DEC);
Serial.print(" , ");
Serial.print("buff addr = ");
Serial.print((unsigned long)img.getImgBuff(), HEX);
Serial.println("");
}
else
{
Serial.println("Failed to get video stream image");
}
}
/**
* @brief Initialize camera
*/
void setup()
{
CamErr err;
/* Open serial communications and wait for port to open */
Serial.begin(BAUDRATE);
while (!Serial)
{
; /* wait for serial port to connect. Needed for native USB port only */
}
/* Initialize SD */
while (!theSD.begin())
{
/* wait until SD card is mounted. */
Serial.println("Insert SD card.");
}
/* begin() without parameters means that
* number of buffers = 1, 30FPS, QVGA, YUV 4:2:2 format */
Serial.println("Prepare camera");
err = theCamera.begin();
if (err != CAM_ERR_SUCCESS)
{
printError(err);
}
/* Start video stream.
* If received video stream data from camera device,
* camera library call CamCB.
*/
Serial.println("Start streaming");
err = theCamera.startStreaming(true, CamCB);
if (err != CAM_ERR_SUCCESS)
{
printError(err);
}
/* Auto white balance configuration */
Serial.println("Set Auto white balance parameter");
err = theCamera.setAutoWhiteBalanceMode(CAM_WHITE_BALANCE_DAYLIGHT);
if (err != CAM_ERR_SUCCESS)
{
printError(err);
}
/* Set parameters about still picture.
* In the following case, QUADVGA and JPEG.
*/
Serial.println("Set still picture format");
err = theCamera.setStillPictureImageFormat(
CAM_IMGSIZE_QUADVGA_H,
CAM_IMGSIZE_QUADVGA_V,
CAM_IMAGE_PIX_FMT_JPG);
if (err != CAM_ERR_SUCCESS)
{
printError(err);
}
}
/**
* @brief Take picture with format JPEG per second
*/
void loop()
{
sleep(1); /* wait for one second to take still picture. */
/* You can change the format of still picture at here also, if you want. */
/* theCamera.setStillPictureImageFormat(
* CAM_IMGSIZE_HD_H,
* CAM_IMGSIZE_HD_V,
* CAM_IMAGE_PIX_FMT_JPG);
*/
/* This sample code can take pictures in every one second from starting. */
if (take_picture_count < TOTAL_PICTURE_COUNT)
{
/* Take still picture.
* Unlike video stream(startStreaming) , this API wait to receive image data
* from camera device.
*/
Serial.println("call takePicture()");
CamImage img = theCamera.takePicture();
/* Check availability of the img instance. */
/* If any errors occur, the img is not available. */
if (img.isAvailable())
{
/* Create file name */
char filename[16] = {0};
sprintf(filename, "PICT%03d.JPG", take_picture_count);
Serial.print("Save taken picture as ");
Serial.print(filename);
Serial.println("");
/* Remove the old file with the same file name as new created file,
* and create new file.
*/
theSD.remove(filename);
File myAudioFile = theSD.open(filename, FILE_WRITE);
myAudioFile.write(img.getImgBuff(), img.getImgSize());
myAudioFile.close();
}
else
{
/* The size of a picture may exceed the allocated memory size.
* Then, allocate the larger memory size and/or decrease the size of a picture.
* [How to allocate the larger memory]
* - Decrease jpgbufsize_divisor specified by setStillPictureImageFormat()
* - Increase the Memory size from Arduino IDE tools Menu
* [How to decrease the size of a picture]
* - Decrease the JPEG quality by setJPEGQuality()
*/
Serial.println("Failed to take picture");
}
}
else if (take_picture_count == TOTAL_PICTURE_COUNT)
{
Serial.println("Picture capture completed.");
theCamera.end();
/* Images have been taken, so record 10 seconds of audio.
*
*/
bool ErrEnd = false;
/**
* @brief Audio attention callback
*
* When audio internal error occurs, this function will be called back.
*/
//set up for recording
/**
* @brief Setup recording of mp3 stream to file
*
* Select input device as microphone <br>
* Initialize filetype to stereo mp3 with 48 Kb/s sampling rate <br>
* Open RECORD_FILE_NAME file in write mode
*/
/* Recording time[second] */
static const int32_t recording_time = 10;
/* Recording bit rate
* Set in bps.
* Note: 96kbps fixed
*/
static const int32_t recording_bitrate = 96000;
/* Bytes per second */
static const int32_t recording_byte_per_second = (recording_bitrate / 8);
/* Total recording size */
static const int32_t recording_size = recording_byte_per_second * recording_time;
{
/* Initialize SD */
while (!theSD.begin())
{
/* wait until SD card is mounted. */
Serial.println("Insert SD card.");
}
theAudio = AudioClass::getInstance();
theAudio->begin(audio_attention_cb);
puts("initialization Audio Library");
/* Select input device as microphone */
theAudio->setRecorderMode(AS_SETRECDR_STS_INPUTDEVICE_MIC);
/*
* Initialize filetype to stereo mp3 with 48 Kb/s sampling rate
* Search for MP3 codec in "/mnt/sd0/BIN" directory
*/
theAudio->initRecorder(AS_CODECTYPE_MP3, "/mnt/sd0/BIN", AS_SAMPLINGRATE_48000, AS_CHANNEL_STEREO);
puts("Init Recorder!");
/* Open file for data write on SD card */
if (theSD.exists(RECORD_FILE_NAME))
{
printf("Remove existing file [%s].\n", RECORD_FILE_NAME);
theSD.remove(RECORD_FILE_NAME);
}
myAudioFile = theSD.open(RECORD_FILE_NAME, FILE_WRITE);
/* Verify file open */
if (!myAudioFile)
{
printf("File open error\n");
exit(1);
}
printf("Open! [%s]\n", RECORD_FILE_NAME);
theAudio->startRecorder();
puts("Recording Start!");
}
/**
* @brief Record given frame number
*/
err_t err;
/* recording end condition */
if (theAudio->getRecordingSize() > recording_size)
{
theAudio->stopRecorder();
sleep(1);
err = theAudio->readFrames(myAudioFile);
goto exitRecording;
}
/* Read frames to record in file */
err = theAudio->readFrames(myAudioFile);
if (err != AUDIOLIB_ECODE_OK)
{
printf("File End! =%d\n",err);
theAudio->stopRecorder();
goto exitRecording;
}
if (ErrEnd)
{
printf("Error End\n");
theAudio->stopRecorder();
goto exitRecording;
}
/* This sleep is adjusted by the time to write the audio stream file.
* Please adjust in according with the processing contents
* being processed at the same time by Application.
*
* The usleep() function suspends execution of the calling thread for usec
* microseconds. But the timer resolution depends on the OS system tick time
* which is 10 milliseconds (10,000 microseconds) by default. Therefore,
* it will sleep for a longer time than the time requested here.
*/
// usleep(10000);
return;
exitRecording:
theAudio->closeOutputFile(myAudioFile);
myAudioFile.close();
theAudio->setReadyMode();
theAudio->end();
puts("End Recording");
exit(1);
}
Serial.println("Audio capture completed.");
while(1); //Endless loop to preserve what has been captured and
//prevent over-writing with new data.
take_picture_count++;
}
Comments
Please log in or sign up to comment.