pub struct SongRec { /* private fields */ }Expand description
Main SongRec struct for audio recognition
Implementations§
Source§impl SongRec
impl SongRec
Sourcepub fn new(config: Config) -> Self
pub fn new(config: Config) -> Self
Create a new SongRec instance with the given configuration
Examples found in repository?
examples/device_usage.rs (line 62)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 println!("SongRec Device Management and Live Recognition Examples");
5 println!("========================================================\n");
6
7 // Example 1: List Available Audio Devices
8 println!("Example 1: List Available Audio Devices");
9 println!("---------------------------------------");
10
11 match AudioRecorder::list_input_devices() {
12 Ok(devices) => {
13 if devices.is_empty() {
14 println!("No audio input devices found.");
15 return Ok(());
16 }
17
18 println!("Found {} audio input devices:", devices.len());
19 for (index, device_name) in devices.iter().enumerate() {
20 println!(" {}: {}", index, device_name);
21 }
22 println!();
23
24 // Example 2: Device Selection Strategies
25 println!("Example 2: Device Selection Strategies");
26 println!("--------------------------------------");
27
28 // Strategy 1: Select by exact name
29 let first_device = &devices[0];
30 println!("Strategy 1 - Exact name selection:");
31 println!(" Selected: {}", first_device);
32
33 // Strategy 2: Select by pattern matching
34 println!("\nStrategy 2 - Pattern matching:");
35 for pattern in &["microphone", "mic", "voicemeeter", "stereo mix"] {
36 if let Some(device) = find_device_by_pattern(&devices, pattern) {
37 println!(" Pattern '{}' found: {}", pattern, device);
38 }
39 }
40
41 // Strategy 3: Priority-based selection
42 println!("\nStrategy 3 - Priority-based selection:");
43 let selected_device = select_best_device(&devices);
44 println!(" Best device: {}", selected_device);
45
46 // Example 3: Live Recognition with Device Selection
47 println!("\nExample 3: Live Recognition Setup");
48 println!("---------------------------------");
49
50 // Show how to set up live recognition with different devices
51 println!("Setting up live recognition with various devices:\n");
52
53 for (i, device) in devices.iter().enumerate().take(3) {
54 println!("Device {}: {}", i, device);
55
56 // Configuration for this device
57 let config = Config::default()
58 .with_quiet_mode(true)
59 .with_network_timeout(10)
60 .with_sensitivity(0.6);
61
62 let _songrec = SongRec::new(config);
63
64 println!(" -> Configuration: quiet mode, 10s timeout, 0.6 sensitivity");
65 println!(" -> Usage: songrec.start_continuous_recognition_with_device(Some(\"{}\".to_string()))", device);
66 println!(" -> Ready for live recognition\n");
67 }
68
69 // Example 4: Complete Live Recognition Example (Commented)
70 println!("Example 4: Complete Live Recognition Code");
71 println!("------------------------------------------");
72
73 print_live_recognition_example(&selected_device);
74
75 // Example 5: Device-Specific Configuration
76 println!("\nExample 5: Device-Specific Configuration");
77 println!("----------------------------------------");
78
79 for device in devices.iter().take(2) {
80 let config = create_device_specific_config(device);
81 println!("Device: {}", device);
82 println!(" Recommended config: quiet={}, timeout={}s, sensitivity={}",
83 config.quiet_mode, config.network_timeout, config.sensitivity);
84 }
85
86 // Example 6: Error Handling for Device Operations
87 println!("\nExample 6: Error Handling");
88 println!("-------------------------");
89
90 demonstrate_error_handling();
91
92 }
93 Err(e) => {
94 println!("Error listing audio devices: {}", e);
95 println!("Common causes:");
96 println!("- No audio devices available");
97 println!("- Permission issues");
98 println!("- Audio system not initialized");
99 println!("- Driver problems");
100 }
101 }
102
103 Ok(())
104}More examples
examples/library_usage.rs (line 17)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 println!("SongRec Library Usage Examples");
6 println!("===============================\n");
7
8 // Example 1: Basic Configuration
9 println!("Example 1: Configuration");
10 println!("------------------------");
11
12 let config = Config::default()
13 .with_quiet_mode(true)
14 .with_network_timeout(15)
15 .with_sensitivity(0.7);
16
17 let songrec = SongRec::new(config);
18 println!("Created SongRec instance with custom settings\n");
19
20 // Example 2: File Recognition and Data Access
21 println!("Example 2: File Recognition");
22 println!("---------------------------");
23
24 let audio_file = "tests/test_audio.wav";
25
26 if Path::new(audio_file).exists() {
27 match songrec.recognize_from_file(audio_file) {
28 Ok(result) => {
29 // Direct access to recognition data
30 println!("Recognition data:");
31 println!(" Artist: {}", result.artist_name);
32 println!(" Song: {}", result.song_name);
33 println!(" Album: {}", result.album_name.as_deref().unwrap_or("Unknown"));
34 println!(" Year: {}", result.release_year.as_deref().unwrap_or("Unknown"));
35 println!(" Genre: {}", result.genre.as_deref().unwrap_or("Unknown"));
36 println!(" Track Key: {}", result.track_key);
37 println!(" Timestamp: {}", result.recognition_timestamp);
38
39 // Example 3: Output Formats
40 println!("\nExample 3: Output Formats");
41 println!("-------------------------");
42
43 // Simple format
44 let simple = RecognitionOutput::format_result(&result, OutputFormat::Simple);
45 println!("Simple: {}", simple.content);
46
47 // JSON format
48 let json = RecognitionOutput::format_result(&result, OutputFormat::Json);
49 println!("JSON length: {} characters", json.content.len());
50
51 // Parse JSON to access fields
52 let parsed: serde_json::Value = serde_json::from_str(&json.content)?;
53 println!("Parsed JSON - Song: {}", parsed["song_name"]);
54
55 // CSV format
56 let csv = RecognitionOutput::format_result(&result, OutputFormat::Csv);
57 println!("CSV: {}", csv.content);
58
59 // Example 4: Raw API Response
60 println!("\nExample 4: Raw API Data");
61 println!("-----------------------");
62
63 // Access raw Shazam API response
64 if let Some(track) = result.raw_response.get("track") {
65 if let Some(images) = track.get("images") {
66 println!("Album art available: {}", images.is_object());
67 }
68 if let Some(hub) = track.get("hub") {
69 println!("Streaming links available: {}", hub.is_object());
70 }
71 }
72
73 }
74 Err(e) => {
75 println!("Recognition failed: {}", e);
76 }
77 }
78 } else {
79 println!("Audio file not found, skipping recognition");
80 }
81
82 // Example 5: Function for Integration
83 println!("\nExample 5: Integration Function");
84 println!("-------------------------------");
85
86 fn recognize_audio(file_path: &str) -> Result<serde_json::Value, Box<dyn std::error::Error>> {
87 let config = Config::default().with_quiet_mode(true);
88 let songrec = SongRec::new(config);
89
90 let result = songrec.recognize_from_file(file_path)?;
91 let json_output = RecognitionOutput::format_result(&result, OutputFormat::Json);
92 let parsed = serde_json::from_str(&json_output.content)?;
93
94 Ok(parsed)
95 }
96
97 if Path::new(audio_file).exists() {
98 match recognize_audio(audio_file) {
99 Ok(data) => {
100 println!("Function returned JSON with {} fields",
101 data.as_object().map(|o| o.len()).unwrap_or(0));
102 }
103 Err(e) => println!("Function error: {}", e)
104 }
105 }
106
107 // Example 6: Configuration Options
108 println!("\nExample 6: Configuration Options");
109 println!("--------------------------------");
110
111 let configs = [
112 ("High sensitivity", Config::default().with_sensitivity(0.9)),
113 ("Low sensitivity", Config::default().with_sensitivity(0.3)),
114 ("Fast timeout", Config::default().with_network_timeout(5)),
115 ("Long timeout", Config::default().with_network_timeout(30)),
116 ("Verbose mode", Config::default().with_quiet_mode(false)),
117 ];
118
119 for (name, config) in configs {
120 let _instance = SongRec::new(config);
121 println!("Created: {}", name);
122 }
123
124 // Example 7: Error Handling
125 println!("\nExample 7: Error Handling");
126 println!("-------------------------");
127
128 fn safe_recognize(file_path: &str) -> Result<(String, String), String> {
129 if !Path::new(file_path).exists() {
130 return Err(format!("File not found: {}", file_path));
131 }
132
133 let config = Config::default().with_quiet_mode(true);
134 let songrec = SongRec::new(config);
135
136 match songrec.recognize_from_file(file_path) {
137 Ok(result) => Ok((result.artist_name, result.song_name)),
138 Err(e) => Err(format!("Recognition error: {}", e)),
139 }
140 }
141
142 // Test with invalid file
143 match safe_recognize("nonexistent.wav") {
144 Ok((artist, song)) => println!("Result: {} - {}", artist, song),
145 Err(e) => println!("Expected error: {}", e),
146 }
147
148 // Example 8: Data Structure Access
149 println!("\nExample 8: Data Structure Access");
150 println!("--------------------------------");
151
152 if Path::new(audio_file).exists() {
153 if let Ok(result) = songrec.recognize_from_file(audio_file) {
154 // Access all available fields
155 println!("Available data fields:");
156 println!(" song_name: {}", result.song_name);
157 println!(" artist_name: {}", result.artist_name);
158 println!(" album_name: {:?}", result.album_name);
159 println!(" track_key: {}", result.track_key);
160 println!(" release_year: {:?}", result.release_year);
161 println!(" genre: {:?}", result.genre);
162 println!(" recognition_timestamp: {}", result.recognition_timestamp);
163 println!(" raw_response keys: {:?}",
164 result.raw_response.as_object().map(|o| o.keys().collect::<Vec<_>>()));
165 }
166 }
167
168 // Example 9: Available Audio Devices
169 println!("\nExample 9: Available Audio Devices");
170 println!("----------------------------------");
171
172 match songrec::audio::AudioRecorder::list_input_devices() {
173 Ok(devices) => {
174 println!("Found {} audio input devices:", devices.len());
175 for (index, device_name) in devices.iter().enumerate() {
176 println!(" Device {}: {}", index, device_name);
177 }
178
179 // Show how to use a specific device for live recognition
180 if !devices.is_empty() {
181 println!("\nExample: Using device for live recognition:");
182 println!("let device_name = \"{}\";", devices[0]);
183 println!("let stream = songrec.start_continuous_recognition_with_device(Some(device_name.to_string()))?;");
184 println!("for result in stream {{");
185 println!(" match result {{");
186 println!(" Ok(recognition) => println!(\"Recognized: {{}} - {{}}\", recognition.artist_name, recognition.song_name),");
187 println!(" Err(e) => eprintln!(\"Recognition error: {{}}\", e),");
188 println!(" }}");
189 println!("}}");
190 }
191 }
192 Err(e) => {
193 println!("Error listing audio devices: {}", e);
194 println!("This may occur if no audio devices are available or there are permission issues.");
195 }
196 }
197
198 // Example 10: Device Selection Function
199 println!("\nExample 10: Device Selection Function");
200 println!("------------------------------------");
201
202 fn select_audio_device(device_name_pattern: &str) -> Result<String, String> {
203 let devices = songrec::audio::AudioRecorder::list_input_devices()
204 .map_err(|e| format!("Failed to list devices: {}", e))?;
205
206 // Find device by name pattern
207 for device in devices {
208 if device.to_lowercase().contains(&device_name_pattern.to_lowercase()) {
209 return Ok(device);
210 }
211 }
212
213 Err(format!("No device found matching pattern: {}", device_name_pattern))
214 }
215
216 // Test device selection
217 match select_audio_device("microphone") {
218 Ok(device) => println!("Found microphone device: {}", device),
219 Err(e) => println!("Device selection result: {}", e),
220 }
221
222 match select_audio_device("voicemeeter") {
223 Ok(device) => println!("Found Voicemeeter device: {}", device),
224 Err(e) => println!("Voicemeeter search result: {}", e),
225 }
226
227 // Example 11: Complete Device Integration Example
228 println!("\nExample 11: Complete Device Integration");
229 println!("--------------------------------------");
230
231 fn get_best_audio_device() -> Result<String, String> {
232 let devices = songrec::audio::AudioRecorder::list_input_devices()
233 .map_err(|e| format!("Cannot access audio devices: {}", e))?;
234
235 if devices.is_empty() {
236 return Err("No audio devices available".to_string());
237 }
238
239 // Priority order for device selection
240 let preferred_patterns = ["voicemeeter", "stereo mix", "microphone", "mic"];
241
242 for pattern in preferred_patterns {
243 for device in &devices {
244 if device.to_lowercase().contains(pattern) {
245 return Ok(device.clone());
246 }
247 }
248 }
249
250 // Fallback to first available device
251 Ok(devices[0].clone())
252 }
253
254 match get_best_audio_device() {
255 Ok(device) => {
256 println!("Selected audio device: {}", device);
257 println!("This device can be used for live recognition:");
258 println!(" songrec.start_continuous_recognition_with_device(Some(\"{}\".to_string()))", device);
259 }
260 Err(e) => println!("Device selection failed: {}", e),
261 }
262
263 println!("\nLibrary demonstration complete.");
264
265 Ok(())
266}Sourcepub fn recognize_from_file(&self, file_path: &str) -> Result<RecognitionResult>
pub fn recognize_from_file(&self, file_path: &str) -> Result<RecognitionResult>
Recognize a song from an audio file
Examples found in repository?
examples/library_usage.rs (line 27)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 println!("SongRec Library Usage Examples");
6 println!("===============================\n");
7
8 // Example 1: Basic Configuration
9 println!("Example 1: Configuration");
10 println!("------------------------");
11
12 let config = Config::default()
13 .with_quiet_mode(true)
14 .with_network_timeout(15)
15 .with_sensitivity(0.7);
16
17 let songrec = SongRec::new(config);
18 println!("Created SongRec instance with custom settings\n");
19
20 // Example 2: File Recognition and Data Access
21 println!("Example 2: File Recognition");
22 println!("---------------------------");
23
24 let audio_file = "tests/test_audio.wav";
25
26 if Path::new(audio_file).exists() {
27 match songrec.recognize_from_file(audio_file) {
28 Ok(result) => {
29 // Direct access to recognition data
30 println!("Recognition data:");
31 println!(" Artist: {}", result.artist_name);
32 println!(" Song: {}", result.song_name);
33 println!(" Album: {}", result.album_name.as_deref().unwrap_or("Unknown"));
34 println!(" Year: {}", result.release_year.as_deref().unwrap_or("Unknown"));
35 println!(" Genre: {}", result.genre.as_deref().unwrap_or("Unknown"));
36 println!(" Track Key: {}", result.track_key);
37 println!(" Timestamp: {}", result.recognition_timestamp);
38
39 // Example 3: Output Formats
40 println!("\nExample 3: Output Formats");
41 println!("-------------------------");
42
43 // Simple format
44 let simple = RecognitionOutput::format_result(&result, OutputFormat::Simple);
45 println!("Simple: {}", simple.content);
46
47 // JSON format
48 let json = RecognitionOutput::format_result(&result, OutputFormat::Json);
49 println!("JSON length: {} characters", json.content.len());
50
51 // Parse JSON to access fields
52 let parsed: serde_json::Value = serde_json::from_str(&json.content)?;
53 println!("Parsed JSON - Song: {}", parsed["song_name"]);
54
55 // CSV format
56 let csv = RecognitionOutput::format_result(&result, OutputFormat::Csv);
57 println!("CSV: {}", csv.content);
58
59 // Example 4: Raw API Response
60 println!("\nExample 4: Raw API Data");
61 println!("-----------------------");
62
63 // Access raw Shazam API response
64 if let Some(track) = result.raw_response.get("track") {
65 if let Some(images) = track.get("images") {
66 println!("Album art available: {}", images.is_object());
67 }
68 if let Some(hub) = track.get("hub") {
69 println!("Streaming links available: {}", hub.is_object());
70 }
71 }
72
73 }
74 Err(e) => {
75 println!("Recognition failed: {}", e);
76 }
77 }
78 } else {
79 println!("Audio file not found, skipping recognition");
80 }
81
82 // Example 5: Function for Integration
83 println!("\nExample 5: Integration Function");
84 println!("-------------------------------");
85
86 fn recognize_audio(file_path: &str) -> Result<serde_json::Value, Box<dyn std::error::Error>> {
87 let config = Config::default().with_quiet_mode(true);
88 let songrec = SongRec::new(config);
89
90 let result = songrec.recognize_from_file(file_path)?;
91 let json_output = RecognitionOutput::format_result(&result, OutputFormat::Json);
92 let parsed = serde_json::from_str(&json_output.content)?;
93
94 Ok(parsed)
95 }
96
97 if Path::new(audio_file).exists() {
98 match recognize_audio(audio_file) {
99 Ok(data) => {
100 println!("Function returned JSON with {} fields",
101 data.as_object().map(|o| o.len()).unwrap_or(0));
102 }
103 Err(e) => println!("Function error: {}", e)
104 }
105 }
106
107 // Example 6: Configuration Options
108 println!("\nExample 6: Configuration Options");
109 println!("--------------------------------");
110
111 let configs = [
112 ("High sensitivity", Config::default().with_sensitivity(0.9)),
113 ("Low sensitivity", Config::default().with_sensitivity(0.3)),
114 ("Fast timeout", Config::default().with_network_timeout(5)),
115 ("Long timeout", Config::default().with_network_timeout(30)),
116 ("Verbose mode", Config::default().with_quiet_mode(false)),
117 ];
118
119 for (name, config) in configs {
120 let _instance = SongRec::new(config);
121 println!("Created: {}", name);
122 }
123
124 // Example 7: Error Handling
125 println!("\nExample 7: Error Handling");
126 println!("-------------------------");
127
128 fn safe_recognize(file_path: &str) -> Result<(String, String), String> {
129 if !Path::new(file_path).exists() {
130 return Err(format!("File not found: {}", file_path));
131 }
132
133 let config = Config::default().with_quiet_mode(true);
134 let songrec = SongRec::new(config);
135
136 match songrec.recognize_from_file(file_path) {
137 Ok(result) => Ok((result.artist_name, result.song_name)),
138 Err(e) => Err(format!("Recognition error: {}", e)),
139 }
140 }
141
142 // Test with invalid file
143 match safe_recognize("nonexistent.wav") {
144 Ok((artist, song)) => println!("Result: {} - {}", artist, song),
145 Err(e) => println!("Expected error: {}", e),
146 }
147
148 // Example 8: Data Structure Access
149 println!("\nExample 8: Data Structure Access");
150 println!("--------------------------------");
151
152 if Path::new(audio_file).exists() {
153 if let Ok(result) = songrec.recognize_from_file(audio_file) {
154 // Access all available fields
155 println!("Available data fields:");
156 println!(" song_name: {}", result.song_name);
157 println!(" artist_name: {}", result.artist_name);
158 println!(" album_name: {:?}", result.album_name);
159 println!(" track_key: {}", result.track_key);
160 println!(" release_year: {:?}", result.release_year);
161 println!(" genre: {:?}", result.genre);
162 println!(" recognition_timestamp: {}", result.recognition_timestamp);
163 println!(" raw_response keys: {:?}",
164 result.raw_response.as_object().map(|o| o.keys().collect::<Vec<_>>()));
165 }
166 }
167
168 // Example 9: Available Audio Devices
169 println!("\nExample 9: Available Audio Devices");
170 println!("----------------------------------");
171
172 match songrec::audio::AudioRecorder::list_input_devices() {
173 Ok(devices) => {
174 println!("Found {} audio input devices:", devices.len());
175 for (index, device_name) in devices.iter().enumerate() {
176 println!(" Device {}: {}", index, device_name);
177 }
178
179 // Show how to use a specific device for live recognition
180 if !devices.is_empty() {
181 println!("\nExample: Using device for live recognition:");
182 println!("let device_name = \"{}\";", devices[0]);
183 println!("let stream = songrec.start_continuous_recognition_with_device(Some(device_name.to_string()))?;");
184 println!("for result in stream {{");
185 println!(" match result {{");
186 println!(" Ok(recognition) => println!(\"Recognized: {{}} - {{}}\", recognition.artist_name, recognition.song_name),");
187 println!(" Err(e) => eprintln!(\"Recognition error: {{}}\", e),");
188 println!(" }}");
189 println!("}}");
190 }
191 }
192 Err(e) => {
193 println!("Error listing audio devices: {}", e);
194 println!("This may occur if no audio devices are available or there are permission issues.");
195 }
196 }
197
198 // Example 10: Device Selection Function
199 println!("\nExample 10: Device Selection Function");
200 println!("------------------------------------");
201
202 fn select_audio_device(device_name_pattern: &str) -> Result<String, String> {
203 let devices = songrec::audio::AudioRecorder::list_input_devices()
204 .map_err(|e| format!("Failed to list devices: {}", e))?;
205
206 // Find device by name pattern
207 for device in devices {
208 if device.to_lowercase().contains(&device_name_pattern.to_lowercase()) {
209 return Ok(device);
210 }
211 }
212
213 Err(format!("No device found matching pattern: {}", device_name_pattern))
214 }
215
216 // Test device selection
217 match select_audio_device("microphone") {
218 Ok(device) => println!("Found microphone device: {}", device),
219 Err(e) => println!("Device selection result: {}", e),
220 }
221
222 match select_audio_device("voicemeeter") {
223 Ok(device) => println!("Found Voicemeeter device: {}", device),
224 Err(e) => println!("Voicemeeter search result: {}", e),
225 }
226
227 // Example 11: Complete Device Integration Example
228 println!("\nExample 11: Complete Device Integration");
229 println!("--------------------------------------");
230
231 fn get_best_audio_device() -> Result<String, String> {
232 let devices = songrec::audio::AudioRecorder::list_input_devices()
233 .map_err(|e| format!("Cannot access audio devices: {}", e))?;
234
235 if devices.is_empty() {
236 return Err("No audio devices available".to_string());
237 }
238
239 // Priority order for device selection
240 let preferred_patterns = ["voicemeeter", "stereo mix", "microphone", "mic"];
241
242 for pattern in preferred_patterns {
243 for device in &devices {
244 if device.to_lowercase().contains(pattern) {
245 return Ok(device.clone());
246 }
247 }
248 }
249
250 // Fallback to first available device
251 Ok(devices[0].clone())
252 }
253
254 match get_best_audio_device() {
255 Ok(device) => {
256 println!("Selected audio device: {}", device);
257 println!("This device can be used for live recognition:");
258 println!(" songrec.start_continuous_recognition_with_device(Some(\"{}\".to_string()))", device);
259 }
260 Err(e) => println!("Device selection failed: {}", e),
261 }
262
263 println!("\nLibrary demonstration complete.");
264
265 Ok(())
266}Sourcepub fn recognize_from_samples(
&self,
samples: &[i16],
sample_rate: u32,
) -> Result<RecognitionResult>
pub fn recognize_from_samples( &self, samples: &[i16], sample_rate: u32, ) -> Result<RecognitionResult>
Recognize a song from raw audio samples
Sourcepub fn start_continuous_recognition(&self) -> Result<RecognitionStream>
pub fn start_continuous_recognition(&self) -> Result<RecognitionStream>
Start continuous recognition from the default audio device
Sourcepub fn start_continuous_recognition_with_device(
&self,
device_name: Option<String>,
) -> Result<RecognitionStream>
pub fn start_continuous_recognition_with_device( &self, device_name: Option<String>, ) -> Result<RecognitionStream>
Start continuous recognition from a specific audio device
Auto Trait Implementations§
impl Freeze for SongRec
impl RefUnwindSafe for SongRec
impl Send for SongRec
impl Sync for SongRec
impl Unpin for SongRec
impl UnwindSafe for SongRec
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more