| | import sys |
| | |
| | |
| | import requests |
| | import re |
| | import struct |
| | import numpy as np |
| | from concurrent.futures import ThreadPoolExecutor |
| |
|
| |
|
| | def fill_hann_window(size, periodic=True): |
| | if periodic: |
| | return np.hanning(size + 1)[:-1] |
| | return np.hanning(size) |
| |
|
| |
|
| | def irfft(n_fft, complex_input): |
| | return np.fft.irfft(complex_input, n=n_fft) |
| |
|
| |
|
| | def fold(buffer, n_out, n_win, n_hop, n_pad): |
| | result = np.zeros(n_out) |
| | n_frames = len(buffer) // n_win |
| |
|
| | for i in range(n_frames): |
| | start = i * n_hop |
| | end = start + n_win |
| | result[start:end] += buffer[i * n_win:(i + 1) * n_win] |
| |
|
| | return result[n_pad:-n_pad] if n_pad > 0 else result |
| |
|
| |
|
| | def process_frame(args): |
| | l, n_fft, ST, hann = args |
| | frame = irfft(n_fft, ST[l]) |
| | frame = frame * hann |
| | hann2 = hann * hann |
| | return frame, hann2 |
| |
|
| |
|
| | def embd_to_audio(embd, n_codes, n_embd, n_thread=4): |
| | embd = np.asarray(embd, dtype=np.float32).reshape(n_codes, n_embd) |
| |
|
| | n_fft = 1280 |
| | n_hop = 320 |
| | n_win = 1280 |
| | n_pad = (n_win - n_hop) // 2 |
| | n_out = (n_codes - 1) * n_hop + n_win |
| |
|
| | hann = fill_hann_window(n_fft, True) |
| |
|
| | E = np.zeros((n_embd, n_codes), dtype=np.float32) |
| | for l in range(n_codes): |
| | for k in range(n_embd): |
| | E[k, l] = embd[l, k] |
| |
|
| | half_embd = n_embd // 2 |
| | S = np.zeros((n_codes, half_embd + 1), dtype=np.complex64) |
| |
|
| | for k in range(half_embd): |
| | for l in range(n_codes): |
| | mag = E[k, l] |
| | phi = E[k + half_embd, l] |
| |
|
| | mag = np.clip(np.exp(mag), 0, 1e2) |
| | S[l, k] = mag * np.exp(1j * phi) |
| |
|
| | res = np.zeros(n_codes * n_fft) |
| | hann2_buffer = np.zeros(n_codes * n_fft) |
| |
|
| | with ThreadPoolExecutor(max_workers=n_thread) as executor: |
| | args = [(l, n_fft, S, hann) for l in range(n_codes)] |
| | results = list(executor.map(process_frame, args)) |
| |
|
| | for l, (frame, hann2) in enumerate(results): |
| | res[l*n_fft:(l+1)*n_fft] = frame |
| | hann2_buffer[l*n_fft:(l+1)*n_fft] = hann2 |
| |
|
| | audio = fold(res, n_out, n_win, n_hop, n_pad) |
| | env = fold(hann2_buffer, n_out, n_win, n_hop, n_pad) |
| |
|
| | mask = env > 1e-10 |
| | audio[mask] /= env[mask] |
| |
|
| | return audio |
| |
|
| |
|
| | def save_wav(filename, audio_data, sample_rate): |
| | num_channels = 1 |
| | bits_per_sample = 16 |
| | bytes_per_sample = bits_per_sample // 8 |
| | data_size = len(audio_data) * bytes_per_sample |
| | byte_rate = sample_rate * num_channels * bytes_per_sample |
| | block_align = num_channels * bytes_per_sample |
| | chunk_size = 36 + data_size |
| |
|
| | header = struct.pack( |
| | '<4sI4s4sIHHIIHH4sI', |
| | b'RIFF', |
| | chunk_size, |
| | b'WAVE', |
| | b'fmt ', |
| | 16, |
| | 1, |
| | num_channels, |
| | sample_rate, |
| | byte_rate, |
| | block_align, |
| | bits_per_sample, |
| | b'data', |
| | data_size |
| | ) |
| |
|
| | audio_data = np.clip(audio_data * 32767, -32768, 32767) |
| | pcm_data = audio_data.astype(np.int16) |
| |
|
| | with open(filename, 'wb') as f: |
| | f.write(header) |
| | f.write(pcm_data.tobytes()) |
| |
|
| |
|
| | def process_text(text: str): |
| | text = re.sub(r'\d+(\.\d+)?', lambda x: x.group(), text.lower()) |
| | text = re.sub(r'[-_/,\.\\]', ' ', text) |
| | text = re.sub(r'[^a-z\s]', '', text) |
| | text = re.sub(r'\s+', ' ', text).strip() |
| | return text.split() |
| |
|
| | |
| | |
| |
|
| | if len(sys.argv) <= 3: |
| | print("usage: python tts-outetts.py http://server-llm:port http://server-dec:port \"text\"") |
| | exit(1) |
| |
|
| | host_llm = sys.argv[1] |
| | host_dec = sys.argv[2] |
| | text = sys.argv[3] |
| |
|
| | prefix = """<|im_start|> |
| | <|text_start|>the<|text_sep|>overall<|text_sep|>package<|text_sep|>from<|text_sep|>just<|text_sep|>two<|text_sep|>people<|text_sep|>is<|text_sep|>pretty<|text_sep|>remarkable<|text_sep|>sure<|text_sep|>i<|text_sep|>have<|text_sep|>some<|text_sep|>critiques<|text_sep|>about<|text_sep|>some<|text_sep|>of<|text_sep|>the<|text_sep|>gameplay<|text_sep|>aspects<|text_sep|>but<|text_sep|>its<|text_sep|>still<|text_sep|>really<|text_sep|>enjoyable<|text_sep|>and<|text_sep|>it<|text_sep|>looks<|text_sep|>lovely<|text_sep|>""" |
| |
|
| | words = process_text(text) |
| | words = "<|text_sep|>".join([i.strip() for i in words]) |
| | words += "<|text_end|>\n" |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | suffix = [ 151667, 198, 1782, 155780, 151669, 151929, 152412, 152308, 152585, 152460, 153375, 151670, 198, 74455, |
| | 155808, 151669, 151799, 151873, 151863, 152446, 152372, 152204, 152728, 152229, 152470, 151970, 153413, |
| | 152419, 153334, 153289, 153374, 153199, 152040, 153260, 152721, 152680, 153297, 152419, 153248, 152400, |
| | 152691, 153368, 153437, 151670, 198, 1722, 155828, 151669, 152607, 152256, 152991, 152299, 152688, 153163, |
| | 153016, 152789, 153198, 152712, 151911, 153107, 152623, 152170, 152395, 152852, 152207, 152461, 153321, |
| | 153309, 151750, 152137, 153340, 152573, 152267, 153347, 151789, 152681, 153339, 151992, 152512, 151751, |
| | 152179, 153434, 153180, 152900, 153440, 152474, 153122, 153129, 151904, 152311, 151670, 198, 1499, 155791, |
| | 151669, 152276, 152454, 153354, 152544, 153204, 153272, 152708, 153433, 152319, 153226, 153043, 152325, |
| | 153267, 152622, 151670, 198, 4250, 155797, 151669, 153454, 153342, 151989, 152458, 153420, 152303, 152271, |
| | 152827, 153036, 153196, 151708, 153263, 152561, 153207, 152213, 152112, 153204, 151722, 152542, 151670, 198, |
| | 19789, 155796, 151669, 153353, 153182, 152345, 152471, 152477, 153014, 152002, 152191, 151734, 152312, 152810, |
| | 152237, 153224, 153169, 153224, 152244, 153387, 153404, 151670, 198, 16069, 155811, 151669, 152265, 151946, |
| | 151808, 152412, 152363, 152305, 153156, 152733, 152810, 153157, 152016, 152100, 152069, 153234, 152317, |
| | 152589, 152707, 153121, 153341, 152159, 152114, 153156, 153001, 153504, 153376, 152272, 152433, 152325, |
| | 151941, 151670, 198, 285, 155788, 151669, 152238, 152255, 153427, 152318, 153009, 152381, 152474, 152680, |
| | 152157, 153255, 152324, 151682, 151670, 198, 32955, 155804, 151669, 153490, 153419, 152364, 152405, 152682, |
| | 152206, 152078, 153369, 152725, 153193, 153027, 152946, 152488, 153070, 151883, 152890, 152489, 153144, |
| | 153375, 152358, 151685, 152494, 152117, 152740, 151670, 198, 37448, 480, 155840, 151669, 151902, 152720, |
| | 153377, 152027, 152378, 152821, 153207, 153459, 153028, 153068, 152507, 153255, 152158, 152921, 151958, |
| | 152609, 152748, 152822, 152286, 151714, 152730, 152377, 152353, 152470, 152606, 152162, 152186, 153071, |
| | 152244, 153118, 153375, 153018, 152712, 153098, 152976, 152336, 151843, 153202, 152297, 151736, 153380, |
| | 153502, 152702, 152115, 153181, 152735, 153277, 153457, 152393, 153112, 152595, 151670, 198, 19098, 155808, |
| | 151669, 152464, 153452, 152595, 153312, 151937, 151933, 153197, 152239, 153163, 152922, 153402, 152034, |
| | 152591, 153438, 152215, 151673, 152005, 151785, 152642, 151924, 153278, 151805, 151974, 153482, 152718, |
| | 152862, 153347, 151670, 198, 72, 155780, 151669, 151795, 152111, 152746, 152377, 153471, 152309, 151670, 198, |
| | 19016, 155788, 151669, 153181, 152271, 152190, 152842, 152224, 152701, 152939, 152536, 152091, 151815, 152733, |
| | 151672, 151670, 198, 14689, 155788, 151669, 152291, 152072, 152942, 151734, 153042, 153504, 152589, 153333, |
| | 151839, 151941, 153038, 153180, 151670, 198, 36996, 8303, 155832, 151669, 152231, 152256, 152835, 152801, |
| | 152985, 153400, 152393, 152818, 152765, 152249, 152600, 151699, 152302, 152752, 153018, 153009, 151992, |
| | 153054, 152847, 153354, 153228, 152662, 153355, 152532, 153393, 151782, 152458, 152048, 152757, 152428, |
| | 153195, 151906, 153006, 153178, 153250, 152331, 152284, 152780, 153138, 153319, 151980, 153142, 152418, |
| | 152228, 152733, 151670, 198, 9096, 155801, 151669, 151698, 153321, 152217, 153039, 152935, 153400, 152122, |
| | 152531, 153106, 152169, 152892, 152957, 151851, 152427, 152826, 152451, 151851, 152901, 152885, 152594, |
| | 153446, 153080, 151670, 198, 14689, 155795, 151669, 152658, 151700, 153321, 152450, 152530, 153191, 151673, |
| | 151690, 151698, 152714, 152846, 152981, 153171, 153384, 153364, 153188, 153246, 151670, 198, 1055, 155779, |
| | 151669, 151869, 152388, 152711, 153334, 151736, 151670, 198, 1782, 155780, 151669, 153483, 153240, 152241, |
| | 152558, 152697, 153046, 151670, 198, 5804, 1363, 155820, 151669, 152941, 152764, 152605, 153034, 153434, |
| | 153372, 153347, 151887, 152453, 152758, 152133, 152510, 152694, 152431, 152321, 153088, 152676, 152223, |
| | 152581, 152459, 152015, 152502, 153063, 152712, 153294, 153451, 153032, 152903, 152859, 152989, 151748, |
| | 152669, 152661, 152650, 152409, 151861, 151670, 198, 300, 7973, 155828, 151669, 153095, 152469, 152988, |
| | 152894, 151819, 152391, 153019, 152058, 153062, 153230, 151826, 152112, 152306, 152264, 152769, 153390, |
| | 152384, 152435, 152790, 153393, 152983, 152540, 152252, 152034, 153107, 152540, 151919, 151893, 152558, |
| | 152817, 152946, 152956, 152129, 152715, 153131, 153490, 151734, 152271, 152707, 151734, 153321, 152450, |
| | 151670, 198, 8088, 155792, 151669, 152452, 153497, 153353, 152679, 152533, 152382, 152374, 152611, 153341, |
| | 153163, 152285, 153411, 152495, 153141, 152320, 151670, 198, 1199, 155781, 151669, 151764, 152360, 153295, |
| | 152634, 153342, 152199, 152271, 151670, 198, 43366, 155799, 151669, 152308, 151682, 152889, 152016, 152385, |
| | 152629, 152495, 151826, 153321, 152958, 152180, 151886, 153432, 152922, 152128, 153024, 153040, 152593, |
| | 152287, 151677, 151670, 198, 53660, 155808, 151669, 151727, 152092, 152680, 153331, 151699, 152316, 152938, |
| | 152289, 152433, 153384, 151781, 153137, 153259, 152175, 153213, 152291, 151869, 152691, 152489, 151941, |
| | 152049, 152034, 153053, 152179, 153160, 151676, 153367, 151670, 198, 268, 4123, 480, 155821, 151669, 152350, |
| | 152173, 152536, 151991, 151960, 153144, 153013, 152358, 152234, 153135, 152291, 153235, 152143, 152583, |
| | 152402, 153483, 152678, 152192, 152533, 152946, 151797, 153103, 152310, 152293, 151825, 152548, 153442, |
| | 152109, 152659, 153325, 152781, 152570, 152957, 151752, 152265, 153381, 152515, 151670, 198, 437, 155787, |
| | 151669, 152957, 152659, 151975, 152709, 152402, 152836, 152174, 151792, 153409, 153327, 152990, 151670, 198, |
| | 275, 155781, 151669, 152520, 153038, 152067, 153273, 153185, 152265, 152974, 151670, 198, 94273, 155799, |
| | 151669, 152953, 152938, 153427, 152244, 151920, 153423, 152929, 152367, 153052, 152129, 152331, 152257, |
| | 152987, 152777, 153448, 152408, 151696, 152408, 152326, 152699, 151670, 198, 385, 16239, 155828, 151669, |
| | 152306, 152268, 153438, 153228, 152978, 152957, 153153, 153393, 152795, 152110, 152918, 152923, 152467, |
| | 152331, 153053, 153330, 151889, 153444, 152234, 152624, 151779, 152801, 152784, 152139, 152222, 152751, |
| | 152512, 153287, 153141, 153052, 151840, 152589, 152508, 153499, 152109, 152255, 151739, 152267, 152759, |
| | 153318, 153165, 153349, 151670, ] |
| |
|
| | response = requests.post( |
| | host_llm + "/completion", |
| | json={ |
| | "prompt": [prefix + words, *suffix], |
| | "n_predict": 1024, |
| | "cache_prompt": True, |
| | "return_tokens": True, |
| | "samplers": ["top_k"], |
| | "top_k": 16, |
| | "seed": 1003, |
| | } |
| | ) |
| |
|
| | response_json = response.json() |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | codes = response_json["tokens"] |
| |
|
| | codes = [t - 151672 for t in codes if t >= 151672 and t <= 155772] |
| |
|
| | response = requests.post( |
| | host_dec + "/embeddings", |
| | json={ |
| | "input": [*codes], |
| | } |
| | ) |
| |
|
| | response_json = response.json() |
| |
|
| | |
| |
|
| | |
| | embd = response_json[0]["embedding"] |
| |
|
| | n_codes = len(embd) |
| | n_embd = len(embd[0]) |
| |
|
| | print('spectrogram generated: n_codes: %d, n_embd: %d' % (n_codes, n_embd)) |
| |
|
| | |
| | print('converting to audio ...') |
| | audio = embd_to_audio(embd, n_codes, n_embd) |
| | print('audio generated: %d samples' % len(audio)) |
| |
|
| | filename = "output.wav" |
| | sample_rate = 24000 |
| |
|
| | |
| | audio[:24000 // 4] = 0.0 |
| |
|
| | save_wav(filename, audio, sample_rate) |
| | print('audio written to file "%s"' % filename) |
| |
|