The "GR-PEACH_Audio_Playback_Sample" is a sample code that can provides high-resolution audio playback of FLAC format files. It also allows the user to audio-playback control functions such as play, pause, and stop by manipulating key switches.

Dependencies:   R_BSP TLV320_RBSP USBHost_custom

Note

For a sample program of with LCD Board,
please refer to GR-PEACH_Audio_Playback_7InchLCD_Sample.

Introduction

The "GR-PEACH_Audio_Playback_Sample" is a sample code that can provides high-resolution audio playback of FLAC format files. It also allows the user to audio-playback control functions such as play, pause, and stop by manipulating key switches.

1. Overview of the Sample Code

1.1 Software Block Diagram

Figure 1.1 shows the software block diagram.

/media/uploads/dkato/audioplayback_figure1_1x.png

1.2 Pin Definitions

Table 1.1 shows the pins that this sample code are to use.

/media/uploads/dkato/audioplayback_table1_1.png

2. Sample Code Operating Environment

This sample code runs in GR-PEACH + the Audio/Camera shield for the GR-PEACH environment. This section explains the functions of the ports that are used by this sample code.

2.1 Operating Environment

Figure 2.1 shows the configuration of the operating environment for running this sample code.

/media/uploads/dkato/audioplayback_figure2_1.png /media/uploads/1050186/figure2_2.png /media/uploads/dkato/audioplayback_figure2_3.png

2.2 List of User Operations

A list of user operations on the command line, TFT touch keys, and switch key that the user can perform for this sample code is shown in. Table 2.1.

/media/uploads/dkato/audioplayback_table2_1x.png

3. Function Outline

The functions of this sample code are summarized in Table 3.1 to Table 3.3.

/media/uploads/dkato/audioplayback_table3_1.png /media/uploads/dkato/audioplayback_table3_2.png /media/uploads/dkato/audioplayback_table3_3.png /media/uploads/dkato/audioplayback_figure3_1.png

3.1 Playback Control

The playback control that the sample code supports include play, pause, stop, skip to next, and skip to previous.

3.2 Trick Play Control

Manipulating "Repeat" alternates between "Repeat mode On" and "Repeat mode Off". The default mode is "Repeat mode On". When the repeat mode is on, the playback of the first song starts after the playback of the last song is finished. When the repeat mode is off, the sample code enters the stopped state after the playback of the last song is finished.

3.3 Acquisition of the Song Information

The information of the song being played is obtained by operating the "Play info" during the playback of the song. Table 3.4 lists the items of information that can be obtained by the "Play info" operation.

/media/uploads/dkato/audioplayback_table3_4.png

3.4 How the Folder Structure is Analyzed

The sample coded analyzes the folder structure in the breadth-first search order. The order in which files are numbered is illustrated in Table 3.5. The sample code does not sort the files by file or folder name.

/media/uploads/dkato/audioplayback_table3_5.png

4.Others

The default setting of serial communication (baud rate etc.) in mbed is shown the following link.
Please refer to the link and change the settings of your PC terminal software.
The default value of baud rate in mbed is 9600, and this application uses baud rate 9600.
https://developer.mbed.org/teams/Renesas/wiki/GR-PEACH-Getting-Started#install-the-usb-serial-communication

Committer:
dkato
Date:
Fri Oct 16 04:28:07 2015 +0000
Revision:
0:ee40da884cfc
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dkato 0:ee40da884cfc 1 #ifdef HAVE_CONFIG_H
dkato 0:ee40da884cfc 2 # include <config.h>
dkato 0:ee40da884cfc 3 #endif
dkato 0:ee40da884cfc 4
dkato 0:ee40da884cfc 5 #include <stdlib.h> /* for malloc() */
dkato 0:ee40da884cfc 6 #include <string.h> /* for memcpy() */
dkato 0:ee40da884cfc 7
dkato 0:ee40da884cfc 8 #include "private/md5.h"
dkato 0:ee40da884cfc 9 #include "share/alloc.h"
dkato 0:ee40da884cfc 10 #include "share/endswap.h"
dkato 0:ee40da884cfc 11
dkato 0:ee40da884cfc 12 /*
dkato 0:ee40da884cfc 13 * This code implements the MD5 message-digest algorithm.
dkato 0:ee40da884cfc 14 * The algorithm is due to Ron Rivest. This code was
dkato 0:ee40da884cfc 15 * written by Colin Plumb in 1993, no copyright is claimed.
dkato 0:ee40da884cfc 16 * This code is in the public domain; do with it what you wish.
dkato 0:ee40da884cfc 17 *
dkato 0:ee40da884cfc 18 * Equivalent code is available from RSA Data Security, Inc.
dkato 0:ee40da884cfc 19 * This code has been tested against that, and is equivalent,
dkato 0:ee40da884cfc 20 * except that you don't need to include two pages of legalese
dkato 0:ee40da884cfc 21 * with every copy.
dkato 0:ee40da884cfc 22 *
dkato 0:ee40da884cfc 23 * To compute the message digest of a chunk of bytes, declare an
dkato 0:ee40da884cfc 24 * MD5Context structure, pass it to MD5Init, call MD5Update as
dkato 0:ee40da884cfc 25 * needed on buffers full of bytes, and then call MD5Final, which
dkato 0:ee40da884cfc 26 * will fill a supplied 16-byte array with the digest.
dkato 0:ee40da884cfc 27 *
dkato 0:ee40da884cfc 28 * Changed so as no longer to depend on Colin Plumb's `usual.h' header
dkato 0:ee40da884cfc 29 * definitions; now uses stuff from dpkg's config.h.
dkato 0:ee40da884cfc 30 * - Ian Jackson <ijackson@nyx.cs.du.edu>.
dkato 0:ee40da884cfc 31 * Still in the public domain.
dkato 0:ee40da884cfc 32 *
dkato 0:ee40da884cfc 33 * Josh Coalson: made some changes to integrate with libFLAC.
dkato 0:ee40da884cfc 34 * Still in the public domain.
dkato 0:ee40da884cfc 35 */
dkato 0:ee40da884cfc 36
dkato 0:ee40da884cfc 37 /* The four core functions - F1 is optimized somewhat */
dkato 0:ee40da884cfc 38
dkato 0:ee40da884cfc 39 /* #define F1(x, y, z) (x & y | ~x & z) */
dkato 0:ee40da884cfc 40 #define F1(x, y, z) (z ^ (x & (y ^ z)))
dkato 0:ee40da884cfc 41 #define F2(x, y, z) F1(z, x, y)
dkato 0:ee40da884cfc 42 #define F3(x, y, z) (x ^ y ^ z)
dkato 0:ee40da884cfc 43 #define F4(x, y, z) (y ^ (x | ~z))
dkato 0:ee40da884cfc 44
dkato 0:ee40da884cfc 45 /* This is the central step in the MD5 algorithm. */
dkato 0:ee40da884cfc 46 #define MD5STEP(f,w,x,y,z,in,s) \
dkato 0:ee40da884cfc 47 (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
dkato 0:ee40da884cfc 48
dkato 0:ee40da884cfc 49 /*
dkato 0:ee40da884cfc 50 * The core of the MD5 algorithm, this alters an existing MD5 hash to
dkato 0:ee40da884cfc 51 * reflect the addition of 16 longwords of new data. MD5Update blocks
dkato 0:ee40da884cfc 52 * the data and converts bytes into longwords for this routine.
dkato 0:ee40da884cfc 53 */
dkato 0:ee40da884cfc 54 static void FLAC__MD5Transform(FLAC__uint32 buf[4], FLAC__uint32 const in[16])
dkato 0:ee40da884cfc 55 {
dkato 0:ee40da884cfc 56 register FLAC__uint32 a, b, c, d;
dkato 0:ee40da884cfc 57
dkato 0:ee40da884cfc 58 a = buf[0];
dkato 0:ee40da884cfc 59 b = buf[1];
dkato 0:ee40da884cfc 60 c = buf[2];
dkato 0:ee40da884cfc 61 d = buf[3];
dkato 0:ee40da884cfc 62
dkato 0:ee40da884cfc 63 MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
dkato 0:ee40da884cfc 64 MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
dkato 0:ee40da884cfc 65 MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
dkato 0:ee40da884cfc 66 MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
dkato 0:ee40da884cfc 67 MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
dkato 0:ee40da884cfc 68 MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
dkato 0:ee40da884cfc 69 MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
dkato 0:ee40da884cfc 70 MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
dkato 0:ee40da884cfc 71 MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
dkato 0:ee40da884cfc 72 MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
dkato 0:ee40da884cfc 73 MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
dkato 0:ee40da884cfc 74 MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
dkato 0:ee40da884cfc 75 MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
dkato 0:ee40da884cfc 76 MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
dkato 0:ee40da884cfc 77 MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
dkato 0:ee40da884cfc 78 MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
dkato 0:ee40da884cfc 79
dkato 0:ee40da884cfc 80 MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
dkato 0:ee40da884cfc 81 MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
dkato 0:ee40da884cfc 82 MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
dkato 0:ee40da884cfc 83 MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
dkato 0:ee40da884cfc 84 MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
dkato 0:ee40da884cfc 85 MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
dkato 0:ee40da884cfc 86 MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
dkato 0:ee40da884cfc 87 MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
dkato 0:ee40da884cfc 88 MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
dkato 0:ee40da884cfc 89 MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
dkato 0:ee40da884cfc 90 MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
dkato 0:ee40da884cfc 91 MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
dkato 0:ee40da884cfc 92 MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
dkato 0:ee40da884cfc 93 MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
dkato 0:ee40da884cfc 94 MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
dkato 0:ee40da884cfc 95 MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
dkato 0:ee40da884cfc 96
dkato 0:ee40da884cfc 97 MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
dkato 0:ee40da884cfc 98 MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
dkato 0:ee40da884cfc 99 MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
dkato 0:ee40da884cfc 100 MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
dkato 0:ee40da884cfc 101 MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
dkato 0:ee40da884cfc 102 MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
dkato 0:ee40da884cfc 103 MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
dkato 0:ee40da884cfc 104 MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
dkato 0:ee40da884cfc 105 MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
dkato 0:ee40da884cfc 106 MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
dkato 0:ee40da884cfc 107 MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
dkato 0:ee40da884cfc 108 MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
dkato 0:ee40da884cfc 109 MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
dkato 0:ee40da884cfc 110 MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
dkato 0:ee40da884cfc 111 MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
dkato 0:ee40da884cfc 112 MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
dkato 0:ee40da884cfc 113
dkato 0:ee40da884cfc 114 MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
dkato 0:ee40da884cfc 115 MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
dkato 0:ee40da884cfc 116 MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
dkato 0:ee40da884cfc 117 MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
dkato 0:ee40da884cfc 118 MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
dkato 0:ee40da884cfc 119 MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
dkato 0:ee40da884cfc 120 MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
dkato 0:ee40da884cfc 121 MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
dkato 0:ee40da884cfc 122 MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
dkato 0:ee40da884cfc 123 MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
dkato 0:ee40da884cfc 124 MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
dkato 0:ee40da884cfc 125 MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
dkato 0:ee40da884cfc 126 MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
dkato 0:ee40da884cfc 127 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
dkato 0:ee40da884cfc 128 MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
dkato 0:ee40da884cfc 129 MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
dkato 0:ee40da884cfc 130
dkato 0:ee40da884cfc 131 buf[0] += a;
dkato 0:ee40da884cfc 132 buf[1] += b;
dkato 0:ee40da884cfc 133 buf[2] += c;
dkato 0:ee40da884cfc 134 buf[3] += d;
dkato 0:ee40da884cfc 135 }
dkato 0:ee40da884cfc 136
dkato 0:ee40da884cfc 137 #if WORDS_BIGENDIAN
dkato 0:ee40da884cfc 138 //@@@@@@ OPT: use bswap/intrinsics
dkato 0:ee40da884cfc 139 static void byteSwap(FLAC__uint32 *buf, unsigned words)
dkato 0:ee40da884cfc 140 {
dkato 0:ee40da884cfc 141 register FLAC__uint32 x;
dkato 0:ee40da884cfc 142 do {
dkato 0:ee40da884cfc 143 x = *buf;
dkato 0:ee40da884cfc 144 x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff);
dkato 0:ee40da884cfc 145 *buf++ = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 146 } while (--words);
dkato 0:ee40da884cfc 147 }
dkato 0:ee40da884cfc 148 static void byteSwapX16(FLAC__uint32 *buf)
dkato 0:ee40da884cfc 149 {
dkato 0:ee40da884cfc 150 register FLAC__uint32 x;
dkato 0:ee40da884cfc 151
dkato 0:ee40da884cfc 152 x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 153 x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 154 x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 155 x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 156 x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 157 x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 158 x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 159 x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 160 x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 161 x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 162 x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 163 x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 164 x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 165 x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 166 x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 167 x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf = (x >> 16) | (x << 16);
dkato 0:ee40da884cfc 168 }
dkato 0:ee40da884cfc 169 #else
dkato 0:ee40da884cfc 170 #define byteSwap(buf, words)
dkato 0:ee40da884cfc 171 #define byteSwapX16(buf)
dkato 0:ee40da884cfc 172 #endif
dkato 0:ee40da884cfc 173
dkato 0:ee40da884cfc 174 /*
dkato 0:ee40da884cfc 175 * Update context to reflect the concatenation of another buffer full
dkato 0:ee40da884cfc 176 * of bytes.
dkato 0:ee40da884cfc 177 */
dkato 0:ee40da884cfc 178 static void FLAC__MD5Update(FLAC__MD5Context *ctx, FLAC__byte const *buf, unsigned len)
dkato 0:ee40da884cfc 179 {
dkato 0:ee40da884cfc 180 FLAC__uint32 t;
dkato 0:ee40da884cfc 181
dkato 0:ee40da884cfc 182 /* Update byte count */
dkato 0:ee40da884cfc 183
dkato 0:ee40da884cfc 184 t = ctx->bytes[0];
dkato 0:ee40da884cfc 185 if ((ctx->bytes[0] = t + len) < t)
dkato 0:ee40da884cfc 186 ctx->bytes[1]++; /* Carry from low to high */
dkato 0:ee40da884cfc 187
dkato 0:ee40da884cfc 188 t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */
dkato 0:ee40da884cfc 189 if (t > len) {
dkato 0:ee40da884cfc 190 memcpy((FLAC__byte *)ctx->in + 64 - t, buf, len);
dkato 0:ee40da884cfc 191 return;
dkato 0:ee40da884cfc 192 }
dkato 0:ee40da884cfc 193 /* First chunk is an odd size */
dkato 0:ee40da884cfc 194 memcpy((FLAC__byte *)ctx->in + 64 - t, buf, t);
dkato 0:ee40da884cfc 195 byteSwapX16(ctx->in);
dkato 0:ee40da884cfc 196 FLAC__MD5Transform(ctx->buf, ctx->in);
dkato 0:ee40da884cfc 197 buf += t;
dkato 0:ee40da884cfc 198 len -= t;
dkato 0:ee40da884cfc 199
dkato 0:ee40da884cfc 200 /* Process data in 64-byte chunks */
dkato 0:ee40da884cfc 201 while (len >= 64) {
dkato 0:ee40da884cfc 202 memcpy(ctx->in, buf, 64);
dkato 0:ee40da884cfc 203 byteSwapX16(ctx->in);
dkato 0:ee40da884cfc 204 FLAC__MD5Transform(ctx->buf, ctx->in);
dkato 0:ee40da884cfc 205 buf += 64;
dkato 0:ee40da884cfc 206 len -= 64;
dkato 0:ee40da884cfc 207 }
dkato 0:ee40da884cfc 208
dkato 0:ee40da884cfc 209 /* Handle any remaining bytes of data. */
dkato 0:ee40da884cfc 210 memcpy(ctx->in, buf, len);
dkato 0:ee40da884cfc 211 }
dkato 0:ee40da884cfc 212
dkato 0:ee40da884cfc 213 /*
dkato 0:ee40da884cfc 214 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
dkato 0:ee40da884cfc 215 * initialization constants.
dkato 0:ee40da884cfc 216 */
dkato 0:ee40da884cfc 217 void FLAC__MD5Init(FLAC__MD5Context *ctx)
dkato 0:ee40da884cfc 218 {
dkato 0:ee40da884cfc 219 ctx->buf[0] = 0x67452301;
dkato 0:ee40da884cfc 220 ctx->buf[1] = 0xefcdab89;
dkato 0:ee40da884cfc 221 ctx->buf[2] = 0x98badcfe;
dkato 0:ee40da884cfc 222 ctx->buf[3] = 0x10325476;
dkato 0:ee40da884cfc 223
dkato 0:ee40da884cfc 224 ctx->bytes[0] = 0;
dkato 0:ee40da884cfc 225 ctx->bytes[1] = 0;
dkato 0:ee40da884cfc 226
dkato 0:ee40da884cfc 227 ctx->internal_buf.p8= 0;
dkato 0:ee40da884cfc 228 ctx->capacity = 0;
dkato 0:ee40da884cfc 229 }
dkato 0:ee40da884cfc 230
dkato 0:ee40da884cfc 231 /*
dkato 0:ee40da884cfc 232 * Final wrapup - pad to 64-byte boundary with the bit pattern
dkato 0:ee40da884cfc 233 * 1 0* (64-bit count of bits processed, MSB-first)
dkato 0:ee40da884cfc 234 */
dkato 0:ee40da884cfc 235 void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx)
dkato 0:ee40da884cfc 236 {
dkato 0:ee40da884cfc 237 int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
dkato 0:ee40da884cfc 238 FLAC__byte *p = (FLAC__byte *)ctx->in + count;
dkato 0:ee40da884cfc 239
dkato 0:ee40da884cfc 240 /* Set the first char of padding to 0x80. There is always room. */
dkato 0:ee40da884cfc 241 *p++ = 0x80;
dkato 0:ee40da884cfc 242
dkato 0:ee40da884cfc 243 /* Bytes of padding needed to make 56 bytes (-8..55) */
dkato 0:ee40da884cfc 244 count = 56 - 1 - count;
dkato 0:ee40da884cfc 245
dkato 0:ee40da884cfc 246 if (count < 0) { /* Padding forces an extra block */
dkato 0:ee40da884cfc 247 memset(p, 0, count + 8);
dkato 0:ee40da884cfc 248 byteSwapX16(ctx->in);
dkato 0:ee40da884cfc 249 FLAC__MD5Transform(ctx->buf, ctx->in);
dkato 0:ee40da884cfc 250 p = (FLAC__byte *)ctx->in;
dkato 0:ee40da884cfc 251 count = 56;
dkato 0:ee40da884cfc 252 }
dkato 0:ee40da884cfc 253 memset(p, 0, count);
dkato 0:ee40da884cfc 254 byteSwap(ctx->in, 14);
dkato 0:ee40da884cfc 255
dkato 0:ee40da884cfc 256 /* Append length in bits and transform */
dkato 0:ee40da884cfc 257 ctx->in[14] = ctx->bytes[0] << 3;
dkato 0:ee40da884cfc 258 ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
dkato 0:ee40da884cfc 259 FLAC__MD5Transform(ctx->buf, ctx->in);
dkato 0:ee40da884cfc 260
dkato 0:ee40da884cfc 261 byteSwap(ctx->buf, 4);
dkato 0:ee40da884cfc 262 memcpy(digest, ctx->buf, 16);
dkato 0:ee40da884cfc 263 if (0 != ctx->internal_buf.p8) {
dkato 0:ee40da884cfc 264 free(ctx->internal_buf.p8);
dkato 0:ee40da884cfc 265 ctx->internal_buf.p8= 0;
dkato 0:ee40da884cfc 266 ctx->capacity = 0;
dkato 0:ee40da884cfc 267 }
dkato 0:ee40da884cfc 268 memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
dkato 0:ee40da884cfc 269 }
dkato 0:ee40da884cfc 270
dkato 0:ee40da884cfc 271 /*
dkato 0:ee40da884cfc 272 * Convert the incoming audio signal to a byte stream
dkato 0:ee40da884cfc 273 */
dkato 0:ee40da884cfc 274 static void format_input_(FLAC__multibyte *mbuf, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample)
dkato 0:ee40da884cfc 275 {
dkato 0:ee40da884cfc 276 FLAC__byte *buf_ = mbuf->p8;
dkato 0:ee40da884cfc 277 FLAC__int16 *buf16 = mbuf->p16;
dkato 0:ee40da884cfc 278 FLAC__int32 *buf32 = mbuf->p32;
dkato 0:ee40da884cfc 279 FLAC__int32 a_word;
dkato 0:ee40da884cfc 280 unsigned channel, sample;
dkato 0:ee40da884cfc 281
dkato 0:ee40da884cfc 282 /* Storage in the output buffer, buf, is little endian. */
dkato 0:ee40da884cfc 283
dkato 0:ee40da884cfc 284 #define BYTES_CHANNEL_SELECTOR(bytes, channels) (bytes * 100 + channels)
dkato 0:ee40da884cfc 285
dkato 0:ee40da884cfc 286 /* First do the most commonly used combinations. */
dkato 0:ee40da884cfc 287 switch (BYTES_CHANNEL_SELECTOR (bytes_per_sample, channels)) {
dkato 0:ee40da884cfc 288 /* One byte per sample. */
dkato 0:ee40da884cfc 289 case (BYTES_CHANNEL_SELECTOR (1, 1)):
dkato 0:ee40da884cfc 290 for (sample = 0; sample < samples; sample++)
dkato 0:ee40da884cfc 291 *buf_++ = signal[0][sample];
dkato 0:ee40da884cfc 292 return;
dkato 0:ee40da884cfc 293
dkato 0:ee40da884cfc 294 case (BYTES_CHANNEL_SELECTOR (1, 2)):
dkato 0:ee40da884cfc 295 for (sample = 0; sample < samples; sample++) {
dkato 0:ee40da884cfc 296 *buf_++ = signal[0][sample];
dkato 0:ee40da884cfc 297 *buf_++ = signal[1][sample];
dkato 0:ee40da884cfc 298 }
dkato 0:ee40da884cfc 299 return;
dkato 0:ee40da884cfc 300
dkato 0:ee40da884cfc 301 case (BYTES_CHANNEL_SELECTOR (1, 4)):
dkato 0:ee40da884cfc 302 for (sample = 0; sample < samples; sample++) {
dkato 0:ee40da884cfc 303 *buf_++ = signal[0][sample];
dkato 0:ee40da884cfc 304 *buf_++ = signal[1][sample];
dkato 0:ee40da884cfc 305 *buf_++ = signal[2][sample];
dkato 0:ee40da884cfc 306 *buf_++ = signal[3][sample];
dkato 0:ee40da884cfc 307 }
dkato 0:ee40da884cfc 308 return;
dkato 0:ee40da884cfc 309
dkato 0:ee40da884cfc 310 case (BYTES_CHANNEL_SELECTOR (1, 6)):
dkato 0:ee40da884cfc 311 for (sample = 0; sample < samples; sample++) {
dkato 0:ee40da884cfc 312 *buf_++ = signal[0][sample];
dkato 0:ee40da884cfc 313 *buf_++ = signal[1][sample];
dkato 0:ee40da884cfc 314 *buf_++ = signal[2][sample];
dkato 0:ee40da884cfc 315 *buf_++ = signal[3][sample];
dkato 0:ee40da884cfc 316 *buf_++ = signal[4][sample];
dkato 0:ee40da884cfc 317 *buf_++ = signal[5][sample];
dkato 0:ee40da884cfc 318 }
dkato 0:ee40da884cfc 319 return;
dkato 0:ee40da884cfc 320
dkato 0:ee40da884cfc 321 case (BYTES_CHANNEL_SELECTOR (1, 8)):
dkato 0:ee40da884cfc 322 for (sample = 0; sample < samples; sample++) {
dkato 0:ee40da884cfc 323 *buf_++ = signal[0][sample];
dkato 0:ee40da884cfc 324 *buf_++ = signal[1][sample];
dkato 0:ee40da884cfc 325 *buf_++ = signal[2][sample];
dkato 0:ee40da884cfc 326 *buf_++ = signal[3][sample];
dkato 0:ee40da884cfc 327 *buf_++ = signal[4][sample];
dkato 0:ee40da884cfc 328 *buf_++ = signal[5][sample];
dkato 0:ee40da884cfc 329 *buf_++ = signal[6][sample];
dkato 0:ee40da884cfc 330 *buf_++ = signal[7][sample];
dkato 0:ee40da884cfc 331 }
dkato 0:ee40da884cfc 332 return;
dkato 0:ee40da884cfc 333
dkato 0:ee40da884cfc 334 /* Two bytes per sample. */
dkato 0:ee40da884cfc 335 case (BYTES_CHANNEL_SELECTOR (2, 1)):
dkato 0:ee40da884cfc 336 for (sample = 0; sample < samples; sample++)
dkato 0:ee40da884cfc 337 *buf16++ = H2LE_16(signal[0][sample]);
dkato 0:ee40da884cfc 338 return;
dkato 0:ee40da884cfc 339
dkato 0:ee40da884cfc 340 case (BYTES_CHANNEL_SELECTOR (2, 2)):
dkato 0:ee40da884cfc 341 for (sample = 0; sample < samples; sample++) {
dkato 0:ee40da884cfc 342 *buf16++ = H2LE_16(signal[0][sample]);
dkato 0:ee40da884cfc 343 *buf16++ = H2LE_16(signal[1][sample]);
dkato 0:ee40da884cfc 344 }
dkato 0:ee40da884cfc 345 return;
dkato 0:ee40da884cfc 346
dkato 0:ee40da884cfc 347 case (BYTES_CHANNEL_SELECTOR (2, 4)):
dkato 0:ee40da884cfc 348 for (sample = 0; sample < samples; sample++) {
dkato 0:ee40da884cfc 349 *buf16++ = H2LE_16(signal[0][sample]);
dkato 0:ee40da884cfc 350 *buf16++ = H2LE_16(signal[1][sample]);
dkato 0:ee40da884cfc 351 *buf16++ = H2LE_16(signal[2][sample]);
dkato 0:ee40da884cfc 352 *buf16++ = H2LE_16(signal[3][sample]);
dkato 0:ee40da884cfc 353 }
dkato 0:ee40da884cfc 354 return;
dkato 0:ee40da884cfc 355
dkato 0:ee40da884cfc 356 case (BYTES_CHANNEL_SELECTOR (2, 6)):
dkato 0:ee40da884cfc 357 for (sample = 0; sample < samples; sample++) {
dkato 0:ee40da884cfc 358 *buf16++ = H2LE_16(signal[0][sample]);
dkato 0:ee40da884cfc 359 *buf16++ = H2LE_16(signal[1][sample]);
dkato 0:ee40da884cfc 360 *buf16++ = H2LE_16(signal[2][sample]);
dkato 0:ee40da884cfc 361 *buf16++ = H2LE_16(signal[3][sample]);
dkato 0:ee40da884cfc 362 *buf16++ = H2LE_16(signal[4][sample]);
dkato 0:ee40da884cfc 363 *buf16++ = H2LE_16(signal[5][sample]);
dkato 0:ee40da884cfc 364 }
dkato 0:ee40da884cfc 365 return;
dkato 0:ee40da884cfc 366
dkato 0:ee40da884cfc 367 case (BYTES_CHANNEL_SELECTOR (2, 8)):
dkato 0:ee40da884cfc 368 for (sample = 0; sample < samples; sample++) {
dkato 0:ee40da884cfc 369 *buf16++ = H2LE_16(signal[0][sample]);
dkato 0:ee40da884cfc 370 *buf16++ = H2LE_16(signal[1][sample]);
dkato 0:ee40da884cfc 371 *buf16++ = H2LE_16(signal[2][sample]);
dkato 0:ee40da884cfc 372 *buf16++ = H2LE_16(signal[3][sample]);
dkato 0:ee40da884cfc 373 *buf16++ = H2LE_16(signal[4][sample]);
dkato 0:ee40da884cfc 374 *buf16++ = H2LE_16(signal[5][sample]);
dkato 0:ee40da884cfc 375 *buf16++ = H2LE_16(signal[6][sample]);
dkato 0:ee40da884cfc 376 *buf16++ = H2LE_16(signal[7][sample]);
dkato 0:ee40da884cfc 377 }
dkato 0:ee40da884cfc 378 return;
dkato 0:ee40da884cfc 379
dkato 0:ee40da884cfc 380 /* Three bytes per sample. */
dkato 0:ee40da884cfc 381 case (BYTES_CHANNEL_SELECTOR (3, 1)):
dkato 0:ee40da884cfc 382 for (sample = 0; sample < samples; sample++) {
dkato 0:ee40da884cfc 383 a_word = signal[0][sample];
dkato 0:ee40da884cfc 384 *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
dkato 0:ee40da884cfc 385 *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
dkato 0:ee40da884cfc 386 *buf_++ = (FLAC__byte)a_word;
dkato 0:ee40da884cfc 387 }
dkato 0:ee40da884cfc 388 return;
dkato 0:ee40da884cfc 389
dkato 0:ee40da884cfc 390 case (BYTES_CHANNEL_SELECTOR (3, 2)):
dkato 0:ee40da884cfc 391 for (sample = 0; sample < samples; sample++) {
dkato 0:ee40da884cfc 392 a_word = signal[0][sample];
dkato 0:ee40da884cfc 393 *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
dkato 0:ee40da884cfc 394 *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
dkato 0:ee40da884cfc 395 *buf_++ = (FLAC__byte)a_word;
dkato 0:ee40da884cfc 396 a_word = signal[1][sample];
dkato 0:ee40da884cfc 397 *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
dkato 0:ee40da884cfc 398 *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
dkato 0:ee40da884cfc 399 *buf_++ = (FLAC__byte)a_word;
dkato 0:ee40da884cfc 400 }
dkato 0:ee40da884cfc 401 return;
dkato 0:ee40da884cfc 402
dkato 0:ee40da884cfc 403 /* Four bytes per sample. */
dkato 0:ee40da884cfc 404 case (BYTES_CHANNEL_SELECTOR (4, 1)):
dkato 0:ee40da884cfc 405 for (sample = 0; sample < samples; sample++)
dkato 0:ee40da884cfc 406 *buf32++ = H2LE_32(signal[0][sample]);
dkato 0:ee40da884cfc 407 return;
dkato 0:ee40da884cfc 408
dkato 0:ee40da884cfc 409 case (BYTES_CHANNEL_SELECTOR (4, 2)):
dkato 0:ee40da884cfc 410 for (sample = 0; sample < samples; sample++) {
dkato 0:ee40da884cfc 411 *buf32++ = H2LE_32(signal[0][sample]);
dkato 0:ee40da884cfc 412 *buf32++ = H2LE_32(signal[1][sample]);
dkato 0:ee40da884cfc 413 }
dkato 0:ee40da884cfc 414 return;
dkato 0:ee40da884cfc 415
dkato 0:ee40da884cfc 416 case (BYTES_CHANNEL_SELECTOR (4, 4)):
dkato 0:ee40da884cfc 417 for (sample = 0; sample < samples; sample++) {
dkato 0:ee40da884cfc 418 *buf32++ = H2LE_32(signal[0][sample]);
dkato 0:ee40da884cfc 419 *buf32++ = H2LE_32(signal[1][sample]);
dkato 0:ee40da884cfc 420 *buf32++ = H2LE_32(signal[2][sample]);
dkato 0:ee40da884cfc 421 *buf32++ = H2LE_32(signal[3][sample]);
dkato 0:ee40da884cfc 422 }
dkato 0:ee40da884cfc 423 return;
dkato 0:ee40da884cfc 424
dkato 0:ee40da884cfc 425 case (BYTES_CHANNEL_SELECTOR (4, 6)):
dkato 0:ee40da884cfc 426 for (sample = 0; sample < samples; sample++) {
dkato 0:ee40da884cfc 427 *buf32++ = H2LE_32(signal[0][sample]);
dkato 0:ee40da884cfc 428 *buf32++ = H2LE_32(signal[1][sample]);
dkato 0:ee40da884cfc 429 *buf32++ = H2LE_32(signal[2][sample]);
dkato 0:ee40da884cfc 430 *buf32++ = H2LE_32(signal[3][sample]);
dkato 0:ee40da884cfc 431 *buf32++ = H2LE_32(signal[4][sample]);
dkato 0:ee40da884cfc 432 *buf32++ = H2LE_32(signal[5][sample]);
dkato 0:ee40da884cfc 433 }
dkato 0:ee40da884cfc 434 return;
dkato 0:ee40da884cfc 435
dkato 0:ee40da884cfc 436 case (BYTES_CHANNEL_SELECTOR (4, 8)):
dkato 0:ee40da884cfc 437 for (sample = 0; sample < samples; sample++) {
dkato 0:ee40da884cfc 438 *buf32++ = H2LE_32(signal[0][sample]);
dkato 0:ee40da884cfc 439 *buf32++ = H2LE_32(signal[1][sample]);
dkato 0:ee40da884cfc 440 *buf32++ = H2LE_32(signal[2][sample]);
dkato 0:ee40da884cfc 441 *buf32++ = H2LE_32(signal[3][sample]);
dkato 0:ee40da884cfc 442 *buf32++ = H2LE_32(signal[4][sample]);
dkato 0:ee40da884cfc 443 *buf32++ = H2LE_32(signal[5][sample]);
dkato 0:ee40da884cfc 444 *buf32++ = H2LE_32(signal[6][sample]);
dkato 0:ee40da884cfc 445 *buf32++ = H2LE_32(signal[7][sample]);
dkato 0:ee40da884cfc 446 }
dkato 0:ee40da884cfc 447 return;
dkato 0:ee40da884cfc 448
dkato 0:ee40da884cfc 449 default:
dkato 0:ee40da884cfc 450 break;
dkato 0:ee40da884cfc 451 }
dkato 0:ee40da884cfc 452
dkato 0:ee40da884cfc 453 /* General version. */
dkato 0:ee40da884cfc 454 switch (bytes_per_sample) {
dkato 0:ee40da884cfc 455 case 1:
dkato 0:ee40da884cfc 456 for (sample = 0; sample < samples; sample++)
dkato 0:ee40da884cfc 457 for (channel = 0; channel < channels; channel++)
dkato 0:ee40da884cfc 458 *buf_++ = signal[channel][sample];
dkato 0:ee40da884cfc 459 return;
dkato 0:ee40da884cfc 460
dkato 0:ee40da884cfc 461 case 2:
dkato 0:ee40da884cfc 462 for (sample = 0; sample < samples; sample++)
dkato 0:ee40da884cfc 463 for (channel = 0; channel < channels; channel++)
dkato 0:ee40da884cfc 464 *buf16++ = H2LE_16(signal[channel][sample]);
dkato 0:ee40da884cfc 465 return;
dkato 0:ee40da884cfc 466
dkato 0:ee40da884cfc 467 case 3:
dkato 0:ee40da884cfc 468 for (sample = 0; sample < samples; sample++)
dkato 0:ee40da884cfc 469 for (channel = 0; channel < channels; channel++) {
dkato 0:ee40da884cfc 470 a_word = signal[channel][sample];
dkato 0:ee40da884cfc 471 *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
dkato 0:ee40da884cfc 472 *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
dkato 0:ee40da884cfc 473 *buf_++ = (FLAC__byte)a_word;
dkato 0:ee40da884cfc 474 }
dkato 0:ee40da884cfc 475 return;
dkato 0:ee40da884cfc 476
dkato 0:ee40da884cfc 477 case 4:
dkato 0:ee40da884cfc 478 for (sample = 0; sample < samples; sample++)
dkato 0:ee40da884cfc 479 for (channel = 0; channel < channels; channel++)
dkato 0:ee40da884cfc 480 *buf32++ = H2LE_32(signal[channel][sample]);
dkato 0:ee40da884cfc 481 return;
dkato 0:ee40da884cfc 482
dkato 0:ee40da884cfc 483 default:
dkato 0:ee40da884cfc 484 break;
dkato 0:ee40da884cfc 485 }
dkato 0:ee40da884cfc 486 }
dkato 0:ee40da884cfc 487
dkato 0:ee40da884cfc 488 /*
dkato 0:ee40da884cfc 489 * Convert the incoming audio signal to a byte stream and FLAC__MD5Update it.
dkato 0:ee40da884cfc 490 */
dkato 0:ee40da884cfc 491 FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample)
dkato 0:ee40da884cfc 492 {
dkato 0:ee40da884cfc 493 const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample;
dkato 0:ee40da884cfc 494
dkato 0:ee40da884cfc 495 /* overflow check */
dkato 0:ee40da884cfc 496 if ((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample)
dkato 0:ee40da884cfc 497 return false;
dkato 0:ee40da884cfc 498 if ((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples)
dkato 0:ee40da884cfc 499 return false;
dkato 0:ee40da884cfc 500
dkato 0:ee40da884cfc 501 if (ctx->capacity < bytes_needed) {
dkato 0:ee40da884cfc 502 FLAC__byte *tmp = realloc(ctx->internal_buf.p8, bytes_needed);
dkato 0:ee40da884cfc 503 if (0 == tmp) {
dkato 0:ee40da884cfc 504 free(ctx->internal_buf.p8);
dkato 0:ee40da884cfc 505 if (0 == (ctx->internal_buf.p8= safe_malloc_(bytes_needed)))
dkato 0:ee40da884cfc 506 return false;
dkato 0:ee40da884cfc 507 }
dkato 0:ee40da884cfc 508 else
dkato 0:ee40da884cfc 509 ctx->internal_buf.p8= tmp;
dkato 0:ee40da884cfc 510 ctx->capacity = bytes_needed;
dkato 0:ee40da884cfc 511 }
dkato 0:ee40da884cfc 512
dkato 0:ee40da884cfc 513 format_input_(&ctx->internal_buf, signal, channels, samples, bytes_per_sample);
dkato 0:ee40da884cfc 514
dkato 0:ee40da884cfc 515 FLAC__MD5Update(ctx, ctx->internal_buf.p8, bytes_needed);
dkato 0:ee40da884cfc 516
dkato 0:ee40da884cfc 517 return true;
dkato 0:ee40da884cfc 518 }