Advertisement
Guest User

Untitled

a guest
Sep 19th, 2019
249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
MatLab 5.80 KB | None | 0 0
  1. % I have used some functions which are at the bottom of this file. I placed
  2. % comments in the function code as well, so in the 'main' code I will not
  3. % explain how the function works, just what it returns.
  4.  
  5. % I will give comments AFTER every line of code.
  6.  
  7. % I used the matlab-given function 'arrayfun' a few times. What this
  8. % function does is that it passes every point in a given array to a
  9. % function, and places the result in it's respective place in a new array.
  10. % It's syntax is "NewArray = arrayfun(@FunctionName, DataArray".
  11.  
  12. %% ****No for loops were used or harmed in the creation of this code.****
  13. %% Code Below
  14.  
  15. Fs = 44100;
  16. % Fs = The number of samples per second in which the input file is divided.
  17. % See lecture notes for how/why this method is used for digitalizing sound.
  18. % The industry standard is 44100.
  19.  
  20. [arr_A,Fs] = audioread('klaatu.wav');
  21. % Read the audio file and store it's data in array form.
  22.  
  23. arr_B = arrayfun(@absolute,arr_A);
  24. % We make the input data absolute (the root-square step of the RMS) so that
  25. % when we take the 'integral' of the data it doesn't result in 0.
  26.  
  27. K = 100001;
  28. arr_C = smoothdata(arr_B, 'movmean', K);
  29. % We use the 'smoothdata' function supplied by matlab to find the average
  30. % ('movmean' flag) 'loudness' over a certain timeperiod (in this case the
  31. % timeperiod is K = 100 001 samples long). For every point in arr_B it
  32. % looks X values back and X values forward, adds these values together and
  33. % divides this by X+X+1 to get the average over that period, and places it
  34. % in arr_C. This is the 'Mean' step of RMS.
  35.  
  36. % If K were to be too small, let's say K = 1, then later on when
  37. % normalizing the sound, the result for every data point would be exactly
  38. % the same, removing the variations needed for carrying the data (The
  39. % result would probably be a continuous single tone, if it results in
  40. % anything at all).
  41.  
  42. global MaxValRMS;
  43. MaxValRMS = max(arr_C);
  44. % We find the highest point of the RMS. We will use this to find the
  45. % average amplification that every datapoint will strive towards. See the
  46. % explanation at the amplitudeMod function for more info.
  47.  
  48. % The variable MaxValRms is declared global because matlab works in such a
  49. % way that any variable in any scope is NOT accesable in any other scope.
  50. % In this case, we're in the 'Base' scope, but any functions have their own
  51. % 'Function' scope, and cannot see any variables in the 'Base' scope.
  52. % Declaring the variable as global in both 'Base' and 'Function' allows for
  53. % sharing a single variable accross multiple scopes.
  54.  
  55. arr_AmpMod = arrayfun(@amplitudeMod,arr_C);
  56. % We make an array with values that are the INVERSE of the RMS. The loud
  57. % parts will have a low value, and the quit parts will have a high value.
  58.  
  59. arr_Normalized = arr_A .* arr_AmpMod;
  60. % We now multiply the original input signal with the inverse-RMS. Since the
  61. % quit parts have a high inverse-RMS value, multiplying them with the input
  62. % signal will increase the 'quit part' amplitude. Since the loud parts have
  63. % a low inverse-RMS value, multiplying the input with this inverse RMS
  64. % value results in a lower amplitude.
  65. % Basically, this is the part where we make the quit parts loud and the
  66. % loud parts quit, as to make them all approximately the same level.
  67.  
  68. global MaxValInput;
  69. MaxValInput = max(arr_B);
  70. arr_Output = arrayfun(@removePeaks,arr_Normalized);
  71. % This part above is completely optional. After running the normalization
  72. % part above, I saw that there were some data spikes caused by the fact
  73. % that the RMS is the value over a certain period, but in this period could
  74. % be very high peaks that now also get amplified the same as its quiter
  75. % neighbour values. This results in an output with some spikes at some
  76. % parts, which could be unenjoyable. This part just removes the peaks.
  77.  
  78. audiowrite('output.flac',arr_Output,Fs);
  79. % Write the final output in a sound file to be able to listen to the
  80. % result.
  81.  
  82. %% The part below plots all the graph of every intermediate step.
  83.  
  84. figure(1);
  85. plot(arr_A);
  86. % "Representation of Input Data"
  87. figure(2);
  88. plot(arr_B);
  89. % "Absolute-ed input data"
  90. hold on
  91. plot(arr_C);
  92. % RMS of absolute'd input array, overlayed on the absolute'd array to show
  93. % the level of RMS at any point in time, and easily visually compare to the
  94. % input data.
  95. figure(3);
  96. plot(arr_AmpMod);
  97. % "Inverse of RMS"
  98. figure(4);
  99. plot(arr_Normalized);
  100. % "Input data multiplied by the inverse amplitudes, normalized"
  101. figure(5);
  102. plot(arr_Output);
  103. % "Output array, without spikes"
  104.  
  105. %% Functions
  106. function output = absolute(x)
  107.     output = sqrt(x^2);
  108. end
  109. % Takes the input value, squares it and takes the root of this new value.
  110. % This is now the absolute value of the original value.
  111.  
  112. function output = amplitudeMod(x)
  113.     global MaxValRMS;
  114.     output = (MaxValRMS/2) / x;
  115. end
  116. % As explained above, MaxValRMS is global to be accesable in this scope.
  117. % MaxValRms/2 is half the loudness of the loud parts, which should also be
  118. % about double the loudness of quit parts. By dividing this by low (quit)
  119. % value, it will return a high value (1 / 0.5 = 2), and by dividing the
  120. % MaxValRMS/2 by a high value, it will return a lower value (1 / 2 = 0.5).
  121.  
  122. % Basically this returns the amplification needed to get a datapoint to
  123. % the average loudness.
  124.  
  125. function output = removePeaks(x)
  126.     global MaxValInput;
  127.     if x > ((MaxValInput/3)*2)
  128.         output = ((MaxValInput/3)*2);
  129.     elseif x < ((-MaxValInput / 3) * 2)
  130.         output = ((-MaxValInput/3)*2);
  131.     else
  132.         output = x;
  133.     end
  134. end
  135. % This function checks if the data point is above 2/3rd of the original
  136. % 'loud' part (meaning it is a spike), and if that is the case it changes
  137. % its value to be 2/3rd of the original input loud part. This checks for
  138. % both positive and negative datapoints since sound in this case is an
  139. % osscilation around zero.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement