old demo that i want to try in mbed studio

Dependencies:   mbed SDFileSystem_Copy_of_mbed_version I2S

Committer:
roryhand
Date:
Sat May 16 21:25:28 2020 +0000
Branch:
LargeFile_Tests
Revision:
90:1dce46f0d9e5
Parent:
87:f5c9beae06ac
current version to try in mbed studio

Who changed what in which revision?

UserRevisionLine numberNew contents of line
roryhand 1:aac37edee302 1
roryhand 0:e89d7a0bfa3b 2 // 24/03/2018 update - I appear to be able to address the device and write something, as I am getting an ACK returned from the i2c write() function.
roryhand 0:e89d7a0bfa3b 3 //however if i use the write function with 4 arguments (as opposed to just 1 argument) then it doesnt work
roryhand 0:e89d7a0bfa3b 4 //only works with the 1 argument version!!!
roryhand 0:e89d7a0bfa3b 5
roryhand 0:e89d7a0bfa3b 6
roryhand 0:e89d7a0bfa3b 7 //THIS VERSION WORKED, CHANGED SOME THINGS, THEN CHANGED THEM BACK. NOW IT NO LONGER WORKS!!!!
roryhand 0:e89d7a0bfa3b 8 #include "mbed.h"
roryhand 0:e89d7a0bfa3b 9 #include "math.h"
roryhand 1:aac37edee302 10 #include "I2S.h"
roryhand 1:aac37edee302 11 #include "SDFileSystem.h"
roryhand 0:e89d7a0bfa3b 12 #include "wm8731_Config_setup.h"
roryhand 0:e89d7a0bfa3b 13 #include "WOLFSON_config_consts.h"
roryhand 54:606a83fff291 14 //#include "BlockDevice.h"
roryhand 37:a563899ac0df 15 #include <string>
roryhand 0:e89d7a0bfa3b 16 #include <stdlib.h>
roryhand 27:a378f1f937ee 17 #include <fstream>
roryhand 27:a378f1f937ee 18 #include <iostream>
roryhand 0:e89d7a0bfa3b 19 #include <vector>
roryhand 0:e89d7a0bfa3b 20 #include <string>
roryhand 0:e89d7a0bfa3b 21 #define sample_freq 11025
roryhand 90:1dce46f0d9e5 22 //#pragma import __use_two_region_memory
roryhand 54:606a83fff291 23 //BlockDevice *bd = BlockDevice::get_default_instance();
roryhand 54:606a83fff291 24 //#include "LittleFileSystem.h"
roryhand 54:606a83fff291 25 //LittleFileSystem fs("fs");
roryhand 54:606a83fff291 26
roryhand 0:e89d7a0bfa3b 27 DigitalOut myled(LED1);
roryhand 0:e89d7a0bfa3b 28 DigitalOut led2(LED2);
roryhand 0:e89d7a0bfa3b 29 DigitalOut led3(LED3);
roryhand 0:e89d7a0bfa3b 30 DigitalIn NotchUp(p16);
roryhand 38:3b4c05af5f36 31 DigitalIn NotchDown(p17);//check the pin!!! Dont know if this will actually work...
roryhand 0:e89d7a0bfa3b 32 InterruptIn Horn(p16);
roryhand 0:e89d7a0bfa3b 33 Ticker sampletick;
roryhand 73:a5ab93214728 34 Ticker NotchUpTick;
roryhand 45:0e8e1f2ec5d2 35
roryhand 0:e89d7a0bfa3b 36 Ticker TickFadeOut;
roryhand 0:e89d7a0bfa3b 37 Timer t;
roryhand 0:e89d7a0bfa3b 38 Timer t2;
roryhand 75:8a71e269b890 39 Timer OperationsTimer;
roryhand 3:6169aeeaeeb4 40 Timer NotchTimer;
roryhand 27:a378f1f937ee 41 Timer timer_open;
roryhand 0:e89d7a0bfa3b 42
roryhand 0:e89d7a0bfa3b 43 Serial pc(USBTX, USBRX); // tx, rx //FOR DEBUGGING PROGRAM USING GNU SCREEN
roryhand 0:e89d7a0bfa3b 44 DigitalOut cs(p8);
roryhand 0:e89d7a0bfa3b 45 I2S i2s(I2S_TRANSMIT, p5, p6, p7);
roryhand 0:e89d7a0bfa3b 46 SDFileSystem sd(p11, p12, p13, p8, "sd"); // the new pinout that i am using
roryhand 0:e89d7a0bfa3b 47
roryhand 65:8b6a4e307941 48 class classFade
roryhand 65:8b6a4e307941 49 {
roryhand 65:8b6a4e307941 50 public:
roryhand 65:8b6a4e307941 51
roryhand 65:8b6a4e307941 52 float powerval;
roryhand 65:8b6a4e307941 53 float FadeIteration;
roryhand 65:8b6a4e307941 54 float DecayFactor;
roryhand 65:8b6a4e307941 55 float Denom;
roryhand 65:8b6a4e307941 56 float FadeCoeff;
roryhand 65:8b6a4e307941 57 float Natural_Exp;
roryhand 65:8b6a4e307941 58 int LengthSecs;
roryhand 65:8b6a4e307941 59 int Length;
roryhand 67:043fe0b81343 60 void FadeDataInitialise()
roryhand 67:043fe0b81343 61 {
roryhand 67:043fe0b81343 62 DecayFactor = 1.3;
roryhand 67:043fe0b81343 63 FadeIteration = 1;
roryhand 67:043fe0b81343 64 //FadeData.Denom = 11025*FadeData.DecayFactor;
roryhand 67:043fe0b81343 65 Denom = 11025*DecayFactor;
roryhand 67:043fe0b81343 66 Natural_Exp = 2.7183;
roryhand 67:043fe0b81343 67 Length = 11025*LengthSecs;
roryhand 67:043fe0b81343 68 //FadeData.Natural_Exp = 2.7;
roryhand 67:043fe0b81343 69 }
roryhand 65:8b6a4e307941 70 //member Functions
roryhand 65:8b6a4e307941 71 float FadeOut(void)
roryhand 65:8b6a4e307941 72 {
roryhand 65:8b6a4e307941 73 powerval = -FadeIteration/Denom;
roryhand 65:8b6a4e307941 74 if (FadeIteration >=Length) {
roryhand 65:8b6a4e307941 75 FadeCoeff = 0;
roryhand 65:8b6a4e307941 76
roryhand 65:8b6a4e307941 77 } else {
roryhand 65:8b6a4e307941 78 FadeCoeff = (Length - FadeIteration)/Length;
roryhand 65:8b6a4e307941 79 }
roryhand 65:8b6a4e307941 80 FadeIteration = FadeIteration + 1;
roryhand 65:8b6a4e307941 81 return FadeCoeff;
roryhand 65:8b6a4e307941 82
roryhand 65:8b6a4e307941 83 }
roryhand 65:8b6a4e307941 84 float FadeIn(void)
roryhand 65:8b6a4e307941 85 {
roryhand 65:8b6a4e307941 86 powerval = FadeIteration/Denom;
roryhand 65:8b6a4e307941 87 if (FadeIteration >=Length) {
roryhand 65:8b6a4e307941 88 FadeCoeff = 1;
roryhand 65:8b6a4e307941 89
roryhand 65:8b6a4e307941 90 } else {
roryhand 65:8b6a4e307941 91 FadeCoeff = FadeIteration/Length;
roryhand 65:8b6a4e307941 92 }
roryhand 65:8b6a4e307941 93
roryhand 65:8b6a4e307941 94 FadeIteration = FadeIteration + 1;
roryhand 65:8b6a4e307941 95 return FadeCoeff;
roryhand 65:8b6a4e307941 96
roryhand 65:8b6a4e307941 97 }
roryhand 65:8b6a4e307941 98 };
roryhand 65:8b6a4e307941 99
roryhand 65:8b6a4e307941 100
roryhand 67:043fe0b81343 101 //Do these variables have to be global?? Find out - may be better (safer) to make them local.
roryhand 67:043fe0b81343 102 classFade NotchFadeIn;
roryhand 67:043fe0b81343 103 classFade NotchFadeOut;
roryhand 67:043fe0b81343 104
roryhand 67:043fe0b81343 105
roryhand 67:043fe0b81343 106 //Dont require the class below. Turns out I had already made a Structure to hold the same information.
roryhand 67:043fe0b81343 107 //If in the futre I need to embed functions then I will switch to using this class
roryhand 67:043fe0b81343 108
roryhand 67:043fe0b81343 109
roryhand 1:aac37edee302 110 typedef struct uFMT_STRUCT {
roryhand 1:aac37edee302 111 short comp_code;
roryhand 1:aac37edee302 112 short num_channels;
roryhand 1:aac37edee302 113 unsigned sample_rate;
roryhand 1:aac37edee302 114 unsigned avg_Bps;
roryhand 1:aac37edee302 115 short block_align;
roryhand 1:aac37edee302 116 short sig_bps;
roryhand 0:e89d7a0bfa3b 117 } FMT_STRUCT;
roryhand 0:e89d7a0bfa3b 118
roryhand 1:aac37edee302 119 typedef struct uNotch_STRUCT {
roryhand 1:aac37edee302 120 short Notch;
roryhand 1:aac37edee302 121 short NotchTransUp;
roryhand 1:aac37edee302 122 short NotchTransDown;
roryhand 1:aac37edee302 123 short NotchDirection;
roryhand 1:aac37edee302 124 } Notch_STRUCT;
roryhand 1:aac37edee302 125
roryhand 67:043fe0b81343 126 Notch_STRUCT NotchingSet;
roryhand 67:043fe0b81343 127
roryhand 67:043fe0b81343 128
roryhand 0:e89d7a0bfa3b 129 typedef struct uDATA_STRUCT {
roryhand 1:aac37edee302 130 unsigned subchunk2_ID;
roryhand 1:aac37edee302 131 unsigned subchunk2_size;
roryhand 1:aac37edee302 132 char * data_buf;
roryhand 1:aac37edee302 133 } DATA_STRUCT;
roryhand 0:e89d7a0bfa3b 134
roryhand 1:aac37edee302 135 typedef struct uWAV_FILE_STRUCT {
roryhand 1:aac37edee302 136 FILE *WavFile;
roryhand 1:aac37edee302 137 int id_number;
roryhand 1:aac37edee302 138 char *slice_buf;
roryhand 1:aac37edee302 139 int num_slices;
roryhand 1:aac37edee302 140 FMT_STRUCT FileFormat;
roryhand 1:aac37edee302 141 DATA_STRUCT FileData;
roryhand 0:e89d7a0bfa3b 142 } WAV_FILE_STRUCT;
roryhand 0:e89d7a0bfa3b 143
roryhand 0:e89d7a0bfa3b 144 /*typedef struct uWAV_FILE_STRUCT{
roryhand 1:aac37edee302 145 FILE* WavFile;
roryhand 1:aac37edee302 146
roryhand 1:aac37edee302 147
roryhand 0:e89d7a0bfa3b 148 }WAV_FILE_STRUCT;*/
roryhand 59:8e7c25a915a0 149
roryhand 59:8e7c25a915a0 150
roryhand 59:8e7c25a915a0 151
roryhand 59:8e7c25a915a0 152
roryhand 59:8e7c25a915a0 153
roryhand 59:8e7c25a915a0 154 class classSoundFile
roryhand 59:8e7c25a915a0 155 {
roryhand 59:8e7c25a915a0 156 public:
roryhand 59:8e7c25a915a0 157
roryhand 59:8e7c25a915a0 158 //add a class constructor at some point in the future (perform tests in visual studio)
roryhand 59:8e7c25a915a0 159 WAV_FILE_STRUCT FileInfo;
roryhand 59:8e7c25a915a0 160 short * data_sptr;
roryhand 59:8e7c25a915a0 161 string file_location;
roryhand 59:8e7c25a915a0 162 //classSoundFile(string filename);//this is the constructor
roryhand 59:8e7c25a915a0 163 //string filename;
roryhand 59:8e7c25a915a0 164 };
roryhand 58:a174e7a8f5f2 165 class classPositionIndicators
roryhand 57:0c76b15cabaf 166 {
roryhand 57:0c76b15cabaf 167 public:
roryhand 57:0c76b15cabaf 168 int notch1_indicator, notch2_indicator, notch3_indicator, notch4_indicator;
roryhand 57:0c76b15cabaf 169 int notch5_indicator, notch6_indicator, notch7_indicator, notch8_indicator;
roryhand 57:0c76b15cabaf 170 int notch1_start_pt, notch2_start_pt, notch3_start_pt, notch4_start_pt;
roryhand 57:0c76b15cabaf 171 int notch5_start_pt, notch6_start_pt, notch7_start_pt, notch8_start_pt;
roryhand 63:a8c1971d3d42 172 int N1N2_start_pt, N2N3_start_pt, N3N4_start_pt, N4N5_start_pt, N5N6_start_pt;
roryhand 63:a8c1971d3d42 173 int N6N7_start_pt, N7N8_start_pt, N8N7_start_pt, N7N6_start_pt, N6N5_start_pt;
roryhand 63:a8c1971d3d42 174 int N5N4_start_pt, N4N3_start_pt, N3N2_start_pt, N2N1_start_pt;
roryhand 67:043fe0b81343 175
roryhand 61:212d2db45c56 176 int notch_start_pts [9];
roryhand 61:212d2db45c56 177 int notch_position_indicators[9];
roryhand 61:212d2db45c56 178 int notch_transitions_start_pts[15];
roryhand 61:212d2db45c56 179 int notch_transitions_position_indicators[15];
roryhand 61:212d2db45c56 180 int auxiliary_start_pts[5];
roryhand 61:212d2db45c56 181 int auxiliary_position_indicators[5];
roryhand 58:a174e7a8f5f2 182 classPositionIndicators()
roryhand 57:0c76b15cabaf 183 {
roryhand 57:0c76b15cabaf 184 notch1_start_pt = 44;
roryhand 57:0c76b15cabaf 185 notch2_start_pt = 220884+44;
roryhand 57:0c76b15cabaf 186 notch3_start_pt = notch2_start_pt+217698;
roryhand 57:0c76b15cabaf 187 notch4_start_pt = notch3_start_pt + 193060;
roryhand 57:0c76b15cabaf 188 notch5_start_pt = notch4_start_pt + 92010;
roryhand 57:0c76b15cabaf 189 notch6_start_pt = notch5_start_pt + 216642;
roryhand 57:0c76b15cabaf 190 notch7_start_pt = notch6_start_pt + 250316;
roryhand 61:212d2db45c56 191 notch8_start_pt = notch7_start_pt + 150152;
roryhand 57:0c76b15cabaf 192 notch1_indicator = notch1_start_pt;
roryhand 57:0c76b15cabaf 193 notch2_indicator = notch2_start_pt;
roryhand 57:0c76b15cabaf 194 notch3_indicator = notch3_start_pt;
roryhand 57:0c76b15cabaf 195 notch4_indicator = notch4_start_pt;
roryhand 57:0c76b15cabaf 196 notch5_indicator = notch5_start_pt;
roryhand 57:0c76b15cabaf 197 notch6_indicator = notch6_start_pt;
roryhand 57:0c76b15cabaf 198 notch7_indicator = notch7_start_pt;
roryhand 57:0c76b15cabaf 199 notch8_indicator = notch8_start_pt;
roryhand 61:212d2db45c56 200 notch_start_pts[1] = notch1_start_pt;
roryhand 61:212d2db45c56 201 notch_start_pts[2] = notch2_start_pt;
roryhand 61:212d2db45c56 202 notch_start_pts[3] = notch3_start_pt;
roryhand 61:212d2db45c56 203 notch_start_pts[4] = notch4_start_pt;
roryhand 61:212d2db45c56 204 notch_start_pts[5] = notch5_start_pt;
roryhand 61:212d2db45c56 205 notch_start_pts[6] = notch6_start_pt;
roryhand 61:212d2db45c56 206 notch_start_pts[7] = notch7_start_pt;
roryhand 61:212d2db45c56 207 notch_start_pts[8] = notch8_start_pt;
roryhand 61:212d2db45c56 208 notch_position_indicators[1] = notch1_indicator;
roryhand 61:212d2db45c56 209 notch_position_indicators[2] = notch2_indicator;
roryhand 61:212d2db45c56 210 notch_position_indicators[3] = notch3_indicator;
roryhand 61:212d2db45c56 211 notch_position_indicators[4] = notch4_indicator;
roryhand 61:212d2db45c56 212 notch_position_indicators[5] = notch5_indicator;
roryhand 61:212d2db45c56 213 notch_position_indicators[6] = notch6_indicator;
roryhand 61:212d2db45c56 214 notch_position_indicators[7] = notch7_indicator;
roryhand 61:212d2db45c56 215 notch_position_indicators[8] = notch8_indicator;
roryhand 67:043fe0b81343 216
roryhand 63:a8c1971d3d42 217 N1N2_start_pt = 44;
roryhand 63:a8c1971d3d42 218 N2N3_start_pt = N1N2_start_pt + 73220;
roryhand 63:a8c1971d3d42 219 N3N4_start_pt = N2N3_start_pt + 78164;
roryhand 63:a8c1971d3d42 220 N4N5_start_pt = N3N4_start_pt + 59432;
roryhand 63:a8c1971d3d42 221 N5N6_start_pt = N4N5_start_pt + 64984;
roryhand 63:a8c1971d3d42 222 N6N7_start_pt = N5N6_start_pt + 59924;
roryhand 63:a8c1971d3d42 223 N7N8_start_pt = N6N7_start_pt + 97874;
roryhand 63:a8c1971d3d42 224 N8N7_start_pt = N7N8_start_pt + 63992;
roryhand 63:a8c1971d3d42 225 N7N6_start_pt = N8N7_start_pt + 44506;
roryhand 63:a8c1971d3d42 226 N6N5_start_pt = N7N6_start_pt + 55052;
roryhand 63:a8c1971d3d42 227 N5N4_start_pt = N6N5_start_pt + 37038;
roryhand 63:a8c1971d3d42 228 N4N3_start_pt = N5N4_start_pt + 49692;
roryhand 63:a8c1971d3d42 229 N3N2_start_pt = N4N3_start_pt + 44100;
roryhand 63:a8c1971d3d42 230 N2N1_start_pt = N3N2_start_pt + 58346;
roryhand 67:043fe0b81343 231
roryhand 67:043fe0b81343 232
roryhand 63:a8c1971d3d42 233 notch_transitions_start_pts[1] = N1N2_start_pt;
roryhand 63:a8c1971d3d42 234 notch_transitions_start_pts[2] = N2N3_start_pt;
roryhand 63:a8c1971d3d42 235 notch_transitions_start_pts[3] = N3N4_start_pt;
roryhand 63:a8c1971d3d42 236 notch_transitions_start_pts[4] = N4N5_start_pt;
roryhand 63:a8c1971d3d42 237 notch_transitions_start_pts[5] = N5N6_start_pt;
roryhand 63:a8c1971d3d42 238 notch_transitions_start_pts[6] = N6N7_start_pt;
roryhand 63:a8c1971d3d42 239 notch_transitions_start_pts[7] = N7N8_start_pt;
roryhand 63:a8c1971d3d42 240 notch_transitions_start_pts[8] = N8N7_start_pt;
roryhand 63:a8c1971d3d42 241 notch_transitions_start_pts[9] = N7N6_start_pt;
roryhand 63:a8c1971d3d42 242 notch_transitions_start_pts[10] = N6N5_start_pt;
roryhand 63:a8c1971d3d42 243 notch_transitions_start_pts[11] = N5N4_start_pt;
roryhand 63:a8c1971d3d42 244 notch_transitions_start_pts[12] = N4N3_start_pt;
roryhand 63:a8c1971d3d42 245 notch_transitions_start_pts[13] = N3N2_start_pt;
roryhand 63:a8c1971d3d42 246 notch_transitions_start_pts[14] = N2N1_start_pt;
roryhand 67:043fe0b81343 247
roryhand 67:043fe0b81343 248
roryhand 63:a8c1971d3d42 249 notch_transitions_position_indicators[1] = N1N2_start_pt;
roryhand 63:a8c1971d3d42 250 notch_transitions_position_indicators[2] = N2N3_start_pt;
roryhand 63:a8c1971d3d42 251 notch_transitions_position_indicators[3] = N3N4_start_pt;
roryhand 63:a8c1971d3d42 252 notch_transitions_position_indicators[4] = N4N5_start_pt;
roryhand 63:a8c1971d3d42 253 notch_transitions_position_indicators[5] = N5N6_start_pt;
roryhand 63:a8c1971d3d42 254 notch_transitions_position_indicators[6] = N6N7_start_pt;
roryhand 63:a8c1971d3d42 255 notch_transitions_position_indicators[7] = N7N8_start_pt;
roryhand 63:a8c1971d3d42 256 notch_transitions_position_indicators[8] = N8N7_start_pt;
roryhand 63:a8c1971d3d42 257 notch_transitions_position_indicators[9] = N7N6_start_pt;
roryhand 63:a8c1971d3d42 258 notch_transitions_position_indicators[10] = N6N5_start_pt;
roryhand 63:a8c1971d3d42 259 notch_transitions_position_indicators[11] = N5N4_start_pt;
roryhand 63:a8c1971d3d42 260 notch_transitions_position_indicators[12] = N4N3_start_pt;
roryhand 63:a8c1971d3d42 261 notch_transitions_position_indicators[13] = N3N2_start_pt;
roryhand 63:a8c1971d3d42 262 notch_transitions_position_indicators[14] = N2N1_start_pt;
roryhand 57:0c76b15cabaf 263 }
roryhand 57:0c76b15cabaf 264 };
roryhand 57:0c76b15cabaf 265
roryhand 73:a5ab93214728 266 int TransitionFlag;
roryhand 66:edf370edd21c 267 void NotchUpIsr()
roryhand 66:edf370edd21c 268 {
roryhand 66:edf370edd21c 269 if(1 <= NotchingSet.Notch < 8) {
roryhand 66:edf370edd21c 270
roryhand 66:edf370edd21c 271 NotchingSet.Notch = NotchingSet.Notch + 1;
roryhand 66:edf370edd21c 272 NotchingSet.NotchTransUp = NotchingSet.Notch + 7;
roryhand 66:edf370edd21c 273 NotchingSet.NotchDirection = 1;
roryhand 67:043fe0b81343 274 NotchFadeIn.FadeDataInitialise();
roryhand 67:043fe0b81343 275 NotchFadeOut.FadeDataInitialise();
roryhand 73:a5ab93214728 276 TransitionFlag = 1;
roryhand 74:e71a7815f63d 277 //printf("We are in the NotchUpIsr() section \n\r");
roryhand 67:043fe0b81343 278 //NotchFadeOut.FadeDataInitialise;
roryhand 66:edf370edd21c 279 }
roryhand 66:edf370edd21c 280 }
roryhand 66:edf370edd21c 281
roryhand 66:edf370edd21c 282 void NotchDownIsr()
roryhand 66:edf370edd21c 283 {
roryhand 66:edf370edd21c 284 if(1 < NotchingSet.Notch <= 8) {
roryhand 66:edf370edd21c 285 NotchingSet.Notch = NotchingSet.Notch - 1;
roryhand 67:043fe0b81343 286 NotchingSet.NotchTransDown = NotchingSet.Notch + 15;
roryhand 66:edf370edd21c 287 NotchingSet.NotchDirection = 0;
roryhand 67:043fe0b81343 288 NotchFadeIn.FadeDataInitialise();
roryhand 67:043fe0b81343 289 NotchFadeOut.FadeDataInitialise();
roryhand 74:e71a7815f63d 290 TransitionFlag = 1;
roryhand 66:edf370edd21c 291 }
roryhand 66:edf370edd21c 292 }
roryhand 73:a5ab93214728 293 short * data_sptr1;
roryhand 73:a5ab93214728 294 short * data_sptr2;
roryhand 73:a5ab93214728 295 short * data_sptr3;
roryhand 69:df10ee3ad523 296 char *slice_buf1;
roryhand 69:df10ee3ad523 297 char *slice_buf2;
roryhand 69:df10ee3ad523 298 char *slice_buf3;
roryhand 67:043fe0b81343 299
roryhand 54:606a83fff291 300 int OneOff = 0;
roryhand 38:3b4c05af5f36 301 int notch_flag = 0;
roryhand 0:e89d7a0bfa3b 302 int i = 0;
roryhand 0:e89d7a0bfa3b 303 int h = 0;
roryhand 0:e89d7a0bfa3b 304 short bufflen = 1;
roryhand 0:e89d7a0bfa3b 305 int buffer[1];
roryhand 86:404ce47e1e6e 306
roryhand 0:e89d7a0bfa3b 307 char *slice_buf;
roryhand 0:e89d7a0bfa3b 308 short *data_sptr;
roryhand 86:404ce47e1e6e 309
roryhand 86:404ce47e1e6e 310
roryhand 86:404ce47e1e6e 311
roryhand 0:e89d7a0bfa3b 312 unsigned channel;
roryhand 45:0e8e1f2ec5d2 313 long slice, slice1, slice2, slice3, num_slices;
roryhand 0:e89d7a0bfa3b 314 int interrupt_condition = 1;
roryhand 0:e89d7a0bfa3b 315 int sampling_freq = 11025;
roryhand 0:e89d7a0bfa3b 316 const int BufferLen = 2000;
roryhand 0:e89d7a0bfa3b 317 short Buffer1[BufferLen];
roryhand 0:e89d7a0bfa3b 318 short Buffer2[BufferLen];
roryhand 0:e89d7a0bfa3b 319 short place_hold1 = 0;
roryhand 0:e89d7a0bfa3b 320 short place_hold2 = 0;
roryhand 0:e89d7a0bfa3b 321
roryhand 3:6169aeeaeeb4 322
roryhand 86:404ce47e1e6e 323
roryhand 3:6169aeeaeeb4 324
roryhand 0:e89d7a0bfa3b 325 volatile int flag1 = 1;
roryhand 0:e89d7a0bfa3b 326 volatile int flag2 = 0;
roryhand 0:e89d7a0bfa3b 327 volatile int flag3 = 1;
roryhand 0:e89d7a0bfa3b 328 volatile int flag4 = 0;
roryhand 0:e89d7a0bfa3b 329 int FLAGBUFF1 = 0;
roryhand 0:e89d7a0bfa3b 330 int FLAGBUFF2 = 0;
roryhand 0:e89d7a0bfa3b 331 int BellFlag = 0;
roryhand 0:e89d7a0bfa3b 332 int BellFlag2 = 0;
roryhand 0:e89d7a0bfa3b 333 int FadeFlag = 0;
roryhand 54:606a83fff291 334 int BlockFlag = 0;
roryhand 86:404ce47e1e6e 335
roryhand 0:e89d7a0bfa3b 336
roryhand 0:e89d7a0bfa3b 337
roryhand 0:e89d7a0bfa3b 338 short value[1];
roryhand 59:8e7c25a915a0 339
roryhand 0:e89d7a0bfa3b 340 //long long slice_value;
roryhand 0:e89d7a0bfa3b 341 int slice_value[1];
roryhand 0:e89d7a0bfa3b 342
roryhand 0:e89d7a0bfa3b 343
roryhand 45:0e8e1f2ec5d2 344
roryhand 45:0e8e1f2ec5d2 345
roryhand 0:e89d7a0bfa3b 346
roryhand 0:e89d7a0bfa3b 347 void isr()
roryhand 0:e89d7a0bfa3b 348 {
roryhand 54:606a83fff291 349 //timer_interrupt.start();
roryhand 1:aac37edee302 350 if(flag1 == 0) {
roryhand 0:e89d7a0bfa3b 351 value[0] = Buffer1[place_hold1]>>4;
roryhand 0:e89d7a0bfa3b 352 i2s.write(value,1);//Send next PWM value to amp
roryhand 0:e89d7a0bfa3b 353 place_hold1 = place_hold1 + 1;
roryhand 1:aac37edee302 354 if( (place_hold1 >= BufferLen)) {
roryhand 0:e89d7a0bfa3b 355 led2 = !led2;
roryhand 0:e89d7a0bfa3b 356 place_hold1 = 0;
roryhand 0:e89d7a0bfa3b 357 place_hold2 = 0;
roryhand 0:e89d7a0bfa3b 358 flag1 = 1;
roryhand 0:e89d7a0bfa3b 359 flag2 = 0;
roryhand 1:aac37edee302 360 }
roryhand 1:aac37edee302 361 } else if(flag2 == 0) {
roryhand 0:e89d7a0bfa3b 362 value[0] = Buffer2[place_hold2]>>4;
roryhand 0:e89d7a0bfa3b 363 i2s.write(value,1);//Send next PWM value to amp
roryhand 0:e89d7a0bfa3b 364 place_hold2 = place_hold2 + 1;
roryhand 1:aac37edee302 365 if( (place_hold2 >= BufferLen) ) {
roryhand 0:e89d7a0bfa3b 366 led2 = !led2;
roryhand 0:e89d7a0bfa3b 367 place_hold1 = 0;
roryhand 0:e89d7a0bfa3b 368 place_hold2 = 0;
roryhand 0:e89d7a0bfa3b 369 flag1 = 0;
roryhand 1:aac37edee302 370 flag2 = 1;
roryhand 0:e89d7a0bfa3b 371 FLAGBUFF2 = 0;
roryhand 1:aac37edee302 372 }
roryhand 0:e89d7a0bfa3b 373 }
roryhand 54:606a83fff291 374
roryhand 54:606a83fff291 375 //timer_interrupt.stop();
roryhand 54:606a83fff291 376
roryhand 0:e89d7a0bfa3b 377 }
roryhand 1:aac37edee302 378
roryhand 38:3b4c05af5f36 379
roryhand 38:3b4c05af5f36 380
roryhand 38:3b4c05af5f36 381
roryhand 38:3b4c05af5f36 382
roryhand 0:e89d7a0bfa3b 383
roryhand 59:8e7c25a915a0 384
roryhand 59:8e7c25a915a0 385
roryhand 59:8e7c25a915a0 386
roryhand 59:8e7c25a915a0 387
roryhand 59:8e7c25a915a0 388
roryhand 3:6169aeeaeeb4 389
roryhand 3:6169aeeaeeb4 390
roryhand 3:6169aeeaeeb4 391
roryhand 3:6169aeeaeeb4 392
roryhand 3:6169aeeaeeb4 393
roryhand 3:6169aeeaeeb4 394 //function prototypes
roryhand 67:043fe0b81343 395 //classFade FadeDataInitialise(classFade FadeData);
roryhand 45:0e8e1f2ec5d2 396 classSoundFile ReadFileInfo(classSoundFile Sound, FILE * wav_file);
roryhand 3:6169aeeaeeb4 397 classSoundFile LoadFileStream(classSoundFile FileInfo, string filename);
roryhand 3:6169aeeaeeb4 398 void Play_WaveFile(FILE * my_wav, WAV_FILE_STRUCT FileInfo);
roryhand 32:6ee488c97dcc 399 void Play_WaveFileDual(FILE * my_wav, WAV_FILE_STRUCT FileInfo);
roryhand 77:e93c944ed30f 400 void Play_WaveFileLoop(classSoundFile Sound1, classSoundFile Sound2, FILE* wavfile1, FILE* wavfile2,classPositionIndicators Positions);
roryhand 0:e89d7a0bfa3b 401
roryhand 1:aac37edee302 402 int main()
roryhand 1:aac37edee302 403 {
roryhand 44:a9e84d333a6a 404
roryhand 0:e89d7a0bfa3b 405 NotchUp.mode(PullUp);
roryhand 38:3b4c05af5f36 406 NotchDown.mode(PullUp);
roryhand 0:e89d7a0bfa3b 407
roryhand 0:e89d7a0bfa3b 408 pc.printf("Beginning of program\n");
roryhand 32:6ee488c97dcc 409
roryhand 13:8e93396a27c5 410
roryhand 13:8e93396a27c5 411
roryhand 4:55fbbb049bae 412
roryhand 25:5336e1cf38d6 413 printf("Do we even get to this stupid bloody point\n\r");
roryhand 0:e89d7a0bfa3b 414 //Populate our class instances with some data (is there an implicit way to do this?)
roryhand 28:6b2353fad12d 415
roryhand 1:aac37edee302 416
roryhand 3:6169aeeaeeb4 417 printf("hello\n\r");
roryhand 0:e89d7a0bfa3b 418 //Set up the wolfson Audio Codec board
roryhand 74:e71a7815f63d 419
roryhand 74:e71a7815f63d 420
roryhand 0:e89d7a0bfa3b 421 wm8731_Config_setup();
roryhand 0:e89d7a0bfa3b 422 //i2s audio data transfer code??
roryhand 0:e89d7a0bfa3b 423 i2s.stereomono(I2S_STEREO);
roryhand 0:e89d7a0bfa3b 424 i2s.masterslave(I2S_MASTER);
roryhand 0:e89d7a0bfa3b 425 led3 = 1;
roryhand 0:e89d7a0bfa3b 426 led2 = 1;
roryhand 45:0e8e1f2ec5d2 427 printf("Hello i2s has started!");
roryhand 30:4a8e80b243c4 428 i2s.start();
roryhand 0:e89d7a0bfa3b 429 sampletick.attach(&isr,1.0/sampling_freq); //1/16000
roryhand 73:a5ab93214728 430 NotchUpTick.attach(&NotchUpIsr,10.0);
roryhand 67:043fe0b81343 431
roryhand 74:e71a7815f63d 432
roryhand 74:e71a7815f63d 433
roryhand 67:043fe0b81343 434 NotchFadeIn.LengthSecs = 2;
roryhand 67:043fe0b81343 435 NotchFadeOut.LengthSecs = 2;
roryhand 67:043fe0b81343 436
roryhand 67:043fe0b81343 437 NotchFadeIn.FadeDataInitialise();
roryhand 67:043fe0b81343 438 NotchFadeOut.FadeDataInitialise();
roryhand 67:043fe0b81343 439
roryhand 74:e71a7815f63d 440
roryhand 58:a174e7a8f5f2 441 classPositionIndicators Positions;
roryhand 74:e71a7815f63d 442 slice1 = Positions.notch_start_pts[1];
roryhand 74:e71a7815f63d 443
roryhand 74:e71a7815f63d 444
roryhand 73:a5ab93214728 445
roryhand 73:a5ab93214728 446 TransitionFlag = 0;
roryhand 73:a5ab93214728 447
roryhand 87:f5c9beae06ac 448 FILE* wavfile1 = fopen("/sd/mydir/SoundDecoder_second/01.wav","rb");
roryhand 86:404ce47e1e6e 449 FILE* wavfile2 = fopen("/sd/mydir/SoundDecoder_second/04.wav","rb");
roryhand 86:404ce47e1e6e 450 FILE* wavfile3 = fopen("/sd/mydir/SoundDecoder_second/05.wav","rb");
roryhand 74:e71a7815f63d 451
roryhand 60:36df2997de3d 452 //FILE* wavfile1 = fopen("/sd/mydir/SoundDecoder_second/01.wav","rb");
roryhand 58:a174e7a8f5f2 453 classSoundFile Sound1;
roryhand 73:a5ab93214728 454 classSoundFile Sound2;
roryhand 86:404ce47e1e6e 455 classSoundFile Sound4;
roryhand 86:404ce47e1e6e 456
roryhand 86:404ce47e1e6e 457
roryhand 86:404ce47e1e6e 458 Sound4 = ReadFileInfo(Sound4, wavfile3);
roryhand 73:a5ab93214728 459 Sound2 = ReadFileInfo(Sound2, wavfile2);
roryhand 58:a174e7a8f5f2 460 Sound1 = ReadFileInfo(Sound1, wavfile1);
roryhand 86:404ce47e1e6e 461 printf("sizeof(Sound1): %d bytes\n\r",sizeof(Sound1));
roryhand 73:a5ab93214728 462 NotchingSet.Notch = 1;
roryhand 77:e93c944ed30f 463 //Positions.notch_position_indicators[1] = 44;
roryhand 73:a5ab93214728 464 fseek(wavfile1,Positions.notch_start_pts[1],SEEK_SET);
roryhand 73:a5ab93214728 465 fseek(wavfile2,Positions.notch_transitions_start_pts[1],SEEK_SET);
roryhand 20:9cc7d825c07b 466 printf("about to play wav file\n\r");
roryhand 77:e93c944ed30f 467 Play_WaveFileLoop(Sound1,Sound2, wavfile1,wavfile2, Positions);
roryhand 20:9cc7d825c07b 468 printf("finished playing Wav file\n\r");
roryhand 54:606a83fff291 469
roryhand 54:606a83fff291 470
roryhand 31:0f8c3adf09c3 471 timer_open.reset();
roryhand 31:0f8c3adf09c3 472 timer_open.start();
roryhand 45:0e8e1f2ec5d2 473 fclose(wavfile1);
roryhand 31:0f8c3adf09c3 474 timer_open.stop();
roryhand 31:0f8c3adf09c3 475 printf("It took %d useconds to close file\n\r",timer_open.read_us());
roryhand 54:606a83fff291 476
roryhand 54:606a83fff291 477
roryhand 54:606a83fff291 478
roryhand 54:606a83fff291 479
roryhand 9:dd9cae06b202 480 /************************************PLAY WAV FILE LOOP*******************/
roryhand 9:dd9cae06b202 481 /************************************END OF PLAY WAV FILE LOOP*************/
roryhand 13:8e93396a27c5 482
roryhand 13:8e93396a27c5 483
roryhand 1:aac37edee302 484 i2s.stop();
roryhand 74:e71a7815f63d 485
roryhand 0:e89d7a0bfa3b 486
roryhand 0:e89d7a0bfa3b 487 }
roryhand 0:e89d7a0bfa3b 488
roryhand 0:e89d7a0bfa3b 489
roryhand 3:6169aeeaeeb4 490
roryhand 3:6169aeeaeeb4 491
roryhand 3:6169aeeaeeb4 492
roryhand 3:6169aeeaeeb4 493
roryhand 45:0e8e1f2ec5d2 494 classSoundFile ReadFileInfo(classSoundFile Sound, FILE * wav_file)
roryhand 0:e89d7a0bfa3b 495 {
roryhand 0:e89d7a0bfa3b 496 fseek(wav_file,20,SEEK_SET);
roryhand 22:706e86dc0d45 497 printf("We have just seeked through this file\n\r");
roryhand 45:0e8e1f2ec5d2 498 fread(&Sound.FileInfo.FileFormat,sizeof(Sound.FileInfo.FileFormat),1,wav_file);
roryhand 1:aac37edee302 499 //printf("wav_format.sample_rate: %d\n\r",FileInfo.FileFormat.sample_rate);
roryhand 1:aac37edee302 500
roryhand 45:0e8e1f2ec5d2 501 fread(&Sound.FileInfo.FileData,sizeof(Sound.FileInfo.FileData),1,wav_file);
roryhand 55:5a441d3b0d57 502 printf("wav_data.subchunk2_size: %d\n\r",Sound.FileInfo.FileData.subchunk2_size);
roryhand 45:0e8e1f2ec5d2 503 Sound.FileInfo.slice_buf = ( char *)malloc(Sound.FileInfo.FileFormat.block_align);
roryhand 59:8e7c25a915a0 504 printf("Wav File Block Align (number of bytes per sample!!: %d\n\r", Sound.FileInfo.FileFormat.block_align);
roryhand 45:0e8e1f2ec5d2 505 fread(Sound.FileInfo.slice_buf,Sound.FileInfo.FileFormat.block_align,1,wav_file); //This isnt actually required, its just a test
roryhand 45:0e8e1f2ec5d2 506 Sound.FileInfo.num_slices = Sound.FileInfo.FileData.subchunk2_size/Sound.FileInfo.FileFormat.block_align;
roryhand 1:aac37edee302 507 //printf("Number of Slices: %d\n\r",FileInfo.num_slices);
roryhand 45:0e8e1f2ec5d2 508 return Sound;
roryhand 0:e89d7a0bfa3b 509 }
roryhand 1:aac37edee302 510
roryhand 1:aac37edee302 511
roryhand 64:6061ffe25985 512 //Function to initialise Data for classFade objects. Perhaps move this into a constructor for the class? (class still to be added)
roryhand 67:043fe0b81343 513 /*
roryhand 64:6061ffe25985 514 classFade FadeDataInitialise(classFade FadeData)
roryhand 64:6061ffe25985 515 {
roryhand 64:6061ffe25985 516 FadeData.DecayFactor = 1.3;
roryhand 64:6061ffe25985 517 FadeData.FadeIteration = 1;
roryhand 64:6061ffe25985 518 //FadeData.Denom = 11025*FadeData.DecayFactor;
roryhand 64:6061ffe25985 519 FadeData.Denom = 11025*FadeData.DecayFactor;
roryhand 64:6061ffe25985 520 FadeData.Natural_Exp = 2.7183;
roryhand 64:6061ffe25985 521 FadeData.Length = 11025*FadeData.LengthSecs;
roryhand 64:6061ffe25985 522 //FadeData.Natural_Exp = 2.7;
roryhand 64:6061ffe25985 523 return FadeData;
roryhand 64:6061ffe25985 524 }
roryhand 67:043fe0b81343 525 */
roryhand 1:aac37edee302 526
roryhand 1:aac37edee302 527
roryhand 1:aac37edee302 528
roryhand 0:e89d7a0bfa3b 529
roryhand 0:e89d7a0bfa3b 530 void Play_WaveFile(FILE * my_wav, WAV_FILE_STRUCT FileInfo)
roryhand 0:e89d7a0bfa3b 531 {
roryhand 1:aac37edee302 532 while(slice<FileInfo.num_slices) {
roryhand 1:aac37edee302 533 fread(FileInfo.slice_buf,FileInfo.FileFormat.block_align,1,my_wav);
roryhand 1:aac37edee302 534 data_sptr=(short *)FileInfo.slice_buf; // 16 bit samples
roryhand 1:aac37edee302 535 for (channel=0; channel<FileInfo.FileFormat.num_channels; channel++) {
roryhand 1:aac37edee302 536 if(flag1 == 1) {
roryhand 1:aac37edee302 537 Buffer1[place_hold1] = data_sptr[channel];
roryhand 1:aac37edee302 538 place_hold1 = place_hold1 + 1;
roryhand 1:aac37edee302 539 if(place_hold1 >= BufferLen) {
roryhand 1:aac37edee302 540 while(1) {
roryhand 1:aac37edee302 541 if(flag1 == 0) {
roryhand 0:e89d7a0bfa3b 542
roryhand 1:aac37edee302 543 break;
roryhand 0:e89d7a0bfa3b 544 }
roryhand 1:aac37edee302 545
roryhand 0:e89d7a0bfa3b 546 }
roryhand 1:aac37edee302 547 }
roryhand 1:aac37edee302 548
roryhand 1:aac37edee302 549 } else if(flag2 == 1) {
roryhand 1:aac37edee302 550 Buffer2[place_hold2] = data_sptr[channel];
roryhand 1:aac37edee302 551 place_hold2 = place_hold2 + 1;
roryhand 1:aac37edee302 552 if(place_hold2 >= BufferLen) {
roryhand 1:aac37edee302 553
roryhand 1:aac37edee302 554 while(1) {
roryhand 1:aac37edee302 555 if(flag2 == 0) {
roryhand 1:aac37edee302 556
roryhand 1:aac37edee302 557 break;
roryhand 1:aac37edee302 558 }
roryhand 0:e89d7a0bfa3b 559 }
roryhand 1:aac37edee302 560 }
roryhand 0:e89d7a0bfa3b 561 }
roryhand 1:aac37edee302 562
roryhand 1:aac37edee302 563 }
roryhand 1:aac37edee302 564 slice = slice + 1;
roryhand 0:e89d7a0bfa3b 565 }
roryhand 0:e89d7a0bfa3b 566 }
roryhand 0:e89d7a0bfa3b 567
roryhand 0:e89d7a0bfa3b 568
roryhand 0:e89d7a0bfa3b 569
roryhand 0:e89d7a0bfa3b 570
roryhand 38:3b4c05af5f36 571 //***************************************************************************//
roryhand 38:3b4c05af5f36 572
roryhand 38:3b4c05af5f36 573 //**************************************************************************//
roryhand 38:3b4c05af5f36 574
roryhand 38:3b4c05af5f36 575
roryhand 38:3b4c05af5f36 576
roryhand 38:3b4c05af5f36 577
roryhand 38:3b4c05af5f36 578
roryhand 59:8e7c25a915a0 579
roryhand 44:a9e84d333a6a 580
roryhand 77:e93c944ed30f 581 void Play_WaveFileLoop(classSoundFile Sound1, classSoundFile Sound2, FILE *wavfile1, FILE* wavfile2, classPositionIndicators Positions)
roryhand 45:0e8e1f2ec5d2 582 {
roryhand 45:0e8e1f2ec5d2 583 while(1) { //might have to change this to a while(1) loop?
roryhand 44:a9e84d333a6a 584
roryhand 2:957d3b2afff4 585
roryhand 44:a9e84d333a6a 586
roryhand 44:a9e84d333a6a 587
roryhand 54:606a83fff291 588
roryhand 44:a9e84d333a6a 589 //Sound1=======================================================================================
roryhand 69:df10ee3ad523 590 if( slice1 == (Positions.notch_start_pts[NotchingSet.Notch + 1]) ) {
roryhand 69:df10ee3ad523 591 slice1 = Positions.notch_start_pts[NotchingSet.Notch];
roryhand 69:df10ee3ad523 592 fseek(wavfile1,Positions.notch_start_pts[NotchingSet.Notch],SEEK_SET);
roryhand 67:043fe0b81343 593 }
roryhand 86:404ce47e1e6e 594
roryhand 69:df10ee3ad523 595 fread(Sound1.FileInfo.slice_buf,Sound1.FileInfo.FileFormat.block_align,1,wavfile1);
roryhand 77:e93c944ed30f 596 /*OperationsTimer.stop();
roryhand 76:9535aedba4da 597 printf("It took %d useconds to perform fread operation.\n\r",OperationsTimer.read_us());
roryhand 76:9535aedba4da 598 Positions.notch_position_indicators[1] = Positions.notch_position_indicators[1] + 2;//i.e. 2 bytes, per sample, for 2-byte (16-bit) data
roryhand 77:e93c944ed30f 599 */
roryhand 84:0a259e261532 600 data_sptr1=(short *)Sound1.FileInfo.slice_buf;
roryhand 84:0a259e261532 601 *Sound1.data_sptr = *data_sptr1;
roryhand 84:0a259e261532 602 //Sound1.data_sptr=(short *)Sound1.FileInfo.slice_buf; // 16 bit samples
roryhand 73:a5ab93214728 603
roryhand 86:404ce47e1e6e 604
roryhand 44:a9e84d333a6a 605 //=============================================================================================
roryhand 44:a9e84d333a6a 606
roryhand 67:043fe0b81343 607
roryhand 1:aac37edee302 608
roryhand 1:aac37edee302 609
roryhand 44:a9e84d333a6a 610
roryhand 45:0e8e1f2ec5d2 611 for (channel=0; channel<Sound1.FileInfo.FileFormat.num_channels; channel++) {
roryhand 45:0e8e1f2ec5d2 612 switch (Sound1.FileInfo.FileFormat.sig_bps) {
roryhand 0:e89d7a0bfa3b 613 case 16:
roryhand 1:aac37edee302 614 if(flag1 == 1) {
roryhand 45:0e8e1f2ec5d2 615 Buffer1[place_hold1] = Sound1.data_sptr[channel];
roryhand 1:aac37edee302 616 place_hold1 = place_hold1 + 1;
roryhand 1:aac37edee302 617 if(place_hold1 >= BufferLen) {
roryhand 1:aac37edee302 618 while(1) {
roryhand 1:aac37edee302 619 if(flag1 == 0) {
roryhand 1:aac37edee302 620 break;
roryhand 1:aac37edee302 621 }//if(flag1 == 0)
roryhand 1:aac37edee302 622
roryhand 1:aac37edee302 623
roryhand 1:aac37edee302 624 }//while(1)
roryhand 1:aac37edee302 625 }//if(place_hold1 > = BufferLen)
roryhand 0:e89d7a0bfa3b 626
roryhand 1:aac37edee302 627 } else if(flag2 == 1) {
roryhand 45:0e8e1f2ec5d2 628 Buffer2[place_hold2] = Sound1.data_sptr[channel];
roryhand 1:aac37edee302 629 place_hold2 = place_hold2 + 1;
roryhand 1:aac37edee302 630 if(place_hold2 >= BufferLen) {
roryhand 1:aac37edee302 631 while(1) {
roryhand 1:aac37edee302 632
roryhand 1:aac37edee302 633 if(flag2 == 0) {
roryhand 1:aac37edee302 634 break;
roryhand 1:aac37edee302 635 }
roryhand 1:aac37edee302 636 }
roryhand 0:e89d7a0bfa3b 637 }
roryhand 1:aac37edee302 638
roryhand 1:aac37edee302 639 }
roryhand 0:e89d7a0bfa3b 640 }
roryhand 0:e89d7a0bfa3b 641 }
roryhand 59:8e7c25a915a0 642 slice1 = slice1 + 2;//increment up by the number of bytes per Audio data sample! Makes sense it is 2 bytes, as this is 16-bit data.
roryhand 45:0e8e1f2ec5d2 643 slice2 = slice2 + 1;
roryhand 45:0e8e1f2ec5d2 644 slice3 = slice3 + 1;
roryhand 0:e89d7a0bfa3b 645 }
roryhand 0:e89d7a0bfa3b 646 }
roryhand 0:e89d7a0bfa3b 647
roryhand 0:e89d7a0bfa3b 648
roryhand 0:e89d7a0bfa3b 649
roryhand 0:e89d7a0bfa3b 650
roryhand 0:e89d7a0bfa3b 651
roryhand 0:e89d7a0bfa3b 652
roryhand 59:8e7c25a915a0 653