Browse Source

Add AudioPlayMemory object

dds
PaulStoffregen 11 years ago
parent
commit
c62c430c16
2 changed files with 303 additions and 0 deletions
  1. +287
    -0
      Audio.cpp
  2. +16
    -0
      Audio.h

+ 287
- 0
Audio.cpp View File

@@ -1527,6 +1527,293 @@ void AudioPlaySDcardRAW::update(void)
}


/******************************************************************/



void AudioPlayMemory::play(const unsigned int *data)
{
uint32_t format;

playing = 0;
length = *data++;
format = *data++;
next = data;
prior = 0;
fraction = 0;
if (format == (44100 | (8 << 24))) {
playing = 1;
} else if (format == (44100 | (16 << 24))) {
playing = 2;
} else if (format == (22050 | (8 << 24))) {
playing = 3;
} else if (format == (22050 | (16 << 24))) {
playing = 4;
} else if (format == (11025 | (8 << 24))) {
playing = 5;
} else if (format == (11025 | (16 << 24))) {
playing = 6;
} else if (format == (8000 | (8 << 24))) {
playing = 7;
}
}

void AudioPlayMemory::stop(void)
{
playing = 0;
}


void AudioPlayMemory::update(void)
{
audio_block_t *block;
const unsigned int *in;
int16_t *out;
uint32_t tmp32, consumed;
int16_t s0, s1, s2, s3, s4;
int i;

if (!playing) return;
block = allocate();
if (block == NULL) return;

//Serial.write('.');

out = block->data;
in = next;
s0 = prior;

switch (playing) {
case 1: // 8 bits, 44100 Hz - works
for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 4) {
tmp32 = *in++;
*out++ = (int8_t)(tmp32 & 255) << 8;
*out++ = (int8_t)((tmp32 >> 8) & 255) << 8;
*out++ = (int8_t)((tmp32 >> 16) & 255) << 8;
*out++ = (int8_t)((tmp32 >> 24) & 255) << 8;
}
consumed = 128;
break;

case 2: // 16 bits, 44100 Hz - ???
for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 2) {
tmp32 = *in++;
*out++ = (int16_t)(tmp32 & 65535);
*out++ = (int16_t)(tmp32 >> 16);
}
consumed = 128;
break;

case 3: // 8 bits, 22050 Hz - works
for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 8) {
tmp32 = *in++;
s1 = (int8_t)((tmp32 >> 0) & 255) << 8;
s2 = (int8_t)((tmp32 >> 8) & 255) << 8;
s3 = (int8_t)((tmp32 >> 16) & 255) << 8;
s4 = (int8_t)((tmp32 >> 24) & 255) << 8;
*out++ = (s0 + s1) >> 1;
*out++ = s1;
*out++ = (s1 + s2) >> 1;
*out++ = s2;
*out++ = (s2 + s3) >> 1;
*out++ = s3;
*out++ = (s3 + s4) >> 1;
*out++ = s4;
s0 = s4;
}
consumed = 64;
break;

case 4: // 16 bits, 22050 Hz - ??
for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 4) {
tmp32 = *in++;
s1 = (int16_t)(tmp32 & 65535);
s2 = (int16_t)(tmp32 >> 16);
*out++ = (s0 + s1) >> 1;
*out++ = s1;
*out++ = (s1 + s2) >> 1;
*out++ = s2;
s0 = s2;
}
consumed = 64;
break;

case 5: // 8 bits, 11025 Hz - ??
for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 16) {
tmp32 = *in++;
s1 = (int8_t)((tmp32 >> 0) & 255) << 8;
s2 = (int8_t)((tmp32 >> 8) & 255) << 8;
s3 = (int8_t)((tmp32 >> 16) & 255) << 8;
s4 = (int8_t)((tmp32 >> 24) & 255) << 8;
*out++ = (s0 * 3 + s1) >> 2;
*out++ = (s0 + s1) >> 1;
*out++ = (s0 + s1 * 3) >> 2;
*out++ = s1;
*out++ = (s1 * 3 + s2) >> 2;
*out++ = (s1 + s2) >> 1;
*out++ = (s1 + s2 * 3) >> 2;
*out++ = s2;
*out++ = (s2 * 3 + s3) >> 2;
*out++ = (s2 + s3) >> 1;
*out++ = (s2 + s3 * 3) >> 2;
*out++ = s3;
*out++ = (s3 * 3 + s4) >> 2;
*out++ = (s3 + s4) >> 1;
*out++ = (s3 + s4 * 3) >> 2;
*out++ = s4;
s0 = s4;
}
consumed = 32;
break;

case 6: // 16 bits, 11025 Hz - ??
for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 8) {
tmp32 = *in++;
s1 = (int16_t)(tmp32 & 65535);
s2 = (int16_t)(tmp32 >> 16);
*out++ = (s0 * 3 + s1) >> 2;
*out++ = (s0 + s1) >> 1;
*out++ = (s0 + s1 * 3) >> 2;
*out++ = s1;
*out++ = (s1 * 3 + s2) >> 2;
*out++ = (s1 + s2) >> 1;
*out++ = (s1 + s2 * 3) >> 2;
*out++ = s2;
s0 = s2;
}
consumed = 32;
break;

case 7: // 8 bits, 8000 Hz - has audible problem, pull requests welcome!
if (fraction > 0) {
tmp32 = *in++;
s1 = (int8_t)((tmp32 >> 0) & 255) << 8;
s2 = (int8_t)((tmp32 >> 8) & 255) << 8;
s3 = (int8_t)((tmp32 >> 16) & 255) << 8;
s4 = (int8_t)((tmp32 >> 24) & 255) << 8;
switch (fraction) {
case 20: *out++ = (s0 * 7447 + s1 * 8937) >> 14;
*out++ = (s0 * 4468 + s1 * 11916) >> 14;
case 18: *out++ = (s0 * 1489 + s1 * 14894) >> 14;
*out++ = (s1 * 14894 + s2 * 1489) >> 14;
case 16: *out++ = (s1 * 11916 + s2 * 4468) >> 14;
*out++ = (s1 * 8937 + s2 * 7447) >> 14;
case 14: *out++ = (s1 * 5958 + s2 * 10426) >> 14;
*out++ = (s1 * 2978 + s2 * 13405) >> 14;
case 12: *out++ = s2;
*out++ = (s2 * 13405 + s3 * 2978) >> 14;
case 10: *out++ = (s2 * 10426 + s3 * 5958) >> 14;
*out++ = (s2 * 7447 + s3 * 8937) >> 14;
case 8: *out++ = (s2 * 4468 + s3 * 11916) >> 14;
*out++ = (s2 * 1489 + s3 * 14894) >> 14;
case 6: *out++ = (s3 * 14894 + s4 * 1489) >> 14;
*out++ = (s3 * 11916 + s4 * 4468) >> 14;
case 4: *out++ = (s3 * 8937 + s4 * 7447) >> 14;
*out++ = (s3 * 5958 + s4 * 10426) >> 14;
case 2: *out++ = (s3 * 2978 + s4 * 13405) >> 14;
*out++ = s4;
}
s0 = s4;
consumed = 4;
} else {
consumed = 0;
}
for (i = fraction; i < AUDIO_BLOCK_SAMPLES-22 /* 106 */ ; i += 22) {
tmp32 = *in++;
s1 = (int8_t)((tmp32 >> 0) & 255) << 8;
s2 = (int8_t)((tmp32 >> 8) & 255) << 8;
s3 = (int8_t)((tmp32 >> 16) & 255) << 8;
s4 = (int8_t)((tmp32 >> 24) & 255) << 8;
*out++ = (s0 * 13405 + s1 * 2978) >> 14;
*out++ = (s0 * 10426 + s1 * 5958) >> 14;
*out++ = (s0 * 7447 + s1 * 8937) >> 14;
*out++ = (s0 * 4468 + s1 * 11916) >> 14;
*out++ = (s0 * 1489 + s1 * 14894) >> 14;
*out++ = (s1 * 14894 + s2 * 1489) >> 14;
*out++ = (s1 * 11916 + s2 * 4468) >> 14;
*out++ = (s1 * 8937 + s2 * 7447) >> 14;
*out++ = (s1 * 5958 + s2 * 10426) >> 14;
*out++ = (s1 * 2978 + s2 * 13405) >> 14;
*out++ = s2;
*out++ = (s2 * 13405 + s3 * 2978) >> 14;
*out++ = (s2 * 10426 + s3 * 5958) >> 14;
*out++ = (s2 * 7447 + s3 * 8937) >> 14;
*out++ = (s2 * 4468 + s3 * 11916) >> 14;
*out++ = (s2 * 1489 + s3 * 14894) >> 14;
*out++ = (s3 * 14894 + s4 * 1489) >> 14;
*out++ = (s3 * 11916 + s4 * 4468) >> 14;
*out++ = (s3 * 8937 + s4 * 7447) >> 14;
*out++ = (s3 * 5958 + s4 * 10426) >> 14;
*out++ = (s3 * 2978 + s4 * 13405) >> 14;
*out++ = s4;
s0 = s4;
consumed += 4;
}
if (i < AUDIO_BLOCK_SAMPLES) {
fraction = 22 - (AUDIO_BLOCK_SAMPLES - i);
tmp32 = *in;
s1 = (int8_t)((tmp32 >> 0) & 255) << 8;
s2 = (int8_t)((tmp32 >> 8) & 255) << 8;
s3 = (int8_t)((tmp32 >> 16) & 255) << 8;
s4 = (int8_t)((tmp32 >> 24) & 255) << 8;
do {
*out++ = (s0 * 13405 + s1 * 2978) >> 14;
*out++ = (s0 * 10426 + s1 * 5958) >> 14;
if ((i += 2) == AUDIO_BLOCK_SAMPLES) break;
*out++ = (s0 * 7447 + s1 * 8937) >> 14;
*out++ = (s0 * 4468 + s1 * 11916) >> 14;
if ((i += 2) == AUDIO_BLOCK_SAMPLES) break;
*out++ = (s0 * 1489 + s1 * 14894) >> 14;
*out++ = (s1 * 14894 + s2 * 1489) >> 14;
if ((i += 2) == AUDIO_BLOCK_SAMPLES) break;
*out++ = (s1 * 11916 + s2 * 4468) >> 14;
*out++ = (s1 * 8937 + s2 * 7447) >> 14;
if ((i += 2) == AUDIO_BLOCK_SAMPLES) break;
*out++ = (s1 * 5958 + s2 * 10426) >> 14;
*out++ = (s1 * 2978 + s2 * 13405) >> 14;
if ((i += 2) == AUDIO_BLOCK_SAMPLES) break;
*out++ = s2;
*out++ = (s2 * 13405 + s3 * 2978) >> 14;
if ((i += 2) == AUDIO_BLOCK_SAMPLES) break;
*out++ = (s2 * 10426 + s3 * 5958) >> 14;
*out++ = (s2 * 7447 + s3 * 8937) >> 14;
if ((i += 2) == AUDIO_BLOCK_SAMPLES) break;
*out++ = (s2 * 4468 + s3 * 11916) >> 14;
*out++ = (s2 * 1489 + s3 * 14894) >> 14;
if ((i += 2) == AUDIO_BLOCK_SAMPLES) break;
*out++ = (s3 * 14894 + s4 * 1489) >> 14;
*out++ = (s3 * 11916 + s4 * 4468) >> 14;
if ((i += 2) == AUDIO_BLOCK_SAMPLES) break;
*out++ = (s3 * 8937 + s4 * 7447) >> 14;
*out++ = (s3 * 5958 + s4 * 10426) >> 14;
} while (0);
} else {
fraction = 0;
}
break;
default:
release(block);
playing = 0;
return;
}
prior = s0;
next = in;
if (length > consumed) {
length -= consumed;
} else {
Serial.println("end");
playing = 0;
}
transmit(block);
release(block);
}











+ 16
- 0
Audio.h View File

@@ -266,6 +266,22 @@ private:



class AudioPlayMemory : public AudioStream
{
public:
AudioPlayMemory(void) : AudioStream(0, NULL), playing(0) { }
void play(const unsigned int *data);
void stop(void);
virtual void update(void);
private:
const unsigned int *next;
uint32_t length;
int16_t prior;
uint8_t fraction;
uint8_t playing;
};






Loading…
Cancel
Save