Compare commits

..

No commits in common. "a9816931214620551132343f25be0cd086903e9e" and "06b8d5d65e086991de3612271a968f0d80667ce0" have entirely different histories.

8 changed files with 82 additions and 92 deletions

View File

@ -5,6 +5,7 @@
*/ */
#include <etk/types.hpp> #include <etk/types.hpp>
#include <etk/os/FSNode.hpp>
#include <audio/ess/debug.hpp> #include <audio/ess/debug.hpp>
#include <audio/ess/decOgg.hpp> #include <audio/ess/decOgg.hpp>
#include <tremor/ivorbiscodec.h> #include <tremor/ivorbiscodec.h>
@ -13,21 +14,21 @@
static size_t LocalReadFunc(void *ptr, size_t size, size_t nmemb, void *datasource) { static size_t LocalReadFunc(void *ptr, size_t size, size_t nmemb, void *datasource) {
etk::io::Interface* fileIO = static_cast<etk::io::Interface*>(datasource); etk::FSNode* file = static_cast<etk::FSNode*>(datasource);
return fileIO->read(ptr, size, nmemb); return file->fileRead(ptr, size, nmemb);
} }
static int localSeekFunc(void *datasource, ogg_int64_t offset, int whence) { static int localSeekFunc(void *datasource, ogg_int64_t offset, int whence) {
etk::io::Interface* fileIO = static_cast<etk::io::Interface*>(datasource); etk::FSNode* file = static_cast<etk::FSNode*>(datasource);
etk::io::SeekMode mode = etk::io::SeekMode::Start; enum etk::seekNode mode = etk::seekNode_start;
if (whence == SEEK_SET) { if (whence == SEEK_SET) {
mode = etk::io::SeekMode::Start; mode = etk::seekNode_start;
} else if (whence == SEEK_END) { } else if (whence == SEEK_END) {
mode = etk::io::SeekMode::End; mode = etk::seekNode_end;
} else if (whence == SEEK_CUR) { } else if (whence == SEEK_CUR) {
mode = etk::io::SeekMode::Current; mode = etk::seekNode_current;
} }
if (fileIO->seek(offset, mode) == true) { if (file->fileSeek(offset, mode) == true) {
return 0; return 0;
} else { } else {
return -1; return -1;
@ -35,17 +36,17 @@ static int localSeekFunc(void *datasource, ogg_int64_t offset, int whence) {
} }
static int localCloseFunc(void *datasource) { static int localCloseFunc(void *datasource) {
etk::io::Interface* fileIO = static_cast<etk::io::Interface*>(datasource); etk::FSNode* file = static_cast<etk::FSNode*>(datasource);
fileIO->close(); file->fileClose();
return 0; return 0;
} }
static long localTellFunc(void *datasource) { static long localTellFunc(void *datasource) {
etk::io::Interface* fileIO = static_cast<etk::io::Interface*>(datasource); etk::FSNode* file = static_cast<etk::FSNode*>(datasource);
return fileIO->tell(); return file->fileTell();
} }
etk::Vector<float> audio::ess::ogg::loadAudioFile(const etk::Uri& _uri, int8_t _nbChan) { etk::Vector<float> audio::ess::ogg::loadAudioFile(const etk::String& _filename, int8_t _nbChan) {
etk::Vector<float> out; etk::Vector<float> out;
OggVorbis_File vf; OggVorbis_File vf;
int32_t eof=0; int32_t eof=0;
@ -56,28 +57,24 @@ etk::Vector<float> audio::ess::ogg::loadAudioFile(const etk::Uri& _uri, int8_t _
localCloseFunc, localCloseFunc,
localTellFunc localTellFunc
}; };
ememory::UniquePtr<etk::FSNode> fileAccess = ememory::UniquePtr<etk::FSNode>(ETK_NEW(etk::FSNode, _filename));
// Start loading the XML : // Start loading the XML :
EWOLSA_DEBUG("open file (OGG) " << _uri); //EWOLSA_DEBUG("open file (OGG) \"" << fileAccess << "\"");
if (etk::uri::exist(_uri) == false) { if (false == fileAccess->exist()) {
EWOLSA_ERROR("File Does not exist : " << _uri); EWOLSA_ERROR("File Does not exist : \"" << *fileAccess << "\"");
return out; return out;
} }
int32_t fileSize = etk::uri::fileSize(_uri); int32_t fileSize = fileAccess->fileSize();
if (fileSize == 0) { if (0 == fileSize) {
EWOLSA_ERROR("This file is empty : " << _uri); EWOLSA_ERROR("This file is empty : \"" << *fileAccess << "\"");
return out; return out;
} }
ememory::SharedPtr<etk::io::Interface> fileIO = etk::uri::get(_uri); if (false == fileAccess->fileOpenRead()) {
if (fileIO == null) { EWOLSA_ERROR("Can not open the file : \"" << *fileAccess << "\"");
EWOLSA_ERROR("CAn not get file interface : " << _uri);
return out; return out;
} }
if (fileIO->open(etk::io::OpenMode::Read) == false) { if (ov_open_callbacks(&(*fileAccess), &vf, null, 0, tmpCallback) < 0) {
EWOLSA_ERROR("Can not open the file : " << _uri); EWOLSA_ERROR("Input does not appear to be an Ogg bitstream.");
return out;
}
if (ov_open_callbacks(fileIO.get(), &vf, null, 0, tmpCallback) < 0) {
EWOLSA_ERROR("Input does not appear to be an Ogg bitstream: " << _uri);
return out; return out;
} }
vorbis_info *vi=ov_info(&vf,-1); vorbis_info *vi=ov_info(&vf,-1);

View File

@ -6,12 +6,11 @@
#pragma once #pragma once
#include <etk/types.hpp> #include <etk/types.hpp>
#include <etk/uri/uri.hpp>
namespace audio { namespace audio {
namespace ess { namespace ess {
namespace ogg { namespace ogg {
etk::Vector<float> loadAudioFile(const etk::Uri& _uri, int8_t _nbChan); etk::Vector<float> loadAudioFile(const etk::String& _filename, int8_t _nbChan);
} }
} }

View File

@ -5,6 +5,7 @@
*/ */
#include <etk/types.hpp> #include <etk/types.hpp>
#include <etk/os/FSNode.hpp>
#include <audio/ess/debug.hpp> #include <audio/ess/debug.hpp>
#include <audio/ess/decWav.hpp> #include <audio/ess/decWav.hpp>
@ -56,40 +57,37 @@ typedef struct {
#define COMPR_G721 (64) #define COMPR_G721 (64)
#define COMPR_MPEG (80) #define COMPR_MPEG (80)
etk::Vector<float> audio::ess::wav::loadAudioFile(const etk::Uri& _uri, int8_t _nbChan) { etk::Vector<float> audio::ess::wav::loadAudioFile(const etk::String& _filename, int8_t _nbChan) {
etk::Vector<float> out; etk::Vector<float> out;
waveHeader myHeader; waveHeader myHeader;
memset(&myHeader, 0, sizeof(waveHeader)); memset(&myHeader, 0, sizeof(waveHeader));
etk::FSNode fileAccess(_filename);
// Start loading the XML : // Start loading the XML :
EWOLSA_DEBUG("open file (WAV) " << _uri); EWOLSA_DEBUG("open file (WAV) \"" << fileAccess << "\"");
if (etk::uri::exist(_uri) == false) {
EWOLSA_ERROR("File Does not exist : " << _uri); if (false == fileAccess.exist()) {
EWOLSA_ERROR("File Does not exist : \"" << fileAccess << "\"");
return out; return out;
} }
int32_t fileSize = etk::uri::fileSize(_uri); int32_t fileSize = fileAccess.fileSize();
if (0 == fileSize) { if (0 == fileSize) {
EWOLSA_ERROR("This file is empty : " << _uri); EWOLSA_ERROR("This file is empty : \"" << fileAccess << "\"");
return out; return out;
} }
ememory::SharedPtr<etk::io::Interface> fileIO = etk::uri::get(_uri); if (false == fileAccess.fileOpenRead()) {
if (fileIO == null) { EWOLSA_ERROR("Can not open the file : \"" << fileAccess << "\"");
EWOLSA_ERROR("CAn not get file interface : " << _uri);
return out;
}
if (fileIO->open(etk::io::OpenMode::Read) == false) {
EWOLSA_ERROR("Can not open the file : " << _uri);
return out; return out;
} }
// try to find endienness : // try to find endienness :
if (fileSize < (int64_t)sizeof(waveHeader)) { if (fileSize < (int64_t)sizeof(waveHeader)) {
EWOLSA_ERROR("File : " << _uri << " == > has not enouth data inside might be minumum of " << (int32_t)(sizeof(waveHeader))); EWOLSA_ERROR("File : \"" << fileAccess << "\" == > has not enouth data inside might be minumum of " << (int32_t)(sizeof(waveHeader)));
return out; return out;
} }
// ---------------------------------------------- // ----------------------------------------------
// read the header : // read the header :
// ---------------------------------------------- // ----------------------------------------------
if (fileIO->read(&myHeader.riffTag, 1, 4)!=4) { if (fileAccess.fileRead(&myHeader.riffTag, 1, 4)!=4) {
EWOLSA_ERROR("Can not 4 element in the file : " << _uri); EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return out; return out;
} }
bool littleEndien = false; bool littleEndien = false;
@ -101,55 +99,55 @@ etk::Vector<float> audio::ess::wav::loadAudioFile(const etk::Uri& _uri, int8_t _
littleEndien = true; littleEndien = true;
} }
} else { } else {
EWOLSA_ERROR("file: " << _uri << " Does not start with 'RIF' " ); EWOLSA_ERROR("file: \"" << fileAccess << "\" Does not start with \"RIF\" " );
return out; return out;
} }
// get the data size : // get the data size :
unsigned char tmpData[32]; unsigned char tmpData[32];
if (fileIO->read(tmpData, 1, 4)!=4) { if (fileAccess.fileRead(tmpData, 1, 4)!=4) {
EWOLSA_ERROR("Can not 4 element in the file : " << _uri); EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return out; return out;
} }
myHeader.size = CONVERT_UINT32(littleEndien, tmpData); myHeader.size = CONVERT_UINT32(littleEndien, tmpData);
// get the data size : // get the data size :
if (fileIO->read(&myHeader.waveTag, 1, 4)!=4) { if (fileAccess.fileRead(&myHeader.waveTag, 1, 4)!=4) {
EWOLSA_ERROR("Can not 4 element in the file : " << _uri); EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return out; return out;
} }
if( myHeader.waveTag[0] != 'W' if( myHeader.waveTag[0] != 'W'
|| myHeader.waveTag[1] != 'A' || myHeader.waveTag[1] != 'A'
|| myHeader.waveTag[2] != 'V' || myHeader.waveTag[2] != 'V'
|| myHeader.waveTag[3] != 'E' ) { || myHeader.waveTag[3] != 'E' ) {
EWOLSA_ERROR("file: " << _uri << " This is not a wave file " << myHeader.waveTag[0] << myHeader.waveTag[1] << myHeader.waveTag[2] << myHeader.waveTag[3] ); EWOLSA_ERROR("file: \"" << fileAccess << "\" This is not a wave file " << myHeader.waveTag[0] << myHeader.waveTag[1] << myHeader.waveTag[2] << myHeader.waveTag[3] );
return out; return out;
} }
// get the data size : // get the data size :
if (fileIO->read(&myHeader.fmtTag, 1, 4)!=4) { if (fileAccess.fileRead(&myHeader.fmtTag, 1, 4)!=4) {
EWOLSA_ERROR("Can not 4 element in the file : " << _uri); EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return out; return out;
} }
if( myHeader.fmtTag[0] != 'f' if( myHeader.fmtTag[0] != 'f'
|| myHeader.fmtTag[1] != 'm' || myHeader.fmtTag[1] != 'm'
|| myHeader.fmtTag[2] != 't' || myHeader.fmtTag[2] != 't'
|| myHeader.fmtTag[3] != ' ' ) { || myHeader.fmtTag[3] != ' ' ) {
EWOLSA_ERROR("file: " << _uri << " header error ..." << myHeader.fmtTag[0] << myHeader.fmtTag[1] << myHeader.fmtTag[2] << myHeader.fmtTag[3]); EWOLSA_ERROR("file: \"" << fileAccess << "\" header error ..." << myHeader.fmtTag[0] << myHeader.fmtTag[1] << myHeader.fmtTag[2] << myHeader.fmtTag[3]);
return out; return out;
} }
// get the data size : // get the data size :
if (fileIO->read(tmpData, 1, 4)!=4) { if (fileAccess.fileRead(tmpData, 1, 4)!=4) {
EWOLSA_ERROR("Can not 4 element in the file : " << _uri); EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return out; return out;
} }
myHeader.waveFormatSize = CONVERT_UINT32(littleEndien, tmpData); myHeader.waveFormatSize = CONVERT_UINT32(littleEndien, tmpData);
if (myHeader.waveFormatSize != 16) { if (myHeader.waveFormatSize != 16) {
EWOLSA_ERROR("file : " << _uri << " == > header error ..."); EWOLSA_ERROR("file : \"" << fileAccess << "\" == > header error ...");
return out; return out;
} }
if (fileIO->read(tmpData, 1, 16)!=16) { if (fileAccess.fileRead(tmpData, 1, 16)!=16) {
EWOLSA_ERROR("Can not 16 element in the file : " << _uri); EWOLSA_ERROR("Can not 16 element in the file : \"" << fileAccess << "\"");
return out; return out;
} }
unsigned char * tmppp = tmpData; unsigned char * tmppp = tmpData;
@ -172,20 +170,20 @@ etk::Vector<float> audio::ess::wav::loadAudioFile(const etk::Uri& _uri, int8_t _
EWOLSA_DEBUG(" bytesPerFrame : " << myHeader.waveFormat.bytesPerFrame); EWOLSA_DEBUG(" bytesPerFrame : " << myHeader.waveFormat.bytesPerFrame);
EWOLSA_DEBUG(" bitsPerSample : " << myHeader.waveFormat.bitsPerSample); EWOLSA_DEBUG(" bitsPerSample : " << myHeader.waveFormat.bitsPerSample);
// get the data size : // get the data size :
if (fileIO->read(&myHeader.dataTag, 1, 4)!=4) { if (fileAccess.fileRead(&myHeader.dataTag, 1, 4)!=4) {
EWOLSA_ERROR("Can not 4 element in the file : " << _uri); EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return out; return out;
} }
if( myHeader.dataTag[0] != 'd' if( myHeader.dataTag[0] != 'd'
|| myHeader.dataTag[1] != 'a' || myHeader.dataTag[1] != 'a'
|| myHeader.dataTag[2] != 't' || myHeader.dataTag[2] != 't'
|| myHeader.dataTag[3] != 'a' ) { || myHeader.dataTag[3] != 'a' ) {
EWOLSA_ERROR("file: " << _uri << " header error ..." << myHeader.dataTag[0] << myHeader.dataTag[1] << myHeader.dataTag[2] << myHeader.dataTag[3]); EWOLSA_ERROR("file: \"" << fileAccess << "\" header error ..." << myHeader.dataTag[0] << myHeader.dataTag[1] << myHeader.dataTag[2] << myHeader.dataTag[3]);
return out; return out;
} }
// get the data size : // get the data size :
if (fileIO->read(tmpData, 1, 4)!=4) { if (fileAccess.fileRead(tmpData, 1, 4)!=4) {
EWOLSA_ERROR("Can not 4 element in the file : " << _uri); EWOLSA_ERROR("Can not 4 element in the file : \"" << fileAccess << "\"");
return out; return out;
} }
myHeader.dataSize = CONVERT_UINT32(littleEndien, tmpData); myHeader.dataSize = CONVERT_UINT32(littleEndien, tmpData);
@ -196,22 +194,22 @@ etk::Vector<float> audio::ess::wav::loadAudioFile(const etk::Uri& _uri, int8_t _
//Parse the data and transform it if needed ... //Parse the data and transform it if needed ...
if (COMPR_PCM != myHeader.waveFormat.type) { if (COMPR_PCM != myHeader.waveFormat.type) {
EWOLSA_ERROR("File : " << _uri << " == > support only PCM compression ..."); EWOLSA_ERROR("File : \"" << fileAccess << "\" == > support only PCM compression ...");
return out; return out;
} }
if (myHeader.waveFormat.channelCount == 0 || myHeader.waveFormat.channelCount>2) { if (myHeader.waveFormat.channelCount == 0 || myHeader.waveFormat.channelCount>2) {
EWOLSA_ERROR("File : " << _uri << " == > support only mono or stereo ..." << myHeader.waveFormat.channelCount); EWOLSA_ERROR("File : \"" << fileAccess << "\" == > support only mono or stereo ..." << myHeader.waveFormat.channelCount);
return out; return out;
} }
if ( ! ( myHeader.waveFormat.bitsPerSample == 16 if ( ! ( myHeader.waveFormat.bitsPerSample == 16
|| myHeader.waveFormat.bitsPerSample == 24 || myHeader.waveFormat.bitsPerSample == 24
|| myHeader.waveFormat.bitsPerSample == 32 ) ) { || myHeader.waveFormat.bitsPerSample == 32 ) ) {
EWOLSA_ERROR("File : " << _uri << " == > not supported bit/sample ..." << myHeader.waveFormat.bitsPerSample); EWOLSA_ERROR("File : \"" << fileAccess << "\" == > not supported bit/sample ..." << myHeader.waveFormat.bitsPerSample);
return out; return out;
} }
if( ! ( 44100 == myHeader.waveFormat.samplesPerSec if( ! ( 44100 == myHeader.waveFormat.samplesPerSec
|| 48000 == myHeader.waveFormat.samplesPerSec) ) { || 48000 == myHeader.waveFormat.samplesPerSec) ) {
EWOLSA_ERROR("File : " << _uri << " == > not supported frequency " << myHeader.waveFormat.samplesPerSec << " != 48000"); EWOLSA_ERROR("File : \"" << fileAccess << "\" == > not supported frequency " << myHeader.waveFormat.samplesPerSec << " != 48000");
return out; return out;
} }
EWOLSA_DEBUG(" dataSize : " << myHeader.dataSize); EWOLSA_DEBUG(" dataSize : " << myHeader.dataSize);
@ -226,14 +224,14 @@ etk::Vector<float> audio::ess::wav::loadAudioFile(const etk::Uri& _uri, int8_t _
char audioSample[8]; char audioSample[8];
if (myHeader.waveFormat.bitsPerSample == 16) { if (myHeader.waveFormat.bitsPerSample == 16) {
if (myHeader.waveFormat.channelCount == 1) { if (myHeader.waveFormat.channelCount == 1) {
if (fileIO->read(audioSample, 1, 2)!=2) { if (fileAccess.fileRead(audioSample, 1, 2)!=2) {
EWOLSA_ERROR("Read Error at position : " << iii); EWOLSA_ERROR("Read Error at position : " << iii);
return out; return out;
} }
left = ((int32_t)((int16_t)CONVERT_INT16(littleEndien, audioSample))) << 16; left = ((int32_t)((int16_t)CONVERT_INT16(littleEndien, audioSample))) << 16;
right = left; right = left;
} else { } else {
if (fileIO->read(audioSample, 1, 4)!=4) { if (fileAccess.fileRead(audioSample, 1, 4)!=4) {
EWOLSA_ERROR("Read Error at position : " << iii); EWOLSA_ERROR("Read Error at position : " << iii);
return out; return out;
} }
@ -242,14 +240,14 @@ etk::Vector<float> audio::ess::wav::loadAudioFile(const etk::Uri& _uri, int8_t _
} }
} else if (myHeader.waveFormat.bitsPerSample == 24) { } else if (myHeader.waveFormat.bitsPerSample == 24) {
if (myHeader.waveFormat.channelCount == 1) { if (myHeader.waveFormat.channelCount == 1) {
if (fileIO->read(audioSample, 1, 3)!=3) { if (fileAccess.fileRead(audioSample, 1, 3)!=3) {
EWOLSA_ERROR("Read Error at position : " << iii); EWOLSA_ERROR("Read Error at position : " << iii);
return out; return out;
} }
left = CONVERT_INT24(littleEndien, audioSample); left = CONVERT_INT24(littleEndien, audioSample);
right = left; right = left;
} else { } else {
if (fileIO->read(audioSample, 1, 6)!=6) { if (fileAccess.fileRead(audioSample, 1, 6)!=6) {
EWOLSA_ERROR("Read Error at position : " << iii); EWOLSA_ERROR("Read Error at position : " << iii);
return out; return out;
} }
@ -258,14 +256,14 @@ etk::Vector<float> audio::ess::wav::loadAudioFile(const etk::Uri& _uri, int8_t _
} }
} else if (myHeader.waveFormat.bitsPerSample == 32) { } else if (myHeader.waveFormat.bitsPerSample == 32) {
if (myHeader.waveFormat.channelCount == 1) { if (myHeader.waveFormat.channelCount == 1) {
if (fileIO->read(audioSample, 1, 4)!=4) { if (fileAccess.fileRead(audioSample, 1, 4)!=4) {
EWOLSA_ERROR("Read Error at position : " << iii); EWOLSA_ERROR("Read Error at position : " << iii);
return out; return out;
} }
left = CONVERT_INT32(littleEndien, audioSample); left = CONVERT_INT32(littleEndien, audioSample);
right = left; right = left;
} else { } else {
if (fileIO->read(audioSample, 1, 8)!=8) { if (fileAccess.fileRead(audioSample, 1, 8)!=8) {
EWOLSA_ERROR("Read Error at position : " << iii); EWOLSA_ERROR("Read Error at position : " << iii);
return out; return out;
} }
@ -282,7 +280,7 @@ etk::Vector<float> audio::ess::wav::loadAudioFile(const etk::Uri& _uri, int8_t _
} }
} }
// close the file: // close the file:
fileIO->close(); fileAccess.fileClose();
return out; return out;
} }

View File

@ -6,12 +6,11 @@
#pragma once #pragma once
#include <etk/types.hpp> #include <etk/types.hpp>
#include <etk/uri/uri.hpp>
namespace audio { namespace audio {
namespace ess { namespace ess {
namespace wav { namespace wav {
etk::Vector<float> loadAudioFile(const etk::Uri& _uri, int8_t _nbChan); etk::Vector<float> loadAudioFile(const etk::String& _filename, int8_t _nbChan);
} }
} }
} }

View File

@ -12,7 +12,6 @@
#include <audio/ess/ess.hpp> #include <audio/ess/ess.hpp>
#include <audio/ess/debug.hpp> #include <audio/ess/debug.hpp>
#include <ejson/ejson.hpp> #include <ejson/ejson.hpp>
#include <etk/uri/uri.hpp>
ememory::SharedPtr<audio::river::Manager> g_audioManager; ememory::SharedPtr<audio::river::Manager> g_audioManager;
ememory::SharedPtr<audio::ess::Effects> g_effects; ememory::SharedPtr<audio::ess::Effects> g_effects;
@ -53,10 +52,8 @@ void audio::ess::soundSetParse(const etk::String& _data) {
} }
} }
void audio::ess::soundSetLoad(const etk::Uri& _uri) { void audio::ess::soundSetLoad(const etk::String& _file) {
etk::String data; soundSetParse(etk::FSNodeReadAllData(_file));
etk::uri::readAll(_uri, data);
soundSetParse(data);
} }
void audio::ess::musicPlay(const etk::String& _name) { void audio::ess::musicPlay(const etk::String& _name) {

View File

@ -32,9 +32,9 @@ namespace audio {
void soundSetParse(const etk::String& _data); void soundSetParse(const etk::String& _data);
/** /**
* @brief Parse a configuration file of a soundset * @brief Parse a configuration file of a soundset
* @param[in] _uri JSON file to parse * @param[in] _file JSON file to parse
*/ */
void soundSetLoad(const etk::Uri& _uri); void soundSetLoad(const etk::String& _file);
/** /**
* @brief Play a music with his name * @brief Play a music with his name

View File

@ -24,14 +24,14 @@ A simple example:
```{.json} ```{.json}
{ {
musics:{ musics:{
"BG-1":"DATA:///audio/Clean Soul.ogg" "BG-1":"DATA:audio/Clean Soul.ogg"
"BG-22":"DATA:///audio/Dark knight.ogg" "BG-22":"DATA:audio/Dark knight.ogg"
}, },
effects:{ effects:{
"end":"DATA:///audio/end.wav", "end":"DATA:audio/end.wav",
"error":"DATA:///audio/error.wav", "error":"DATA:audio/error.wav",
"levelup":"DATA:///audio/levelup.wav", "levelup":"DATA:audio/levelup.wav",
"ok":"DATA:///audio/ok.wav" "ok":"DATA:audio/ok.wav"
} }
} }
``` ```

View File

@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
import lutin.tools as tools import lutin.tools as tools
import realog.debug as debug import lutin.debug as debug
def get_type(): def get_type():