1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//! All objects related to audio defined by Spotify API

use serde::{Deserialize, Serialize};

use chrono::Duration;

use crate::{
    custom_serde::{duration_ms, modality},
    Modality, TrackId,
};

/// Audio Feature Object
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct AudioFeatures {
    pub acousticness: f32,
    pub analysis_url: String,
    pub danceability: f32,
    #[serde(with = "duration_ms", rename = "duration_ms")]
    pub duration: Duration,
    pub energy: f32,
    pub id: TrackId<'static>,
    pub instrumentalness: f32,
    pub key: i32,
    pub liveness: f32,
    pub loudness: f32,
    #[serde(with = "modality")]
    pub mode: Modality,
    pub speechiness: f32,
    pub tempo: f32,
    pub time_signature: i32,
    pub track_href: String,
    pub valence: f32,
}

/// Intermediate audio feature object wrapped by `Vec`
#[derive(Deserialize)]
pub struct AudioFeaturesPayload {
    pub audio_features: Vec<Option<AudioFeatures>>,
}

/// Audio analysis object
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct AudioAnalysis {
    pub bars: Vec<TimeInterval>,
    pub beats: Vec<TimeInterval>,
    pub meta: AudioAnalysisMeta,
    pub sections: Vec<AudioAnalysisSection>,
    pub segments: Vec<AudioAnalysisSegment>,
    pub tatums: Vec<TimeInterval>,
    pub track: AudioAnalysisTrack,
}

/// Time interval object
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)]
pub struct TimeInterval {
    pub start: f32,
    pub duration: f32,
    pub confidence: f32,
}

/// Audio analysis section object
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct AudioAnalysisSection {
    #[serde(flatten)]
    pub time_interval: TimeInterval,
    pub loudness: f32,
    pub tempo: f32,
    pub tempo_confidence: f32,
    pub key: i32,
    pub key_confidence: f32,
    #[serde(with = "modality")]
    pub mode: Modality,
    pub mode_confidence: f32,
    pub time_signature: i32,
    pub time_signature_confidence: f32,
}

/// Audio analysis meta object
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)]
pub struct AudioAnalysisMeta {
    pub analyzer_version: String,
    pub platform: String,
    pub detailed_status: String,
    pub status_code: i32,
    pub timestamp: u64,
    pub analysis_time: f32,
    pub input_process: String,
}

/// Audio analysis segment object
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)]
pub struct AudioAnalysisSegment {
    #[serde(flatten)]
    pub time_interval: TimeInterval,
    pub loudness_start: f32,
    pub loudness_max_time: f32,
    pub loudness_max: f32,
    pub loudness_end: Option<f32>,
    pub pitches: Vec<f32>,
    pub timbre: Vec<f32>,
}

/// Audio analysis track object
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct AudioAnalysisTrack {
    pub num_samples: u32,
    pub duration: f32,
    pub sample_md5: String,
    pub offset_seconds: u32,
    pub window_seconds: u32,
    pub analysis_sample_rate: i32,
    pub analysis_channels: u32,
    pub end_of_fade_in: f32,
    pub start_of_fade_out: f32,
    pub loudness: f32,
    pub tempo: f32,
    pub tempo_confidence: f32,
    pub time_signature: i32,
    pub time_signature_confidence: f32,
    pub key: u32,
    pub key_confidence: f32,
    #[serde(with = "modality")]
    pub mode: Modality,
    pub mode_confidence: f32,
    pub codestring: String,
    pub code_version: f32,
    pub echoprintstring: String,
    pub echoprint_version: f32,
    pub synchstring: String,
    pub synch_version: f32,
    pub rhythmstring: String,
    pub rhythm_version: f32,
}