used black
This commit is contained in:
@@ -40,7 +40,9 @@ class SignatureGenerator:
|
||||
|
||||
# Used when processing input:
|
||||
|
||||
self.ring_buffer_of_samples: RingBuffer[int] = RingBuffer(buffer_size=2048, default_value=0)
|
||||
self.ring_buffer_of_samples: RingBuffer[int] = RingBuffer(
|
||||
buffer_size=2048, default_value=0
|
||||
)
|
||||
|
||||
self.fft_outputs: RingBuffer[List[float]] = RingBuffer(
|
||||
buffer_size=256, default_value=[0.0 * 1025]
|
||||
@@ -91,12 +93,15 @@ class SignatureGenerator:
|
||||
self.next_signature.number_samples / self.next_signature.sample_rate_hz
|
||||
< self.MAX_TIME_SECONDS
|
||||
or sum(
|
||||
len(peaks) for peaks in self.next_signature.frequency_band_to_sound_peaks.values()
|
||||
len(peaks)
|
||||
for peaks in self.next_signature.frequency_band_to_sound_peaks.values()
|
||||
)
|
||||
< self.MAX_PEAKS
|
||||
):
|
||||
self.process_input(
|
||||
self.input_pending_processing[self.samples_processed : self.samples_processed + 128]
|
||||
self.input_pending_processing[
|
||||
self.samples_processed : self.samples_processed + 128
|
||||
]
|
||||
)
|
||||
self.samples_processed += 128
|
||||
|
||||
@@ -107,7 +112,9 @@ class SignatureGenerator:
|
||||
self.next_signature.number_samples = 0
|
||||
self.next_signature.frequency_band_to_sound_peaks = {}
|
||||
|
||||
self.ring_buffer_of_samples: RingBuffer[int] = RingBuffer(buffer_size=2048, default_value=0)
|
||||
self.ring_buffer_of_samples: RingBuffer[int] = RingBuffer(
|
||||
buffer_size=2048, default_value=0
|
||||
)
|
||||
self.fft_outputs: RingBuffer[List[float]] = RingBuffer(
|
||||
buffer_size=256, default_value=[0.0 * 1025]
|
||||
)
|
||||
@@ -124,7 +131,9 @@ class SignatureGenerator:
|
||||
self.do_peak_spreading_and_recognition()
|
||||
|
||||
def do_fft(self, batch_of_128_s16le_mono_samples):
|
||||
type_ring = self.ring_buffer_of_samples.position + len(batch_of_128_s16le_mono_samples)
|
||||
type_ring = self.ring_buffer_of_samples.position + len(
|
||||
batch_of_128_s16le_mono_samples
|
||||
)
|
||||
self.ring_buffer_of_samples[
|
||||
self.ring_buffer_of_samples.position : type_ring
|
||||
] = batch_of_128_s16le_mono_samples
|
||||
@@ -159,10 +168,13 @@ class SignatureGenerator:
|
||||
temporary_array_1[1] = np.roll(temporary_array_1[1], -1)
|
||||
temporary_array_1[2] = np.roll(temporary_array_1[2], -2)
|
||||
|
||||
origin_last_fft_np = np.hstack([temporary_array_1.max(axis=0)[:-3], origin_last_fft[-3:]])
|
||||
origin_last_fft_np = np.hstack(
|
||||
[temporary_array_1.max(axis=0)[:-3], origin_last_fft[-3:]]
|
||||
)
|
||||
|
||||
i1, i2, i3 = [
|
||||
(self.spread_fft_output.position + former_fft_num) % self.spread_fft_output.buffer_size
|
||||
(self.spread_fft_output.position + former_fft_num)
|
||||
% self.spread_fft_output.buffer_size
|
||||
for former_fft_num in [-1, -3, -6]
|
||||
]
|
||||
|
||||
@@ -234,27 +246,38 @@ class SignatureGenerator:
|
||||
fft_number = self.spread_fft_output.num_written - 46
|
||||
|
||||
peak_magnitude = (
|
||||
np.log(max(1 / 64, fft_minus_46[bin_position])) * 1477.3 + 6144
|
||||
np.log(max(1 / 64, fft_minus_46[bin_position])) * 1477.3
|
||||
+ 6144
|
||||
)
|
||||
peak_magnitude_before = (
|
||||
np.log(max(1 / 64, fft_minus_46[bin_position - 1])) * 1477.3 + 6144
|
||||
np.log(max(1 / 64, fft_minus_46[bin_position - 1])) * 1477.3
|
||||
+ 6144
|
||||
)
|
||||
peak_magnitude_after = (
|
||||
np.log(max(1 / 64, fft_minus_46[bin_position + 1])) * 1477.3 + 6144
|
||||
np.log(max(1 / 64, fft_minus_46[bin_position + 1])) * 1477.3
|
||||
+ 6144
|
||||
)
|
||||
|
||||
peak_variation_1 = (
|
||||
peak_magnitude * 2 - peak_magnitude_before - peak_magnitude_after
|
||||
peak_magnitude * 2
|
||||
- peak_magnitude_before
|
||||
- peak_magnitude_after
|
||||
)
|
||||
peak_variation_2 = (
|
||||
(peak_magnitude_after - peak_magnitude_before) * 32 / peak_variation_1
|
||||
(peak_magnitude_after - peak_magnitude_before)
|
||||
* 32
|
||||
/ peak_variation_1
|
||||
)
|
||||
|
||||
corrected_peak_frequency_bin = bin_position * 64 + peak_variation_2
|
||||
corrected_peak_frequency_bin = (
|
||||
bin_position * 64 + peak_variation_2
|
||||
)
|
||||
|
||||
assert peak_variation_1 > 0
|
||||
|
||||
frequency_hz = corrected_peak_frequency_bin * (16000 / 2 / 1024 / 64)
|
||||
frequency_hz = corrected_peak_frequency_bin * (
|
||||
16000 / 2 / 1024 / 64
|
||||
)
|
||||
|
||||
if 250 < frequency_hz < 520:
|
||||
band = FrequencyBand.hz_250_520
|
||||
@@ -267,7 +290,10 @@ class SignatureGenerator:
|
||||
else:
|
||||
continue
|
||||
|
||||
if band not in self.next_signature.frequency_band_to_sound_peaks:
|
||||
if (
|
||||
band
|
||||
not in self.next_signature.frequency_band_to_sound_peaks
|
||||
):
|
||||
self.next_signature.frequency_band_to_sound_peaks[band] = []
|
||||
|
||||
self.next_signature.frequency_band_to_sound_peaks[band].append(
|
||||
|
||||
@@ -27,7 +27,9 @@ class Shazam(Converter, Geo, Request):
|
||||
self.language = language
|
||||
self.endpoint_country = endpoint_country
|
||||
|
||||
async def top_world_tracks(self, limit: int = 200, offset: int = 0) -> Dict[str, Any]:
|
||||
async def top_world_tracks(
|
||||
self, limit: int = 200, offset: int = 0
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Search top world tracks
|
||||
|
||||
@@ -292,7 +294,9 @@ class Shazam(Converter, Geo, Request):
|
||||
headers=self.headers(),
|
||||
)
|
||||
|
||||
async def search_track(self, query: str, limit: int = 10, offset: int = 0) -> Dict[str, Any]:
|
||||
async def search_track(
|
||||
self, query: str, limit: int = 10, offset: int = 0
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Search all tracks by prefix
|
||||
:param query: Track full title or prefix title
|
||||
|
||||
@@ -60,5 +60,7 @@ class Converter:
|
||||
signature_generator.feed_input(audio.get_array_of_samples())
|
||||
signature_generator.MAX_TIME_SECONDS = 12
|
||||
if audio.duration_seconds > 12 * 3:
|
||||
signature_generator.samples_processed += 16000 * (int(audio.duration_seconds / 2) - 6)
|
||||
signature_generator.samples_processed += 16000 * (
|
||||
int(audio.duration_seconds / 2) - 6
|
||||
)
|
||||
return signature_generator
|
||||
|
||||
@@ -47,9 +47,7 @@ class ShazamUrl:
|
||||
)
|
||||
LISTENING_COUNTER = "https://www.shazam.com/services/count/v2/web/track/{}"
|
||||
|
||||
SEARCH_ARTIST_V2 = (
|
||||
"https://www.shazam.com/services/amapi/v1/catalog/{endpoint_country}/artists/{artist_id}"
|
||||
)
|
||||
SEARCH_ARTIST_V2 = "https://www.shazam.com/services/amapi/v1/catalog/{endpoint_country}/artists/{artist_id}"
|
||||
|
||||
|
||||
class Request:
|
||||
|
||||
@@ -80,7 +80,9 @@ class ArtistRelationships(BaseModel):
|
||||
|
||||
|
||||
class ArtistViews(BaseModel):
|
||||
top_music_videos: Optional[TopMusicVideosView] = Field(None, alias="top-music-videos")
|
||||
top_music_videos: Optional[TopMusicVideosView] = Field(
|
||||
None, alias="top-music-videos"
|
||||
)
|
||||
simular_artists: Optional[SimularArtist] = Field(None, alias="similar-artists")
|
||||
latest_release: Optional[LastReleaseModel] = Field(None, alias="latest-release")
|
||||
full_albums: Optional[FullAlbumsModel] = Field(None, alias="full-albums")
|
||||
|
||||
@@ -31,7 +31,7 @@ class RawSignatureHeader(LittleEndianStructure):
|
||||
# field above,
|
||||
# it can be inferred and subtracted so that we obtain the number of samples,
|
||||
# and from the number of samples and sample rate we can obtain the length of the recording
|
||||
("fixed_value", c_uint32)
|
||||
("fixed_value", c_uint32),
|
||||
# Calculated as ((15 << 19) + 0x40000) - 0x7c0000 or 00 00 7c 00 - seems pretty constant,
|
||||
# may be different in the "SigType.STREAMING" mode
|
||||
]
|
||||
@@ -100,7 +100,9 @@ class DecodedMessage:
|
||||
assert crc32(check_summable_data) & 0xFFFFFFFF == header.crc32
|
||||
assert header.magic2 == 0x94119C00
|
||||
|
||||
self.sample_rate_hz = int(SampleRate(header.shifted_sample_rate_id >> 27).name.strip("_"))
|
||||
self.sample_rate_hz = int(
|
||||
SampleRate(header.shifted_sample_rate_id >> 27).name.strip("_")
|
||||
)
|
||||
|
||||
self.number_samples = int(
|
||||
header.number_samples_plus_divided_sample_rate - self.sample_rate_hz * 0.24
|
||||
@@ -145,13 +147,17 @@ class DecodedMessage:
|
||||
|
||||
fft_pass_offset: int = raw_fft_pass[0]
|
||||
if fft_pass_offset == 0xFF:
|
||||
fft_pass_number = int.from_bytes(frequency_peaks_buf.read(4), "little")
|
||||
fft_pass_number = int.from_bytes(
|
||||
frequency_peaks_buf.read(4), "little"
|
||||
)
|
||||
continue
|
||||
else:
|
||||
fft_pass_number += fft_pass_offset
|
||||
|
||||
peak_magnitude = int.from_bytes(frequency_peaks_buf.read(2), "little")
|
||||
corrected_peak_frequency_bin = int.from_bytes(frequency_peaks_buf.read(2), "little")
|
||||
corrected_peak_frequency_bin = int.from_bytes(
|
||||
frequency_peaks_buf.read(2), "little"
|
||||
)
|
||||
|
||||
self.frequency_band_to_sound_peaks[frequency_band].append(
|
||||
FrequencyPeak(
|
||||
@@ -203,7 +209,9 @@ class DecodedMessage:
|
||||
|
||||
header.magic1 = 0xCAFE2580
|
||||
header.magic2 = 0x94119C00
|
||||
header.shifted_sample_rate_id = int(getattr(SampleRate, "_%s" % self.sample_rate_hz)) << 27
|
||||
header.shifted_sample_rate_id = (
|
||||
int(getattr(SampleRate, "_%s" % self.sample_rate_hz)) << 27
|
||||
)
|
||||
header.fixed_value = (15 << 19) + 0x40000
|
||||
header.number_samples_plus_divided_sample_rate = int(
|
||||
self.number_samples + self.sample_rate_hz * 0.24
|
||||
@@ -211,7 +219,9 @@ class DecodedMessage:
|
||||
|
||||
contents_buf = BytesIO()
|
||||
|
||||
for frequency_band, frequency_peaks in sorted(self.frequency_band_to_sound_peaks.items()):
|
||||
for frequency_band, frequency_peaks in sorted(
|
||||
self.frequency_band_to_sound_peaks.items()
|
||||
):
|
||||
peaks_buf = BytesIO()
|
||||
|
||||
fft_pass_number = 0
|
||||
@@ -225,13 +235,19 @@ class DecodedMessage:
|
||||
|
||||
if frequency_peak.fft_pass_number - fft_pass_number >= 255:
|
||||
peaks_buf.write(b"\xff")
|
||||
peaks_buf.write(frequency_peak.fft_pass_number.to_bytes(4, "little"))
|
||||
peaks_buf.write(
|
||||
frequency_peak.fft_pass_number.to_bytes(4, "little")
|
||||
)
|
||||
|
||||
fft_pass_number = frequency_peak.fft_pass_number
|
||||
|
||||
peaks_buf.write(bytes([frequency_peak.fft_pass_number - fft_pass_number]))
|
||||
peaks_buf.write(
|
||||
bytes([frequency_peak.fft_pass_number - fft_pass_number])
|
||||
)
|
||||
peaks_buf.write(frequency_peak.peak_magnitude.to_bytes(2, "little"))
|
||||
peaks_buf.write(frequency_peak.corrected_peak_frequency_bin.to_bytes(2, "little"))
|
||||
peaks_buf.write(
|
||||
frequency_peak.corrected_peak_frequency_bin.to_bytes(2, "little")
|
||||
)
|
||||
|
||||
fft_pass_number = frequency_peak.fft_pass_number
|
||||
|
||||
@@ -245,7 +261,9 @@ class DecodedMessage:
|
||||
header.size_minus_header = len(contents_buf.getvalue()) + 8
|
||||
|
||||
buf = BytesIO()
|
||||
buf.write(header) # We will rewrite it just after in order to include the final CRC-32
|
||||
buf.write(
|
||||
header
|
||||
) # We will rewrite it just after in order to include the final CRC-32
|
||||
|
||||
buf.write((0x40000000).to_bytes(4, "little"))
|
||||
buf.write((len(contents_buf.getvalue()) + 8).to_bytes(4, "little"))
|
||||
|
||||
Reference in New Issue
Block a user