%Based on the Talkie project by Peter Knight.
%https://github.com/going-digital/Talkie

function [] = LPC_Clock()

clearvars;
clc;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Speech Data%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%Female clock speech.
spTHE = uint8([8 232 62 85 1 195 134 39 175 114 13 77 151 213 188 100 60 242 92 81 241 147 54 143 79 89 42 66 122 50 195 100 255 63]);
spTIME = uint8([14 40 172 45 1 93 182 13 51 243 84 179 96 186 140 84 92 205 45 212 50 115 15 142 52 51 203 74 37 212 37 131 44 43 213 80 151 8 50 236 212 220 76 51 200 112 115 15 51 205 32 195 203 67 221 60 205 140 32 119 137 244 148 178 226 226 53 34 93 214 74 138 150 204 54 37 45 201 154 123 194 24 135 36 75 28 201 80 25 146 44 113 52 75 69 138 139 196 150 182 90 41 42 146 90 202 83 150 32 5 9 245 146 93 188 232 88 74 221 174 115 189 101 75 141 120 202 43 78 216 217 237 34 32 6 117 0 0 128 255 7]);  
spIS = uint8([33 24 150 56 183 20 141 96 58 166 232 81 180 220 46 72 123 90 241 112 27 163 236 9 198 203 235 146 61 167 105 31 175 113 137 156 162 179 252 202 53 114 154 209 240 171 18 179 43 198 205 79 204 50 38 25 7 223 11 143 184 164 237 124 207 35 98 139 142 241 35 10 139 110 203 206 239 84 68 60 220 8 96 11 55 1 28 83 38 128 21 78 20 176 84 43 2 164 105 255 127]);
spA_M_ = uint8([205 239 134 171 87 109 15 175 113 173 73 85 60 252 46 197 183 92 241 242 135 102 221 78 197 195 239 146 226 58 101 183 160 9 170 27 151 84 130 46 40 119 92 82 9 26 163 184 118 73 37 104 140 115 219 36 149 160 50 169 107 167 217 130 38 169 118 66 214 8 186 225 232 14 90 43 234 158 61 39 24 173 168 7 241 152 144 53 162 150 68 163 93 102 139 107 18 205 50 133 37 201 129 45 195 100 133 52 88 137 148 82 28 82 47 53 218 199 81 72 35 151 204 44 151 46 243 92 243 162 20 186 44 72 206 202 118 232 50 47 52 178 219 133 201 131 144 168 44 87 38 143 156 189 162 83 217 194 84 89 40 153 75 44 93 255 63]);   
spP_M_ = uint8([14 152 65 84 0 67 160 5 171 66 142 29 163 21 236 78 88 247 146 102 112 27 102 219 115 153 193 235 152 237 214 37 37 111 112 146 221 100 216 252 97 208 102 131 214 10 134 35 171 105 218 43 24 158 61 55 105 157 168 7 113 159 160 189 162 22 213 124 84 246 136 107 84 139 52 73 45 41 73 60 52 100 165 36 27 54 215 114 19 146 164 196 45 195 179 75 163 98 15 43 55 110 139 90 212 61 221 154 45 80 147 246 76 170 182 196 133 59 178 177 216 147 32 77 143 36 255 15]);    
spOH = uint8([198 201 113 90 162 146 20 47 110 151 156 70 157 220 176 77 98 27 85 112 221 85 190 14 54 193 51 55 169 167 81 27 207 60 165 158 68 172 60 125 152 123 82 150 114 101 75 246 26 217 202 245 145 45 162 42 75 247 255 1]);   
spOCLOCK = uint8([33 78 61 184 43 25 187 36 14 229 236 96 228 242 144 19 212 42 17 128 0 66 105 38 64 208 43 4 104 224 77 0 58 53 53 51 182 81 217 100 52 130 180 154 99 146 85 137 82 91 202 46 52 37 78 99 40 58 80 149 38 141 230 170 100 88 234 146 206 194 70 21 155 134 205 42 46 55 0 0 0 12 200 221 5 1 185 51 33 160 116 215 255 7]);  
spONE = uint8([204 103 117 66 89 93 58 79 157 54 99 183 89 220 48 91 92 35 97 243 226 28 241 240 152 195 75 125 57 202 29 44 47 183 21 239 112 121 188 210 70 124 82 229 241 74 106 179 113 71 195 45 57 52 75 35 53 183 122 85 51 143 89 220 162 68 181 188 102 114 139 100 245 246 152 193 77 66 212 39 98 56 47 74 182 156 136 104 188 166 149 248 92 161 9 134 119 145 17 91 255 15]);  
spTWO = uint8([14 56 110 37 0 163 13 58 160 55 197 160 5 158 86 53 134 170 94 140 164 130 178 215 116 49 34 105 173 28 211 193 208 250 40 43 45 71 195 27 194 196 174 198 205 156 72 83 154 255 15]);
spTHREE = uint8([2 216 46 156 1 219 166 51 96 251 48 1 236 32 18 140 228 216 202 50 150 115 99 65 57 137 152 193 77 13 237 176 42 5 55 15 180 165 174 92 220 54 208 131 47 74 113 123 3 247 56 89 205 237 30 180 107 20 53 183 107 148 153 145 213 220 38 72 119 75 102 113 27 33 219 45 138 201 109 136 252 38 40 58 183 33 244 31 163 101 188 2 56 187 61 142 240 43 226 8 183 52 255 15]);  
spFOUR = uint8([12 24 182 154 1 195 117 9 96 216 14 9 48 160 155 182 160 187 176 170 22 78 130 235 234 169 250 89 73 158 89 35 154 39 59 120 102 174 74 156 156 224 153 211 42 189 114 146 239 230 136 228 69 77 126 152 45 98 103 55 249 161 55 167 108 148 228 199 30 220 60 165 131 31 139 235 82 14 14 126 46 78 199 49 210 121 165 58 13 217 196 255 7]);   
spFIVE = uint8([2 232 62 140 1 221 101 8 96 152 76 6 52 147 206 128 230 218 154 20 107 170 71 209 94 86 170 109 86 205 120 217 169 28 103 5 131 225 164 186 56 238 22 134 155 250 96 135 91 24 110 238 139 29 110 97 185 105 54 101 186 141 229 229 62 28 233 14 150 155 91 171 149 43 88 110 206 229 58 106 243 184 53 132 123 5 163 227 54 239 146 25 180 134 219 180 105 180 209 42 78 101 154 153 206 40 217 133 113 76 24 109 103 71 198 94 83 74 156 181 226 133 69 38 254 127]);
spSIX = uint8([14 216 174 221 3 14 56 166 210 1 211 180 44 173 106 53 157 177 125 220 238 196 101 215 241 114 71 36 179 25 217 217 5 112 64 73 234 2 152 190 66 1 223 164 105 64 0 223 149 252 63]);
spSEVEN = uint8([2 184 58 140 1 223 164 115 64 1 71 185 47 51 59 115 95 83 124 236 154 197 99 213 209 117 174 91 252 100 92 53 135 145 241 131 54 181 104 85 197 111 218 69 45 28 45 183 56 55 159 96 60 188 154 133 163 37 102 247 138 87 28 169 103 86 202 94 240 178 22 178 241 137 206 139 146 37 199 43 51 207 72 177 153 180 243 255]);
spEIGHT = uint8([195 108 134 179 39 109 15 167 72 153 78 85 60 188 34 101 54 77 209 240 50 211 190 52 218 195 235 130 226 218 101 53 175 49 242 107 151 149 188 134 216 111 130 166 115 11 198 158 114 153 204 203 2 173 60 154 16 96 171 98 5 44 55 132 0 169 115 0 0 254 31]);  
spNINE = uint8([204 161 38 187 131 147 24 207 74 173 46 49 237 60 167 36 38 195 84 241 146 100 139 138 152 203 43 46 52 83 45 14 47 87 179 12 13 60 188 60 76 75 202 244 240 114 15 110 73 83 205 203 83 45 53 77 15 47 15 215 12 13 61 188 220 77 211 221 194 240 114 82 79 87 155 195 171 137 189 66 45 15 175 90 209 113 145 85 188 44 197 59 216 101 242 130 148 24 78 59 193 115 66 50 51 21 69 79 121 82 106 85 166 163 255 7]);   
spTEN = uint8([14 216 177 221 1 61 168 36 123 4 39 118 119 220 236 194 197 35 132 205 114 154 81 247 98 69 199 235 78 53 74 20 45 191 69 182 10 117 184 252 22 217 42 217 214 10 90 16 205 162 72 35 168 129 53 75 44 167 32 105 10 175 182 21 130 164 41 60 199 82 8 162 34 207 104 75 46 240 138 189 163 44 171 64 27 206 170 178 108 130 64 77 125 194 137 136 138 97 204 116 213 255 15]);
spELEVEN = uint8([195 205 118 92 174 20 15 55 155 113 222 146 85 188 44 39 112 211 118 240 131 94 163 94 90 193 247 97 88 167 25 53 63 153 49 222 82 116 252 162 38 100 75 209 241 171 174 208 45 197 199 47 54 221 39 21 15 63 217 8 159 98 228 194 44 212 216 211 137 11 27 87 17 11 59 197 207 214 204 198 100 53 175 24 115 31 161 93 188 98 69 179 69 81 240 162 98 171 74 91 201 75 138 45 179 108 6 47 41 178 172 138 24 188 40 217 170 210 146 241 188 224 152 140 72 204 23 82 163 39 109 147 208 75 142 14 119 2 0 255 15]);
spTWELVE = uint8([6 40 70 211 1 37 6 19 32 186 112 112 182 121 202 54 174 40 56 225 41 197 53 163 230 196 22 106 83 140 151 155 114 134 79 40 26 110 10 89 54 174 104 248 41 103 250 6 163 22 196 150 230 83 172 90 156 86 114 119 49 78 73 92 141 91 41 59 36 97 30 108 155 108 151 248 167 52 25 146 76 98 158 114 101 88 18 177 126 9 213 46 83 197 186 54 107 185 45 23 5 238 154 110 142 5 80 108 25 7 24 80 189 59 1 146 8 65 64 16 166 255 15]);
spTHIRTEEN = uint8([8 232 44 21 1 67 7 19 224 152 180 166 53 169 30 222 86 142 83 156 122 231 202 94 118 141 148 229 43 171 217 181 98 164 156 228 230 180 65 30 124 182 147 215 22 153 90 205 97 118 85 194 145 97 27 192 1 93 133 5 224 104 81 7 28 169 100 128 29 76 156 149 136 212 4 59 77 78 33 92 147 168 38 185 5 75 110 160 226 228 87 194 185 193 178 147 95 9 215 36 203 78 65 37 84 29 98 59 5 141 82 87 170 173 16 36 38 227 225 54 93 16 133 180 151 133 114 65 20 82 94 26 202 249 145 107 122 91 196 224 23 45 84 29 146 140 31 37 75 143 178 22 65 161 74 62 230 250 255 1]);
spFOURTEEN = uint8([12 88 174 92 1 217 135 7 81 183 37 179 138 21 44 247 28 53 135 77 178 221 83 206 40 43 201 14 151 45 189 42 23 39 118 142 210 154 108 128 148 113 0 0 2 176 88 88 0 158 11 10 192 178 206 193 200 152 122 82 149 36 43 17 237 54 212 146 220 76 181 199 200 83 241 42 229 26 23 85 197 175 148 187 205 28 38 191 82 154 114 83 152 252 194 104 210 77 97 240 163 144 182 214 80 193 143 66 218 74 67 57 63 72 45 107 51 249 255]);
spFIFTEEN = uint8([8 232 42 13 1 221 186 49 96 106 247 160 174 84 170 90 118 151 217 52 105 239 50 30 102 225 226 179 67 169 24 85 146 78 55 45 103 111 223 162 90 182 4 48 85 168 0 134 9 231 0 1 22 23 5 112 64 87 229 1 248 33 52 0 211 25 51 128 137 154 98 52 76 213 73 174 139 83 9 247 38 217 106 126 35 92 19 18 179 4 157 80 79 177 173 20 21 194 211 161 182 66 148 168 140 135 219 116 177 112 89 225 46 201 197 129 91 85 164 76 23 71 193 109 227 129 83 156 132 106 70 217 76 81 49 66 217 102 201 68 133 41 106 155 173 255 7]);
spSIXTEEN = uint8([10 88 90 93 0 147 151 11 96 169 72 5 12 21 174 128 173 61 20 48 125 217 80 146 146 172 13 197 205 42 130 170 59 152 4 179 74 200 154 144 5 9 104 81 212 1 35 159 26 96 169 18 3 220 80 129 128 34 220 32 0 203 6 58 96 22 227 100 100 66 221 205 106 138 93 40 117 7 169 42 94 101 52 237 100 187 248 133 242 148 139 173 228 55 74 91 33 182 82 80 25 173 167 216 74 65 20 218 94 18 58 4 145 75 123 105 168 16 36 46 229 163 129 82 144 148 90 85 152 50 65 80 204 147 46 71 133 137 27 91 90 98 4 68 227 2 128 128 100 221 255 31]);
spSEVENTEEN = uint8([2 152 58 66 0 91 166 9 96 219 82 6 28 147 41 128 169 82 135 154 181 153 79 200 62 70 214 94 126 102 251 152 197 90 198 154 156 99 21 107 17 19 138 156 151 185 154 90 57 113 238 210 41 194 166 184 88 89 153 86 20 163 225 38 25 25 227 140 147 23 180 70 181 136 113 158 151 158 177 44 197 248 86 196 88 163 28 225 51 157 19 65 138 67 88 173 149 169 219 54 192 209 201 14 88 78 69 1 35 169 4 55 19 174 77 101 82 130 202 169 55 153 77 137 186 192 188 20 54 37 234 28 115 82 29 151 184 51 172 14 117 156 226 206 176 218 195 81 74 26 165 202 112 91 33 206 76 38 210 108 186 56 113 46 31 45 237 226 36 184 188 61 82 136 171 80 142 168 72 34 78 66 160 38 85 253 63]);
spEIGHTEEN = uint8([46 156 209 77 84 236 44 191 27 138 153 112 124 252 46 41 111 82 246 241 186 32 191 54 217 205 237 12 243 39 100 23 115 43 162 153 144 101 236 237 64 115 50 18 177 175 48 53 11 199 0 224 128 174 221 28 112 67 170 3 134 81 54 192 48 100 206 76 152 251 92 101 7 175 16 234 11 102 27 252 70 168 62 9 77 8 42 166 62 103 54 33 42 152 103 157 21 167 168 96 238 182 148 153 162 74 120 34 194 166 139 140 142 204 76 138 46 138 76 211 87 3 135 40 113 9 31 43 228 162 196 197 109 173 84 136 178 99 201 242 80 46 138 74 56 74 236 136 40 8 227 40 73 243 255]);
spNINETEEN = uint8([194 234 138 149 43 106 5 63 113 113 95 13 18 252 40 37 98 53 240 240 179 72 30 15 201 203 47 69 124 44 37 31 191 20 179 44 181 117 252 90 92 163 93 225 241 122 118 179 78 69 199 237 150 35 59 24 55 123 24 204 9 81 19 76 171 108 76 75 150 210 73 170 54 11 197 194 32 38 39 53 99 9 61 48 139 240 72 92 202 97 221 203 205 145 3 142 75 118 192 204 77 6 152 49 49 152 153 112 109 42 163 228 22 202 189 206 92 146 87 40 207 9 105 46 126 165 60 99 162 48 5 149 210 116 152 205 20 84 202 83 169 150 82 80 40 111 186 203 12 65 80 222 101 46 211 5 137 75 123 107 32 23 68 174 237 35 129 82 144 133 115 87 208 114 65 177 2 222 46 219 4 137 5 121 187 98 229 118 17 202 97 14 255 31]);
spTWENTY = uint8([1 152 209 194 0 205 164 50 32 121 19 4 40 231 146 220 112 204 93 219 118 243 210 50 11 11 91 195 43 205 212 221 35 53 175 68 225 240 176 109 60 169 173 61 53 14 241 12 139 40 247 52 1 104 34 205 0 199 164 4 187 50 214 172 86 156 220 202 40 102 83 81 112 43 165 188 13 154 193 235 20 115 55 41 25 175 51 140 59 167 36 188 66 176 183 89 9 9 60 150 233 244 88 255 15]);  
spTHIRTY = uint8([8 152 214 21 1 67 187 10 32 27 139 229 22 163 30 182 182 150 151 60 87 212 42 94 126 78 216 225 107 123 248 57 99 13 159 149 225 231 76 118 188 145 91 144 19 198 104 87 78 65 139 16 94 29 169 68 211 186 71 184 221 228 53 134 17 147 148 146 95 41 199 76 48 12 65 197 28 59 46 211 5 21 83 108 7 77 21 20 140 181 201 106 68 144 16 78 154 182 33 129 35 58 145 145 232 255 1]);
spFOURTY = uint8([4 24 182 76 0 195 86 48 160 232 244 160 152 153 98 145 174 131 107 119 137 120 59 9 174 189 166 30 99 59 121 126 113 90 143 149 230 165 74 105 185 78 138 95 18 86 228 88 105 225 54 161 105 46 43 249 149 147 85 23 237 228 55 198 186 147 178 146 223 25 217 110 200 10 254 96 232 55 33 201 249 141 97 95 50 19 231 23 76 211 198 177 148 151 16 143 139 173 17 126 161 154 38 146 246 255 1]);  
spFIFTY = uint8([8 232 46 132 0 35 132 19 96 56 149 165 15 207 226 121 138 143 55 2 179 213 42 110 94 147 148 121 69 217 5 93 10 185 151 99 2 116 167 130 128 238 195 16 208 125 40 3 110 20 6 112 230 10 201 154 78 55 217 149 81 206 186 162 20 12 129 54 27 178 92 48 56 250 156 201 50 65 167 24 59 162 72 4 5 81 79 145 109 18 4 32 155 97 137 255 31]);   
spGOOD = uint8([10 40 205 52 32 217 26 69 116 228 102 36 173 186 177 140 155 145 165 100 230 152 33 22 11 150 155 76 229 255 1]);
spMORNING = uint8([206 8 82 42 53 93 57 83 41 91 183 10 21 12 238 42 66 86 102 210 85 46 55 47 217 69 179 211 197 202 109 39 213 238 80 245 80 148 20 119 45 216 93 73 146 253 177 100 47 169 73 12 147 75 173 25 23 62 102 30 241 162 91 132 226 41 143 139 114 16 181 177 46 75 212 69 137 74 236 92 149 20 43 138 156 52 82 93 188 204 181 59 73 105 137 135 193 152 86 58 33 43 130 103 204 92 133 181 74 138 246 100 169 150 196 105 60 82 129 88 28 151 246 14 27 204 13 66 50 170 101 18 103 212 106 97 82 252 255]);
spAFTERNOON = uint8([199 206 206 58 203 88 31 59 7 157 40 113 180 172 156 116 90 66 85 51 178 147 10 9 212 197 154 214 68 69 227 56 96 154 50 5 244 24 1 9 216 169 194 0 94 202 36 213 91 157 74 149 234 52 238 99 146 92 77 208 164 238 88 12 185 77 205 66 162 58 36 55 37 138 168 142 160 83 228 40 35 38 19 114 145 162 118 187 114 56 69 10 70 99 202 105 39 57 88 177 141 96 28 52 27 52 195 85 142 115 69 45 79 74 58 38 16 161 202 45 233 152 36 10 30 109 151 41 210 204 113 162 220 134 200 18 167 142 8 133 34 141 156 67 167 18 178 46 80 9 239 81 197 186 40 88 173 219 225 255 3]);
spEVENING = uint8([205 109 152 115 71 101 13 109 16 178 93 147 53 148 193 208 118 77 102 147 167 4 189 113 217 69 174 146 213 172 83 7 109 165 118 99 81 146 212 161 131 212 203 178 81 136 205 245 80 69 206 162 46 39 40 84 21 55 10 207 117 97 93 162 196 181 199 68 85 138 11 163 110 23 149 33 169 12 55 205 21 186 212 43 111 179 84 228 210 200 100 188 76 145 73 18 231 178 177 208 34 13 156 221 171 98 169 56 83 17 169 116 44 210 202 89 52 163 229 255 3]);
spPAUSE1 = uint8([0 0 0 0 255 15]);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Clock Routine%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

ampm = 0; %0 for am, 1 for pm.
c = clock;
fix(c);
tens = mod(c(5), 10); %Get tens digit.

a = say(spGOOD);

if c(4) < 12
    a = [a say(spMORNING)];
elseif c(4) < 17
    a = [a say(spAFTERNOON)];
else
    a = [a say(spEVENING)];
end

a = [a say(spPAUSE1)];
a = [a say(spTHE)];
a = [a say(spTIME)];
a = [a say(spIS)];

if c(4) == 0
   a = [a say(spTWELVE)];
elseif c(4) == 1
   a = [a say(spONE)];
elseif c(4) == 2
    a = [a say(spTWO)];
elseif c(4) == 3
    a = [a say(spTHREE)];
elseif c(4) == 4
    a = [a say(spFOUR)];
elseif c(4) == 5
    a = [a say(spFIVE)];
elseif c(4) == 6
    a = [a say(spSIX)];
elseif c(4) == 7
    a = [a say(spSEVEN)];
elseif c(4) == 8
    a = [a say(spEIGHT)];
elseif c(4) == 9
    a = [a say(spNINE)];
elseif c(4) == 10
    a = [a say(spTEN)];
elseif c(4) == 11
    a = [a say(spELEVEN)];
elseif c(4) == 12
    a = [a say(spTWELVE)];
    ampm = 1;
elseif c(4) == 13
    a = [a say(spONE)];
    ampm = 1;
elseif c(4) == 14
    a = [a say(spTWO)];
    ampm = 1;
elseif c(4) == 15
    a = [a say(spTHREE)];
    ampm = 1;
elseif c(4) == 16
    a = [a say(spFOUR)];
    ampm = 1;
elseif c(4) == 17
    a = [a say(spFIVE)];
    ampm = 1;
elseif c(4) == 18
    a = [a say(spSIX)];
    ampm = 1;
elseif c(4) == 19
    a = [a say(spSEVEN)];
    ampm = 1;
elseif c(4) == 20
    a = [a say(spEIGHT)];
    ampm = 1;
elseif c(4) == 21
    a = [a say(spNINE)];
    ampm = 1;
elseif c(4) == 22
    a = [a say(spTEN)];
    ampm = 1;
elseif c(4) == 23
    a = [a say(spELEVEN)];
    ampm = 1;
else    
    a = [a say(spTWELVE)];
    ampm = 1;
end

a = [a say(spPAUSE1)];

if c(5) == 00
    a = [a say(spOCLOCK)];
elseif c(5) < 10
     a = [a say(spOH)];
elseif c(5) == 10
    a = [a say(spTEN)];
elseif c(5) == 11
    a = [a say(spELEVEN)];
elseif c(5) == 12
    a = [a say(spTWELVE)];
elseif c(5) == 13
    a = [a say(spTHIRTEEN)];
elseif c(5) == 14   
    a = [a say(spFOURTEEN)];
elseif c(5) == 15
    a = [a say(spFIFTEEN)];
elseif c(5) == 16
    a = [a say(spSIXTEEN)];
elseif c(5) == 17
    a = [a say(spSEVENTEEN)];
elseif c(5) == 18
    a = [a say(spEIGHTEEN)];
elseif c(5) == 19    
    a = [a say(spNINETEEN)];   
elseif c(5) < 30
    a = [a say(spTWENTY)];
elseif c(5) < 40
    a = [a say(spTHIRTY)];
elseif c(5) < 50
    a = [a say(spFOURTY)];
else
    a = [a say(spFIFTY)];
end

a = [a say(spPAUSE1)];

if c(5) < 10 || c(5) > 20
    if(tens ~= 0)
        if tens == 1
            a = [a say(spONE)];    
        elseif tens == 2
            a = [a say(spTWO)];
        elseif tens == 3
            a = [a say(spTHREE)];
        elseif tens == 4
            a = [a say(spFOUR)];
        elseif tens == 5
            a = [a say(spFIVE)];
        elseif tens == 6
            a = [a say(spSIX)];
        elseif tens == 7
            a = [a say(spSEVEN)];
        elseif tens == 8
            a = [a say(spEIGHT)];
        else
            a = [a say(spNINE)];
        end
    end
end

a = [a say(spPAUSE1)];

if ampm == 0
    a = [a say(spA_M_)];
else
    a = [a say(spP_M_)];
end

a = double(a);
soundsc(a, 8000);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Function: say%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [A] = say(array)

%INPUTS:
%array: LPC-10 data array of speech to play.

%OUTPUTS:
%A: Fully synthesized speech.

SPF = 180; %Samples per frame.

Energy = uint8([0 2 3 4 5 7 10 15 20 32 41 57 81 114 161 255]);
Period = uint8([0 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ...
          33 34 35 36 37 38 39 40 41 42 43 45 47 49 51 53 54 57 59 61 ...
          63 66 69 71 73 77 79 81 85 87 92 95 99 102 106 110 115 119 ...
          123 128 133 138 143 149 154 160]);
K1 = int16([-32064 -31872 -31808 -31680 -31552 -31424 -31232 -30848 ...
          -30592 -30336 -30016 -29696 -29376 -28928 -28480 -27968 ...
          -26368 -24256 -21632 -18368 -14528 -10048 -5184 0 5184 10048 ...
          14528 18368 21632 24256 26368 27968]);
K2 = int16([-20992 -19328 -17536 -15552 -13440 -11200 -8768 -6272 ...
          -3712 -1088 1536 4160 6720 9216 11584 13824 15936 17856 19648 ...
          21248 22656 24000 25152 26176 27072 27840 28544 29120 29632 ...
          30080 30464, 32384]);
K3    = int8([-110 -97 -83 -70 -56 -43 -29 -16 -2 11 25 38 52 65 79 92]);
K4    = int8([-82 -68 -54 -40 -26 -12 1 15 29 43 57 71 85 99 113 126]);
K5    = int8([-82 -70 -59 -47 -35 -24 -12 -1 11 23 34 46 57 69 81 92]);
K6    = int8([-64 -53 -42 -31 -20 -9 3 14 25 36 47 58 69 80 91 102]);
K7    = int8([-77 -65 -53 -41 -29 -17 -5 7 19 31 43 55 67 79 90 102]);
K8    = int8([-64 -40 -16 7 31 55 79 102]);
K9    = int8([-64 -44 -24 -4 16 37 57 77]);
K10   = int8([-51 -33 -15 4 22 32 59 77]);
chirp = int8([0 42 -44 50 -78 18 37 20 2 -31 -59 2 95 90 5 15 38 -4 -91 ...
          -91 -42 -35 -36 -4 37 43 34 33 15 -1 -8 -18 -19 -17 -9 -10 -6 ...
          0 3 2 1 ]);

synthPeriod = uint8(0);
synthK1 = int16(0);
synthK2 = int16(0);
synthK3 = int8(0);
synthK4 = int8(0);
synthK5 = int8(0);
synthK6 = int8(0);
synthK7 = int8(0);
synthK8 = int8(0);
synthK9 = int8(0);
synthK10 = int8(0);

arIndex = 1;
bitIndex = 0;
energy = 0;

init = 0;
u = int16(zeros(1,11));
x = int16(zeros(1,10));
periodCounter = uint8(0);
synthRand = uint16(1);

while energy ~= 15
    [energy, arIndex, bitIndex] = getBits(4, array, arIndex, bitIndex);
    
    if energy == 0
        synthEnergy = 0;
                
    elseif energy == 15 %Energy = 15: stop frame. Silence the synthesiser.       
        synthEnergy = 0;
        synthK1 = 0;
        synthK2 = 0;
        synthK3 = 0;
        synthK4 = 0;
        synthK5 = 0;
        synthK6 = 0;
        synthK7 = 0;
        synthK8 = 0;
        synthK9 = 0;
        synthK10 = 0;
                
    else
        synthEnergy = Energy(energy+1);
                
        [repeat, arIndex, bitIndex] = getBits(1, array, arIndex, bitIndex);
                
        [synthPeriod, arIndex, bitIndex] = getBits(6, array, arIndex, bitIndex);
        synthPeriod = Period(synthPeriod+1);
                
        if repeat == 0
            [synthK1, arIndex, bitIndex] = getBits(5, array, arIndex, bitIndex);            
            [synthK2, arIndex, bitIndex] = getBits(5, array, arIndex, bitIndex);
            [synthK3, arIndex, bitIndex] = getBits(4, array, arIndex, bitIndex);
            [synthK4, arIndex, bitIndex] = getBits(4, array, arIndex, bitIndex);
            synthK1 = K1(synthK1+1);
            synthK2 = K2(synthK2+1);
            synthK3 = K3(synthK3+1);
            synthK4 = K4(synthK4+1);
                        
            if synthPeriod ~= 0
                [synthK5, arIndex, bitIndex]  = getBits(4, array, arIndex, bitIndex);
                [synthK6, arIndex, bitIndex]  = getBits(4, array, arIndex, bitIndex);
                [synthK7, arIndex, bitIndex]  = getBits(4, array, arIndex, bitIndex);
                [synthK8, arIndex, bitIndex]  = getBits(3, array, arIndex, bitIndex);
                [synthK9, arIndex, bitIndex]  = getBits(3, array, arIndex, bitIndex);
                [synthK10, arIndex, bitIndex] = getBits(3, array, arIndex, bitIndex);
                synthK5  = K5(synthK5+1);
                synthK6  = K6(synthK6+1);
                synthK7  = K7(synthK7+1);
                synthK8  = K8(synthK8+1);
                synthK9  = K9(synthK9+1);
                synthK10 = K10(synthK10+1);
            end        
        end        
    end
    
    for ii = 1:SPF    
        if synthPeriod ~= 0 %Voiced source
            if periodCounter < synthPeriod            
                periodCounter = periodCounter+1;               
            else            
                periodCounter = 0;
            end
        
            if periodCounter < length(chirp)
                u(11) = bitshift((int16(chirp(periodCounter+1))*int16(synthEnergy)), -8);
            else
                u(11) = 0;
            end
            
        else %Unvoiced source               
            if bitand(synthRand, 1) ~= 0          
                LSFRVal = 47104;
            else            
                LSFRVal = 0;
            end
        
            synthRand = bitxor(bitshift(synthRand, -1), LSFRVal);
                       
            if bitand(synthRand, 1) ~= 0        
                u(11) = int16(synthEnergy);        
            else        
                u(11) = -int16(synthEnergy);
            end
        end
        
        %Lattice filter forward path
        u(10) = u(11) - bitshift(int16(synthK10)*x(10), -7);  
        u(9)  = u(10) - bitshift(int16(synthK9) *x(9),  -7);
        u(8)  = u(9)  - bitshift(int16(synthK8) *x(8),  -7);    
        u(7)  = u(8)  - bitshift(int16(synthK7) *x(7),  -7);
        u(6)  = u(7)  - bitshift(int16(synthK6) *x(6),  -7);
        u(5)  = u(6)  - bitshift(int16(synthK5) *x(5),  -7);
        u(4)  = u(5)  - bitshift(int16(synthK4) *x(4),  -7);
        u(3)  = u(4)  - bitshift(int16(synthK3) *x(3),  -7);
        u(2)  = u(3)  - int16(bitshift(int32(synthK2)*int32(x(2)), -15));
        u(1)  = u(2)  - int16(bitshift(int32(synthK1)*int32(x(1)), -15));
          
        %Output clamp
        if u(1) > 511
            u(1) = 511;
        end
        if u(1) < -512
            u(1) = -512;
        end
 
        %Lattice filter reverse path
        x(10) = x(9) + bitshift(int16(synthK9)*u(9), -7);
        x(9)  = x(8) + bitshift(int16(synthK8)*u(8), -7);
        x(8)  = x(7) + bitshift(int16(synthK7)*u(7), -7);  
        x(7)  = x(6) + bitshift(int16(synthK6)*u(6), -7);
        x(6)  = x(5) + bitshift(int16(synthK5)*u(5), -7);
        x(5)  = x(4) + bitshift(int16(synthK4)*u(4), -7);
        x(4)  = x(3) + bitshift(int16(synthK3)*u(3), -7);
        x(3)  = x(2) + int16(bitshift(int32(synthK2)*int32(u(2)), -15));
        x(2)  = x(1) + int16(bitshift(int32(synthK1)*int32(u(1)), -15));     
        x(1) = u(1);
        
        if init == 0
            A = int16(u(1));
            init = 1;
        else
            A = int16([A u(1)]);
        end        
    end
end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Function: rev%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [val] = rev(a)

%The ROMs used with the TI speech were serial, not byte wide.
%Here's a handy routine to flip ROM data which is usually reversed.
val = uint8(a); %76543210

%Swap in groups of 4. 32107654.
val = bitor(bitshift(val,-4), bitshift(val,4));

%Swap in groups of 2. 10325476.
val = bitor(bitshift(bitand(val,204),-2), bitshift(bitand(val,51),2));

%Swap bit pairs. 01234567.
val = bitor(bitshift(bitand(val,170),-1), bitshift(bitand(val,85),1));
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Function: getBits%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [val, arIndex, bitIndex] = getBits(bits, ar, arIndex, bitIndex)

data = bitshift(uint16(rev(ar(arIndex))),8);

if bitIndex+bits > 8
    data = bitor(data, uint16(rev(ar(arIndex+1))));
end

data = bitshift(data, bitIndex);
val = bitshift(data, -(16-bits));
bitIndex = bitIndex + bits;

if bitIndex >= 8
    bitIndex = bitIndex - 8;
    arIndex = arIndex + 1;
end
end