TinyArcade/サウンド再生
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
[[戻る>TinyArcade]]
*サウンド再生 [#ac881d44]
サウンドを再生するだけのプログラムです。どうしても長くな...
本当はすべてinoファイルに書こうと思たんだけどどうしても~
void TC5_Handler(void) __attribute__ ((weak, alias("Soun...
の行でエラーになってしまったのでcppファイルに分割しました...
とにかくわかる範囲で説明。~
TCは多分タイムカウンタの事。このカウンタ使って周期的に割...
このプログラムでは1秒間に11025回の割り込み処理を起こしそ...
10bitDACに送るデータ形式は符号なし10bitデータなので符号な...
stream_bufferはリングバッファになっていて800バイト確保し...
UpdateSoundStream()はloopで毎回呼び出す必要があり、GetSou...
このプログラムはwaveの終端になったらwaveの先頭に戻ってル...
またTinyArcadeは1チャンネル分しかサウンドを再生することが...
~
要するにこのプログラムはBGM再生中にSEが再生できないためこ...
*サンプルプログラム [#qe1538e7]
-SoundSample1.ino
#include <TinyScreen.h>
#include "SoundStream.hpp"
#include "TwinkleBeep01.h"
TinyScreen tiny_screen = TinyScreen(TinyScreenPlus);
int wave_sample;
void setup()
{
tiny_screen.begin();
tiny_screen.setBitDepth(TSBitDepth8);
tiny_screen.setBrightness(8);
tiny_screen.setFont(liberationSansNarrow_12ptFontInfo);
tiny_screen.fontColor(TS_8b_White, TS_8b_Black);
InitializeSoundStream();
wave_sample = 0;
}
void loop()
{
tiny_screen.setCursor(0,0);
tiny_screen.print("Now playing!");
UpdateSoundStream();
int writable_size = GetSoundStreamWritableSize();
int wave_size = static_cast<int>(sizeof(TwinkleBeep01_w...
if(writable_size > 0)
{
size_t write_size = writable_size;
size_t left_size = wave_size - wave_sample;
if(left_size < writable_size)
{
write_size = left_size;
}
if(write_size > 0)
{
unsigned char* write_wave_buffer = new unsigned char[...
memcpy(write_wave_buffer, &TwinkleBeep01_wave[wave_sa...
wave_sample += write_size;
if(writable_size > left_size)
{
int left_write_size = writable_size - left_size;
if(left_write_size > 0)
{
wave_sample = 0;
memcpy(&write_wave_buffer[write_size], &TwinkleBeep...
wave_sample += left_write_size;
}
}
WriteSoundStream(write_wave_buffer);
delete [] write_wave_buffer;
}
if(wave_sample >= wave_size)
{
wave_sample = 0;
}
}
}
-SoundStream.hpp
#ifndef SOUNDSTREAM_HPP
#define SOUNDSTREAM_HPP
static const int SOUND_BUFFER_SIZE = 800;
static const int SOUND_BUFFER_SIZE_HALF = SOUND_BUFFER_S...
static const int SOUND_FREQUENCY = 11025;
void InitializeSoundStream();
void FinalizeSoundStream(void);
void UpdateSoundStream(void);
int GetSoundStreamWritableSize(void);
bool WriteSoundStream(const unsigned char* buffer);
#endif
-SoundStream.cpp
#include <TinyScreen.h>
#include "SoundStream.hpp"
unsigned char stream_buffer[SOUND_BUFFER_SIZE];
int sample_index;
int write_buffer;
bool request;
bool tcIsSyncing(void)
{
return TC5->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY;
}
void tcReset(void)
{
// Reset TCx
TC5->COUNT16.CTRLA.reg = TC_CTRLA_SWRST;
while(tcIsSyncing());
while(TC5->COUNT16.CTRLA.bit.SWRST);
}
void InitializeSoundStream(void)
{
memset(stream_buffer, 0x80, SOUND_BUFFER_SIZE);
sample_index = 0;
write_buffer = 0;
request = false;
analogWrite(A0, 0);
// Enable GCLK for TCC2 and TC5 (timer counter input cl...
GCLK->CLKCTRL.reg = static_cast<unsigned short>((GCLK_C...
while(GCLK->STATUS.bit.SYNCBUSY);
tcReset();
// Set Timer counter Mode to 16 bits
TC5->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16;
// Set TC5 mode as match frequency
TC5->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;
TC5->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1;
TC5->COUNT16.CC[0].reg = static_cast<unsigned short>((S...
while(tcIsSyncing());
// Configure interrupt request
NVIC_DisableIRQ(TC5_IRQn);
NVIC_ClearPendingIRQ(TC5_IRQn);
NVIC_SetPriority(TC5_IRQn, 0);
NVIC_EnableIRQ(TC5_IRQn);
// Enable the TC5 interrupt request
TC5->COUNT16.INTENSET.bit.MC0 = 1;
while(tcIsSyncing());
// Enable TC
TC5->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE;
while(tcIsSyncing());
}
void FinalizeSoundStream(void)
{
// Disable TC5
TC5->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE;
while(tcIsSyncing());
// Reset TCx
TC5->COUNT16.CTRLA.reg = TC_CTRLA_SWRST;
while(tcIsSyncing());
while(TC5->COUNT16.CTRLA.bit.SWRST);
}
void UpdateSoundStream(void)
{
int play_buffer = 0;
if(sample_index >= SOUND_BUFFER_SIZE_HALF)
{
play_buffer = 1;
}
if(write_buffer == play_buffer)
{
request = true;
}
}
int GetSoundStreamWritableSize(void)
{
if(request == false)
{
return 0;
}
return SOUND_BUFFER_SIZE_HALF;
}
bool WriteSoundStream(const unsigned char* buffer)
{
int play_buffer = 0;
if(sample_index >= SOUND_BUFFER_SIZE_HALF)
{
play_buffer = 1;
}
write_buffer = 1 - play_buffer;
memcpy(&stream_buffer[SOUND_BUFFER_SIZE_HALF * write_bu...
request = false;
return true;
}
#ifdef __cplusplus
extern "C"
{
#endif
void SoundStreamCallback(void)
{
while(DAC->STATUS.bit.SYNCBUSY == 1);
DAC->DATA.reg = static_cast<unsigned short>(stream_buf...
while(DAC->STATUS.bit.SYNCBUSY == 1);
++ sample_index;
if(sample_index >= SOUND_BUFFER_SIZE)
{
sample_index = 0;
}
TC5->COUNT16.INTFLAG.bit.MC0 = 1;
}
void TC5_Handler(void) __attribute__ ((weak, alias("Sou...
#ifdef __cplusplus
}
#endif
-TwinkleBeep01.h
// 11025Hz 8bit mono wavedata
const unsigned char TwinkleBeep01_wave[40045] =
{
128, 128, 122, 116, 113, 119, 139, 150, 152, 141, 105, ...
178, 174, 128, 79, 76, 84, 132, 186, 196, 190, 151, 92,...
197, 194, 159, 95, 64, 63, 80, 135, 178, 179, 168, 117,...
:
:
:
続く
*実行結果 [#n36c708f]
#ref(SoundSample1.jpg,,,100%)
TwinkleBeep01_waveがループ再生されます。~
*サンプルプログラムのダウンロード [#s4bd33eb]
#ref(SoundSample1.zip)~
終了行:
[[戻る>TinyArcade]]
*サウンド再生 [#ac881d44]
サウンドを再生するだけのプログラムです。どうしても長くな...
本当はすべてinoファイルに書こうと思たんだけどどうしても~
void TC5_Handler(void) __attribute__ ((weak, alias("Soun...
の行でエラーになってしまったのでcppファイルに分割しました...
とにかくわかる範囲で説明。~
TCは多分タイムカウンタの事。このカウンタ使って周期的に割...
このプログラムでは1秒間に11025回の割り込み処理を起こしそ...
10bitDACに送るデータ形式は符号なし10bitデータなので符号な...
stream_bufferはリングバッファになっていて800バイト確保し...
UpdateSoundStream()はloopで毎回呼び出す必要があり、GetSou...
このプログラムはwaveの終端になったらwaveの先頭に戻ってル...
またTinyArcadeは1チャンネル分しかサウンドを再生することが...
~
要するにこのプログラムはBGM再生中にSEが再生できないためこ...
*サンプルプログラム [#qe1538e7]
-SoundSample1.ino
#include <TinyScreen.h>
#include "SoundStream.hpp"
#include "TwinkleBeep01.h"
TinyScreen tiny_screen = TinyScreen(TinyScreenPlus);
int wave_sample;
void setup()
{
tiny_screen.begin();
tiny_screen.setBitDepth(TSBitDepth8);
tiny_screen.setBrightness(8);
tiny_screen.setFont(liberationSansNarrow_12ptFontInfo);
tiny_screen.fontColor(TS_8b_White, TS_8b_Black);
InitializeSoundStream();
wave_sample = 0;
}
void loop()
{
tiny_screen.setCursor(0,0);
tiny_screen.print("Now playing!");
UpdateSoundStream();
int writable_size = GetSoundStreamWritableSize();
int wave_size = static_cast<int>(sizeof(TwinkleBeep01_w...
if(writable_size > 0)
{
size_t write_size = writable_size;
size_t left_size = wave_size - wave_sample;
if(left_size < writable_size)
{
write_size = left_size;
}
if(write_size > 0)
{
unsigned char* write_wave_buffer = new unsigned char[...
memcpy(write_wave_buffer, &TwinkleBeep01_wave[wave_sa...
wave_sample += write_size;
if(writable_size > left_size)
{
int left_write_size = writable_size - left_size;
if(left_write_size > 0)
{
wave_sample = 0;
memcpy(&write_wave_buffer[write_size], &TwinkleBeep...
wave_sample += left_write_size;
}
}
WriteSoundStream(write_wave_buffer);
delete [] write_wave_buffer;
}
if(wave_sample >= wave_size)
{
wave_sample = 0;
}
}
}
-SoundStream.hpp
#ifndef SOUNDSTREAM_HPP
#define SOUNDSTREAM_HPP
static const int SOUND_BUFFER_SIZE = 800;
static const int SOUND_BUFFER_SIZE_HALF = SOUND_BUFFER_S...
static const int SOUND_FREQUENCY = 11025;
void InitializeSoundStream();
void FinalizeSoundStream(void);
void UpdateSoundStream(void);
int GetSoundStreamWritableSize(void);
bool WriteSoundStream(const unsigned char* buffer);
#endif
-SoundStream.cpp
#include <TinyScreen.h>
#include "SoundStream.hpp"
unsigned char stream_buffer[SOUND_BUFFER_SIZE];
int sample_index;
int write_buffer;
bool request;
bool tcIsSyncing(void)
{
return TC5->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY;
}
void tcReset(void)
{
// Reset TCx
TC5->COUNT16.CTRLA.reg = TC_CTRLA_SWRST;
while(tcIsSyncing());
while(TC5->COUNT16.CTRLA.bit.SWRST);
}
void InitializeSoundStream(void)
{
memset(stream_buffer, 0x80, SOUND_BUFFER_SIZE);
sample_index = 0;
write_buffer = 0;
request = false;
analogWrite(A0, 0);
// Enable GCLK for TCC2 and TC5 (timer counter input cl...
GCLK->CLKCTRL.reg = static_cast<unsigned short>((GCLK_C...
while(GCLK->STATUS.bit.SYNCBUSY);
tcReset();
// Set Timer counter Mode to 16 bits
TC5->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16;
// Set TC5 mode as match frequency
TC5->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;
TC5->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1;
TC5->COUNT16.CC[0].reg = static_cast<unsigned short>((S...
while(tcIsSyncing());
// Configure interrupt request
NVIC_DisableIRQ(TC5_IRQn);
NVIC_ClearPendingIRQ(TC5_IRQn);
NVIC_SetPriority(TC5_IRQn, 0);
NVIC_EnableIRQ(TC5_IRQn);
// Enable the TC5 interrupt request
TC5->COUNT16.INTENSET.bit.MC0 = 1;
while(tcIsSyncing());
// Enable TC
TC5->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE;
while(tcIsSyncing());
}
void FinalizeSoundStream(void)
{
// Disable TC5
TC5->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE;
while(tcIsSyncing());
// Reset TCx
TC5->COUNT16.CTRLA.reg = TC_CTRLA_SWRST;
while(tcIsSyncing());
while(TC5->COUNT16.CTRLA.bit.SWRST);
}
void UpdateSoundStream(void)
{
int play_buffer = 0;
if(sample_index >= SOUND_BUFFER_SIZE_HALF)
{
play_buffer = 1;
}
if(write_buffer == play_buffer)
{
request = true;
}
}
int GetSoundStreamWritableSize(void)
{
if(request == false)
{
return 0;
}
return SOUND_BUFFER_SIZE_HALF;
}
bool WriteSoundStream(const unsigned char* buffer)
{
int play_buffer = 0;
if(sample_index >= SOUND_BUFFER_SIZE_HALF)
{
play_buffer = 1;
}
write_buffer = 1 - play_buffer;
memcpy(&stream_buffer[SOUND_BUFFER_SIZE_HALF * write_bu...
request = false;
return true;
}
#ifdef __cplusplus
extern "C"
{
#endif
void SoundStreamCallback(void)
{
while(DAC->STATUS.bit.SYNCBUSY == 1);
DAC->DATA.reg = static_cast<unsigned short>(stream_buf...
while(DAC->STATUS.bit.SYNCBUSY == 1);
++ sample_index;
if(sample_index >= SOUND_BUFFER_SIZE)
{
sample_index = 0;
}
TC5->COUNT16.INTFLAG.bit.MC0 = 1;
}
void TC5_Handler(void) __attribute__ ((weak, alias("Sou...
#ifdef __cplusplus
}
#endif
-TwinkleBeep01.h
// 11025Hz 8bit mono wavedata
const unsigned char TwinkleBeep01_wave[40045] =
{
128, 128, 122, 116, 113, 119, 139, 150, 152, 141, 105, ...
178, 174, 128, 79, 76, 84, 132, 186, 196, 190, 151, 92,...
197, 194, 159, 95, 64, 63, 80, 135, 178, 179, 168, 117,...
:
:
:
続く
*実行結果 [#n36c708f]
#ref(SoundSample1.jpg,,,100%)
TwinkleBeep01_waveがループ再生されます。~
*サンプルプログラムのダウンロード [#s4bd33eb]
#ref(SoundSample1.zip)~
ページ名: