Hugo Flores Garcia commited on
Commit
7a44f56
·
1 Parent(s): 797f98f

quality of life UI improvements

Browse files
Files changed (7) hide show
  1. .gitignore +3 -1
  2. README.md +2 -2
  3. app.py +144 -67
  4. scratch/rms_mask.txt +3 -3
  5. setup.py +1 -1
  6. unloop/client.py +1 -153
  7. vampnet/interface.py +1 -1
.gitignore CHANGED
@@ -201,4 +201,6 @@ lib/
201
  _outputs/
202
  debug.txt
203
 
204
- scratch/*
 
 
 
201
  _outputs/
202
  debug.txt
203
 
204
+ scratch/*
205
+
206
+ .gradio
README.md CHANGED
@@ -4,8 +4,8 @@ emoji: 🥗
4
  colorFrom: yellow
5
  colorTo: green
6
  sdk: gradio
7
- sdk_version: 4.43.0
8
- python_version: 3.9.17
9
  app_file: app.py
10
  pinned: false
11
  license: cc-by-nc-4.0
 
4
  colorFrom: yellow
5
  colorTo: green
6
  sdk: gradio
7
+ sdk_version: 5.23.2
8
+ python_version: 3.11
9
  app_file: app.py
10
  pinned: false
11
  license: cc-by-nc-4.0
app.py CHANGED
@@ -107,11 +107,30 @@ def new_vampnet_mask(self,
107
  mask = mask.to(self.device)
108
  return mask[:, :, :]
109
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  @spaces.GPU
111
- def _vamp(
112
  seed, input_audio, model_choice,
113
  pitch_shift_amt, periodic_p,
114
- n_mask_codebooks, periodic_w, onset_mask_width,
115
  dropout, sampletemp, typical_filtering,
116
  typical_mass, typical_min_tokens, top_p,
117
  sample_cutoff, stretch_factor, sampling_steps, beat_mask_ms, num_feedback_steps, api=False
@@ -124,7 +143,6 @@ def _vamp(
124
  print(f"pitch_shift_amt: {pitch_shift_amt}")
125
  print(f"periodic_p: {periodic_p}")
126
  print(f"n_mask_codebooks: {n_mask_codebooks}")
127
- print(f"periodic_w: {periodic_w}")
128
  print(f"onset_mask_width: {onset_mask_width}")
129
  print(f"dropout: {dropout}")
130
  print(f"sampletemp: {sampletemp}")
@@ -149,6 +167,8 @@ def _vamp(
149
  _seed = int(torch.randint(0, 2**32, (1,)).item())
150
  at.util.seed(_seed)
151
 
 
 
152
  sr, input_audio = input_audio
153
  input_audio = input_audio / np.iinfo(input_audio.dtype).max
154
 
@@ -180,7 +200,6 @@ def _vamp(
180
  codes,
181
  sig=sig,
182
  periodic_prompt=periodic_p,
183
- periodic_prompt_width=periodic_w,
184
  onset_mask_width=onset_mask_width,
185
  _dropout=dropout,
186
  upper_codebook_mask=n_mask_codebooks,
@@ -188,7 +207,7 @@ def _vamp(
188
  if beat_mask_ms > 0:
189
  # bm = pmask.mask_or(
190
  # pmask.periodic_mask(
191
- # codes, periodic_p, periodic_w, random_roll=False
192
  # ),
193
  # )
194
  mask = pmask.mask_and(
@@ -208,7 +227,7 @@ def _vamp(
208
  else:
209
  top_p = None
210
 
211
- codes, mask = interface.vamp(
212
  codes, mask,
213
  batch_size=2,
214
  feedback_steps=num_feedback_steps,
@@ -228,36 +247,64 @@ def _vamp(
228
  sig = interface.decode(codes)
229
  sig = sig.normalize(loudness)
230
 
231
- return to_output(sig[0]), to_output(sig[1])
232
-
233
- def vamp(data):
234
- return _vamp(
235
- seed=data[seed],
236
- input_audio=data[input_audio],
237
- model_choice=data[model_choice],
238
- pitch_shift_amt=data[pitch_shift_amt],
239
- periodic_p=data[periodic_p],
240
- n_mask_codebooks=data[n_mask_codebooks],
241
- periodic_w=data[periodic_w],
242
- onset_mask_width=data[onset_mask_width],
243
- dropout=data[dropout],
244
- sampletemp=data[sampletemp],
245
- typical_filtering=data[typical_filtering],
246
- typical_mass=data[typical_mass],
247
- typical_min_tokens=data[typical_min_tokens],
248
- top_p=data[top_p],
249
- sample_cutoff=data[sample_cutoff],
250
- stretch_factor=data[stretch_factor],
251
- sampling_steps=data[sampling_steps],
252
- beat_mask_ms=data[beat_mask_ms],
253
- num_feedback_steps=data[num_feedback_steps],
254
- api=False,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  )
256
 
257
 
258
  def api_vamp(input_audio,
259
  sampletemp, top_p,
260
- periodic_p, periodic_w,
261
  dropout,
262
  stretch_factor,
263
  onset_mask_width,
@@ -271,14 +318,13 @@ def api_vamp(input_audio,
271
  sample_cutoff,
272
  sampling_steps,
273
  beat_mask_ms, num_feedback_steps):
274
- return _vamp(
275
  seed=seed,
276
  input_audio=input_audio,
277
  model_choice=model_choice,
278
  pitch_shift_amt=pitch_shift_amt,
279
  periodic_p=periodic_p,
280
  n_mask_codebooks=n_mask_codebooks,
281
- periodic_w=periodic_w,
282
  onset_mask_width=onset_mask_width,
283
  dropout=dropout,
284
  sampletemp=sampletemp,
@@ -294,6 +340,29 @@ def api_vamp(input_audio,
294
  api=True,
295
  )
296
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
  with gr.Blocks() as demo:
298
  with gr.Row():
299
  with gr.Column():
@@ -309,11 +378,11 @@ with gr.Blocks() as demo:
309
  type="numpy",
310
  )
311
 
312
- audio_mask = gr.Audio(
313
- label="audio mask (listen to this to hear the mask hints)",
314
- interactive=False,
315
- type="numpy",
316
- )
317
 
318
  # connect widgets
319
  load_example_audio_button.click(
@@ -341,13 +410,22 @@ with gr.Blocks() as demo:
341
  )
342
 
343
  onset_mask_width = gr.Slider(
344
- label="onset mask width (multiplies with the periodic mask, 1 step ~= 10milliseconds) ",
345
  minimum=0,
346
  maximum=100,
347
  step=1,
348
  value=0, visible=True
349
  )
350
 
 
 
 
 
 
 
 
 
 
351
  n_mask_codebooks = gr.Slider(
352
  label="compression prompt ",
353
  value=3,
@@ -355,7 +433,15 @@ with gr.Blocks() as demo:
355
  maximum=14,
356
  step=1,
357
  )
358
-
 
 
 
 
 
 
 
 
359
  maskimg = gr.Image(
360
  label="mask image",
361
  interactive=False,
@@ -379,18 +465,7 @@ with gr.Blocks() as demo:
379
  value=1,
380
  )
381
 
382
- periodic_w = gr.Slider(
383
- label="periodic prompt width (steps, 1 step ~= 10milliseconds)",
384
- minimum=1,
385
- maximum=20,
386
- step=1,
387
- value=1,
388
- )
389
 
390
- beat_mask_ms = gr.Number(
391
- label="beat mask width (milliseconds)",
392
- value=0,
393
- )
394
 
395
 
396
  with gr.Accordion("sampling settings", open=False):
@@ -448,17 +523,6 @@ with gr.Blocks() as demo:
448
  )
449
 
450
 
451
-
452
-
453
- dropout = gr.Slider(
454
- label="mask dropout",
455
- minimum=0.0,
456
- maximum=1.0,
457
- step=0.01,
458
- value=0.0
459
- )
460
-
461
-
462
  seed = gr.Number(
463
  label="seed (0 for random)",
464
  value=0,
@@ -499,11 +563,24 @@ with gr.Blocks() as demo:
499
  # download = gr.File(type="filepath", label="download outputs")
500
 
501
 
502
- _inputs = {
 
 
 
 
 
 
 
 
 
 
 
 
 
503
  input_audio,
504
  sampletemp,
505
  top_p,
506
- periodic_p, periodic_w,
507
  dropout,
508
  stretch_factor,
509
  onset_mask_width,
@@ -518,13 +595,13 @@ with gr.Blocks() as demo:
518
  sampling_steps,
519
  beat_mask_ms,
520
  num_feedback_steps
521
- }
522
 
523
  # connect widgets
524
  vamp_button.click(
525
  fn=vamp,
526
  inputs=_inputs,
527
- outputs=[audio_outs[0], audio_outs[1]],
528
  )
529
 
530
  api_vamp_button = gr.Button("api vamp", visible=True)
@@ -532,7 +609,7 @@ with gr.Blocks() as demo:
532
  fn=api_vamp,
533
  inputs=[input_audio,
534
  sampletemp, top_p,
535
- periodic_p, periodic_w,
536
  dropout,
537
  stretch_factor,
538
  onset_mask_width,
 
107
  mask = mask.to(self.device)
108
  return mask[:, :, :]
109
 
110
+ def mask_preview(periodic_p, n_mask_codebooks, onset_mask_width, dropout):
111
+ # make a mask preview
112
+ codes = torch.zeros((1, 14, 80)).to(device)
113
+ mask = interface.build_mask(
114
+ codes,
115
+ periodic_prompt=periodic_p,
116
+ # onset_mask_width=onset_mask_width,
117
+ _dropout=dropout,
118
+ upper_codebook_mask=n_mask_codebooks,
119
+ )
120
+ # mask = mask.cpu().numpy()
121
+ import matplotlib.pyplot as plt
122
+ plt.clf()
123
+ interface.visualize_codes(mask)
124
+ plt.title("mask preview")
125
+ plt.savefig("scratch/mask-prev.png")
126
+ return "scratch/mask-prev.png"
127
+
128
+
129
  @spaces.GPU
130
+ def _vamp_internal(
131
  seed, input_audio, model_choice,
132
  pitch_shift_amt, periodic_p,
133
+ n_mask_codebooks, onset_mask_width,
134
  dropout, sampletemp, typical_filtering,
135
  typical_mass, typical_min_tokens, top_p,
136
  sample_cutoff, stretch_factor, sampling_steps, beat_mask_ms, num_feedback_steps, api=False
 
143
  print(f"pitch_shift_amt: {pitch_shift_amt}")
144
  print(f"periodic_p: {periodic_p}")
145
  print(f"n_mask_codebooks: {n_mask_codebooks}")
 
146
  print(f"onset_mask_width: {onset_mask_width}")
147
  print(f"dropout: {dropout}")
148
  print(f"sampletemp: {sampletemp}")
 
167
  _seed = int(torch.randint(0, 2**32, (1,)).item())
168
  at.util.seed(_seed)
169
 
170
+ if input_audio is None:
171
+ raise gr.Error("no input audio received!")
172
  sr, input_audio = input_audio
173
  input_audio = input_audio / np.iinfo(input_audio.dtype).max
174
 
 
200
  codes,
201
  sig=sig,
202
  periodic_prompt=periodic_p,
 
203
  onset_mask_width=onset_mask_width,
204
  _dropout=dropout,
205
  upper_codebook_mask=n_mask_codebooks,
 
207
  if beat_mask_ms > 0:
208
  # bm = pmask.mask_or(
209
  # pmask.periodic_mask(
210
+ # codes, periodic_p, random_roll=False
211
  # ),
212
  # )
213
  mask = pmask.mask_and(
 
227
  else:
228
  top_p = None
229
 
230
+ codes, mask_z = interface.vamp(
231
  codes, mask,
232
  batch_size=2,
233
  feedback_steps=num_feedback_steps,
 
247
  sig = interface.decode(codes)
248
  sig = sig.normalize(loudness)
249
 
250
+ import matplotlib.pyplot as plt
251
+ plt.clf()
252
+ # plt.imshow(mask_z[0].cpu().numpy(), aspect='auto
253
+ interface.visualize_codes(mask)
254
+ plt.title("actual mask")
255
+ plt.savefig("scratch/mask.png")
256
+ plt.clf()
257
+
258
+ if not api:
259
+ return to_output(sig[0]), to_output(sig[1]), "scratch/mask.png"
260
+ else:
261
+ return to_output(sig[0]), to_output(sig[1])
262
+
263
+
264
+ def vamp(input_audio,
265
+ sampletemp,
266
+ top_p,
267
+ periodic_p,
268
+ dropout,
269
+ stretch_factor,
270
+ onset_mask_width,
271
+ typical_filtering,
272
+ typical_mass,
273
+ typical_min_tokens,
274
+ seed,
275
+ model_choice,
276
+ n_mask_codebooks,
277
+ pitch_shift_amt,
278
+ sample_cutoff,
279
+ sampling_steps,
280
+ beat_mask_ms,
281
+ num_feedback_steps):
282
+ return _vamp_internal(
283
+ seed=seed,
284
+ input_audio=input_audio,
285
+ model_choice=model_choice,
286
+ pitch_shift_amt=pitch_shift_amt,
287
+ periodic_p=periodic_p,
288
+ n_mask_codebooks=n_mask_codebooks,
289
+ onset_mask_width=onset_mask_width,
290
+ dropout=dropout,
291
+ sampletemp=sampletemp,
292
+ typical_filtering=typical_filtering,
293
+ typical_mass=typical_mass,
294
+ typical_min_tokens=typical_min_tokens,
295
+ top_p=top_p,
296
+ sample_cutoff=sample_cutoff,
297
+ stretch_factor=stretch_factor,
298
+ sampling_steps=sampling_steps,
299
+ beat_mask_ms=beat_mask_ms,
300
+ num_feedback_steps=num_feedback_steps,
301
+ api=False,
302
  )
303
 
304
 
305
  def api_vamp(input_audio,
306
  sampletemp, top_p,
307
+ periodic_p,
308
  dropout,
309
  stretch_factor,
310
  onset_mask_width,
 
318
  sample_cutoff,
319
  sampling_steps,
320
  beat_mask_ms, num_feedback_steps):
321
+ return _vamp_internal(
322
  seed=seed,
323
  input_audio=input_audio,
324
  model_choice=model_choice,
325
  pitch_shift_amt=pitch_shift_amt,
326
  periodic_p=periodic_p,
327
  n_mask_codebooks=n_mask_codebooks,
 
328
  onset_mask_width=onset_mask_width,
329
  dropout=dropout,
330
  sampletemp=sampletemp,
 
340
  api=True,
341
  )
342
 
343
+ def harp_vamp(input_audio, sampletemp, periodic_p, dropout, n_mask_codebooks, model_choice, beat_mask_ms):
344
+ return _vamp_internal(
345
+ seed=0,
346
+ input_audio=input_audio,
347
+ model_choice=model_choice,
348
+ pitch_shift_amt=0,
349
+ periodic_p=periodic_p,
350
+ n_mask_codebooks=n_mask_codebooks,
351
+ onset_mask_width=0,
352
+ dropout=dropout,
353
+ sampletemp=sampletemp,
354
+ typical_filtering=False,
355
+ typical_mass=0.15,
356
+ typical_min_tokens=1,
357
+ top_p=None,
358
+ sample_cutoff=1.0,
359
+ stretch_factor=1.0,
360
+ sampling_steps=36,
361
+ beat_mask_ms=beat_mask_ms,
362
+ num_feedback_steps=1
363
+ )
364
+
365
+
366
  with gr.Blocks() as demo:
367
  with gr.Row():
368
  with gr.Column():
 
378
  type="numpy",
379
  )
380
 
381
+ # audio_mask = gr.Audio(
382
+ # label="audio mask (listen to this to hear the mask hints)",
383
+ # interactive=False,
384
+ # type="numpy",
385
+ # )
386
 
387
  # connect widgets
388
  load_example_audio_button.click(
 
410
  )
411
 
412
  onset_mask_width = gr.Slider(
413
+ label="onset mask width (multiplies with the periodic mask, 1 step ~= 10milliseconds) does not affect mask preview",
414
  minimum=0,
415
  maximum=100,
416
  step=1,
417
  value=0, visible=True
418
  )
419
 
420
+ beat_mask_ms = gr.Slider(
421
+ label="beat mask width (milliseconds) does not affect mask preview",
422
+ minimum=1,
423
+ maximum=200,
424
+ step=1,
425
+ value=0,
426
+ visible=True
427
+ )
428
+
429
  n_mask_codebooks = gr.Slider(
430
  label="compression prompt ",
431
  value=3,
 
433
  maximum=14,
434
  step=1,
435
  )
436
+
437
+ dropout = gr.Slider(
438
+ label="mask dropout",
439
+ minimum=0.0,
440
+ maximum=1.0,
441
+ step=0.01,
442
+ value=0.0
443
+ )
444
+
445
  maskimg = gr.Image(
446
  label="mask image",
447
  interactive=False,
 
465
  value=1,
466
  )
467
 
 
 
 
 
 
 
 
468
 
 
 
 
 
469
 
470
 
471
  with gr.Accordion("sampling settings", open=False):
 
523
  )
524
 
525
 
 
 
 
 
 
 
 
 
 
 
 
526
  seed = gr.Number(
527
  label="seed (0 for random)",
528
  value=0,
 
563
  # download = gr.File(type="filepath", label="download outputs")
564
 
565
 
566
+ # mask preview change
567
+ for widget in (
568
+ periodic_p, n_mask_codebooks,
569
+ onset_mask_width, dropout
570
+ ):
571
+ widget.change(
572
+ fn=mask_preview,
573
+ inputs=[periodic_p, n_mask_codebooks,
574
+ onset_mask_width, dropout],
575
+ outputs=[maskimg]
576
+ )
577
+
578
+
579
+ _inputs = [
580
  input_audio,
581
  sampletemp,
582
  top_p,
583
+ periodic_p,
584
  dropout,
585
  stretch_factor,
586
  onset_mask_width,
 
595
  sampling_steps,
596
  beat_mask_ms,
597
  num_feedback_steps
598
+ ]
599
 
600
  # connect widgets
601
  vamp_button.click(
602
  fn=vamp,
603
  inputs=_inputs,
604
+ outputs=[audio_outs[0], audio_outs[1], maskimg],
605
  )
606
 
607
  api_vamp_button = gr.Button("api vamp", visible=True)
 
609
  fn=api_vamp,
610
  inputs=[input_audio,
611
  sampletemp, top_p,
612
+ periodic_p,
613
  dropout,
614
  stretch_factor,
615
  onset_mask_width,
scratch/rms_mask.txt CHANGED
@@ -1,6 +1,6 @@
1
- 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1
2
- 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
3
- 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
4
  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
5
  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
6
  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 
1
+ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1
2
+ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1
3
+ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1
4
  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
5
  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
6
  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
setup.py CHANGED
@@ -21,7 +21,7 @@ setup(
21
  long_description=long_description,
22
  long_description_content_type="text/markdown",
23
  author="Hugo Flores García, Prem Seetharaman",
24
- author_email="hfgacrcia@descript.com",
25
  url="https://github.com/hugofloresgarcia/vampnet",
26
  license="MIT",
27
  packages=find_packages(),
 
21
  long_description=long_description,
22
  long_description_content_type="text/markdown",
23
  author="Hugo Flores García, Prem Seetharaman",
24
+ author_email="hugggofloresgarcia@gmail.com",
25
  url="https://github.com/hugofloresgarcia/vampnet",
26
  license="MIT",
27
  packages=find_packages(),
unloop/client.py CHANGED
@@ -89,8 +89,6 @@ class GradioOSCClient:
89
  ip: str,
90
  s_port: int, r_port: int,
91
  vampnet_url: str = None, # url for vampnet
92
- s2s_urls: str = None, # urls for sketch2sound (multiple for parallel processing)
93
- s2s_vim_url: str = None, # for sketch2sound old version (good at vocal imitations, (vims))
94
  ):
95
  self.osc_manager = OSCManager(
96
  ip=ip, s_port=s_port, r_port=r_port,
@@ -100,13 +98,6 @@ class GradioOSCClient:
100
  self.clients = {}
101
  if vampnet_url is not None:
102
  self.clients["vampnet"] = Client(src=vampnet_url, download_files=DOWNLOADS_DIR)
103
- if s2s_urls is not None:
104
- # self.clients["s2s"] = Client(src=s2s_url, download_files=DOWNLOADS_DIR)
105
- for i, s2s_url in enumerate(s2s_urls):
106
- if s2s_url is not None:
107
- self.clients[f"s2s_{i}"] = Client(src=s2s_url, download_files=DOWNLOADS_DIR)
108
- if s2s_vim_url is not None:
109
- self.clients["s2s_vim"] = Client(src=s2s_vim_url, download_files=DOWNLOADS_DIR)
110
 
111
  assert len(self.clients) > 0, "At least one client must be specified!"
112
 
@@ -174,7 +165,6 @@ class GradioOSCClient:
174
  sampletemp=temperature,
175
  top_p=top_p,
176
  periodic_p=periodic_p,
177
- periodic_w=1,
178
  dropout=dropout,
179
  stretch_factor=1,
180
  onset_mask_width=onset_mask_width,
@@ -237,154 +227,12 @@ class GradioOSCClient:
237
  return
238
  else:
239
  raise ValueError(f"Unknown client type {client_type}")
240
-
241
- def process_s2s(self, address: str, *args):
242
- # client = self.clients["s2s"]
243
-
244
- if address != "/process":
245
- raise ValueError(f"Unknown address {address}")
246
-
247
- print(f"Processing {address} with args {args}")
248
- # unpack the args
249
- query_id = args[0]
250
- client_type = args[1]
251
- audio_path = Path(args[2])
252
- text_prompt = args[3]
253
- use_control = args[4] == 1
254
- looplength = args[5]
255
- guidance_scale = args[6]
256
- seed = args[7]
257
- median_filter_length = args[8]
258
-
259
- sig = at.AudioSignal(audio_path)
260
- looplength_ms = looplength
261
- # grab the looplength only
262
- # TODO: although I added this,
263
- # the max patch is still configured to crop anything past the looplength off
264
- # so we'll have to change that in order to make an effect.
265
- end_sample = int(looplength_ms * sig.sample_rate / 1000)
266
- sig.samples = sig.samples[..., :end_sample]
267
-
268
- # grab the remainder of the waveform
269
- num_cut_samples = sig.samples.shape[-1] - end_sample
270
- cut_wav = sig.samples[..., -num_cut_samples:]
271
-
272
- # write the file back
273
- sig.write(audio_path)
274
-
275
- # make sure it exists, otherwise send an error message
276
- if not audio_path.exists():
277
- print(f"File {audio_path} does not exist")
278
- self.osc_manager.error(f"File {audio_path} does not exist")
279
- return
280
-
281
-
282
- timer.tick(f"predict-{query_id}")
283
- # NEW API
284
- if use_control and "s2s_vim" in self.clients:
285
- client = self.clients["s2s_vim"]
286
- job = client.submit(
287
- data=handle_file(audio_path),
288
- param_1=-20, # comp threshold
289
- param_2=1, # comp ratio
290
- param_3=seed, # random seed
291
- param_4=text_prompt, # text prompt
292
- param_5=5, # text guid
293
- param_6=1, # ctrl guid
294
- param_7=-1, # t_low
295
- param_8=1, # t_high
296
- param_9=15, # median filt
297
- param_10=True, # use centroid
298
- param_11=True, # use pitch
299
- param_12=True, # use ldns
300
- param_13=0, # transpose (semis)
301
- param_14=0, # pitch shift semis
302
- param_15=0, # pitchiness ofset
303
- param_16=0, # gain db
304
- param_17=100, # num steps
305
- api_name="/generate"
306
- )
307
- else:
308
- client = self.clients[f"s2s_{self.inf_idx % len(self.clients)}"]
309
- self.inf_idx += 1
310
- params = {
311
- 'control_guidance_scale': 1.0,
312
- 'guidance_scale': guidance_scale,
313
- 'logsnr_max': 5.0,
314
- 'logsnr_min': -8,
315
- 'num_seconds': looplength / 1000.,
316
- 'num_steps': 24,
317
- 'rho': 7.0,
318
- 'sampler': 'dpmpp-2m-sde',
319
- 'schedule': 'karras'
320
- }
321
- job = client.submit(
322
- text_prompt=text_prompt,
323
- control_audio=handle_file(audio_path) if use_control else None,
324
- seed=seed,
325
- median_filter_length=median_filter_length,
326
- normalize_db=-16,
327
- duration=looplength / 1000.,
328
- params_str=json.dumps(params),
329
- api_name="/generate_with_params"
330
- )
331
-
332
- while not job.done():
333
- time.sleep(0.1)
334
- status = str(job.status().code)
335
-
336
- if "FINISHED" in status:
337
- status = "STATUS.WAITING"
338
-
339
- self.osc_manager.client.send_message("/progress", [query_id, status])
340
-
341
- result = job.result()
342
- self.osc_manager.client.send_message("/progress", [query_id, "STATUS.FINISHED"])
343
- timer.tock(f"predict-{query_id}")
344
- timer.tick(f"postprocess-{query_id}")
345
- audio_files = list(result[:self.batch_size])
346
- # if each file is missing a .wav at the end, add it
347
- first_audio = audio_files[0]
348
- if not first_audio.endswith(".wav"):
349
- for audio_file in set(audio_files):
350
- if not audio_file.endswith(".wav"):
351
- shutil.move(audio_file, f"{audio_file}.wav")
352
- audio_files = [f"{audio}.wav" for audio in audio_files]
353
-
354
- for audio_file in audio_files:
355
- # load the file, add the cut samples back
356
- sig = at.AudioSignal(audio_file)
357
- sig = sig.to_mono()
358
- sig.samples = torch.cat([sig.samples, cut_wav], dim=-1)
359
- sig.write(audio_file)
360
- seed = result[-1]
361
- timer.tock(f"postprocess-{query_id}")
362
-
363
- # send a message that the process is done
364
- self.osc_manager.log(f"query {query_id} has been processed")
365
- self.osc_manager.client.send_message("/process-result", [query_id] + audio_files)
366
-
367
- # schedule to delete the file after 30 seconds
368
- time.sleep(30)
369
- print("deleting files from query", query_id)
370
- for audio_file in audio_files:
371
- clear_file(audio_file)
372
- # import shutil
373
- print(str(Path(audio_files[0]).parent))
374
- shutil.rmtree(str(Path(audio_files[0]).parent))
375
-
376
-
377
  def gradio_main(
378
- s2s_url: str = None,
379
- s2s_url_2: str = None,
380
- s2s_vim_url: str = None,
381
  vampnet_url: str = None
382
  ):
383
- s2s_urls = [s2s_url, s2s_url_2]
384
  system = GradioOSCClient(
385
  vampnet_url=vampnet_url,
386
- s2s_urls=s2s_urls,
387
- s2s_vim_url=s2s_vim_url,
388
  ip="127.0.0.1", s_port=8003, r_port=8001,
389
  )
390
 
 
89
  ip: str,
90
  s_port: int, r_port: int,
91
  vampnet_url: str = None, # url for vampnet
 
 
92
  ):
93
  self.osc_manager = OSCManager(
94
  ip=ip, s_port=s_port, r_port=r_port,
 
98
  self.clients = {}
99
  if vampnet_url is not None:
100
  self.clients["vampnet"] = Client(src=vampnet_url, download_files=DOWNLOADS_DIR)
 
 
 
 
 
 
 
101
 
102
  assert len(self.clients) > 0, "At least one client must be specified!"
103
 
 
165
  sampletemp=temperature,
166
  top_p=top_p,
167
  periodic_p=periodic_p,
 
168
  dropout=dropout,
169
  stretch_factor=1,
170
  onset_mask_width=onset_mask_width,
 
227
  return
228
  else:
229
  raise ValueError(f"Unknown client type {client_type}")
230
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  def gradio_main(
 
 
 
232
  vampnet_url: str = None
233
  ):
 
234
  system = GradioOSCClient(
235
  vampnet_url=vampnet_url,
 
 
236
  ip="127.0.0.1", s_port=8003, r_port=8001,
237
  )
238
 
vampnet/interface.py CHANGED
@@ -568,7 +568,7 @@ class Interface(torch.nn.Module):
568
  # in subplots, plot z[0] and the mask
569
  # set title to "codes" and "mask"
570
  fig.add_subplot(2, 1, 1)
571
- plt.imshow(z[0].cpu().numpy(), aspect='auto', origin='lower', cmap="tab20")
572
  plt.title("codes")
573
  plt.ylabel("codebook index")
574
  # set the xticks to seconds
 
568
  # in subplots, plot z[0] and the mask
569
  # set title to "codes" and "mask"
570
  fig.add_subplot(2, 1, 1)
571
+ plt.imshow(z[0].cpu().numpy(), aspect='auto', origin='lower', cmap="tab20", interpolation='none')
572
  plt.title("codes")
573
  plt.ylabel("codebook index")
574
  # set the xticks to seconds