ok connect pin 17 and 18 connect headphone to 18 joy up to record joy down to playback
Dependencies: FatFileSystem MSCFileSystem SDHCFileSystem mbed wavfile
Fork of SimpleWaveRecorderPlayer by
Diff: main.cpp
- Revision:
- 0:1a515b688b8c
- Child:
- 1:8604a6be9da1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sat Apr 14 02:25:17 2012 +0000 @@ -0,0 +1,321 @@ +/* + * =============================================================== + * A simple wave recorder & player on mbed + * =============================================================== + * Copyright (c) 2011-2012 Shinichiro Nakamura + * + * 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 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 "mbed.h" +#include "SDHCFileSystem.h" +#include "wavfile.h" + +#define RAM_TOTAL 0x1000 + +AnalogOut dacout(p18); +AnalogIn adcin(p20); +DigitalOut led_play_ok(LED1); +DigitalOut led_rec_ok(LED2); + +Timer timer; +Timer iometer; +Ticker ticker; +SDFileSystem sdc(p5, p6, p7, p8, "sdc"); + +float buffer[RAM_TOTAL]; +int rp = 0; +int wp = 0; +int dropout = 0; + +#define WAVFILE_ERROR_PRINT(RESULT) \ + do { \ + WavFileResult R = RESULT; \ + if (R != WavFileResultOK) { \ + char wavfile_error_print_text[BUFSIZ]; \ + wavfile_result_string(R, wavfile_error_print_text, sizeof(wavfile_error_print_text)); \ + printf("%s (code=%d)\r\n", wavfile_error_print_text, R); \ + return 1; \ + } \ + } while(0) + +void tickdummy(void) +{ +} + +void tickplay(void) +{ + /* + * Check the play underflow + */ + if (rp != wp) { + dacout = buffer[rp]; + rp = (rp + 1) & (RAM_TOTAL - 1); + } else { + dropout++; + } + led_play_ok = !led_play_ok; +} + +void tickrec(void) +{ + /* + * Check the rec overflow + */ + int np = (wp + 1) & (RAM_TOTAL - 1); + if (np != rp) { + buffer[wp] = adcin; + wp = np; + } else { + dropout++; + } + led_rec_ok = !led_rec_ok; +} + +int play(const char *filename) +{ + WavFileResult result; + wavfile_info_t info; + wavfile_data_t data; + + WAVFILE *wf = wavfile_open(filename, WavFileModeRead, &result); + WAVFILE_ERROR_PRINT(result); + WAVFILE_ERROR_PRINT(wavfile_read_info(wf, &info)); + + printf("[PLAY:%s]\r\n", filename); + printf("\tWAVFILE_INFO_AUDIO_FORMAT(&info) = %d\r\n", WAVFILE_INFO_AUDIO_FORMAT(&info)); + printf("\tWAVFILE_INFO_NUM_CHANNELS(&info) = %d\r\n", WAVFILE_INFO_NUM_CHANNELS(&info)); + printf("\tWAVFILE_INFO_SAMPLE_RATE(&info) = %d\r\n", WAVFILE_INFO_SAMPLE_RATE(&info)); + printf("\tWAVFILE_INFO_BYTE_RATE(&info) = %d\r\n", WAVFILE_INFO_BYTE_RATE(&info)); + printf("\tWAVFILE_INFO_BLOCK_ALIGN(&info) = %d\r\n", WAVFILE_INFO_BLOCK_ALIGN(&info)); + printf("\tWAVFILE_INFO_BITS_PER_SAMPLE(&info) = %d\r\n", WAVFILE_INFO_BITS_PER_SAMPLE(&info)); + + const int interval_us = 1000000 / WAVFILE_INFO_SAMPLE_RATE(&info); + + rp = 0; + wp = 0; + dropout = 0; + ticker.attach_us(tickplay, interval_us); + while (1) { + int np = (wp + 1) & (RAM_TOTAL - 1); + while (np == rp) { + wait_us(1); + } + WAVFILE_ERROR_PRINT(wavfile_read_data(wf, &data)); + if (WAVFILE_DATA_IS_END_OF_DATA(&data)) { + break; + } + buffer[wp] = WAVFILE_DATA_CHANNEL_DATA(&data, 0); + wp = np; + } + ticker.detach(); + dacout = 0.5; + led_play_ok = 0; + printf("\t-- Play done. (dropout=%d) --\r\n", dropout); + + WAVFILE_ERROR_PRINT(wavfile_close(wf)); + return 0; +} + +int rec(const char *filename, const int nsec) +{ + WavFileResult result; + wavfile_info_t info; + wavfile_data_t data; + + WAVFILE_INFO_AUDIO_FORMAT(&info) = 1; + WAVFILE_INFO_NUM_CHANNELS(&info) = 1; + WAVFILE_INFO_SAMPLE_RATE(&info) = 11025; + WAVFILE_INFO_BYTE_RATE(&info) = 22050; + WAVFILE_INFO_BLOCK_ALIGN(&info) = 2; + WAVFILE_INFO_BITS_PER_SAMPLE(&info) = 16; + + WAVFILE *wf = wavfile_open(filename, WavFileModeWrite, &result); + WAVFILE_ERROR_PRINT(result); + WAVFILE_ERROR_PRINT(wavfile_write_info(wf, &info)); + + printf("[REC:%s]\r\n", filename); + printf("\tWAVFILE_INFO_AUDIO_FORMAT(&info) = %d\r\n", WAVFILE_INFO_AUDIO_FORMAT(&info)); + printf("\tWAVFILE_INFO_NUM_CHANNELS(&info) = %d\r\n", WAVFILE_INFO_NUM_CHANNELS(&info)); + printf("\tWAVFILE_INFO_SAMPLE_RATE(&info) = %d\r\n", WAVFILE_INFO_SAMPLE_RATE(&info)); + printf("\tWAVFILE_INFO_BYTE_RATE(&info) = %d\r\n", WAVFILE_INFO_BYTE_RATE(&info)); + printf("\tWAVFILE_INFO_BLOCK_ALIGN(&info) = %d\r\n", WAVFILE_INFO_BLOCK_ALIGN(&info)); + printf("\tWAVFILE_INFO_BITS_PER_SAMPLE(&info) = %d\r\n", WAVFILE_INFO_BITS_PER_SAMPLE(&info)); + + const int interval_us = 1000000 / WAVFILE_INFO_SAMPLE_RATE(&info); + const unsigned int samples_for_nsec = WAVFILE_INFO_SAMPLE_RATE(&info) * nsec; + + rp = 0; + wp = 0; + dropout = 0; + unsigned int count = 0; + ticker.attach_us(tickrec, interval_us); + WAVFILE_DATA_NUM_CHANNELS(&data) = 1; + while (1) { + while (rp == wp) { + wait_us(1); + } + + WAVFILE_DATA_CHANNEL_DATA(&data, 0) = buffer[rp]; + rp = (rp + 1) & (RAM_TOTAL - 1); + WAVFILE_ERROR_PRINT(wavfile_write_data(wf, &data)); + + count++; + if (count > samples_for_nsec) { + break; + } + } + ticker.detach(); + led_rec_ok = 0; + printf("\t-- Rec done. (dropout=%d) --\r\n", dropout); + + WAVFILE_ERROR_PRINT(wavfile_close(wf)); + return 0; +} + +int perf_read(const char *filename, const int word_size, const int nsec) +{ + FILE *fp = fopen(filename, "rb"); + if (fp == NULL) { + printf("File open failed.\r\n"); + return 1; + } + + printf("[Read performance checking...]\r\n"); + + unsigned int total_byte_size = 0; + int min_us = 0; + int max_us = 0; + timer.reset(); + timer.start(); + while (timer.read() < nsec) { + for (int i = 0; i < word_size; i++) { + iometer.reset(); + iometer.start(); + volatile int c = fgetc(fp); + iometer.stop(); + int iomv = iometer.read_us(); + if (iomv < min_us) { + min_us = iomv; + } + if (max_us < iomv) { + max_us = iomv; + } + total_byte_size++; + } + } + timer.stop(); + + printf("\tfilename(%s), word_size(%d)\r\n", filename, word_size); + printf("\ttime(%d[ms]), total_byte_size(%d)\r\n", timer.read_ms(), total_byte_size); + printf("\tThroughput=%f[Bytes/Sec]\r\n", (double)total_byte_size / timer.read_ms() * 1000.0); + printf("\tmin_us(%d), max_us(%d), average_us(%d)\r\n", min_us, max_us, timer.read_us() / total_byte_size); + + fclose(fp); + return 0; +} + +int perf_write(const char *filename, const int word_size, const int nsec) +{ + FILE *fp = fopen(filename, "wb"); + if (fp == NULL) { + printf("File open failed.\r\n"); + return 1; + } + + printf("[Write performance checking...]\r\n"); + + unsigned int total_byte_size = 0; + int min_us = 0; + int max_us = 0; + timer.reset(); + timer.start(); + while (timer.read() < nsec) { + for (int i = 0; i < word_size; i++) { + volatile int c = 0x55; + iometer.reset(); + iometer.start(); + fputc(c, fp); + iometer.stop(); + int iomv = iometer.read_us(); + if (iomv < min_us) { + min_us = iomv; + } + if (max_us < iomv) { + max_us = iomv; + } + total_byte_size++; + } + } + timer.stop(); + + printf("\tfilename(%s), word_size(%d)\r\n", filename, word_size); + printf("\ttime(%d[ms]), total_byte_size(%d)\r\n", timer.read_ms(), total_byte_size); + printf("\tThroughput=%f[Bytes/Sec]\r\n", (double)total_byte_size / timer.read_ms() * 1000.0); + printf("\tmin_us(%d), max_us(%d), average_us(%d)\r\n", min_us, max_us, timer.read_us() / total_byte_size); + + fclose(fp); + return 0; +} + +int main(void) +{ + printf("\r\n\r\n"); + printf("=======================================================\r\n"); + printf(" A simple wave recorder & player on mbed \r\n"); + printf(" Copyright(C) 2012 Shinichiro Nakamura (CuBeatSystems) \r\n"); + printf("=======================================================\r\n"); + + ticker.attach_us(tickdummy, 100); + wait(1); + ticker.detach(); + + { + const char *perf_filename = "/sdc/perf.bin"; + const int word_size = 2; + const int nsec_write = 20; + const int nsec_read = 10; + perf_write(perf_filename, word_size, nsec_write); + perf_read(perf_filename, word_size, nsec_read); + } + + { + static const char *target_filename = "/sdc/rec-test.wav"; + while (1) { + /* + * 30 seconds recording. + */ + if (rec(target_filename, 30) != 0) { + break; + } + /* + * Play it! + */ + if (play(target_filename) != 0) { + break; + } + } + } + + return 0; +}