I will summarize the introduction to sound in R language. I've summarized python several times before, but I'll write it for comparison. At the same time, I would like to listen to the sound of the explosion of the Nikkei 225, which is aperiodic time series data. The reference is as follows. Reference ③ shows how to install tuneR. ①How to get started with sound in R (pdf) ②Play sound in Python ③Basic Sound Processing with R
environment
Windows10
RStudio;Version 1.2.5042
python3.6.10
mic;hdmi
I've done it several times before, but I save the csv file and numerical string prepared last time as a sound with the following code as a wav file and output it.
import csv
with open('pl3_seasonal.csv', 'w') as f:
fieldnames = ['seasonal']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer = csv.writer(f, delimiter='\n')
for i in range(20):
writer.writerow(pl3)
I was able to store and use 4 data in pandas for a little more general purpose as follows.
df = pd.DataFrame({'seasonal': pl3,
'trend': pl2,
'resid':pl4,
'observed':pl1})
df.to_csv('seasonal_trend.csv', index=False)
I have added 20 times below.
for i in range(20):
df.to_csv('seasonal_trend.csv', mode='a', header=False, index=False)
The csv file reading is as follows.
df = pd.read_csv('seasonal_trend.csv')
pl3_seasonal = df['seasonal']
The following code is used to create and save the main sound file.
import wave
import numpy as np
import struct
import pyaudio
fs = 800 #Sampling frequency
#Sine wave-Convert from 32768 to 32767 integer value(to signed 16bit pcm)
pl3_n = 32767*pl3_seasonal/max(pl3_seasonal)
swav = [int(x ) for x in pl3_n]
#Binary
binwave = struct.pack("h" * len(swav), *swav)
#Export sine wave as wav file
w = wave.Wave_write("pl3_seasonal.wav")
params = (1, 2, fs, len(binwave), 'NONE', 'not compressed')
w.setparams(params)
w.writeframes(binwave)
w.close()
And you can play the sound with the following code. The following will play the'pl3_seasonal.wav' saved above.
from playsound import playsound
playsound('pl3_seasonal.wav')
Sound output is the first in R, but it's easy to do. Simply read the audio file ‘mywave.wav’ in the directory and make a sound.
library(tuneR) #load tuenR package
mwav = readWave("mywave.wav")
play(mwav)
The following calculates the wave with a sine wave, converts it to a wav file, and outputs it.
#make a simple sine wave and play
t = seq(0, 3, 1/8000)
u = (2^15-1)*sin(2*pi*440*t)
w = Wave(u, samp.rate = 8000, bit=16)
play(w)
In the following, it is saved as'w_1.wav'once, then loaded and played.
writeWave(w, 'w_1.wav')
rw = readWave("w_1.wav")
play(rw)
I found above that if you have a numeric string, you can create a wav file from it and save it. Therefore, in the following, I will convert the decompose_seasonal data that has been decomposed into time-series elements into a wav file and output it as sound. And finally save the wav file.
ds <- read.csv(file = 'decompose_seasonal.csv')
ds_w = Wave(32678/max(abs(ds))*ds, samp.rate = 8000, bit=16)
play(ds_w)
writeWave(ds_w, 'ds_w.wav')
Although it is aperiodic data, stock prices are a typical example of data that changes while vibrating. So, let's decompose the recent stock price fluctuation and convert it into a sound, and listen to this sound. ** * Please do not imitate this as I am looking forward to it ** For the time being, we will use the R code. Download and prepare the latest data of Nikkei 225. Although hz = 18 has no period, it is defined as a variable so that it can be analyzed at various period intervals. Since the number of data is not always an integral multiple of hz, we have introduced ls to adjust the number of data.
data <- read.csv("./industrial/nikkei_225_.csv",encoding = "utf-8")
hz=18
ls = round(908/hz)*hz
IIP <- ts(data,start=c(1),frequency=1)
IIP=IIP[0:ls]
IIP <- ts(IIP,start=c(1),frequency=hz)
decompose_IIP <- decompose(IIP)
Trend, random, seasonal, observed (IIP) are as follows
plot(decompose_IIP$trend)
plot(decompose_IIP$random)
plot(decompose_IIP$seasonal[0:72])
lines(decompose_IIP$seasonal[0:72])
seasonal | random |
---|---|
trend | observed |
Same picture as above, but find seasonal_beer by averaging m_beer as shown below, and output 3 of them.
m_beer = t(matrix(data = decompose_IIP$seasonal, nrow = hz))
seasonal_beer = colMeans(m_beer, na.rm = T)
plot(as.ts(rep(seasonal_beer,3)))
Unlike the graph above, it was obtained as a line graph. The contents are the same. This was output to csv as 130 pieces.
write.csv(as.ts(rep(seasonal_beer,130)), file = 'decompose_seasonal130.csv')
From here, it is the same chord as the above sound generation. That is, read the csv file as follows.
ds <- read.csv(file = 'decompose_seasonal130.csv')
Here, too, the tuneR library is used to generate the following sounds. In this way, sound was generated. I want to maximize the sound, so I standardize the numbers like python.
library(tuneR)
ds_w = Wave(32678/max(abs(ds[2]))*ds[2], samp.rate = 150*hz, bit=16)
play(ds_w)
Finally, save it to a file.
file_n <- paste('ds_',hz,'.wav')
writeWave(ds_w, file_n)
In this way, when hz is changed, the typical sound waveform changes as follows. In other words, it looks like a vowel is reproduced at some point. The actual sound sounds more similar than the waveform, so I literally doubt my ears.
hz | Close vowels | Waveform | vowel |
---|---|---|---|
18 | Ah | ||
40 | e | ||
128 | I | ||
16 | O | ||
17 | U |
・ R_Audio / data / Under the above R_Audio/data/1_a_ds_ 18 .wav Please download and play it.
I'm wondering why this is happening, so let's take a look at the data structure. Set hz = 16 as shown below, and decompose () in groups of 16 each. First, when you output the data
hz=16
ls = round(908/hz)*hz
IIP <- ts(data,start=c(1),frequency=1)
IIP=IIP[0:ls]
IIP <- ts(IIP,start=c(1),frequency=hz)
print(IIP[0:ls])
> source('C:/R_data/decompose_audio.R')
[1] 16820 17200 16930 16970 16820 16870 17030 16560 16800 16790 17410 17510 16870 16790 17230 17280
[17] 17460 17780 18180 17980 17700 17120 17220 17560 17520 17710 17920 17920 17200 17140 17240 17270
...
[897] 20070 19940 19920 19930 20010 19940 19990 20010 20050 20000 20020 20010 NA NA NA NA
And the important part is as follows
decompose_IIP <- decompose(IIP)
print(decompose_IIP$seasonal)
In other words, decompose_IIP $ seasonal is averaged by 16 pieces as shown below.
Time Series:
Start = c(1, 1)
End = c(57, 16)
Frequency = 16
[1] 16.659497 17.697443 16.413961 16.955256 -14.905540 -7.621449 13.458097 10.605824
[9] -2.302557 -11.895191 4.550122 17.479809 -19.166396 -26.945414 -21.738941 -9.244521
...
[897] 16.659497 17.697443 16.413961 16.955256 -14.905540 -7.621449 13.458097 10.605824
[905] -2.302557 -11.895191 4.550122 17.479809 -19.166396 -26.945414 -21.738941 -9.244521
When plotted on the graph, it looks like this: If you count the plots, you can see that there are 16 cycles.
This data is being played. And the important thing is that if you consider stock price data to be periodic and average it as a group with an appropriate number, some data will give you a data string similar to a vowel. Even if the same processing is performed on a complete random number sequence, such a result will not be obtained, but I think that it happens that the stock price data contains such a structure.
** Ah ~, you can't hear the original explosion sound with this method. .. .. ** **
・ I compared R and Python's introduction to sound. ・ Decompose the stock price, which is aperiodic data, and convert the seasonal fluctuations that became periodic data into sound to generate it. ・ It was found that by sampling at an appropriate cycle, a sound similar to a vowel is generated.
・ I will devise a little more and try to predict / predict using decompose () and sound generation.